Version 2.5.0-dev.3.0

Merge commit '9f13d07670ac27597538309954d3e21b49752748' into dev
diff --git a/BUILD.gn b/BUILD.gn
index c9f1531..5fd2b63 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -16,7 +16,7 @@
   deps = [
     ":runtime",
   ]
-  if (checkout_llvm) {
+  if (defined(checkout_llvm) && checkout_llvm) {
     deps += [
       ":llvm_codegen"
     ]
@@ -126,7 +126,7 @@
 }
 
 group("check_llvm") {
-  if (checkout_llvm) {
+  if (defined(checkout_llvm) && checkout_llvm) {
     deps = [
       "runtime/llvm_codegen/test",
     ]
@@ -134,7 +134,7 @@
 }
 
 group("llvm_codegen") {
-  if (checkout_llvm) {
+  if (defined(checkout_llvm) && checkout_llvm) {
     deps = [
       "runtime/llvm_codegen/codegen",
       "runtime/llvm_codegen/bit",
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a0fafe4..c048c13 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,46 @@
 
 ### Language
 
+The set of operations allowed in constant expressions has been expanded as
+described in
+the [constant update proposal](https://github.com/dart-lang/language/issues/61).
+The control flow and spread collection features shipped in Dart 2.3 are now also
+supported in constants
+as
+[described in the specification here](https://github.com/dart-lang/language/blob/master/accepted/2.3/unified-collections/feature-specification.md#constant-semantics).
+
+Specifically, it is now valid to use the following operations in constant
+expressions under the appropriate conditions:
+  - Casts (`e as T`) and type tests (`e is T`).
+  - Comparisons to `null`, even for types which override the `==` operator.
+  - The `&`, `|`, and `^` binary operators on booleans.
+  - The spread operators (`...` and `...?`).
+  - An `if` element in a collection literal.
+
+```dart
+// Example: these are now valid constants.
+const i = 3;
+const list = [i as int];
+const set = {if (list is List<int>) ...list};
+const map = {if (i is int) i : "int"};
+```
+
+In addition, the semantics of constant evaluation has been changed as follows:
+  - The `&&` operator only evaluates its second operand if the first evaluates
+  to true.
+  - The `||` operator only evaluates its second operand if the first evaluates
+  to false.
+  - The `??` operator only evaluates its second operand if the first evaluates
+  to null.
+  - The conditional operator (`e ? e1 : e2`) only evaluates one of the two
+    branches, depending on the value of the first operand.
+
+```dart
+// Example: x is now a valid constant definition.
+const String s = null;
+const int x = (s == null) ? 0 : s.length;
+```
+
 ### Core libraries
 
 * **Breaking change** [#36900](https://github.com/dart-lang/sdk/issues/36900):
diff --git a/DEPS b/DEPS
index c512f03..b32253a 100644
--- a/DEPS
+++ b/DEPS
@@ -36,7 +36,7 @@
   "chromium_git": "https://chromium.googlesource.com",
   "fuchsia_git": "https://fuchsia.googlesource.com",
 
-  "co19_2_rev": "a6f62f2024492b2c79b741d4b96e67fce31a9830",
+  "co19_2_rev": "d2c051f7537e6fe47c8ccf0bd7a7e84b02010a2a",
 
   # As Flutter does, we use Fuchsia's GN and Clang toolchain. These revision
   # should be kept up to date with the revisions pulled by the Flutter engine.
@@ -135,7 +135,7 @@
   "term_glyph_tag": "1.0.1",
   "test_reflective_loader_tag": "0.1.8",
   "test_tag": "test-v1.6.4",
-  "tflite_native_rev": "7f3748a2adf0e7c246813d0b206396312cbaa0db",
+  "tflite_native_rev": "65889224d8ee32ceaf4f78d8d29fd59750e1b817",
   "typed_data_tag": "1.1.6",
   "unittest_rev": "2b8375bc98bb9dc81c539c91aaea6adce12e1072",
   "usage_tag": "3.4.0",
diff --git a/PATENTS b/PATENT_GRANT
similarity index 100%
rename from PATENTS
rename to PATENT_GRANT
diff --git a/README.md b/README.md
index 288dac5..e0d4071 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,7 @@
 
 Dart is free and open source.
 
-See [LICENSE][license] and [PATENTS][patents].
+See [LICENSE][license] and [PATENT_GRANT][patent_grant].
 
 ## Using Dart
 
@@ -63,4 +63,4 @@
 [dartbug]: http://dartbug.com
 [contrib]: https://github.com/dart-lang/sdk/wiki/Contributing
 [pubsite]: https://pub.dev
-[patents]: https://github.com/dart-lang/sdk/blob/master/PATENTS
+[patent_grant]: https://github.com/dart-lang/sdk/blob/master/PATENT_GRANT
diff --git a/WATCHLISTS b/WATCHLISTS
index 0316d25..1e08225 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -69,8 +69,7 @@
     'dart2js': [ 'johnniwinther@google.com', 'sigmund@google.com',
                  'sra@google.com', 'fishythefish@google.com' ],
     'front_end': [ 'dart-fe-team+reviews@google.com' ],
-    'kernel': [ 'karlklose@google.com', 'jensj@google.com',
-                'alexmarkov@google.com' ],
+    'kernel': [ 'jensj@google.com', 'alexmarkov@google.com' ],
     'messages_review': [ 'dart-uxr+reviews@google.com' ],
     'observatory': [ 'bkonyi@google.com' ],
     'package_vm': [ 'alexmarkov@google.com' ],
diff --git a/pkg/analysis_server/analysis_options.yaml b/pkg/analysis_server/analysis_options.yaml
index 06e27a6..295dd33 100644
--- a/pkg/analysis_server/analysis_options.yaml
+++ b/pkg/analysis_server/analysis_options.yaml
@@ -1,4 +1,7 @@
 analyzer:
+  # This currently finds ~1,200 implicit-casts issues when enabled.
+  # strong-mode:
+  #   implicit-casts: false
   exclude:
     - test/mock_packages/**
 
diff --git a/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart b/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
index 85b9e43..0054ab8 100644
--- a/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
+++ b/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
@@ -55,6 +55,9 @@
   if (kind == engine.ElementKind.CONSTRUCTOR) {
     return ElementKind.CONSTRUCTOR;
   }
+  if (kind == engine.ElementKind.EXTENSION) {
+    return ElementKind.EXTENSION;
+  }
   if (kind == engine.ElementKind.FIELD) {
     return ElementKind.FIELD;
   }
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 6f3daf6..88d6f46 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -744,6 +744,9 @@
   /// Whether to use the Language Server Protocol.
   bool useLanguageServerProtocol = false;
 
+  /// Whether or not to enable ML code completion.
+  bool enableCompletionModel = false;
+
   /// Base path to locate trained completion language model files.
   String completionModelFolder;
 
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index cecf404..ec7b422 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -6,6 +6,7 @@
 import 'dart:ffi' as ffi;
 import 'dart:io';
 import 'dart:math';
+import 'package:path/path.dart' as path;
 
 import 'package:analysis_server/protocol/protocol_constants.dart'
     show PROTOCOL_VERSION;
@@ -287,6 +288,11 @@
   static const String USE_LSP = "lsp";
 
   /**
+   * Whether or not to enable ML ranking for code completion.
+   */
+  static const String ENABLE_COMPLETION_MODEL = "enable-completion-model";
+
+  /**
    * The path on disk to a directory containing language model files for smart
    * code completion.
    */
@@ -349,6 +355,20 @@
     analysisServerOptions.useLanguageServerProtocol = results[USE_LSP];
     analysisServerOptions.completionModelFolder =
         results[COMPLETION_MODEL_FOLDER];
+    if (results[ENABLE_COMPLETION_MODEL] &&
+        analysisServerOptions.completionModelFolder == null) {
+      // The user has enabled ML code completion without explicitly setting
+      // a model for us to choose, so use the default one. We need to walk over
+      // from $SDK/bin/snapshots/analysis_server.dart.snapshot to
+      // $SDK/model/lexeme.
+      analysisServerOptions.completionModelFolder = path.join(
+          File.fromUri(Platform.script).parent.path,
+          '..',
+          '..',
+          'model',
+          'lexeme');
+    }
+
     AnalysisDriver.useSummary2 = results[USE_SUMMARY2];
 
     bool disableAnalyticsForSession = results[SUPPRESS_ANALYTICS_FLAG];
@@ -617,25 +637,27 @@
       SocketServer socketServer,
       LspSocketServer lspSocketServer,
       AnalysisServerOptions analysisServerOptions) {
-    if (analysisServerOptions.completionModelFolder != null &&
-        ffi.sizeOf<ffi.IntPtr>() != 4) {
-      // Start completion model isolate if this is a 64 bit system and
-      // analysis server was configured to load a language model on disk.
-      CompletionRanking.instance =
-          CompletionRanking(analysisServerOptions.completionModelFolder);
-      CompletionRanking.instance.start().catchError((error) {
-        // Disable smart ranking if model startup fails.
-        analysisServerOptions.completionModelFolder = null;
-        CompletionRanking.instance = null;
-        if (socketServer != null) {
-          socketServer.analysisServer.sendServerErrorNotification(
-              'Failed to start ranking model isolate', error, error.stackTrace);
-        } else {
-          lspSocketServer.analysisServer.sendServerErrorNotification(
-              'Failed to start ranking model isolate', error, error.stackTrace);
-        }
-      });
+    if (analysisServerOptions.completionModelFolder == null ||
+        ffi.sizeOf<ffi.IntPtr>() == 4) {
+      return;
     }
+
+    // Start completion model isolate if this is a 64 bit system and
+    // analysis server was configured to load a language model on disk.
+    CompletionRanking.instance =
+        CompletionRanking(analysisServerOptions.completionModelFolder);
+    CompletionRanking.instance.start().catchError((error) {
+      // Disable smart ranking if model startup fails.
+      analysisServerOptions.completionModelFolder = null;
+      CompletionRanking.instance = null;
+      if (socketServer != null) {
+        socketServer.analysisServer.sendServerErrorNotification(
+            'Failed to start ranking model isolate', error, error.stackTrace);
+      } else {
+        lspSocketServer.analysisServer.sendServerErrorNotification(
+            'Failed to start ranking model isolate', error, error.stackTrace);
+      }
+    });
   }
 
   /**
@@ -762,6 +784,8 @@
         help: "Whether to enable parsing via the Fasta parser");
     parser.addFlag(USE_LSP,
         defaultsTo: false, help: "Whether to use the Language Server Protocol");
+    parser.addFlag(ENABLE_COMPLETION_MODEL,
+        help: "Whether or not to turn on ML ranking for code completion");
     parser.addOption(COMPLETION_MODEL_FOLDER,
         help: "[path] path to the location of a code completion model");
     parser.addFlag(USE_SUMMARY2,
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
index fecfc80..27b6639 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
@@ -15,6 +15,7 @@
 import 'package:analysis_server/src/services/completion/dart/common_usage_sorter.dart';
 import 'package:analysis_server/src/services/completion/dart/completion_ranking.dart';
 import 'package:analysis_server/src/services/completion/dart/contribution_sorter.dart';
+import 'package:analysis_server/src/services/completion/dart/extension_member_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/field_formal_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/imported_reference_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/inherited_reference_contributor.dart';
@@ -110,6 +111,7 @@
     List<DartCompletionContributor> contributors = <DartCompletionContributor>[
       new ArgListContributor(),
       new CombinatorContributor(),
+      new ExtensionMemberContributor(),
       new FieldFormalContributor(),
       new InheritedReferenceContributor(),
       new KeywordContributor(),
@@ -179,6 +181,7 @@
     performance.logStartTime(SORT_TAG);
     await contributionSorter.sort(dartRequest, suggestions);
     if (ranking != null) {
+      request.checkAborted();
       suggestions = await ranking.rerank(
           probabilityFuture,
           suggestions,
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_ranking.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_ranking.dart
index 5c7fde6..5858406 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_ranking.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_ranking.dart
@@ -76,6 +76,7 @@
       return Future.value(null);
     }
 
+    request.checkAborted();
     final response = await makeRequest('predict', query);
     return response['data'];
   }
@@ -116,10 +117,7 @@
     if (testInsideQuotes(request)) {
       // If completion is requested inside of quotes, remove any suggestions
       // which are not string literal.
-      entries = entries
-          .where((MapEntry entry) =>
-              isStringLiteral(entry.key) && isNotWhitespace(entry.key))
-          .toList();
+      entries = selectStringLiterals(entries);
     } else if (request.opType.includeVarNameSuggestions &&
         suggestions.every((CompletionSuggestion suggestion) =>
             suggestion.kind == CompletionSuggestionKind.IDENTIFIER)) {
@@ -158,8 +156,10 @@
         } else {
           suggestions
               .add(createCompletionSuggestion(entry.key, featureSet, high--));
-          includedSuggestionRelevanceTags
-              .add(IncludedSuggestionRelevanceTag(entry.key, relevance));
+          if (includedSuggestionRelevanceTags != null) {
+            includedSuggestionRelevanceTags
+                .add(IncludedSuggestionRelevanceTag(entry.key, relevance));
+          }
         }
       } else if (completionSuggestions.isNotEmpty ||
           includedSuggestions.isNotEmpty) {
@@ -174,8 +174,10 @@
         final relevance = low--;
         suggestions
             .add(createCompletionSuggestion(entry.key, featureSet, relevance));
-        includedSuggestionRelevanceTags
-            .add(IncludedSuggestionRelevanceTag(entry.key, relevance));
+        if (includedSuggestionRelevanceTags != null) {
+          includedSuggestionRelevanceTags
+              .add(IncludedSuggestionRelevanceTag(entry.key, relevance));
+        }
       }
     });
 
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_ranking_internal.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_ranking_internal.dart
index cb8c923..b552cf6 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_ranking_internal.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_ranking_internal.dart
@@ -160,7 +160,9 @@
   }
 
   final result = List<String>();
-  for (var size = 0; size < n && !token.isEof; token = token.previous) {
+  for (var size = 0;
+      size < n && token != null && !token.isEof;
+      token = token.previous) {
     if (!token.isSynthetic && token is! ErrorToken) {
       result.add(token.lexeme);
       size += 1;
@@ -180,3 +182,21 @@
 
   return tag.substring(index + 2);
 }
+
+/// Filters the entries list down to only those which represent string literals
+/// and then strips quotes.
+List<MapEntry<String, double>> selectStringLiterals(List<MapEntry> entries) {
+  return entries
+      .where((MapEntry entry) =>
+          isStringLiteral(entry.key) && isNotWhitespace(entry.key))
+      .map<MapEntry<String, double>>(
+          (MapEntry entry) => MapEntry(trimQuotes(entry.key), entry.value))
+      .toList();
+}
+
+String trimQuotes(String input) {
+  final result = input[0] == '\'' ? input.substring(1) : input;
+  return result[result.length - 1] == '\''
+      ? result.substring(0, result.length - 1)
+      : result;
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/extension_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/extension_member_contributor.dart
new file mode 100644
index 0000000..ab489ad
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/extension_member_contributor.dart
@@ -0,0 +1,114 @@
+// 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.
+
+import 'dart:async';
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+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/src/dart/element/type_algebra.dart';
+import 'package:analyzer/src/dart/resolver/scope.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/type_system.dart';
+
+import '../../../protocol_server.dart' show CompletionSuggestion;
+
+/// A contributor for calculating suggestions based on the members of
+/// extensions.
+class ExtensionMemberContributor extends DartCompletionContributor {
+  MemberSuggestionBuilder builder;
+
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request) async {
+    LibraryElement containingLibrary = request.libraryElement;
+    // Gracefully degrade if the library element is not resolved
+    // e.g. detached part file or source change
+    if (containingLibrary == null) {
+      return const <CompletionSuggestion>[];
+    }
+
+    // Recompute the target since resolution may have changed it.
+    Expression expression = request.dotTarget;
+    if (expression == null || expression.isSynthetic) {
+      return const <CompletionSuggestion>[];
+    }
+    if (expression is Identifier) {
+      Element elem = expression.staticElement;
+      if (elem is ClassElement) {
+        // Suggestions provided by StaticMemberContributor
+        return const <CompletionSuggestion>[];
+      }
+      if (elem is PrefixElement) {
+        // Suggestions provided by LibraryMemberContributor
+        return const <CompletionSuggestion>[];
+      }
+    }
+    builder = MemberSuggestionBuilder(containingLibrary);
+    if (expression is ExtensionOverride) {
+      _addInstanceMembers(expression.staticElement);
+    } else {
+      var type = expression.staticType;
+      LibraryScope nameScope = new LibraryScope(containingLibrary);
+      for (var extension in nameScope.extensions) {
+        var typeSystem = containingLibrary.context.typeSystem;
+        var typeProvider = containingLibrary.context.typeProvider;
+        var extendedType =
+            _resolveExtendedType(typeSystem, typeProvider, extension, type);
+        if (extendedType != null &&
+            typeSystem.isSubtypeOf(type, extendedType)) {
+          // TODO(brianwilkerson) We might want to apply the substitution to the
+          //  members of the extension for display purposes.
+          _addInstanceMembers(extension);
+        }
+      }
+      expression.staticType;
+    }
+    return builder.suggestions.toList();
+  }
+
+  void _addInstanceMembers(ExtensionElement extension) {
+    for (MethodElement method in extension.methods) {
+      if (!method.isStatic) {
+        builder.addSuggestion(method);
+      }
+    }
+    for (PropertyAccessorElement accessor in extension.accessors) {
+      if (!accessor.isStatic) {
+        builder.addSuggestion(accessor);
+      }
+    }
+  }
+
+  /// Use the [typeProvider], [typeSystem] and the [type] of the object being
+  /// extended to compute the actual type extended by the [extension]. Return
+  /// the computed type, or `null` if the type cannot be computed.
+  DartType _resolveExtendedType(TypeSystem typeSystem,
+      TypeProvider typeProvider, ExtensionElement extension, DartType type) {
+    var typeParameters = extension.typeParameters;
+    var inferrer = GenericInferrer(
+      typeProvider,
+      typeSystem,
+      typeParameters,
+    );
+    inferrer.constrainArgument(
+      type,
+      extension.extendedType,
+      'extendedType',
+    );
+    var typeArguments = inferrer.infer(typeParameters, failAtError: true);
+    if (typeArguments == null) {
+      return null;
+    }
+    var substitution = Substitution.fromPairs(
+      typeParameters,
+      typeArguments,
+    );
+    return substitution.substituteType(
+      extension.extendedType,
+    );
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/language_model.dart b/pkg/analysis_server/lib/src/services/completion/dart/language_model.dart
index 71c209a..67a4ebc 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/language_model.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/language_model.dart
@@ -105,6 +105,6 @@
 
     // Get tokens with scores, limiting the length.
     return Map.fromEntries(entries.sublist(0, completions))
-        .map((k, v) => MapEntry(_idx2word[k], v));
+        .map((k, v) => MapEntry(_idx2word[k].replaceAll('"', '\''), v));
   }
 }
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 5d4dfaf..327aca1 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
@@ -2,6 +2,8 @@
 // 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:collection';
+
 import 'package:analysis_server/src/protocol_server.dart' as protocol;
 import 'package:analysis_server/src/protocol_server.dart'
     hide Element, ElementKind;
@@ -12,6 +14,8 @@
 import 'package:analyzer/dart/element/visitor.dart';
 import 'package:analyzer/src/util/comment.dart';
 
+import '../../../protocol_server.dart' show CompletionSuggestion;
+
 /**
  * Return a suggestion based upon the given element or `null` if a suggestion
  * is not appropriate for the given element.
@@ -238,3 +242,124 @@
     }
   }
 }
+
+/**
+ * This class provides suggestions based upon the visible instance members in
+ * an interface type.
+ */
+class MemberSuggestionBuilder {
+  /**
+   * Enumerated value indicating that we have not generated any completions for
+   * a given identifier yet.
+   */
+  static const int _COMPLETION_TYPE_NONE = 0;
+
+  /**
+   * Enumerated value indicating that we have generated a completion for a
+   * getter.
+   */
+  static const int _COMPLETION_TYPE_GETTER = 1;
+
+  /**
+   * Enumerated value indicating that we have generated a completion for a
+   * setter.
+   */
+  static const int _COMPLETION_TYPE_SETTER = 2;
+
+  /**
+   * Enumerated value indicating that we have generated a completion for a
+   * field, a method, or a getter/setter pair.
+   */
+  static const int _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET = 3;
+
+  /**
+   * The library containing the unit in which the completion is requested.
+   */
+  final LibraryElement containingLibrary;
+
+  /**
+   * Map indicating, for each possible completion identifier, whether we have
+   * already generated completions for a getter, setter, or both.  The "both"
+   * case also handles the case where have generated a completion for a method
+   * or a field.
+   *
+   * Note: the enumerated values stored in this map are intended to be bitwise
+   * compared.
+   */
+  final Map<String, int> _completionTypesGenerated = new HashMap<String, int>();
+
+  /**
+   * Map from completion identifier to completion suggestion
+   */
+  final Map<String, CompletionSuggestion> _suggestionMap =
+      <String, CompletionSuggestion>{};
+
+  MemberSuggestionBuilder(this.containingLibrary);
+
+  Iterable<CompletionSuggestion> get suggestions => _suggestionMap.values;
+
+  /**
+   * Add a suggestion based upon the given element, provided that it is not
+   * shadowed by a previously added suggestion.
+   */
+  void addSuggestion(Element element,
+      {int relevance = DART_RELEVANCE_DEFAULT}) {
+    if (element.isPrivate) {
+      if (element.library != containingLibrary) {
+        // Do not suggest private members for imported libraries
+        return;
+      }
+    }
+    String identifier = element.displayName;
+
+    if (relevance == DART_RELEVANCE_DEFAULT && identifier != null) {
+      // Decrease relevance of suggestions starting with $
+      // https://github.com/dart-lang/sdk/issues/27303
+      if (identifier.startsWith(r'$')) {
+        relevance = DART_RELEVANCE_LOW;
+      }
+    }
+
+    int alreadyGenerated = _completionTypesGenerated.putIfAbsent(
+        identifier, () => _COMPLETION_TYPE_NONE);
+    if (element is MethodElement) {
+      // Anything shadows a method.
+      if (alreadyGenerated != _COMPLETION_TYPE_NONE) {
+        return;
+      }
+      _completionTypesGenerated[identifier] =
+          _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET;
+    } else if (element is PropertyAccessorElement) {
+      if (element.isGetter) {
+        // Getters, fields, and methods shadow a getter.
+        if ((alreadyGenerated & _COMPLETION_TYPE_GETTER) != 0) {
+          return;
+        }
+        _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_GETTER;
+      } else {
+        // Setters, fields, and methods shadow a setter.
+        if ((alreadyGenerated & _COMPLETION_TYPE_SETTER) != 0) {
+          return;
+        }
+        _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_SETTER;
+      }
+    } else if (element is FieldElement) {
+      // Fields and methods shadow a field.  A getter/setter pair shadows a
+      // field, but a getter or setter by itself doesn't.
+      if (alreadyGenerated == _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET) {
+        return;
+      }
+      _completionTypesGenerated[identifier] =
+          _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET;
+    } else {
+      // Unexpected element type; skip it.
+      assert(false);
+      return;
+    }
+    CompletionSuggestion suggestion =
+        createSuggestion(element, relevance: relevance);
+    if (suggestion != null) {
+      _suggestionMap[suggestion.completion] = suggestion;
+    }
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
index 909a158..ca30c558 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
@@ -236,56 +236,9 @@
  * This class provides suggestions based upon the visible instance members in
  * an interface type.
  */
-class _SuggestionBuilder {
-  /**
-   * Enumerated value indicating that we have not generated any completions for
-   * a given identifier yet.
-   */
-  static const int _COMPLETION_TYPE_NONE = 0;
-
-  /**
-   * Enumerated value indicating that we have generated a completion for a
-   * getter.
-   */
-  static const int _COMPLETION_TYPE_GETTER = 1;
-
-  /**
-   * Enumerated value indicating that we have generated a completion for a
-   * setter.
-   */
-  static const int _COMPLETION_TYPE_SETTER = 2;
-
-  /**
-   * Enumerated value indicating that we have generated a completion for a
-   * field, a method, or a getter/setter pair.
-   */
-  static const int _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET = 3;
-
-  /**
-   * The library containing the unit in which the completion is requested.
-   */
-  final LibraryElement containingLibrary;
-
-  /**
-   * Map indicating, for each possible completion identifier, whether we have
-   * already generated completions for a getter, setter, or both.  The "both"
-   * case also handles the case where have generated a completion for a method
-   * or a field.
-   *
-   * Note: the enumerated values stored in this map are intended to be bitwise
-   * compared.
-   */
-  final Map<String, int> _completionTypesGenerated = new HashMap<String, int>();
-
-  /**
-   * Map from completion identifier to completion suggestion
-   */
-  final Map<String, CompletionSuggestion> _suggestionMap =
-      <String, CompletionSuggestion>{};
-
-  _SuggestionBuilder(this.containingLibrary);
-
-  Iterable<CompletionSuggestion> get suggestions => _suggestionMap.values;
+class _SuggestionBuilder extends MemberSuggestionBuilder {
+  _SuggestionBuilder(LibraryElement containingLibrary)
+      : super(containingLibrary);
 
   /**
    * Return completion suggestions for 'dot' completions on the given [type].
@@ -311,7 +264,7 @@
         if (!method.isStatic) {
           // Boost the relevance of a super expression
           // calling a method of the same name as the containing method
-          _addSuggestion(method,
+          addSuggestion(method,
               relevance: method.name == containingMethodName
                   ? DART_RELEVANCE_HIGH
                   : DART_RELEVANCE_DEFAULT);
@@ -322,10 +275,10 @@
           if (propertyAccessor.isSynthetic) {
             // Avoid visiting a field twice
             if (propertyAccessor.isGetter) {
-              _addSuggestion(propertyAccessor.variable);
+              addSuggestion(propertyAccessor.variable);
             }
           } else {
-            _addSuggestion(propertyAccessor);
+            addSuggestion(propertyAccessor);
           }
         }
       }
@@ -333,71 +286,6 @@
   }
 
   /**
-   * Add a suggestion based upon the given element, provided that it is not
-   * shadowed by a previously added suggestion.
-   */
-  void _addSuggestion(Element element,
-      {int relevance = DART_RELEVANCE_DEFAULT}) {
-    if (element.isPrivate) {
-      if (element.library != containingLibrary) {
-        // Do not suggest private members for imported libraries
-        return;
-      }
-    }
-    String identifier = element.displayName;
-
-    if (relevance == DART_RELEVANCE_DEFAULT && identifier != null) {
-      // Decrease relevance of suggestions starting with $
-      // https://github.com/dart-lang/sdk/issues/27303
-      if (identifier.startsWith(r'$')) {
-        relevance = DART_RELEVANCE_LOW;
-      }
-    }
-
-    int alreadyGenerated = _completionTypesGenerated.putIfAbsent(
-        identifier, () => _COMPLETION_TYPE_NONE);
-    if (element is MethodElement) {
-      // Anything shadows a method.
-      if (alreadyGenerated != _COMPLETION_TYPE_NONE) {
-        return;
-      }
-      _completionTypesGenerated[identifier] =
-          _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET;
-    } else if (element is PropertyAccessorElement) {
-      if (element.isGetter) {
-        // Getters, fields, and methods shadow a getter.
-        if ((alreadyGenerated & _COMPLETION_TYPE_GETTER) != 0) {
-          return;
-        }
-        _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_GETTER;
-      } else {
-        // Setters, fields, and methods shadow a setter.
-        if ((alreadyGenerated & _COMPLETION_TYPE_SETTER) != 0) {
-          return;
-        }
-        _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_SETTER;
-      }
-    } else if (element is FieldElement) {
-      // Fields and methods shadow a field.  A getter/setter pair shadows a
-      // field, but a getter or setter by itself doesn't.
-      if (alreadyGenerated == _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET) {
-        return;
-      }
-      _completionTypesGenerated[identifier] =
-          _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET;
-    } else {
-      // Unexpected element type; skip it.
-      assert(false);
-      return;
-    }
-    CompletionSuggestion suggestion =
-        createSuggestion(element, relevance: relevance);
-    if (suggestion != null) {
-      _suggestionMap[suggestion.completion] = suggestion;
-    }
-  }
-
-  /**
    * Get a list of [InterfaceType]s that should be searched to find the
    * possible completions for an object having type [type].
    */
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index 774612b..d2cd3f5 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -342,13 +342,16 @@
       await _addFix_updateSdkConstraints('2.2.0');
     }
     if (errorCode == HintCode.SDK_VERSION_AS_EXPRESSION_IN_CONST_CONTEXT ||
-        errorCode == HintCode.SDK_VERSION_BOOL_OPERATOR ||
+        errorCode == HintCode.SDK_VERSION_BOOL_OPERATOR_IN_CONST_CONTEXT ||
         errorCode == HintCode.SDK_VERSION_EQ_EQ_OPERATOR_IN_CONST_CONTEXT ||
         errorCode == HintCode.SDK_VERSION_GT_GT_GT_OPERATOR ||
         errorCode == HintCode.SDK_VERSION_IS_EXPRESSION_IN_CONST_CONTEXT ||
         errorCode == HintCode.SDK_VERSION_UI_AS_CODE) {
       await _addFix_updateSdkConstraints('2.2.2');
     }
+    if (errorCode == HintCode.SDK_VERSION_EXTENSION_METHODS) {
+      await _addFix_updateSdkConstraints('2.6.0');
+    }
     if (errorCode == HintCode.TYPE_CHECK_IS_NOT_NULL) {
       await _addFix_isNotNull();
     }
@@ -2103,11 +2106,7 @@
     String prefix = utils.getNodePrefix(target);
     // compute type
     DartType type = _inferUndefinedExpressionType(node);
-    if (!(type == null ||
-        type is InterfaceType ||
-        type is FunctionType &&
-            type.element != null &&
-            !type.element.isSynthetic)) {
+    if (!(type == null || type is InterfaceType || type is FunctionType)) {
       return;
     }
     // build variable declaration source
@@ -4012,21 +4011,18 @@
    * the given [element].
    */
   Future<void> _addFix_useStaticAccess(AstNode target, Element element) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
-    Element declaringElement = element.enclosingElement;
-    if (declaringElement is ClassElement) {
-      DartType declaringType = declaringElement.type;
-      var changeBuilder = _newDartChangeBuilder();
-      await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-        // replace "target" with class name
-        builder.addReplacement(range.node(target), (DartEditBuilder builder) {
-          builder.writeType(declaringType);
-        });
+    var declaringElement = element.enclosingElement;
+    var changeBuilder = _newDartChangeBuilder();
+    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+      builder.addReplacement(range.node(target), (DartEditBuilder builder) {
+        builder.writeReference(declaringElement);
       });
-      _addFixFromBuilder(changeBuilder, DartFixKind.CHANGE_TO_STATIC_ACCESS,
-          args: [declaringType]);
-    }
+    });
+    _addFixFromBuilder(
+      changeBuilder,
+      DartFixKind.CHANGE_TO_STATIC_ACCESS,
+      args: [declaringElement.name],
+    );
   }
 
   Future<void> _addFix_useStaticAccess_method() async {
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
index c88d8a5..233123c 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
@@ -15,6 +15,7 @@
 import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart';
 import 'package:analysis_server/src/services/refactoring/rename_class_member.dart';
 import 'package:analysis_server/src/services/refactoring/rename_unit_member.dart';
+import 'package:analysis_server/src/services/refactoring/visible_ranges_computer.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/analysis/results.dart';
@@ -39,7 +40,8 @@
   Element element = node.staticElement;
   if (element is LocalVariableElement ||
       element is ParameterElement ||
-      element is FunctionElement && element.visibleRange != null) {
+      element is FunctionElement &&
+          element.enclosingElement is! CompilationUnitElement) {
     return element;
   }
   return null;
@@ -93,6 +95,11 @@
   final List<int> lengths = <int>[];
 
   /**
+   * The map of local elements to their visibility ranges.
+   */
+  Map<LocalElement, SourceRange> _visibleRangeMap;
+
+  /**
    * The map of local names to their visibility ranges.
    */
   final Map<String, List<SourceRange>> _localNames =
@@ -733,8 +740,13 @@
     _parameterReferencesMap.clear();
     RefactoringStatus result = new RefactoringStatus();
     List<VariableElement> assignedUsedVariables = [];
-    resolveResult.unit
-        .accept(new _InitializeParametersVisitor(this, assignedUsedVariables));
+
+    var unit = resolveResult.unit;
+    _visibleRangeMap = VisibleRangesComputer.forNode(unit);
+    unit.accept(
+      _InitializeParametersVisitor(this, assignedUsedVariables),
+    );
+
     // single expression
     if (_selectionExpression != null) {
       _returnType = _selectionExpression.staticType;
@@ -1294,7 +1306,7 @@
       // declared local elements
       if (node.inDeclarationContext()) {
         ref._localNames.putIfAbsent(name, () => <SourceRange>[]);
-        ref._localNames[name].add(element.visibleRange);
+        ref._localNames[name].add(ref._visibleRangeMap[element]);
       }
     } else {
       // unqualified non-local names
diff --git a/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart b/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
index 5a1634f..b487d2d 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
@@ -10,6 +10,7 @@
 import 'package:analysis_server/src/services/correction/util.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart';
+import 'package:analysis_server/src/services/refactoring/visible_ranges_computer.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analyzer/dart/analysis/results.dart';
@@ -156,13 +157,12 @@
   {
     SourceRange localsRange = _getLocalsConflictingRange(node);
     AstNode enclosingExecutable = getEnclosingExecutableNode(node);
-    List<LocalElement> elements = getDefinedLocalElements(enclosingExecutable);
-    for (LocalElement element in elements) {
-      SourceRange elementRange = element.visibleRange;
-      if (elementRange != null && elementRange.intersects(localsRange)) {
+    var visibleRangeMap = VisibleRangesComputer.forNode(enclosingExecutable);
+    visibleRangeMap.forEach((element, elementRange) {
+      if (elementRange.intersects(localsRange)) {
         result.add(element.displayName);
       }
-    }
+    });
   }
   // fields
   {
diff --git a/pkg/analysis_server/lib/src/services/refactoring/move_file.dart b/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
index 8bb80c3..5bc5afa 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
@@ -16,7 +16,8 @@
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
 import 'package:path/path.dart' as pathos;
 
 /**
@@ -69,19 +70,21 @@
 
   @override
   Future<SourceChange> createChange() async {
-    final DartChangeBuilder changeBuilder =
-        new DartChangeBuilder(driver.currentSession);
+    final ChangeBuilder changeBuilder = new ChangeBuilder();
     final CompilationUnitElement element = resolvedUnit.unit.declaredElement;
     if (element == null) {
       return changeBuilder.sourceChange;
     }
-    final LibraryElement libraryElement = element.library;
+
+    var libraryElement = element.library;
+    var libraryPath = libraryElement.source.fullName;
 
     // If this element is a library, update outgoing references inside the file.
     if (element == libraryElement.definingCompilationUnit) {
       // Handle part-of directives in this library
       final ResolvedLibraryResult libraryResult = await driver.currentSession
           .getResolvedLibraryByElement(libraryElement);
+      ResolvedUnitResult definingUnitResult;
       for (ResolvedUnitResult result in libraryResult.units) {
         if (result.isPart) {
           Iterable<PartOfDirective> partOfs = result.unit.directives
@@ -103,15 +106,19 @@
             });
           }
         }
+        if (result.path == libraryPath) {
+          definingUnitResult = result;
+        }
       }
 
-      await changeBuilder.addFileEdit(libraryElement.source.fullName,
-          (builder) {
+      await changeBuilder.addFileEdit(definingUnitResult.path, (builder) {
         final String oldDir = pathContext.dirname(oldFile);
         final String newDir = pathContext.dirname(newFile);
-        _updateUriReferences(builder, libraryElement.imports, oldDir, newDir);
-        _updateUriReferences(builder, libraryElement.exports, oldDir, newDir);
-        _updateUriReferences(builder, libraryElement.parts, oldDir, newDir);
+        for (var directive in definingUnitResult.unit.directives) {
+          if (directive is UriBasedDirective) {
+            _updateUriReference(builder, directive, oldDir, newDir);
+          }
+        }
       });
     } else {
       // Otherwise, we need to update any relative part-of references.
@@ -198,25 +205,14 @@
     return true;
   }
 
-  void _updateUriReference(DartFileEditBuilder builder,
-      UriReferencedElement element, String oldDir, String newDir) {
-    if (!element.isSynthetic) {
-      String elementUri = element.uri;
-      if (_isRelativeUri(elementUri)) {
-        String elementPath = pathContext.join(oldDir, elementUri);
-        String newUri = _getRelativeUri(elementPath, newDir);
-        int uriOffset = element.uriOffset;
-        int uriLength = element.uriEnd - uriOffset;
-        builder.addSimpleReplacement(
-            new SourceRange(uriOffset, uriLength), "'$newUri'");
-      }
-    }
-  }
-
-  void _updateUriReferences(DartFileEditBuilder builder,
-      List<UriReferencedElement> elements, String oldDir, String newDir) {
-    for (UriReferencedElement element in elements) {
-      _updateUriReference(builder, element, oldDir, newDir);
+  void _updateUriReference(FileEditBuilder builder, UriBasedDirective directive,
+      String oldDir, String newDir) {
+    var uriNode = directive.uri;
+    var uriValue = uriNode.stringValue;
+    if (_isRelativeUri(uriValue)) {
+      String elementPath = pathContext.join(oldDir, uriValue);
+      String newUri = _getRelativeUri(elementPath, newDir);
+      builder.addSimpleReplacement(range.node(uriNode), "'$newUri'");
     }
   }
 }
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
index 4f8afd4..645e6de 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
@@ -12,6 +12,7 @@
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart';
 import 'package:analysis_server/src/services/refactoring/rename.dart';
+import 'package:analysis_server/src/services/refactoring/visible_ranges_computer.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analyzer/dart/analysis/session.dart';
@@ -257,22 +258,25 @@
   }
 
   Future<_MatchShadowedByLocal> _getShadowingLocalElement() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var localElementMap = <CompilationUnitElement, List<LocalElement>>{};
-    Future<List<LocalElement>> getLocalElements(Element element) async {
-      // TODO(brianwilkerson) Determine whether this await is necessary.
-      await null;
+    var visibleRangeMap = <LocalElement, SourceRange>{};
 
-      var resolvedUnit = await sessionHelper.getResolvedUnitByElement(element);
-      var unitElement = resolvedUnit.unit.declaredElement;
+    Future<List<LocalElement>> getLocalElements(Element element) async {
+      var unitElement = element.getAncestor((e) => e is CompilationUnitElement);
       var localElements = localElementMap[unitElement];
+
       if (localElements == null) {
+        var result = await sessionHelper.getResolvedUnitByElement(element);
+        var unit = result.unit;
+
         var collector = new _LocalElementsCollector(name);
-        resolvedUnit.unit.accept(collector);
+        unit.accept(collector);
         localElements = collector.elements;
         localElementMap[unitElement] = localElements;
+
+        visibleRangeMap.addAll(VisibleRangesComputer.forNode(unit));
       }
+
       return localElements;
     }
 
@@ -284,7 +288,7 @@
       // Check local elements that might shadow the reference.
       var localElements = await getLocalElements(match.element);
       for (LocalElement localElement in localElements) {
-        SourceRange elementRange = localElement.visibleRange;
+        SourceRange elementRange = visibleRangeMap[localElement];
         if (elementRange != null &&
             elementRange.intersects(match.sourceRange)) {
           return new _MatchShadowedByLocal(match, localElement);
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart
index 7fac53a..6d1f602 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart
@@ -11,6 +11,7 @@
 import 'package:analysis_server/src/services/refactoring/naming_conventions.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analysis_server/src/services/refactoring/rename.dart';
+import 'package:analysis_server/src/services/refactoring/visible_ranges_computer.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
@@ -47,14 +48,19 @@
 
   @override
   Future<RefactoringStatus> checkFinalConditions() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     RefactoringStatus result = new RefactoringStatus();
     await _prepareElements();
     for (LocalElement element in elements) {
       var resolvedUnit = await sessionHelper.getResolvedUnitByElement(element);
       var unit = resolvedUnit.unit;
-      unit.accept(new _ConflictValidatorVisitor(result, newName, element));
+      unit.accept(
+        _ConflictValidatorVisitor(
+          result,
+          newName,
+          element,
+          VisibleRangesComputer.forNode(unit),
+        ),
+      );
     }
     return result;
   }
@@ -92,8 +98,6 @@
    * Fills [elements] with [Element]s to rename.
    */
   Future _prepareElements() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     Element element = this.element;
     if (element is ParameterElement && element.isNamed) {
       elements = await getHierarchyNamedParameters(searchEngine, element);
@@ -107,9 +111,15 @@
   final RefactoringStatus result;
   final String newName;
   final LocalElement target;
+  final Map<Element, SourceRange> visibleRangeMap;
   final Set<Element> conflictingLocals = new Set<Element>();
 
-  _ConflictValidatorVisitor(this.result, this.newName, this.target);
+  _ConflictValidatorVisitor(
+    this.result,
+    this.newName,
+    this.target,
+    this.visibleRangeMap,
+  );
 
   @override
   visitSimpleIdentifier(SimpleIdentifier node) {
@@ -127,7 +137,7 @@
         return;
       }
       // Shadowing by the target element.
-      SourceRange targetRange = target.visibleRange;
+      SourceRange targetRange = _getVisibleRange(target);
       if (targetRange != null &&
           targetRange.contains(node.offset) &&
           !node.isQualified &&
@@ -144,13 +154,17 @@
     }
   }
 
+  SourceRange _getVisibleRange(LocalElement element) {
+    return visibleRangeMap[element];
+  }
+
   /**
    * Returns whether [element] and [target] are visible together.
    */
   bool _isVisibleWithTarget(Element element) {
     if (element is LocalElement) {
-      SourceRange targetRange = target.visibleRange;
-      SourceRange elementRange = element.visibleRange;
+      SourceRange targetRange = _getVisibleRange(target);
+      SourceRange elementRange = _getVisibleRange(element);
       return targetRange != null &&
           elementRange != null &&
           elementRange.intersects(targetRange);
diff --git a/pkg/analysis_server/lib/src/services/refactoring/visible_ranges_computer.dart b/pkg/analysis_server/lib/src/services/refactoring/visible_ranges_computer.dart
new file mode 100644
index 0000000..f894bee
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/refactoring/visible_ranges_computer.dart
@@ -0,0 +1,89 @@
+// 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.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+/// Computer of local elements and source ranges in which they are visible.
+class VisibleRangesComputer extends GeneralizingAstVisitor<void> {
+  final Map<LocalElement, SourceRange> _map = {};
+
+  @override
+  void visitCatchClause(CatchClause node) {
+    _addLocalVariable(node, node.exceptionParameter?.staticElement);
+    _addLocalVariable(node, node.stackTraceParameter?.staticElement);
+    node.body.accept(this);
+  }
+
+  @override
+  void visitFormalParameter(FormalParameter node) {
+    var element = node.declaredElement;
+    if (element is ParameterElement) {
+      var body = _getFunctionBody(node);
+      if (body is BlockFunctionBody || body is ExpressionFunctionBody) {
+        _map[element] = range.node(body);
+      }
+    }
+  }
+
+  @override
+  void visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
+    var loop = node.parent;
+    for (var variable in node.variables.variables) {
+      _addLocalVariable(loop, variable.declaredElement);
+      variable.initializer?.accept(this);
+    }
+  }
+
+  @override
+  void visitFunctionDeclaration(FunctionDeclaration node) {
+    var block = node.parent?.parent;
+    if (block is Block) {
+      var element = node.declaredElement as FunctionElement;
+      _map[element] = range.node(block);
+    }
+
+    super.visitFunctionDeclaration(node);
+  }
+
+  @override
+  void visitVariableDeclarationStatement(VariableDeclarationStatement node) {
+    var block = node.parent;
+    for (var variable in node.variables.variables) {
+      _addLocalVariable(block, variable.declaredElement);
+      variable.initializer?.accept(this);
+    }
+  }
+
+  void _addLocalVariable(AstNode scopeNode, Element element) {
+    if (element is LocalVariableElement) {
+      _map[element] = range.node(scopeNode);
+    }
+  }
+
+  static Map<LocalElement, SourceRange> forNode(AstNode unit) {
+    var computer = VisibleRangesComputer();
+    unit.accept(computer);
+    return computer._map;
+  }
+
+  /**
+   * Return the body of the function that contains the given [parameter], or
+   * `null` if no function body could be found.
+   */
+  static FunctionBody _getFunctionBody(FormalParameter parameter) {
+    var parent = parameter?.parent?.parent;
+    if (parent is ConstructorDeclaration) {
+      return parent.body;
+    } else if (parent is FunctionExpression) {
+      return parent.body;
+    } else if (parent is MethodDeclaration) {
+      return parent.body;
+    }
+    return null;
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/search/hierarchy.dart b/pkg/analysis_server/lib/src/services/search/hierarchy.dart
index 461c167..bbac8d1 100644
--- a/pkg/analysis_server/lib/src/services/search/hierarchy.dart
+++ b/pkg/analysis_server/lib/src/services/search/hierarchy.dart
@@ -73,6 +73,11 @@
   // TODO(brianwilkerson) Determine whether this await is necessary.
   await null;
   Set<ClassMemberElement> result = new HashSet<ClassMemberElement>();
+  // extension member
+  if (member.enclosingElement is ExtensionElement) {
+    result.add(member);
+    return new Future.value(result);
+  }
   // static elements
   if (member.isStatic || member is ConstructorElement) {
     result.add(member);
diff --git a/pkg/analysis_server/test/analysis/notification_navigation_test.dart b/pkg/analysis_server/test/analysis/notification_navigation_test.dart
index 4f34392..5783123 100644
--- a/pkg/analysis_server/test/analysis/notification_navigation_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_navigation_test.dart
@@ -363,6 +363,19 @@
     assertHasRegionTarget('BBB p', 'BBB {}');
   }
 
+  test_extension_on() async {
+    createAnalysisOptionsFile(experiments: ['extension-methods']);
+    addTestFile('''
+class C //1
+{}
+extension E on C //2
+{}
+''');
+    await prepareNavigation();
+    assertHasRegion('C //2');
+    assertHasTarget('C //1');
+  }
+
   test_factoryRedirectingConstructor_implicit() async {
     addTestFile('''
 class A {
diff --git a/pkg/analysis_server/test/protocol_server_test.dart b/pkg/analysis_server/test/protocol_server_test.dart
index e3c256c..84fd4df 100644
--- a/pkg/analysis_server/test/protocol_server_test.dart
+++ b/pkg/analysis_server/test/protocol_server_test.dart
@@ -227,7 +227,6 @@
       engine.ElementKind.DYNAMIC: ElementKind.UNKNOWN,
       engine.ElementKind.ERROR: ElementKind.UNKNOWN,
       engine.ElementKind.EXPORT: ElementKind.UNKNOWN,
-      engine.ElementKind.EXTENSION: ElementKind.UNKNOWN,
       engine.ElementKind.GENERIC_FUNCTION_TYPE: ElementKind.FUNCTION_TYPE_ALIAS,
       engine.ElementKind.IMPORT: ElementKind.UNKNOWN,
       engine.ElementKind.NAME: ElementKind.UNKNOWN,
diff --git a/pkg/analysis_server/test/search/element_references_test.dart b/pkg/analysis_server/test/search/element_references_test.dart
index 3e88bcd..eadbc58 100644
--- a/pkg/analysis_server/test/search/element_references_test.dart
+++ b/pkg/analysis_server/test/search/element_references_test.dart
@@ -128,6 +128,26 @@
     assertHasResult(SearchResultKind.REFERENCE, '(1)', 0);
   }
 
+  test_extension() async {
+    createAnalysisOptionsFile(experiments: ['extension-methods']);
+    addTestFile('''
+extension E on int {
+  static void foo() {}
+  void bar() {}
+}
+
+main() {
+  E.foo();
+  E(0).bar();
+}
+''');
+    await findElementReferences('E on int', false);
+    expect(searchElement.kind, ElementKind.EXTENSION);
+    expect(results, hasLength(2));
+    assertHasResult(SearchResultKind.REFERENCE, 'E.foo();');
+    assertHasResult(SearchResultKind.REFERENCE, 'E(0)');
+  }
+
   Future<void> test_field_explicit() async {
     addTestFile('''
 class A {
@@ -218,6 +238,112 @@
     assertHasResult(SearchResultKind.READ, 'fff); // in m()');
   }
 
+  test_field_ofExtension_explicit_static() async {
+    createAnalysisOptionsFile(experiments: ['extension-methods']);
+    addTestFile('''
+extension E on int {
+  static var fff; // declaration
+
+  void m() {
+    fff = 2;
+    fff += 3;
+    print(fff); // in m()
+    fff(); // in m()
+  }
+}
+
+main() {
+  E.fff = 20;
+  E.fff += 30;
+  print(E.fff); // in main()
+  E.fff(); // in main()
+}
+''');
+    await findElementReferences('fff; // declaration', false);
+    expect(searchElement.kind, ElementKind.FIELD);
+    expect(results, hasLength(8));
+    // m()
+    assertHasResult(SearchResultKind.WRITE, 'fff = 2;');
+    assertHasResult(SearchResultKind.WRITE, 'fff += 3;');
+    assertHasResult(SearchResultKind.READ, 'fff); // in m()');
+    assertHasResult(SearchResultKind.INVOCATION, 'fff(); // in m()');
+    // main()
+    assertHasResult(SearchResultKind.WRITE, 'fff = 20;');
+    assertHasResult(SearchResultKind.WRITE, 'fff += 30;');
+    assertHasResult(SearchResultKind.READ, 'fff); // in main()');
+    assertHasResult(SearchResultKind.INVOCATION, 'fff(); // in main()');
+  }
+
+  test_field_ofExtension_implicit_instance() async {
+    createAnalysisOptionsFile(experiments: ['extension-methods']);
+    addTestFile('''
+extension E on int {
+  var get fff => null;
+  set fff(x) {}
+  m() {
+    print(fff); // in m()
+    fff = 1;
+  }
+}
+main() {
+  print(0.fff); // in main()
+  0.fff = 10;
+}
+''');
+    {
+      await findElementReferences('fff =>', false);
+      expect(searchElement.kind, ElementKind.FIELD);
+      expect(results, hasLength(4));
+      assertHasResult(SearchResultKind.READ, 'fff); // in m()');
+      assertHasResult(SearchResultKind.WRITE, 'fff = 1;');
+      assertHasResult(SearchResultKind.READ, 'fff); // in main()');
+      assertHasResult(SearchResultKind.WRITE, 'fff = 10;');
+    }
+    {
+      await findElementReferences('fff(x) {}', false);
+      expect(results, hasLength(4));
+      assertHasResult(SearchResultKind.READ, 'fff); // in m()');
+      assertHasResult(SearchResultKind.WRITE, 'fff = 1;');
+      assertHasResult(SearchResultKind.READ, 'fff); // in main()');
+      assertHasResult(SearchResultKind.WRITE, 'fff = 10;');
+    }
+  }
+
+  test_field_ofExtension_implicit_static() async {
+    createAnalysisOptionsFile(experiments: ['extension-methods']);
+    addTestFile('''
+extension E on int {
+  static var get fff => null;
+  static set fff(x) {}
+  m() {
+    print(fff); // in m()
+    fff = 1;
+  }
+}
+main() {
+  print(E.fff); // in main()
+  E.fff = 10;
+}
+''');
+    {
+      await findElementReferences('fff =>', false);
+      expect(searchElement.kind, ElementKind.FIELD);
+      expect(results, hasLength(4));
+      assertHasResult(SearchResultKind.READ, 'fff); // in m()');
+      assertHasResult(SearchResultKind.WRITE, 'fff = 1;');
+      assertHasResult(SearchResultKind.READ, 'fff); // in main()');
+      assertHasResult(SearchResultKind.WRITE, 'fff = 10;');
+    }
+    {
+      await findElementReferences('fff(x) {}', false);
+      expect(results, hasLength(4));
+      assertHasResult(SearchResultKind.READ, 'fff); // in m()');
+      assertHasResult(SearchResultKind.WRITE, 'fff = 1;');
+      assertHasResult(SearchResultKind.READ, 'fff); // in main()');
+      assertHasResult(SearchResultKind.WRITE, 'fff = 10;');
+    }
+  }
+
   Future<void> test_function() async {
     addTestFile('''
 fff(p) {}
@@ -389,6 +515,29 @@
     assertHasResult(SearchResultKind.REFERENCE, 'mmm); // in main()');
   }
 
+  test_method_ofExtension() async {
+    createAnalysisOptionsFile(experiments: ['extension-methods']);
+    addTestFile('''
+extension E on int {
+  void foo() {}
+}
+
+main() {
+  E(0).foo(); // 1
+  E(0).foo; // 2
+  0.foo(); // 3
+  0.foo; // 4
+}
+''');
+    await findElementReferences('foo() {}', false);
+    expect(searchElement.kind, ElementKind.METHOD);
+    expect(results, hasLength(4));
+    assertHasResult(SearchResultKind.INVOCATION, 'foo(); // 1');
+    assertHasResult(SearchResultKind.REFERENCE, 'foo; // 2');
+    assertHasResult(SearchResultKind.INVOCATION, 'foo(); // 3');
+    assertHasResult(SearchResultKind.REFERENCE, 'foo; // 4');
+  }
+
   Future<void> test_method_propagatedType() async {
     addTestFile('''
 class A {
diff --git a/pkg/analysis_server/test/search/top_level_declarations_test.dart b/pkg/analysis_server/test/search/top_level_declarations_test.dart
index 913f821..b020a05 100644
--- a/pkg/analysis_server/test/search/top_level_declarations_test.dart
+++ b/pkg/analysis_server/test/search/top_level_declarations_test.dart
@@ -57,6 +57,15 @@
     return null;
   }
 
+  test_extensionDeclaration() async {
+    createAnalysisOptionsFile(experiments: ['extension-methods']);
+    addTestFile('''
+extension MyExtension on int {}
+''');
+    await findTopLevelDeclarations('My*');
+    assertHasDeclaration(ElementKind.EXTENSION, 'MyExtension');
+  }
+
   test_invalidRegex() async {
     var result = await findTopLevelDeclarations('[A');
     expect(result, const TypeMatcher<RequestError>());
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_ranking_internal_test.dart b/pkg/analysis_server/test/services/completion/dart/completion_ranking_internal_test.dart
index 1e1e041..ad33cdb 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_ranking_internal_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_ranking_internal_test.dart
@@ -199,4 +199,17 @@
         'package::flutter/src/widgets/preferred_size.dart::::PreferredSizeWidget';
     expect(elementNameFromRelevanceTag(tag), equals('PreferredSizeWidget'));
   });
+
+  test('selectStringLiterals', () {
+    final result = selectStringLiterals([
+      MapEntry('foo', 0.2),
+      MapEntry("'bar'", 0.3),
+      MapEntry('\'baz\'', 0.1),
+      MapEntry("'qu\'ux'", 0.4),
+    ]);
+    expect(result[0].key, equals('bar'));
+    expect(result[1].key, equals('baz'));
+    expect(result[2].key, equals('qu\'ux'));
+    expect(result, hasLength(3));
+  });
 }
diff --git a/pkg/analysis_server/test/services/completion/dart/extension_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/extension_member_contributor_test.dart
new file mode 100644
index 0000000..1e42d22
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/extension_member_contributor_test.dart
@@ -0,0 +1,166 @@
+// 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.
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/extension_member_contributor.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'completion_contributor_util.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ExtensionMemberContributorTest);
+  });
+}
+
+@reflectiveTest
+class ExtensionMemberContributorTest extends DartCompletionContributorTest {
+  @override
+  DartCompletionContributor createContributor() {
+    return new ExtensionMemberContributor();
+  }
+
+  void setUp() {
+    createAnalysisOptionsFile(experiments: ['extension-methods']);
+    super.setUp();
+  }
+
+  test_extensionOverride_doesNotMatch() async {
+    addTestSource('''
+extension E on int {
+  bool a(int b, int c) {}
+  int get b => 0;
+  set c(int d) {}
+}
+void f() {
+  E('3').a^
+}
+''');
+    await computeSuggestions();
+    assertSuggestMethod('a', null, 'bool', defaultArgListString: 'b, c');
+    assertSuggestGetter('b', 'int');
+    assertSuggestSetter('c');
+  }
+
+  test_extensionOverride_matches() async {
+    addTestSource('''
+extension E on int {
+  bool a(int b, int c) {}
+  int get b => 0;
+  set c(int d) {}
+}
+void f() {
+  E(2).a^
+}
+''');
+    await computeSuggestions();
+    assertSuggestMethod('a', null, 'bool', defaultArgListString: 'b, c');
+    assertSuggestGetter('b', 'int');
+    assertSuggestSetter('c');
+  }
+
+  test_function_doesNotMatch() async {
+    addTestSource('''
+extension E<T extends num> on List<T> {
+  bool a(int b, int c) {}
+  int get b => 0;
+  set c(int d) {}
+}
+List<T> g<T>(T x) => [x];
+void f(String s) {
+  g(s).a^
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('c');
+  }
+
+  test_function_matches() async {
+    addTestSource('''
+extension E on int {
+  bool a(int b, int c) {}
+  int get b => 0;
+  set c(int d) {}
+}
+void f() {
+  g().a^
+}
+int g() => 3;
+''');
+    await computeSuggestions();
+    assertSuggestMethod('a', null, 'bool', defaultArgListString: 'b, c');
+    assertSuggestGetter('b', 'int');
+    assertSuggestSetter('c');
+  }
+
+  test_identifier_doesNotMatch() async {
+    addTestSource('''
+extension E<T extends num> on List<T> {
+  bool a(int b, int c) {}
+  int get b => 0;
+  set c(int d) {}
+}
+void f(List<String> l) {
+  l.a^
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('c');
+  }
+
+  test_identifier_matches() async {
+    addTestSource('''
+extension E<T extends num> on List<T> {
+  bool a(int b, int c) {}
+  int get b => 0;
+  set c(int d) {}
+}
+void f(List<int> l) {
+  l.a^
+}
+''');
+    await computeSuggestions();
+    assertSuggestMethod('a', null, 'bool', defaultArgListString: 'b, c');
+    assertSuggestGetter('b', 'int');
+    assertSuggestSetter('c');
+  }
+
+  test_literal_doesNotMatch() async {
+    addTestSource('''
+extension E<T extends num> on List<T> {
+  bool a(int b, int c) {}
+  int get b => 0;
+  set c(int d) {}
+}
+void f() {
+  ['a'].a^
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('c');
+  }
+
+  test_literal_matches() async {
+    addTestSource('''
+extension E on int {
+  bool a(int b, int c) {}
+  int get b => 0;
+  set c(int d) {}
+}
+void f() {
+  2.a^
+}
+''');
+    await computeSuggestions();
+    assertSuggestMethod('a', null, 'bool', defaultArgListString: 'b, c');
+    assertSuggestGetter('b', 'int');
+    assertSuggestSetter('c');
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/language_model_test.dart b/pkg/analysis_server/test/services/completion/dart/language_model_test.dart
index 32a09a8..2163e7b 100644
--- a/pkg/analysis_server/test/services/completion/dart/language_model_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/language_model_test.dart
@@ -48,12 +48,12 @@
     final best = suggestions.entries.first;
     expect(best.key, 'length');
     expect(best.value, greaterThan(0.8));
+    expect(suggestions, hasLength(model.completions));
   });
 
   test('predict when no previous tokens', () {
     final tokens = <String>[];
     final suggestions = model.predict(tokens);
-    expect(suggestions, hasLength(model.completions));
     expect(suggestions.first, isNotEmpty);
   });
 
diff --git a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
index 3cd1ed2..b91a939 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
@@ -5,6 +5,7 @@
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/local_reference_contributor.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -13,6 +14,7 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(LocalReferenceContributorTest);
+    defineReflectiveTests(LocalReferenceContributorWithExtensionMethodsTest);
   });
 }
 
@@ -3947,6 +3949,35 @@
     await computeSuggestions();
   }
 
+  test_mixinDeclaration_body() async {
+    // MixinDeclaration  CompilationUnit
+    addSource('/home/test/lib/b.dart', '''
+class B { }''');
+    addTestSource('''
+import "b.dart" as x;
+mixin M {^}
+class _B {}
+A T;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    CompletionSuggestion suggestionM = assertSuggestMixin('M');
+    if (suggestionM != null) {
+      expect(suggestionM.element.isDeprecated, isFalse);
+      expect(suggestionM.element.isPrivate, isFalse);
+    }
+    CompletionSuggestion suggestionB = assertSuggestClass('_B');
+    if (suggestionB != null) {
+      expect(suggestionB.element.isDeprecated, isFalse);
+      expect(suggestionB.element.isPrivate, isTrue);
+    }
+    assertNotSuggested('Object');
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
   test_new_instance() async {
     addTestSource('import "dart:math"; class A {x() {new Random().^}}');
     await computeSuggestions();
@@ -4905,3 +4936,42 @@
     assertSuggestMixin('M');
   }
 }
+
+@reflectiveTest
+class LocalReferenceContributorWithExtensionMethodsTest
+    extends LocalReferenceContributorTest {
+  @override
+  void setUp() {
+    createAnalysisOptionsFile(
+      experiments: [
+        EnableString.extension_methods,
+      ],
+    );
+    super.setUp();
+  }
+
+  test_extensionDeclaration_body() async {
+    // ExtensionDeclaration  CompilationUnit
+    addSource('/home/test/lib/b.dart', '''
+class B { }''');
+    addTestSource('''
+import "b.dart" as x;
+extension E on int {^}
+class _B {}
+A T;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    CompletionSuggestion suggestionB = assertSuggestClass('_B');
+    if (suggestionB != null) {
+      expect(suggestionB.element.isDeprecated, isFalse);
+      expect(suggestionB.element.isPrivate, isTrue);
+    }
+    assertNotSuggested('Object');
+    assertNotSuggested('T');
+    assertNotSuggested('E');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/test_all.dart b/pkg/analysis_server/test/services/completion/dart/test_all.dart
index d94b577..3bf866a 100644
--- a/pkg/analysis_server/test/services/completion/dart/test_all.dart
+++ b/pkg/analysis_server/test/services/completion/dart/test_all.dart
@@ -8,10 +8,11 @@
 import 'combinator_contributor_test.dart' as combinator_test;
 import 'common_usage_sorter_test.dart' as common_usage_test;
 import 'completion_manager_test.dart' as completion_manager;
-// ignore: unused_import
-import 'completion_ranking_test.dart' as completion_ranking_test;
 import 'completion_ranking_internal_test.dart'
     as completion_ranking_internal_test;
+// ignore: unused_import
+import 'completion_ranking_test.dart' as completion_ranking_test;
+import 'extension_member_contributor_test.dart' as extension_member_contributor;
 import 'field_formal_contributor_test.dart' as field_formal_contributor_test;
 import 'imported_reference_contributor_test.dart' as imported_ref_test;
 import 'inherited_reference_contributor_test.dart' as inherited_ref_test;
@@ -41,6 +42,7 @@
     //   output from the tflite shared library
     // completion_ranking_test.main();
     completion_ranking_internal_test.main();
+    extension_member_contributor.main();
     field_formal_contributor_test.main();
     imported_ref_test.main();
     inherited_ref_test.main();
diff --git a/pkg/analysis_server/test/src/services/correction/fix/change_to_static_access_test.dart b/pkg/analysis_server/test/src/services/correction/fix/change_to_static_access_test.dart
index 507b291..8ae3d08 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/change_to_static_access_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/change_to_static_access_test.dart
@@ -10,12 +10,13 @@
 
 main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(ChangeToStaticAccessTest);
+    defineReflectiveTests(ChangeToStaticAccessClassTest);
+    defineReflectiveTests(ChangeToStaticAccessExtensionTest);
   });
 }
 
 @reflectiveTest
-class ChangeToStaticAccessTest extends FixProcessorTest {
+class ChangeToStaticAccessClassTest extends FixProcessorTest {
   @override
   FixKind get kind => DartFixKind.CHANGE_TO_STATIC_ACCESS;
 
@@ -128,3 +129,50 @@
 ''');
   }
 }
+
+@reflectiveTest
+class ChangeToStaticAccessExtensionTest extends FixProcessorTest {
+  @override
+  FixKind get kind => DartFixKind.CHANGE_TO_STATIC_ACCESS;
+
+  test_method() async {
+    createAnalysisOptionsFile(experiments: ['extension-methods']);
+    await resolveTestUnit('''
+extension E on int {
+  static void foo() {}
+}
+main() {
+  0.foo();
+}
+''');
+    await assertHasFix('''
+extension E on int {
+  static void foo() {}
+}
+main() {
+  E.foo();
+}
+''');
+  }
+
+  @failingTest
+  test_property() async {
+    createAnalysisOptionsFile(experiments: ['extension-methods']);
+    await resolveTestUnit('''
+extension E on int {
+  static int get foo => 42;
+}
+main() {
+  0.foo;
+}
+''');
+    await assertHasFix('''
+extension E on int {
+  static int get foo => 42;
+}
+main() {
+  E.foo;
+}
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_missing_overrides_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_missing_overrides_test.dart
index 03dda70..e240531 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_missing_overrides_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_missing_overrides_test.dart
@@ -87,7 +87,7 @@
 
 class B extends A {
   @override
-  void forEach(int Function(double, String) f) {
+  void forEach(int Function(double p1, String p2) f) {
     // TODO: implement forEach
   }
 }
diff --git a/pkg/analysis_server_client/analysis_options.yaml b/pkg/analysis_server_client/analysis_options.yaml
new file mode 100644
index 0000000..8211da4
--- /dev/null
+++ b/pkg/analysis_server_client/analysis_options.yaml
@@ -0,0 +1,10 @@
+analyzer:
+  #strong-mode:
+  #  implicit-casts: false
+
+linter:
+  rules:
+    - empty_constructor_bodies
+    - empty_statements
+    - unnecessary_brace_in_string_interps
+    - valid_regexps
diff --git a/pkg/analysis_server_client/example/example.dart b/pkg/analysis_server_client/example/example.dart
index 21573b4..f9dc7ce 100644
--- a/pkg/analysis_server_client/example/example.dart
+++ b/pkg/analysis_server_client/example/example.dart
@@ -99,7 +99,7 @@
       if (errorCount == 0) {
         print('No issues found.');
       } else {
-        print('Found ${errorCount} errors/warnings/hints');
+        print('Found $errorCount errors/warnings/hints');
       }
       errorCount = 0;
       print('--------- ctrl-c to exit ---------');
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_util.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_util.dart
index bdce37f..39dc294 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_util.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_util.dart
@@ -32,13 +32,14 @@
   }
 
   /// Combines together two hash codes.
-  static int hash2(a, b) => finish(combine(combine(0, a), b));
+  static int hash2(int a, int b) => finish(combine(combine(0, a), b));
 
   /// Combines together three hash codes.
-  static int hash3(a, b, c) => finish(combine(combine(combine(0, a), b), c));
+  static int hash3(int a, int b, int c) =>
+      finish(combine(combine(combine(0, a), b), c));
 
   /// Combines together four hash codes.
-  static int hash4(a, b, c, d) =>
+  static int hash4(int a, int b, int c, int d) =>
       finish(combine(combine(combine(combine(0, a), b), c), d));
 
   int _hash = 0;
diff --git a/pkg/analysis_tool/analysis_options.yaml b/pkg/analysis_tool/analysis_options.yaml
new file mode 100644
index 0000000..7b2fbe6
--- /dev/null
+++ b/pkg/analysis_tool/analysis_options.yaml
@@ -0,0 +1,10 @@
+analyzer:
+  strong-mode:
+    implicit-casts: false
+
+linter:
+  rules:
+    - empty_constructor_bodies
+    - empty_statements
+    - unnecessary_brace_in_string_interps
+    - valid_regexps
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index a4090eb..3071788 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,6 +1,22 @@
-## 0.37.1 (Not yet published)
+## 0.38.0
+* The deprecated method `AstFactory.compilationUnit2` has been removed.  Clients
+  should switch back to `AstFactory.compilationUnit`.
+* Removed the deprecated constructor `ParsedLibraryResultImpl.tmp` and the
+  deprecated method `ResolvedLibraryResultImpl.tmp`.  Please use
+  `AnalysisSession.getParsedLibraryByElement` and
+  `AnalysisSession.getResolvedLibraryByElement` instead.
+* Removed `MethodElement.getReifiedType`.
+* The return type of `ClassMemberElement.enclosingElement` was changed from
+  `ClassElement` to `Element`.
+
+## 0.37.1+1
+* Reverted an unintentional breaking API change (the return type of
+  `ClassMemberElement.enclosingElement` was changed from `ClassElement` to
+  `Element`).  This change will be postponed until 0.38.0.
+
+## 0.37.1
 * Added the getters `isDartCoreList`, `isDartCoreMap`, `isDartCoreNum`,
-  `isDartCoreSet`, and `isDartCoreSymbol` to `DartType`.
+  `isDartCoreSet`, `isDartCoreSymbol`, and `isDartCoreObject` to `DartType`.
 * Added the method `DartObject.toFunctionValue`.
 * Deprecated the `isEquivalentTo(DartType)` method of `DartType`.
   The operator `==` now correctly considers two types equal if and
@@ -16,6 +32,12 @@
 * Added the optional parameter `path` to `parseString`.
 * Changed `TypeSystem.resolveToBound(DartType)` implementation to do
   what its documentation says.
+* This version of the analyzer should contain all the necessary parsing support
+  and AST data structures for the experimental "extension-methods" feature.
+  Further element model improvements needed to support extension methods will be
+  published in 0.38.x.
+* Deprecated `InterfaceType.isDirectSupertypeOf`.  There is no replacement; this
+  method was not intended to be used outside of the analyzer.
 
 ## 0.37.0
 * Removed deprecated getter `DartType.isUndefined`.
diff --git a/pkg/analyzer/analysis_options.yaml b/pkg/analyzer/analysis_options.yaml
index a8010a3..1c02e60 100644
--- a/pkg/analyzer/analysis_options.yaml
+++ b/pkg/analyzer/analysis_options.yaml
@@ -1,3 +1,8 @@
+analyzer:
+  # This currently finds ~4,500 implicit-casts issues when enabled.
+  # strong-mode:
+  #   implicit-casts: false
+
 linter:
   rules:
     - empty_constructor_bodies # pedantic
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index e389879..588b923 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -989,7 +989,10 @@
   ConstructorDeclaration getConstructor(String name);
 }
 
-/// A node that declares a name within the scope of a class.
+/// A node that declares a name within the scope of a class declarations.
+///
+/// When the 'extension-methods' experiment is enabled, these nodes can also be
+/// located inside extension declarations.
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class ClassMember implements Declaration {}
@@ -2189,6 +2192,10 @@
 ///    fieldDeclaration ::=
 ///        'static'? [VariableDeclarationList] ';'
 ///
+/// Prior to the 'extension-methods' experiment, these nodes were always
+/// children of a class declaration. When the experiment is enabled, these nodes
+/// can also be children of an extension declaration.
+///
 /// Clients may not extend, implement or mix-in this class.
 abstract class FieldDeclaration implements ClassMember {
   /// The 'covariant' keyword, or `null` if the keyword was not used.
@@ -3739,6 +3746,10 @@
 ///        [SimpleIdentifier]
 ///      | 'operator' [SimpleIdentifier]
 ///
+/// Prior to the 'extension-methods' experiment, these nodes were always
+/// children of a class declaration. When the experiment is enabled, these nodes
+/// can also be children of an extension declaration.
+///
 /// Clients may not extend, implement or mix-in this class.
 abstract class MethodDeclaration implements ClassMember {
   /// Return the body of the method.
diff --git a/pkg/analyzer/lib/dart/ast/ast_factory.dart b/pkg/analyzer/lib/dart/ast/ast_factory.dart
index d8cffd0..911b6b5 100644
--- a/pkg/analyzer/lib/dart/ast/ast_factory.dart
+++ b/pkg/analyzer/lib/dart/ast/ast_factory.dart
@@ -167,23 +167,6 @@
       @required Token endToken,
       @required FeatureSet featureSet});
 
-  /// Returns a newly created compilation unit to have the given directives and
-  /// declarations.  The [scriptTag] can be `null` (or omitted) if there is no
-  /// script tag in the compilation unit.  The list of [declarations] can be
-  /// `null` (or omitted) if there are no directives in the compilation unit.
-  /// The list of `declarations` can be `null` (or omitted) if there are no
-  /// declarations in the compilation unit.  The [featureSet] can be `null` if
-  /// the set of features for this compilation unit is not known (this
-  /// restricts what analysis can be done of the compilation unit).
-  @Deprecated('Use compilationUnit')
-  CompilationUnit compilationUnit2(
-      {@required Token beginToken,
-      ScriptTag scriptTag,
-      List<Directive> directives,
-      List<CompilationUnitMember> declarations,
-      @required Token endToken,
-      @required FeatureSet featureSet});
-
   /// Returns a newly created conditional expression.
   ConditionalExpression conditionalExpression(
       Expression condition,
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index 9a1f011..da6c473 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -347,10 +347,14 @@
 
 /// An element that is contained within a [ClassElement].
 ///
+/// When the 'extension-methods' experiment is enabled, these elements can also
+/// be contained within an extension element.
+///
 /// Clients may not extend, implement or mix-in this class.
 abstract class ClassMemberElement implements Element {
   // TODO(brianwilkerson) Either remove this class or rename it to something
-  //  more correct, such as PotentiallyStaticElement.
+  //  more correct.
+
   /// Return `true` if this element is a static element. A static element is an
   /// element that is not associated with a particular instance, but rather with
   /// an entire library or class.
@@ -1090,7 +1094,10 @@
   PropertyAccessorElement /*?*/ getSetter(String name);
 }
 
-/// A field defined within a type.
+/// A field defined within a class.
+///
+/// When the 'extension-methods' experiment is enabled, these elements can also
+/// be contained within an extension element.
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class FieldElement
@@ -1391,21 +1398,16 @@
   bool get isLate;
 }
 
-/// An element that represents a method defined within a type.
+/// An element that represents a method defined within a class.
+///
+/// When the 'extension-methods' experiment is enabled, these elements can also
+/// be contained within an extension element.
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class MethodElement implements ClassMemberElement, ExecutableElement {
   @deprecated
   @override
   MethodDeclaration computeNode();
-
-  /// Gets the reified type of a tear-off of this method.
-  ///
-  /// If any of the parameters in the method are covariant, they are replaced
-  /// with Object in the returned type. If no covariant parameters are present,
-  /// returns `this`.
-  @deprecated
-  FunctionType getReifiedType(DartType objectType);
 }
 
 /// A pseudo-element that represents multiple elements defined within a single
diff --git a/pkg/analyzer/lib/dart/element/type.dart b/pkg/analyzer/lib/dart/element/type.dart
index 30a77d9..f147121 100644
--- a/pkg/analyzer/lib/dart/element/type.dart
+++ b/pkg/analyzer/lib/dart/element/type.dart
@@ -83,6 +83,10 @@
   /// dart:core library.
   bool get isDartCoreNum;
 
+  /// Return `true` if this type represents the type `Object` defined in the
+  /// dart:core library.
+  bool get isDartCoreObject;
+
   /// Returns `true` if this type represents the type 'Set' defined in the
   /// dart:core library.
   bool get isDartCoreSet;
diff --git a/pkg/analyzer/lib/dart/element/type_system.dart b/pkg/analyzer/lib/dart/element/type_system.dart
index 0879f80..433060a 100644
--- a/pkg/analyzer/lib/dart/element/type_system.dart
+++ b/pkg/analyzer/lib/dart/element/type_system.dart
@@ -33,7 +33,7 @@
   /// Other type systems may define this operation differently.
   DartType flatten(DartType type);
 
-  /// Return `true` if the [rightType] is assignable to the [leftType].
+  /// Return `true` if the [leftType] is assignable to the [rightType].
   ///
   /// For the Dart 2.0 type system, the definition of this relationship is given
   /// in the Dart Language Specification, section 19.4 Subtypes:
@@ -46,8 +46,8 @@
   /// The subtype relationship (<:) can be tested using [isSubtypeOf].
   ///
   /// Other type systems may define this operation differently. In particular,
-  /// while the operation is commutative in the Dart 2.0 type system, that is
-  /// not a requirement of a type system, so the order of the arguments is
+  /// while the operation is commutative in the Dart 2.0 type system, it will
+  /// not be commutative when NNBD is enabled, so the order of the arguments is
   /// important.
   bool isAssignableTo(DartType leftType, DartType rightType);
 
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index feb9217..b919610 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -65,7 +65,6 @@
   CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH,
   CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE,
   CompileTimeErrorCode.ACCESS_PRIVATE_ENUM_FIELD,
-  CompileTimeErrorCode.ACCESS_STATIC_EXTENSION_MEMBER,
   CompileTimeErrorCode.AMBIGUOUS_EXPORT,
   CompileTimeErrorCode.AMBIGUOUS_EXTENSION_METHOD_ACCESS,
   CompileTimeErrorCode.AMBIGUOUS_SET_OR_MAP_LITERAL_BOTH,
@@ -137,6 +136,7 @@
   CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS,
   CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS,
   CompileTimeErrorCode.EXTENDS_NON_CLASS,
+  CompileTimeErrorCode.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE,
   CompileTimeErrorCode.EXTENSION_DECLARES_ABSTRACT_MEMBER,
   CompileTimeErrorCode.EXTENSION_DECLARES_CONSTRUCTOR,
   CompileTimeErrorCode.EXTENSION_DECLARES_INSTANCE_FIELD,
@@ -156,6 +156,7 @@
   CompileTimeErrorCode.GENERIC_FUNCTION_TYPED_PARAM_UNSUPPORTED,
   CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND,
   CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
+  CompileTimeErrorCode.IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY,
   CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS,
   CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS,
   CompileTimeErrorCode.IMPLEMENTS_NON_CLASS,
@@ -238,9 +239,6 @@
   CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT,
   CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY,
   CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT,
-  CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY,
-  CompileTimeErrorCode.NON_CONSTANT_SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY,
-  CompileTimeErrorCode.NON_CONSTANT_IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY,
   // ignore: deprecated_member_use_from_same_package
   CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER,
   CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT,
@@ -287,7 +285,9 @@
   CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH,
   CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR,
   CompileTimeErrorCode.RETURN_IN_GENERATOR,
+  CompileTimeErrorCode.SET_ELEMENT_FROM_DEFERRED_LIBRARY,
   CompileTimeErrorCode.SHARED_DEFERRED_PREFIX,
+  CompileTimeErrorCode.SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY,
   CompileTimeErrorCode.SUPER_INITIALIZER_IN_OBJECT,
   CompileTimeErrorCode.SUPER_IN_EXTENSION,
   CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT,
@@ -366,8 +366,9 @@
   HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT,
   HintCode.SDK_VERSION_ASYNC_EXPORTED_FROM_CORE,
   HintCode.SDK_VERSION_AS_EXPRESSION_IN_CONST_CONTEXT,
-  HintCode.SDK_VERSION_BOOL_OPERATOR,
+  HintCode.SDK_VERSION_BOOL_OPERATOR_IN_CONST_CONTEXT,
   HintCode.SDK_VERSION_EQ_EQ_OPERATOR_IN_CONST_CONTEXT,
+  HintCode.SDK_VERSION_EXTENSION_METHODS,
   HintCode.SDK_VERSION_GT_GT_GT_OPERATOR,
   HintCode.SDK_VERSION_IS_EXPRESSION_IN_CONST_CONTEXT,
   HintCode.SDK_VERSION_NEVER,
diff --git a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
index b942b0e..341366d 100644
--- a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
@@ -180,7 +180,7 @@
 /// value in [IsEnabledByDefault]).
 class IsExpired {
   /// Expiration status of the experiment "constant-update-2018"
-  static const bool constant_update_2018 = false;
+  static const bool constant_update_2018 = true;
 
   /// Expiration status of the experiment "control-flow-collections"
   static const bool control_flow_collections = false;
diff --git a/pkg/analyzer/lib/src/dart/analysis/index.dart b/pkg/analyzer/lib/src/dart/analysis/index.dart
index 2292ce4..8d45ba7 100644
--- a/pkg/analyzer/lib/src/dart/analysis/index.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/index.dart
@@ -398,7 +398,8 @@
       nameIdParameter = _getStringInfo(element.name);
       element = element.enclosingElement;
     }
-    if (element?.enclosingElement is ClassElement) {
+    if (element?.enclosingElement is ClassElement ||
+        element?.enclosingElement is ExtensionElement) {
       nameIdClassMember = _getStringInfo(element.name);
       element = element.enclosingElement;
     }
diff --git a/pkg/analyzer/lib/src/dart/analysis/results.dart b/pkg/analyzer/lib/src/dart/analysis/results.dart
index e14ef3f..9da05f9 100644
--- a/pkg/analyzer/lib/src/dart/analysis/results.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/results.dart
@@ -77,39 +77,6 @@
   ParsedLibraryResultImpl.external(AnalysisSession session, Uri uri)
       : this(session, null, uri, null);
 
-  @Deprecated('This factory exists temporary until AnalysisSession migration.')
-  factory ParsedLibraryResultImpl.tmp(LibraryElement library) {
-    var session = library.session;
-    if (session != null) {
-      return session.getParsedLibraryByElement(library);
-    } else {
-      var analysisContext = library.context;
-      var units = <ParsedUnitResult>[];
-      for (var unitElement in library.units) {
-        var unitSource = unitElement.source;
-
-        if (!analysisContext.exists(unitSource)) {
-          continue;
-        }
-
-        var content = analysisContext.getContents(unitSource).data;
-        var lineInfo = analysisContext.getLineInfo(unitSource);
-        var unit = analysisContext.parseCompilationUnit(unitSource);
-        units.add(ParsedUnitResultImpl(
-            null,
-            unitSource.fullName,
-            unitSource.uri,
-            content,
-            lineInfo,
-            unitSource != library.source,
-            unit, const []));
-      }
-      var libraryPath = library.source.fullName;
-      return ParsedLibraryResultImpl(
-          null, libraryPath, library.source.uri, units);
-    }
-  }
-
   @override
   ResultState get state {
     if (path == null) {
@@ -230,34 +197,6 @@
 
     return ElementDeclarationResultImpl(element, declaration, null, unitResult);
   }
-
-  @Deprecated('This method exists temporary until AnalysisSession migration.')
-  static Future<ResolvedLibraryResult> tmp(LibraryElement library) async {
-    var session = library.session;
-    if (session != null) {
-      return session.getResolvedLibraryByElement(library);
-    } else {
-      var units = <ResolvedUnitResult>[];
-      var analysisContext = library.context;
-      for (var unitElement in library.units) {
-        var unitSource = unitElement.source;
-
-        if (!analysisContext.exists(unitSource)) {
-          continue;
-        }
-
-        var path = unitSource.fullName;
-        var content = analysisContext.getContents(unitSource).data;
-        var lineInfo = analysisContext.getLineInfo(unitSource);
-        var unit = analysisContext.resolveCompilationUnit(unitSource, library);
-        units.add(ResolvedUnitResultImpl(null, path, unitSource.uri, true,
-            content, lineInfo, unitSource != library.source, unit, const []));
-      }
-      var libraryPath = library.source.fullName;
-      return ResolvedLibraryResultImpl(null, libraryPath, library.source.uri,
-          library, library.context.typeProvider, units);
-    }
-  }
 }
 
 class ResolvedUnitResultImpl extends FileResultImpl
diff --git a/pkg/analyzer/lib/src/dart/analysis/search.dart b/pkg/analyzer/lib/src/dart/analysis/search.dart
index 1b58efc..7a638cd 100644
--- a/pkg/analyzer/lib/src/dart/analysis/search.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/search.dart
@@ -80,6 +80,7 @@
     ElementKind kind = element.kind;
     if (kind == ElementKind.CLASS ||
         kind == ElementKind.CONSTRUCTOR ||
+        kind == ElementKind.EXTENSION ||
         kind == ElementKind.FUNCTION_TYPE_ALIAS ||
         kind == ElementKind.SETTER) {
       return _searchReferences(element, searchedFiles);
@@ -193,6 +194,7 @@
         CompilationUnitElement unitElement = unitResult.element;
         unitElement.accessors.forEach(addElement);
         unitElement.enums.forEach(addElement);
+        unitElement.extensions.forEach(addElement);
         unitElement.functions.forEach(addElement);
         unitElement.functionTypeAliases.forEach(addElement);
         unitElement.mixins.forEach(addElement);
@@ -817,7 +819,8 @@
    */
   int getElementClassMemberId(Element element) {
     for (; element != null; element = element.enclosingElement) {
-      if (element.enclosingElement is ClassElement) {
+      if (element.enclosingElement is ClassElement ||
+          element.enclosingElement is ExtensionElement) {
         return getStringId(element.name);
       }
     }
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 87d899b..747ecf1 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -4661,6 +4661,7 @@
 
   @override
   Token get beginToken => _variableList?.beginToken ?? super.beginToken;
+
   @override
   Iterable<SyntacticEntity> get childEntities => new ChildEntities()
     ..add(_variableList)
diff --git a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
index f542bd2..9091adc 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
@@ -190,18 +190,6 @@
           endToken, featureSet);
 
   @override
-  @deprecated
-  CompilationUnit compilationUnit2(
-          {Token beginToken,
-          ScriptTag scriptTag,
-          List<Directive> directives,
-          List<CompilationUnitMember> declarations,
-          Token endToken,
-          FeatureSet featureSet}) =>
-      new CompilationUnitImpl(beginToken, scriptTag, directives, declarations,
-          endToken, featureSet);
-
-  @override
   ConditionalExpression conditionalExpression(
           Expression condition,
           Token question,
diff --git a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
index 1ec4362..3c2efbf 100644
--- a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
+++ b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
@@ -600,8 +600,7 @@
       return CompileTimeErrorCode
           .NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY;
     } else if (forSet) {
-      return CompileTimeErrorCode
-          .NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY;
+      return CompileTimeErrorCode.SET_ELEMENT_FROM_DEFERRED_LIBRARY;
     }
 
     return null;
@@ -640,10 +639,8 @@
       // The errors have already been reported.
       if (conditionBool == null) return false;
 
-      verifier._reportErrorIfFromDeferredLibrary(
-          element.condition,
-          CompileTimeErrorCode
-              .NON_CONSTANT_IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY);
+      verifier._reportErrorIfFromDeferredLibrary(element.condition,
+          CompileTimeErrorCode.IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY);
 
       var thenValid = true;
       var elseValid = true;
@@ -670,10 +667,8 @@
       var value = verifier._validate(element.expression, errorCode);
       if (value == null) return false;
 
-      verifier._reportErrorIfFromDeferredLibrary(
-          element.expression,
-          CompileTimeErrorCode
-              .NON_CONSTANT_SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY);
+      verifier._reportErrorIfFromDeferredLibrary(element.expression,
+          CompileTimeErrorCode.SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY);
 
       if (forList || forSet) {
         return _validateListOrSetSpread(element, value);
@@ -896,7 +891,7 @@
 
     verifier._reportErrorIfFromDeferredLibrary(
       expression,
-      CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY,
+      CompileTimeErrorCode.SET_ELEMENT_FROM_DEFERRED_LIBRARY,
     );
 
     if (setUniqueValues.containsKey(value)) {
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index b145b76..00779a3 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -7863,38 +7863,6 @@
   @override
   MethodDeclaration computeNode() =>
       getNodeMatching((node) => node is MethodDeclaration);
-
-  @deprecated
-  @override
-  FunctionType getReifiedType(DartType objectType) {
-    // TODO(jmesserly): this implementation is completely wrong:
-    // It does not handle covariant parameters from a generic class.
-    // It drops type parameters from generic methods.
-    // Since this method was for DDC, it should be removed.
-    //
-    // Check whether we have any covariant parameters.
-    // Usually we don't, so we can use the same type.
-    bool hasCovariant = false;
-    for (ParameterElement parameter in parameters) {
-      if (parameter.isCovariant) {
-        hasCovariant = true;
-        break;
-      }
-    }
-
-    if (!hasCovariant) {
-      return type;
-    }
-
-    List<ParameterElement> covariantParameters = parameters.map((parameter) {
-      DartType type = parameter.isCovariant ? objectType : parameter.type;
-      return new ParameterElementImpl.synthetic(
-          parameter.name, type, parameter.parameterKind);
-    }).toList();
-
-    return new FunctionElementImpl.synthetic(covariantParameters, returnType)
-        .type;
-  }
 }
 
 /// A [ClassElementImpl] representing a mixin declaration.
@@ -10043,6 +10011,11 @@
   /// The unlinked representation of the type parameter in the summary.
   final UnlinkedTypeParam _unlinkedTypeParam;
 
+  /// The default value of the type parameter. It is used to provide the
+  /// corresponding missing type argument in type annotations and as the
+  /// fall-back type value in type inference.
+  DartType _defaultType;
+
   /// The type defined by this type parameter.
   TypeParameterType _type;
 
@@ -10131,12 +10104,18 @@
   /// corresponding missing type argument in type annotations and as the
   /// fall-back type value in type inference.
   DartType get defaultType {
+    if (_defaultType != null) return _defaultType;
+
     if (linkedNode != null) {
-      return linkedContext.getDefaultType(linkedNode);
+      return _defaultType = linkedContext.getDefaultType(linkedNode);
     }
     return null;
   }
 
+  set defaultType(DartType defaultType) {
+    _defaultType = defaultType;
+  }
+
   @override
   String get displayName => name;
 
diff --git a/pkg/analyzer/lib/src/dart/element/handle.dart b/pkg/analyzer/lib/src/dart/element/handle.dart
index 597c39a..ab33e17 100644
--- a/pkg/analyzer/lib/src/dart/element/handle.dart
+++ b/pkg/analyzer/lib/src/dart/element/handle.dart
@@ -1035,11 +1035,6 @@
   @deprecated
   @override
   MethodDeclaration computeNode() => actualElement.computeNode();
-
-  @deprecated
-  @override
-  FunctionType getReifiedType(DartType objectType) =>
-      actualElement.getReifiedType(objectType);
 }
 
 /**
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index 2bbc114..d763f18 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -217,6 +217,10 @@
       combined = Substitution.fromMap(map);
     }
 
+    if (combined.map.isEmpty) {
+      return element;
+    }
+
     if (element is ConstructorElement) {
       return ConstructorMember(element, combined);
     } else if (element is MethodElement) {
@@ -227,20 +231,6 @@
       throw UnimplementedError('(${element.runtimeType}) $element');
     }
   }
-
-  static ExecutableElement from3(
-    ExecutableElement element,
-    List<TypeParameterElement> typeParameters,
-    List<DartType> typeArguments,
-  ) {
-    if (typeParameters.isEmpty) {
-      return element;
-    }
-    return from2(
-      element,
-      Substitution.fromPairs(typeParameters, typeArguments),
-    );
-  }
 }
 
 /**
@@ -541,18 +531,6 @@
     }
   }
 
-  /**
-   * Return the type that results from replacing the type parameters in the
-   * given [type] with the type arguments associated with this member.
-   */
-  @Deprecated("Used only by 'getReifiedType', which is deprecated")
-  DartType substituteFor(DartType type) {
-    if (type == null) {
-      return null;
-    }
-    return _substitution.substituteType(type);
-  }
-
   @override
   void visitChildren(ElementVisitor visitor) {
     // There are no children to visit
@@ -586,11 +564,6 @@
   @override
   MethodDeclaration computeNode() => baseElement.computeNode();
 
-  @deprecated
-  @override
-  FunctionType getReifiedType(DartType objectType) =>
-      substituteFor(baseElement.getReifiedType(objectType));
-
   @override
   String toString() {
     MethodElement baseElement = this.baseElement;
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index d4067ce..3c1e839 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -1286,7 +1286,7 @@
    * Initialize a newly created type to be declared by the given [element].
    */
   InterfaceTypeImpl(ClassElement element,
-      [this.prunedTypedefs, this.nullabilitySuffix = NullabilitySuffix.star])
+      {this.prunedTypedefs, this.nullabilitySuffix = NullabilitySuffix.star})
       : super(element, element.displayName);
 
   /**
@@ -1514,6 +1514,15 @@
   }
 
   @override
+  bool get isDartCoreObject {
+    ClassElement element = this.element;
+    if (element == null) {
+      return false;
+    }
+    return element.name == "Object" && element.library.isDartCore;
+  }
+
+  @override
   bool get isDartCoreSet {
     ClassElement element = this.element;
     if (element == null) {
@@ -2259,8 +2268,8 @@
     List<DartType> newTypeArguments = TypeImpl.substitute(
         typeArguments, argumentTypes, parameterTypes, prune);
 
-    InterfaceTypeImpl newType =
-        new InterfaceTypeImpl(element, prune, nullabilitySuffix);
+    InterfaceTypeImpl newType = new InterfaceTypeImpl(element,
+        prunedTypedefs: prune, nullabilitySuffix: nullabilitySuffix);
     newType.typeArguments = newTypeArguments;
     return newType;
   }
@@ -2503,8 +2512,8 @@
       return NullabilitySuffix.none;
     }
 
-    InterfaceTypeImpl lub =
-        new InterfaceTypeImpl(firstElement, null, computeNullability());
+    InterfaceTypeImpl lub = new InterfaceTypeImpl(firstElement,
+        nullabilitySuffix: computeNullability());
     lub.typeArguments = lubArguments;
     return lub;
   }
@@ -2663,6 +2672,9 @@
   bool get isDartCoreNum => false;
 
   @override
+  bool get isDartCoreObject => false;
+
+  @override
   bool get isDartCoreSet => false;
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/element/type_algebra.dart b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
index fede84b..f3e234d 100644
--- a/pkg/analyzer/lib/src/dart/element/type_algebra.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
@@ -126,7 +126,7 @@
   }
 
   /// Substitutes each parameter to the type it maps to in [map].
-  static Substitution fromMap(Map<TypeParameterElement, DartType> map) {
+  static MapSubstitution fromMap(Map<TypeParameterElement, DartType> map) {
     if (map.isEmpty) {
       return _NullSubstitution.instance;
     }
diff --git a/pkg/analyzer/lib/src/dart/element/wrapped.dart b/pkg/analyzer/lib/src/dart/element/wrapped.dart
index 99d3f9e..4d7e6e6 100644
--- a/pkg/analyzer/lib/src/dart/element/wrapped.dart
+++ b/pkg/analyzer/lib/src/dart/element/wrapped.dart
@@ -194,8 +194,10 @@
       .accept(visitor); // ignore: deprecated_member_use_from_same_package
 
   @override
-  String computeDocumentationComment() =>
-      wrappedUnit.computeDocumentationComment();
+  String computeDocumentationComment() {
+    // ignore: deprecated_member_use_from_same_package
+    return wrappedUnit.computeDocumentationComment();
+  }
 
   @deprecated
   @override
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
index 136e290..e596bcd 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
@@ -649,11 +649,11 @@
    * The operator '&', '|' or '^' is being used on boolean values in code that
    * is expected to run on versions of the SDK that did not support it.
    */
-  static const HintCode SDK_VERSION_BOOL_OPERATOR = const HintCode(
-      'SDK_VERSION_BOOL_OPERATOR',
-      "Using the operator '{0}' for 'bool's wasn't supported until version "
-          "2.3.2, but this code is required to be able to run on earlier "
-          "versions.",
+  static const HintCode SDK_VERSION_BOOL_OPERATOR_IN_CONST_CONTEXT = const HintCode(
+      'SDK_VERSION_BOOL_OPERATOR_IN_CONST_CONTEXT',
+      "Using the operator '{0}' for 'bool's in a constant expression wasn't "
+          "supported until version 2.3.2, but this code is required to be able "
+          "to run on earlier versions.",
       correction: "Try updating the SDK constraints.");
 
   /**
@@ -669,6 +669,16 @@
           correction: "Try updating the SDK constraints.");
 
   /**
+   * Extension method features are being used in code that is expected to run
+   * on versions of the SDK that did not support them.
+   */
+  static const HintCode SDK_VERSION_EXTENSION_METHODS = const HintCode(
+      'SDK_VERSION_EXTENSION_METHODS',
+      "Extension methods weren't supported until version 2.X.0, "
+          "but this code is required to be able to run on earlier versions.",
+      correction: "Try updating the SDK constraints.");
+
+  /**
    * The operator '>>>' is being used in code that is expected to run on
    * versions of the SDK that did not support it.
    */
diff --git a/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart b/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
index 964531c..58353ea5 100644
--- a/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
@@ -3,12 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/ast_factory.dart';
+import 'package:analyzer/dart/ast/standard_ast_factory.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/src/dart/ast/ast_factory.dart';
 import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/element/type.dart';
@@ -56,7 +55,6 @@
       }
       Element element = nameScope.lookup(methodName, definingLibrary);
       if (element is ClassElement) {
-        AstFactory astFactory = new AstFactoryImpl();
         TypeName typeName = astFactory.typeName(methodName, node.typeArguments);
         ConstructorName constructorName =
             astFactory.constructorName(typeName, null, null);
@@ -65,7 +63,6 @@
                 _getKeyword(node), constructorName, node.argumentList);
         NodeReplacer.replace(node, instanceCreationExpression);
       } else if (element is ExtensionElement) {
-        AstFactory astFactory = new AstFactoryImpl();
         ExtensionOverride extensionOverride = astFactory.extensionOverride(
             extensionName: methodName,
             typeArguments: node.typeArguments,
@@ -91,10 +88,10 @@
                 typeArguments,
                 [element.name, constructorElement.name]);
           }
-          AstFactory astFactory = new AstFactoryImpl();
           TypeName typeName = astFactory.typeName(target, null);
           ConstructorName constructorName =
               astFactory.constructorName(typeName, node.operator, methodName);
+          // TODO(scheglov) I think we should drop "typeArguments" below.
           InstanceCreationExpression instanceCreationExpression =
               astFactory.instanceCreationExpression(
                   _getKeyword(node), constructorName, node.argumentList,
@@ -103,7 +100,6 @@
         }
       } else if (element is PrefixElement) {
         // Possible cases: p.C() or p.C<>()
-        AstFactory astFactory = new AstFactoryImpl();
         Identifier identifier = astFactory.prefixedIdentifier(
             astFactory.simpleIdentifier(target.token),
             null,
@@ -120,7 +116,6 @@
                   _getKeyword(node), constructorName, node.argumentList);
           NodeReplacer.replace(node, instanceCreationExpression);
         } else if (prefixedElement is ExtensionElement) {
-          AstFactory astFactory = new AstFactoryImpl();
           PrefixedIdentifier extensionName =
               astFactory.prefixedIdentifier(target, node.operator, methodName);
           ExtensionOverride extensionOverride = astFactory.extensionOverride(
@@ -147,7 +142,6 @@
                   typeArguments,
                   [element.name, constructorElement.name]);
             }
-            AstFactory astFactory = new AstFactoryImpl();
             TypeName typeName = astFactory.typeName(target, typeArguments);
             ConstructorName constructorName =
                 astFactory.constructorName(typeName, node.operator, methodName);
diff --git a/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart
index e7b0ca8..1f86708 100644
--- a/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart
@@ -9,6 +9,7 @@
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/dart/element/type_algebra.dart';
+import 'package:analyzer/src/dart/resolver/resolution_result.dart';
 import 'package:analyzer/src/dart/resolver/scope.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/resolver.dart';
@@ -35,23 +36,21 @@
   /// If no applicable extensions, return `null`.
   ///
   /// If the match is ambiguous, report an error and return `null`.
-  ExtensionResolutionResult findExtension(
+  ResolutionResult findExtension(
       DartType type, String name, Expression target, ElementKind kind) {
     var extensions = _getApplicable(type, name, kind);
 
     if (extensions.isEmpty) {
-      return ExtensionResolutionResult.none;
+      return ResolutionResult.none;
     }
 
     if (extensions.length == 1) {
-      return ExtensionResolutionResult(
-          ExtensionResolutionState.single, extensions[0]);
+      return ResolutionResult(extensions[0].instantiatedMember);
     }
 
     var extension = _chooseMostSpecific(extensions);
     if (extension != null) {
-      return ExtensionResolutionResult(
-          ExtensionResolutionState.single, extension);
+      return ResolutionResult(extension.instantiatedMember);
     }
 
     _errorReporter.reportErrorForNode(
@@ -63,9 +62,36 @@
         extensions[1].element.name,
       ],
     );
-    return ExtensionResolutionResult.ambiguous;
+    return ResolutionResult.ambiguous;
   }
 
+  /// Return the member with the [name] (without `=`) of the given [kind].
+  ///
+  /// The [node] is fully resolved, and its type arguments are set.
+  ExecutableElement getOverrideMember(
+      ExtensionOverride node, String name, ElementKind kind) {
+    ExtensionElement element = node.extensionName.staticElement;
+
+    ExecutableElement member;
+    if (kind == ElementKind.GETTER) {
+      member = element.getGetter(name);
+    } else if (kind == ElementKind.METHOD) {
+      member = element.getMethod(name);
+    } else if (kind == ElementKind.SETTER) {
+      member = element.getSetter(name);
+    }
+    if (member == null) return null;
+
+    return ExecutableMember.from2(
+      member,
+      Substitution.fromPairs(
+        element.typeParameters,
+        node.typeArgumentTypes,
+      ),
+    );
+  }
+
+  /// Perform upward inference for the override.
   void resolveOverride(ExtensionOverride node) {
     var nodeImpl = node as ExtensionOverrideImpl;
     var element = node.staticElement;
@@ -93,17 +119,22 @@
     var receiverExpression = arguments[0];
     var receiverType = receiverExpression.staticType;
 
-    var typeArgumentTypes = _inferTypeArguments(
-      element,
-      receiverType,
-      node.typeArguments,
-    );
-
+    var typeArgumentTypes = _inferTypeArguments(node, receiverType);
     nodeImpl.typeArgumentTypes = typeArgumentTypes;
-    nodeImpl.extendedType = Substitution.fromPairs(
+
+    var substitution = Substitution.fromPairs(
       typeParameters,
       typeArgumentTypes,
-    ).substituteType(element.extendedType);
+    );
+
+    nodeImpl.extendedType = substitution.substituteType(element.extendedType);
+
+    _checkTypeArgumentsMatchingBounds(
+      typeParameters,
+      node.typeArguments,
+      typeArgumentTypes,
+      substitution,
+    );
 
     if (!_typeSystem.isAssignableTo(receiverType, node.extendedType)) {
       _errorReporter.reportErrorForNode(
@@ -114,10 +145,72 @@
     }
   }
 
+  /// Set the type context for the receiver of the override.
+  ///
+  /// The context of the invocation that is made through the override does
+  /// not affect the type inference of the override and the receiver.
+  void setOverrideReceiverContextType(ExtensionOverride node) {
+    var element = node.staticElement;
+    var typeParameters = element.typeParameters;
+
+    var arguments = node.argumentList.arguments;
+    if (arguments.length != 1) {
+      return;
+    }
+
+    List<DartType> typeArgumentTypes;
+    var typeArguments = node.typeArguments;
+    if (typeArguments != null) {
+      var arguments = typeArguments.arguments;
+      if (arguments.length == typeParameters.length) {
+        typeArgumentTypes = arguments.map((a) => a.type).toList();
+      } else {
+        typeArgumentTypes = _listOfDynamic(typeParameters);
+      }
+    } else {
+      typeArgumentTypes = List.filled(
+        typeParameters.length,
+        UnknownInferredType.instance,
+      );
+    }
+
+    var extendedForDownward = Substitution.fromPairs(
+      typeParameters,
+      typeArgumentTypes,
+    ).substituteType(element.extendedType);
+
+    var receiver = arguments[0];
+    InferenceContext.setType(receiver, extendedForDownward);
+  }
+
+  void _checkTypeArgumentsMatchingBounds(
+    List<TypeParameterElement> typeParameters,
+    TypeArgumentList typeArgumentList,
+    List<DartType> typeArgumentTypes,
+    Substitution substitution,
+  ) {
+    if (typeArgumentList != null) {
+      for (var i = 0; i < typeArgumentTypes.length; i++) {
+        var argType = typeArgumentTypes[i];
+        var boundType = typeParameters[i].bound;
+        if (boundType != null) {
+          boundType = substitution.substituteType(boundType);
+          if (!_typeSystem.isSubtypeOf(argType, boundType)) {
+            _errorReporter.reportTypeErrorForNode(
+              CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
+              typeArgumentList.arguments[i],
+              [argType, boundType],
+            );
+          }
+        }
+      }
+    }
+  }
+
   /// Return the most specific extension or `null` if no single one can be
   /// identified.
-  InstantiatedExtension _chooseMostSpecific(
-      List<InstantiatedExtension> extensions) {
+  _InstantiatedExtension _chooseMostSpecific(
+      List<_InstantiatedExtension> extensions) {
     //
     // https://github.com/dart-lang/language/blob/master/accepted/future-releases/static-extension-methods/feature-specification.md#extension-conflict-resolution:
     //
@@ -160,11 +253,11 @@
 
   /// Return extensions for the [type] that match the given [name] in the
   /// current scope.
-  List<InstantiatedExtension> _getApplicable(
+  List<_InstantiatedExtension> _getApplicable(
       DartType type, String name, ElementKind kind) {
     var candidates = _getExtensionsWithMember(name, kind);
 
-    var instantiatedExtensions = <InstantiatedExtension>[];
+    var instantiatedExtensions = <_InstantiatedExtension>[];
     for (var candidate in candidates) {
       var typeParameters = candidate.extension.typeParameters;
       var inferrer = GenericInferrer(
@@ -194,14 +287,12 @@
       }
 
       instantiatedExtensions.add(
-        InstantiatedExtension(
+        _InstantiatedExtension(
           candidate.extension,
           extendedType,
-          // TODO(scheglov) Hm... Maybe not use from3(), but identify null subst?
-          ExecutableMember.from3(
+          ExecutableMember.from2(
             candidate.member,
-            typeParameters,
-            typeArguments,
+            substitution,
           ),
         ),
       );
@@ -269,7 +360,7 @@
     return candidates;
   }
 
-  /// Given the generic [extension] element, either return types specified
+  /// Given the generic [element] element, either return types specified
   /// explicitly in [typeArguments], or infer type arguments from the given
   /// [receiverType].
   ///
@@ -277,15 +368,16 @@
   /// of extension's type parameters, or inference fails, return `dynamic`
   /// for all type parameters.
   List<DartType> _inferTypeArguments(
-    ExtensionElement extension,
+    ExtensionOverride node,
     DartType receiverType,
-    TypeArgumentList typeArguments,
   ) {
-    var typeParameters = extension.typeParameters;
+    var element = node.staticElement;
+    var typeParameters = element.typeParameters;
     if (typeParameters.isEmpty) {
       return const <DartType>[];
     }
 
+    var typeArguments = node.typeArguments;
     if (typeArguments != null) {
       var arguments = typeArguments.arguments;
       if (arguments.length == typeParameters.length) {
@@ -295,21 +387,21 @@
         return _listOfDynamic(typeParameters);
       }
     } else {
-      if (receiverType != null) {
-        var inferrer = GenericInferrer(
-          _typeProvider,
-          _typeSystem,
-          typeParameters,
-        );
-        inferrer.constrainArgument(
-          receiverType,
-          extension.extendedType,
-          'extendedType',
-        );
-        return inferrer.infer(typeParameters);
-      } else {
-        return _listOfDynamic(typeParameters);
-      }
+      var inferrer = GenericInferrer(
+        _typeProvider,
+        _typeSystem,
+        typeParameters,
+      );
+      inferrer.constrainArgument(
+        receiverType,
+        element.extendedType,
+        'extendedType',
+      );
+      return inferrer.infer(
+        typeParameters,
+        errorReporter: _errorReporter,
+        errorNode: node.extensionName,
+      );
     }
   }
 
@@ -323,7 +415,7 @@
     ).substituteType(extension.extendedType);
   }
 
-  bool _isMoreSpecific(InstantiatedExtension e1, InstantiatedExtension e2) {
+  bool _isMoreSpecific(_InstantiatedExtension e1, _InstantiatedExtension e2) {
     var t10 = e1.element.extendedType;
     var t20 = e2.element.extendedType;
     var t11 = e1._extendedType;
@@ -348,9 +440,9 @@
     // 2. they are both declared in platform libraries or both declared in
     //    non-platform libraries, and
     if (_isSubtypeAndNotViceVersa(t11, t21)) {
-      // 3. the instantiated type (the type after applying type inference from the
-      //    receiver) of T1 is a subtype of the instantiated type of T2 and either
-      //    not vice versa
+      // 3. the instantiated type (the type after applying type inference from
+      //    the receiver) of T1 is a subtype of the instantiated type of T2 and
+      //    either not vice versa
       return true;
     }
 
@@ -392,63 +484,21 @@
   }
 }
 
-/// The result of attempting to resolve an identifier to an extension member.
-class ExtensionResolutionResult {
-  /// An instance that can be used anywhere that no extension member was found.
-  static const ExtensionResolutionResult none =
-      ExtensionResolutionResult(ExtensionResolutionState.none, null);
-
-  /// An instance that can be used anywhere that multiple ambiguous members were
-  /// found.
-  static const ExtensionResolutionResult ambiguous =
-      ExtensionResolutionResult(ExtensionResolutionState.ambiguous, null);
-
-  /// The state of the result.
-  final ExtensionResolutionState state;
-
-  /// The extension that was found, or `null` if the [state] is not
-  /// [ExtensionResolutionState.single].
-  final InstantiatedExtension extension;
-
-  /// Initialize a newly created result.
-  const ExtensionResolutionResult(this.state, this.extension);
-
-  /// Return `true` if this result represents the case where no extension member
-  /// was found.
-  bool get isNone => state == ExtensionResolutionState.none;
-
-  /// Return `true` if this result represents the case where a single extension
-  /// member was found.
-  bool get isSingle => extension != null;
-}
-
-/// The state of an [ExtensionResolutionResult].
-enum ExtensionResolutionState {
-  /// Indicates that no extension member was found.
-  none,
-
-  /// Indicates that a single extension member was found.
-  single,
-
-  /// Indicates that multiple ambiguous members were found.
-  ambiguous
-}
-
-class InstantiatedExtension {
-  final ExtensionElement element;
-  final DartType _extendedType;
-  final ExecutableElement instantiatedMember;
-
-  InstantiatedExtension(
-    this.element,
-    this._extendedType,
-    this.instantiatedMember,
-  );
-}
-
 class _CandidateExtension {
   final ExtensionElement extension;
   final ExecutableElement member;
 
   _CandidateExtension(this.extension, this.member);
 }
+
+class _InstantiatedExtension {
+  final ExtensionElement element;
+  final DartType _extendedType;
+  final ExecutableElement instantiatedMember;
+
+  _InstantiatedExtension(
+    this.element,
+    this._extendedType,
+    this.instantiatedMember,
+  );
+}
diff --git a/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
index c126f1f..51d08be 100644
--- a/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
@@ -66,13 +66,10 @@
 
   factory FlowAnalysisHelper(
       TypeSystem typeSystem, AstNode node, bool retainDataForTesting) {
-    var assignedVariables = AssignedVariables<Statement, VariableElement>();
-    node.accept(_AssignedVariablesVisitor(assignedVariables));
-
     return FlowAnalysisHelper._(
         const AnalyzerNodeOperations(),
         _TypeSystemTypeOperations(typeSystem),
-        assignedVariables,
+        computeAssignedVariables(node),
         retainDataForTesting ? FlowAnalysisResult() : null);
   }
 
@@ -169,7 +166,7 @@
   }
 
   void breakStatement(BreakStatement node) {
-    var target = _getLabelTarget(node, node.label?.staticElement);
+    var target = getLabelTarget(node, node.label?.staticElement);
     flow.handleBreak(target);
   }
 
@@ -191,7 +188,7 @@
   }
 
   void continueStatement(ContinueStatement node) {
-    var target = _getLabelTarget(node, node.label?.staticElement);
+    var target = getLabelTarget(node, node.label?.staticElement);
     flow.handleContinue(target);
   }
 
@@ -288,7 +285,7 @@
   /// Return the target of the `break` or `continue` statement with the
   /// [element] label. The [element] might be `null` (when the statement does
   /// not specify a label), so the default enclosing target is returned.
-  AstNode _getLabelTarget(AstNode node, LabelElement element) {
+  static Statement getLabelTarget(AstNode node, LabelElement element) {
     for (; node != null; node = node.parent) {
       if (node is DoStatement ||
           node is ForStatement ||
@@ -318,6 +315,14 @@
     }
     return null;
   }
+
+  /// Computes the [AssignedVariables] map for the given [node].
+  static AssignedVariables<Statement, VariableElement> computeAssignedVariables(
+      AstNode node) {
+    var assignedVariables = AssignedVariables<Statement, VariableElement>();
+    node.accept(_AssignedVariablesVisitor(assignedVariables));
+    return assignedVariables;
+  }
 }
 
 /// The result of performing flow analysis on a unit.
diff --git a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
index 60d1e92..7fe1505 100644
--- a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
@@ -8,9 +8,9 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
-import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/resolver/extension_member_resolver.dart';
+import 'package:analyzer/src/dart/resolver/resolution_result.dart';
 import 'package:analyzer/src/dart/resolver/scope.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/resolver.dart';
@@ -41,23 +41,22 @@
   /// The object providing promoted or declared types of variables.
   final LocalVariableTypeProvider _localVariableTypeProvider;
 
+  /// Helper for extension method resolution.
+  final ExtensionMemberResolver _extensionResolver;
+
   /// The invocation being resolved.
   MethodInvocationImpl _invocation;
 
   /// The [Name] object of the invocation being resolved by [resolve].
   Name _currentName;
 
-  /// Helper for extension method resolution.
-  //todo(pq): consider sharing instance with element_resolver
-  final ExtensionMemberResolver _extensionResolver;
-
   MethodInvocationResolver(this._resolver)
       : _typeType = _resolver.typeProvider.typeType,
         _inheritance = _resolver.inheritance,
         _definingLibrary = _resolver.definingLibrary,
         _definingLibraryUri = _resolver.definingLibrary.source.uri,
         _localVariableTypeProvider = _resolver.localVariableTypeProvider,
-        _extensionResolver = ExtensionMemberResolver(_resolver);
+        _extensionResolver = _resolver.extensionResolver;
 
   /// The scope used to resolve identifiers.
   Scope get nameScope => _resolver.nameScope;
@@ -338,8 +337,9 @@
 
   /// If there is an extension matching the [receiverType] and defining a
   /// member with the given [name], resolve to the corresponding extension
-  /// method and return `true`. Otherwise return `false`.
-  ExtensionResolutionResult _resolveExtension(
+  /// method. Return a result indicating whether the [node] was resolved and if
+  /// not why.
+  ResolutionResult _resolveExtension(
     MethodInvocation node,
     DartType receiverType,
     SimpleIdentifier nameNode,
@@ -357,18 +357,18 @@
       return result;
     }
 
-    ExecutableElement member = result.extension.instantiatedMember;
+    ExecutableElement member = result.element;
+    nameNode.staticElement = member;
 
     if (member.isStatic) {
       _setDynamicResolution(node);
       _resolver.errorReporter.reportErrorForNode(
-        CompileTimeErrorCode.ACCESS_STATIC_EXTENSION_MEMBER,
-        nameNode,
-      );
+          StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER,
+          nameNode,
+          [name, member.kind.displayName, member.enclosingElement.name]);
       return result;
     }
 
-    nameNode.staticElement = member;
     var calleeType = _getCalleeType(node, member);
     _setResolution(node, calleeType);
     return result;
@@ -394,27 +394,22 @@
 
   void _resolveExtensionOverride(MethodInvocation node,
       ExtensionOverride override, SimpleIdentifier nameNode, String name) {
-    ExtensionElement element = override.extensionName.staticElement;
-    ExecutableElement member =
-        element.getMethod(name) ?? element.getGetter(name);
+    var member = _extensionResolver.getOverrideMember(
+            override, name, ElementKind.METHOD) ??
+        _extensionResolver.getOverrideMember(
+            override, name, ElementKind.GETTER);
 
     if (member == null) {
       _setDynamicResolution(node);
       _resolver.errorReporter.reportErrorForNode(
         CompileTimeErrorCode.UNDEFINED_EXTENSION_METHOD,
         nameNode,
-        [name, element.name],
+        [name, override.staticElement.name],
       );
       return;
     }
 
-    member = ExecutableMember.from3(
-      member,
-      element.typeParameters,
-      override.typeArgumentTypes,
-    );
-
-    if (member is ExecutableElement && member.isStatic) {
+    if (member.isStatic) {
       _resolver.errorReporter.reportErrorForNode(
         CompileTimeErrorCode.EXTENSION_OVERRIDE_ACCESS_TO_STATIC_MEMBER,
         nameNode,
@@ -446,9 +441,18 @@
       return;
     }
 
+    ResolutionResult result = _extensionResolver.findExtension(
+        receiverType, name, nameNode, ElementKind.METHOD);
+    if (result.isSingle) {
+      nameNode.staticElement = result.element;
+      var calleeType = _getCalleeType(node, result.element);
+      return _setResolution(node, calleeType);
+    } else if (result.isAmbiguous) {
+      return;
+    }
     // We can invoke Object methods on Function.
     var member = _inheritance.getMember(
-      _resolver.typeProvider.objectType,
+      _resolver.typeProvider.functionType,
       new Name(null, name),
     );
     if (member != null) {
@@ -579,7 +583,7 @@
     var result = _extensionResolver.findExtension(
         receiverType, name, nameNode, ElementKind.METHOD);
     if (result.isSingle) {
-      var target = result.extension.instantiatedMember;
+      var target = result.element;
       if (target != null) {
         nameNode.staticElement = target;
         var calleeType = _getCalleeType(node, target);
@@ -744,7 +748,9 @@
         var result = _extensionResolver.findExtension(
             type, _nameCall.name, node.methodName, ElementKind.METHOD);
         if (result.isSingle) {
-          call = result.extension.instantiatedMember;
+          call = result.element;
+        } else if (result.isAmbiguous) {
+          return;
         }
       }
       if (call != null && call.kind == ElementKind.METHOD) {
diff --git a/pkg/analyzer/lib/src/dart/resolver/resolution_result.dart b/pkg/analyzer/lib/src/dart/resolver/resolution_result.dart
new file mode 100644
index 0000000..1d91bf8
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/resolver/resolution_result.dart
@@ -0,0 +1,56 @@
+// 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.
+
+import 'package:analyzer/dart/element/element.dart';
+
+/// The result of attempting to resolve an identifier to a element.
+class ResolutionResult {
+  /// An instance that can be used anywhere that no element was found.
+  static const ResolutionResult none =
+      ResolutionResult._(_ResolutionResultState.none);
+
+  /// An instance that can be used anywhere that multiple elements were found.
+  static const ResolutionResult ambiguous =
+      ResolutionResult._(_ResolutionResultState.ambiguous);
+
+  /// The state of the result.
+  final _ResolutionResultState state;
+
+  /// The element that was found, or `null` if the [state] is not
+  /// [_ResolutionResultState.single].
+  final ExecutableElement element;
+
+  /// Initialize a newly created result to represent resolving to a single
+  /// [element].
+  ResolutionResult(this.element)
+      : assert(element != null),
+        state = _ResolutionResultState.single;
+
+  /// Initialize a newly created result with no element and the given [state].
+  const ResolutionResult._(this.state) : element = null;
+
+  /// Return `true` if this result represents the case where multiple ambiguous
+  /// elements were found.
+  bool get isAmbiguous => state == _ResolutionResultState.ambiguous;
+
+  /// Return `true` if this result represents the case where no element was
+  /// found.
+  bool get isNone => state == _ResolutionResultState.none;
+
+  /// Return `true` if this result represents the case where a single element
+  /// was found.
+  bool get isSingle => state == _ResolutionResultState.single;
+}
+
+/// The state of a [ResolutionResult].
+enum _ResolutionResultState {
+  /// Indicates that no element was found.
+  none,
+
+  /// Indicates that a single element was found.
+  single,
+
+  /// Indicates that multiple ambiguous elements were found.
+  ambiguous
+}
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index a3db80c..abe1bf8 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -126,15 +126,6 @@
               "same library.");
 
   /**
-   * No parameters.
-   */
-  //todo (pq): refactor to reuse StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER.
-  static const CompileTimeErrorCode ACCESS_STATIC_EXTENSION_MEMBER =
-      const CompileTimeErrorCode('ACCESS_STATIC_EXTENSION_MEMBER',
-          "Static extension members can't be accessed.",
-          correction: "Try removing the static member access.");
-
-  /**
    * 14.2 Exports: It is a compile-time error if a name <i>N</i> is re-exported
    * by a library <i>L</i> and <i>N</i> is introduced into the export namespace
    * of <i>L</i> by more than one export, unless each all exports refer to same
@@ -1269,6 +1260,22 @@
               "removing the extends clause.");
 
   /**
+   * It is for an extension to define a static member and an instance member
+   * with the same base name.
+   *
+   * Parameters:
+   * 0: the name of the extension defining the conflicting member
+   * 1: the name of the conflicting static member
+   */
+  static const CompileTimeErrorCode EXTENSION_CONFLICTING_STATIC_AND_INSTANCE =
+      const CompileTimeErrorCode(
+          'EXTENSION_CONFLICTING_STATIC_AND_INSTANCE',
+          "Extension '{0}' can't define static member '{1}' and instance "
+              "member with the same name.",
+          correction:
+              "Try renaming the member to a name that doesn't conflict.");
+
+  /**
    * No parameters.
    */
   static const CompileTimeErrorCode EXTENSION_DECLARES_ABSTRACT_MEMBER =
@@ -1459,6 +1466,13 @@
               "Try using an explicit typedef, or changing type parameters to "
               "`dynamic`.");
 
+  static const CompileTimeErrorCode IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY =
+      const CompileTimeErrorCode(
+          'IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY',
+          "Constant values from a deferred library can't be used as values in "
+              "an if condition inside a const collection literal.",
+          correction: "Try making the deferred import non-deferred.");
+
   /**
    * 7.10 Superinterfaces: It is a compile-time error if the implements clause
    * of a class <i>C</i> specifies a malformed type or deferred type as a
@@ -2618,30 +2632,6 @@
           "The values in a const set literal must be constants.",
           correction: "Try removing the keyword 'const' from the set literal.");
 
-  static const CompileTimeErrorCode
-      NON_CONSTANT_SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY =
-      const CompileTimeErrorCode(
-          'NON_CONSTANT_SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY',
-          "Constant values from a deferred library can't be spread into a "
-              "const literal.",
-          correction: "Try making the deferred import non-deferred.");
-
-  static const CompileTimeErrorCode
-      NON_CONSTANT_IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY =
-      const CompileTimeErrorCode(
-          'NON_CONSTANT_IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY',
-          "Constant values from a deferred library can't be used as values in "
-              "an if condition inside a const collection literal.",
-          correction: "Try making the deferred import non-deferred.");
-
-  static const CompileTimeErrorCode
-      NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY =
-      const CompileTimeErrorCode(
-          'NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY',
-          "Constant values from a deferred library can't be used as values in "
-              "a 'const' set.",
-          correction: "Try removing the keyword 'const' from the set literal.");
-
   /**
    * This error code is no longer being generated. It should be removed when the
    * reference to it in the linter has been removed and rolled into the SDK.
@@ -3199,6 +3189,13 @@
               "Try removing the value, replacing 'return' with 'yield' or "
               "changing the method body modifier.");
 
+  static const CompileTimeErrorCode SET_ELEMENT_FROM_DEFERRED_LIBRARY =
+      const CompileTimeErrorCode(
+          'SET_ELEMENT_FROM_DEFERRED_LIBRARY',
+          "Constant values from a deferred library can't be used as values in "
+              "a const set.",
+          correction: "Try making the deferred import non-deferred.");
+
   /**
    * 14.1 Imports: It is a compile-time error if a prefix used in a deferred
    * import is used in another import clause.
@@ -3210,6 +3207,13 @@
               "directives.",
           correction: "Try renaming one of the prefixes.");
 
+  static const CompileTimeErrorCode SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY =
+      const CompileTimeErrorCode(
+          'SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY',
+          "Constant values from a deferred library can't be spread into a "
+              "const literal.",
+          correction: "Try making the deferred import non-deferred.");
+
   /**
    * No parameters.
    */
diff --git a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
new file mode 100644
index 0000000..0dfad29
--- /dev/null
+++ b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
@@ -0,0 +1,408 @@
+// 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.
+
+import 'dart:collection';
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/error/codes.dart';
+
+class DuplicateDefinitionVerifier {
+  final LibraryElement _currentLibrary;
+  final ErrorReporter _errorReporter;
+
+  DuplicateDefinitionVerifier(this._currentLibrary, this._errorReporter);
+
+  /// Check that the exception and stack trace parameters have different names.
+  void checkCatchClause(CatchClause node) {
+    SimpleIdentifier exceptionParameter = node.exceptionParameter;
+    SimpleIdentifier stackTraceParameter = node.stackTraceParameter;
+    if (exceptionParameter != null && stackTraceParameter != null) {
+      String exceptionName = exceptionParameter.name;
+      if (exceptionName == stackTraceParameter.name) {
+        _errorReporter.reportErrorForNode(
+            CompileTimeErrorCode.DUPLICATE_DEFINITION,
+            stackTraceParameter,
+            [exceptionName]);
+      }
+    }
+  }
+
+  void checkClass(ClassDeclaration node) {
+    _checkClassMembers(node.declaredElement, node.members);
+  }
+
+  /// Check that there are no members with the same name.
+  void checkEnum(EnumDeclaration node) {
+    ClassElement element = node.declaredElement;
+
+    Map<String, Element> instanceGetters = new HashMap<String, Element>();
+    Map<String, Element> staticGetters = new HashMap<String, Element>();
+
+    String indexName = 'index';
+    String valuesName = 'values';
+    instanceGetters[indexName] = element.getGetter(indexName);
+    staticGetters[valuesName] = element.getGetter(valuesName);
+
+    for (EnumConstantDeclaration constant in node.constants) {
+      _checkDuplicateIdentifier(staticGetters, constant.name);
+    }
+
+    for (EnumConstantDeclaration constant in node.constants) {
+      SimpleIdentifier identifier = constant.name;
+      String name = identifier.name;
+      if (instanceGetters.containsKey(name)) {
+        String enumName = element.displayName;
+        _errorReporter.reportErrorForNode(
+            CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE,
+            identifier,
+            [enumName, name, enumName]);
+      }
+    }
+  }
+
+  /// Check that there are no members with the same name.
+  void checkExtension(ExtensionDeclaration node) {
+    var instanceGetters = <String, Element>{};
+    var instanceSetters = <String, Element>{};
+    var staticGetters = <String, Element>{};
+    var staticSetters = <String, Element>{};
+
+    for (var member in node.members) {
+      if (member is FieldDeclaration) {
+        for (var field in member.fields.variables) {
+          var identifier = field.name;
+          _checkDuplicateIdentifier(
+            member.isStatic ? staticGetters : instanceGetters,
+            identifier,
+            setterScope: member.isStatic ? staticSetters : instanceSetters,
+          );
+        }
+      } else if (member is MethodDeclaration) {
+        _checkDuplicateIdentifier(
+          member.isStatic ? staticGetters : instanceGetters,
+          member.name,
+          setterScope: member.isStatic ? staticSetters : instanceSetters,
+        );
+      }
+    }
+
+    // Check for local static members conflicting with local instance members.
+    for (var member in node.members) {
+      if (member is FieldDeclaration) {
+        if (member.isStatic) {
+          for (var field in member.fields.variables) {
+            var identifier = field.name;
+            var name = identifier.name;
+            if (instanceGetters.containsKey(name) ||
+                instanceSetters.containsKey(name)) {
+              _errorReporter.reportErrorForNode(
+                CompileTimeErrorCode.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE,
+                identifier,
+                [node.declaredElement.name, name],
+              );
+            }
+          }
+        }
+      } else if (member is MethodDeclaration) {
+        if (member.isStatic) {
+          var identifier = member.name;
+          var name = identifier.name;
+          if (instanceGetters.containsKey(name) ||
+              instanceSetters.containsKey(name)) {
+            _errorReporter.reportErrorForNode(
+              CompileTimeErrorCode.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE,
+              identifier,
+              [node.declaredElement.name, name],
+            );
+          }
+        }
+      }
+    }
+  }
+
+  /// Check that the given list of variable declarations does not define
+  /// multiple variables of the same name.
+  void checkForVariables(VariableDeclarationList node) {
+    Map<String, Element> definedNames = new HashMap<String, Element>();
+    for (VariableDeclaration variable in node.variables) {
+      _checkDuplicateIdentifier(definedNames, variable.name);
+    }
+  }
+
+  void checkMixin(MixinDeclaration node) {
+    _checkClassMembers(node.declaredElement, node.members);
+  }
+
+  /**
+   * Check that all of the parameters have unique names.
+   */
+  void checkParameters(FormalParameterList node) {
+    Map<String, Element> definedNames = new HashMap<String, Element>();
+    for (FormalParameter parameter in node.parameters) {
+      SimpleIdentifier identifier = parameter.identifier;
+      if (identifier != null) {
+        // The identifier can be null if this is a parameter list for a generic
+        // function type.
+        _checkDuplicateIdentifier(definedNames, identifier);
+      }
+    }
+  }
+
+  /// Check that all of the variables have unique names.
+  void checkStatements(List<Statement> statements) {
+    Map<String, Element> definedNames = new HashMap<String, Element>();
+    for (Statement statement in statements) {
+      if (statement is VariableDeclarationStatement) {
+        for (VariableDeclaration variable in statement.variables.variables) {
+          _checkDuplicateIdentifier(definedNames, variable.name);
+        }
+      } else if (statement is FunctionDeclarationStatement) {
+        _checkDuplicateIdentifier(
+            definedNames, statement.functionDeclaration.name);
+      }
+    }
+  }
+
+  /// Check that all of the parameters have unique names.
+  void checkTypeParameters(TypeParameterList node) {
+    Map<String, Element> definedNames = new HashMap<String, Element>();
+    for (TypeParameter parameter in node.typeParameters) {
+      _checkDuplicateIdentifier(definedNames, parameter.name);
+    }
+  }
+
+  /// Check that there are no members with the same name.
+  void checkUnit(CompilationUnit node) {
+    Map<String, Element> definedGetters = new HashMap<String, Element>();
+    Map<String, Element> definedSetters = new HashMap<String, Element>();
+
+    void addWithoutChecking(CompilationUnitElement element) {
+      for (PropertyAccessorElement accessor in element.accessors) {
+        String name = accessor.name;
+        if (accessor.isSetter) {
+          name += '=';
+        }
+        definedGetters[name] = accessor;
+      }
+      for (ClassElement type in element.enums) {
+        definedGetters[type.name] = type;
+      }
+      for (FunctionElement function in element.functions) {
+        definedGetters[function.name] = function;
+      }
+      for (FunctionTypeAliasElement alias in element.functionTypeAliases) {
+        definedGetters[alias.name] = alias;
+      }
+      for (TopLevelVariableElement variable in element.topLevelVariables) {
+        definedGetters[variable.name] = variable;
+        if (!variable.isFinal && !variable.isConst) {
+          definedGetters[variable.name + '='] = variable;
+        }
+      }
+      for (ClassElement type in element.types) {
+        definedGetters[type.name] = type;
+      }
+    }
+
+    for (ImportElement importElement in _currentLibrary.imports) {
+      PrefixElement prefix = importElement.prefix;
+      if (prefix != null) {
+        definedGetters[prefix.name] = prefix;
+      }
+    }
+    CompilationUnitElement element = node.declaredElement;
+    if (element != _currentLibrary.definingCompilationUnit) {
+      addWithoutChecking(_currentLibrary.definingCompilationUnit);
+      for (CompilationUnitElement part in _currentLibrary.parts) {
+        if (element == part) {
+          break;
+        }
+        addWithoutChecking(part);
+      }
+    }
+    for (CompilationUnitMember member in node.declarations) {
+      if (member is ExtensionDeclaration) {
+        var identifier = member.name;
+        if (identifier != null) {
+          _checkDuplicateIdentifier(definedGetters, identifier,
+              setterScope: definedSetters);
+        }
+      } else if (member is NamedCompilationUnitMember) {
+        _checkDuplicateIdentifier(definedGetters, member.name,
+            setterScope: definedSetters);
+      } else if (member is TopLevelVariableDeclaration) {
+        for (VariableDeclaration variable in member.variables.variables) {
+          _checkDuplicateIdentifier(definedGetters, variable.name,
+              setterScope: definedSetters);
+        }
+      }
+    }
+  }
+
+  /// Check that there are no members with the same name.
+  void _checkClassMembers(ClassElement element, List<ClassMember> members) {
+    Set<String> constructorNames = new HashSet<String>();
+    Map<String, Element> instanceGetters = new HashMap<String, Element>();
+    Map<String, Element> instanceSetters = new HashMap<String, Element>();
+    Map<String, Element> staticGetters = new HashMap<String, Element>();
+    Map<String, Element> staticSetters = new HashMap<String, Element>();
+
+    for (ClassMember member in members) {
+      if (member is ConstructorDeclaration) {
+        var name = member.name?.name ?? '';
+        if (!constructorNames.add(name)) {
+          if (name.isEmpty) {
+            _errorReporter.reportErrorForNode(
+                CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT, member);
+          } else {
+            _errorReporter.reportErrorForNode(
+                CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME,
+                member,
+                [name]);
+          }
+        }
+      } else if (member is FieldDeclaration) {
+        for (VariableDeclaration field in member.fields.variables) {
+          SimpleIdentifier identifier = field.name;
+          _checkDuplicateIdentifier(
+            member.isStatic ? staticGetters : instanceGetters,
+            identifier,
+            setterScope: member.isStatic ? staticSetters : instanceSetters,
+          );
+        }
+      } else if (member is MethodDeclaration) {
+        _checkDuplicateIdentifier(
+          member.isStatic ? staticGetters : instanceGetters,
+          member.name,
+          setterScope: member.isStatic ? staticSetters : instanceSetters,
+        );
+      }
+    }
+
+    // Check for local static members conflicting with local instance members.
+    for (ClassMember member in members) {
+      if (member is ConstructorDeclaration) {
+        if (member.name != null) {
+          String name = member.name.name;
+          var staticMember = staticGetters[name] ?? staticSetters[name];
+          if (staticMember != null) {
+            if (staticMember is PropertyAccessorElement) {
+              _errorReporter.reportErrorForNode(
+                CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_FIELD,
+                member.name,
+                [name],
+              );
+            } else {
+              _errorReporter.reportErrorForNode(
+                CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_METHOD,
+                member.name,
+                [name],
+              );
+            }
+          }
+        }
+      } else if (member is FieldDeclaration) {
+        if (member.isStatic) {
+          for (VariableDeclaration field in member.fields.variables) {
+            SimpleIdentifier identifier = field.name;
+            String name = identifier.name;
+            if (instanceGetters.containsKey(name) ||
+                instanceSetters.containsKey(name)) {
+              String className = element.displayName;
+              _errorReporter.reportErrorForNode(
+                  CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE,
+                  identifier,
+                  [className, name, className]);
+            }
+          }
+        }
+      } else if (member is MethodDeclaration) {
+        if (member.isStatic) {
+          SimpleIdentifier identifier = member.name;
+          String name = identifier.name;
+          if (instanceGetters.containsKey(name) ||
+              instanceSetters.containsKey(name)) {
+            String className = identifier.staticElement.enclosingElement.name;
+            _errorReporter.reportErrorForNode(
+                CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE,
+                identifier,
+                [className, name, className]);
+          }
+        }
+      }
+    }
+  }
+
+  /// Check whether the given [element] defined by the [identifier] is already
+  /// in one of the scopes - [getterScope] or [setterScope], and produce an
+  /// error if it is.
+  void _checkDuplicateIdentifier(
+      Map<String, Element> getterScope, SimpleIdentifier identifier,
+      {Element element, Map<String, Element> setterScope}) {
+    element ??= identifier.staticElement;
+
+    // Fields define getters and setters, so check them separately.
+    if (element is PropertyInducingElement) {
+      _checkDuplicateIdentifier(getterScope, identifier,
+          element: element.getter, setterScope: setterScope);
+      if (!element.isConst && !element.isFinal) {
+        _checkDuplicateIdentifier(getterScope, identifier,
+            element: element.setter, setterScope: setterScope);
+      }
+      return;
+    }
+
+    ErrorCode getError(Element previous, Element current) {
+      if (previous is PrefixElement) {
+        return CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER;
+      }
+      return CompileTimeErrorCode.DUPLICATE_DEFINITION;
+    }
+
+    bool isGetterSetterPair(Element a, Element b) {
+      if (a is PropertyAccessorElement && b is PropertyAccessorElement) {
+        return a.isGetter && b.isSetter || a.isSetter && b.isGetter;
+      }
+      return false;
+    }
+
+    String name = identifier.name;
+    if (element is MethodElement && element.isOperator && name == '-') {
+      if (element.parameters.isEmpty) {
+        name = 'unary-';
+      }
+    }
+
+    Element previous = getterScope[name];
+    if (previous != null) {
+      if (isGetterSetterPair(element, previous)) {
+        // OK
+      } else {
+        _errorReporter.reportErrorForNode(
+          getError(previous, element),
+          identifier,
+          [name],
+        );
+      }
+    } else {
+      getterScope[name] = element;
+    }
+
+    if (element is PropertyAccessorElement && element.isSetter) {
+      previous = setterScope[name];
+      if (previous != null) {
+        _errorReporter.reportErrorForNode(
+          getError(previous, element),
+          identifier,
+          [name],
+        );
+      } else {
+        setterScope[name] = element;
+      }
+    }
+  }
+}
diff --git a/pkg/analyzer/lib/src/error/type_arguments_verifier.dart b/pkg/analyzer/lib/src/error/type_arguments_verifier.dart
new file mode 100644
index 0000000..634f41a
--- /dev/null
+++ b/pkg/analyzer/lib/src/error/type_arguments_verifier.dart
@@ -0,0 +1,431 @@
+// 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.
+
+import "dart:math" as math;
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
+import 'package:analyzer/src/generated/resolver.dart';
+
+class TypeArgumentsVerifier {
+  final AnalysisOptionsImpl _options;
+  final TypeSystem _typeSystem;
+  final ErrorReporter _errorReporter;
+
+  TypeArgumentsVerifier(this._options, this._typeSystem, this._errorReporter);
+
+  TypeProvider get _typeProvider => _typeSystem.typeProvider;
+
+  void checkFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+    _checkTypeArguments(node);
+    _checkForImplicitDynamicInvoke(node);
+  }
+
+  void checkListLiteral(ListLiteral node) {
+    TypeArgumentList typeArguments = node.typeArguments;
+    if (typeArguments != null) {
+      if (node.isConst) {
+        _checkTypeArgumentConst(
+          typeArguments.arguments,
+          CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST,
+        );
+      }
+      _checkTypeArgumentCount(typeArguments, 1,
+          StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS);
+    }
+    _checkForImplicitDynamicTypedLiteral(node);
+  }
+
+  void checkMapLiteral(SetOrMapLiteral node) {
+    TypeArgumentList typeArguments = node.typeArguments;
+    if (typeArguments != null) {
+      if (node.isConst) {
+        _checkTypeArgumentConst(
+          typeArguments.arguments,
+          CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP,
+        );
+      }
+      _checkTypeArgumentCount(typeArguments, 2,
+          StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS);
+    }
+    _checkForImplicitDynamicTypedLiteral(node);
+  }
+
+  void checkMethodInvocation(MethodInvocation node) {
+    _checkTypeArguments(node);
+    _checkForImplicitDynamicInvoke(node);
+  }
+
+  void checkSetLiteral(SetOrMapLiteral node) {
+    TypeArgumentList typeArguments = node.typeArguments;
+    if (typeArguments != null) {
+      if (node.isConst) {
+        _checkTypeArgumentConst(
+          typeArguments.arguments,
+          CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_SET,
+        );
+      }
+      _checkTypeArgumentCount(typeArguments, 1,
+          StaticTypeWarningCode.EXPECTED_ONE_SET_TYPE_ARGUMENTS);
+    }
+    _checkForImplicitDynamicTypedLiteral(node);
+  }
+
+  void checkTypeName(TypeName node) {
+    _checkForTypeArgumentNotMatchingBounds(node);
+    if (node.parent is ConstructorName &&
+        node.parent.parent is InstanceCreationExpression) {
+      _checkForInferenceFailureOnInstanceCreation(node, node.parent.parent);
+    } else {
+      _checkForRawTypeName(node);
+    }
+  }
+
+  void _checkForImplicitDynamicInvoke(InvocationExpression node) {
+    if (_options.implicitDynamic ||
+        node == null ||
+        node.typeArguments != null) {
+      return;
+    }
+    DartType invokeType = node.staticInvokeType;
+    DartType declaredType = node.function.staticType;
+    if (invokeType is FunctionType &&
+        declaredType is FunctionType &&
+        declaredType.typeFormals.isNotEmpty) {
+      List<DartType> typeArgs = node.typeArgumentTypes;
+      if (typeArgs.any((t) => t.isDynamic)) {
+        // Issue an error depending on what we're trying to call.
+        Expression function = node.function;
+        if (function is Identifier) {
+          Element element = function.staticElement;
+          if (element is MethodElement) {
+            _errorReporter.reportErrorForNode(
+                StrongModeCode.IMPLICIT_DYNAMIC_METHOD,
+                node.function,
+                [element.displayName, element.typeParameters.join(', ')]);
+            return;
+          }
+
+          if (element is FunctionElement) {
+            _errorReporter.reportErrorForNode(
+                StrongModeCode.IMPLICIT_DYNAMIC_FUNCTION,
+                node.function,
+                [element.displayName, element.typeParameters.join(', ')]);
+            return;
+          }
+        }
+
+        // The catch all case if neither of those matched.
+        // For example, invoking a function expression.
+        _errorReporter.reportErrorForNode(
+            StrongModeCode.IMPLICIT_DYNAMIC_INVOKE,
+            node.function,
+            [declaredType]);
+      }
+    }
+  }
+
+  void _checkForImplicitDynamicTypedLiteral(TypedLiteral node) {
+    if (_options.implicitDynamic || node.typeArguments != null) {
+      return;
+    }
+    DartType type = node.staticType;
+    // It's an error if either the key or value was inferred as dynamic.
+    if (type is InterfaceType && type.typeArguments.any((t) => t.isDynamic)) {
+      // TODO(brianwilkerson) Add StrongModeCode.IMPLICIT_DYNAMIC_SET_LITERAL
+      ErrorCode errorCode = node is ListLiteral
+          ? StrongModeCode.IMPLICIT_DYNAMIC_LIST_LITERAL
+          : StrongModeCode.IMPLICIT_DYNAMIC_MAP_LITERAL;
+      _errorReporter.reportErrorForNode(errorCode, node);
+    }
+  }
+
+  /// Checks a type on an instance creation expression for an inference
+  /// failure, and reports the appropriate error if
+  /// [AnalysisOptionsImpl.strictInference] is set.
+  ///
+  /// This checks if [node] refers to a generic type and does not have explicit
+  /// or inferred type arguments. When that happens, it reports a
+  /// HintMode.INFERENCE_FAILURE_ON_INSTANCE_CREATION error.
+  void _checkForInferenceFailureOnInstanceCreation(
+      TypeName node, InstanceCreationExpression inferenceContextNode) {
+    if (!_options.strictInference || node == null) return;
+    if (node.typeArguments != null) {
+      // Type has explicit type arguments.
+      return;
+    }
+    if (_isMissingTypeArguments(
+        node, node.type, node.name.staticElement, inferenceContextNode)) {
+      _errorReporter.reportErrorForNode(
+          HintCode.INFERENCE_FAILURE_ON_INSTANCE_CREATION, node, [node.type]);
+    }
+  }
+
+  /// Checks a type annotation for a raw generic type, and reports the
+  /// appropriate error if [AnalysisOptionsImpl.strictRawTypes] is set.
+  ///
+  /// This checks if [node] refers to a generic type and does not have explicit
+  /// or inferred type arguments. When that happens, it reports error code
+  /// [HintCode.STRICT_RAW_TYPE].
+  void _checkForRawTypeName(TypeName node) {
+    AstNode parentEscapingTypeArguments(TypeName node) {
+      AstNode parent = node.parent;
+      while (parent is TypeArgumentList || parent is TypeName) {
+        if (parent.parent == null) {
+          return parent;
+        }
+        parent = parent.parent;
+      }
+      return parent;
+    }
+
+    if (!_options.strictRawTypes || node == null) return;
+    if (node.typeArguments != null) {
+      // Type has explicit type arguments.
+      return;
+    }
+    if (_isMissingTypeArguments(
+        node, node.type, node.name.staticElement, null)) {
+      AstNode unwrappedParent = parentEscapingTypeArguments(node);
+      if (unwrappedParent is AsExpression) {
+        _errorReporter.reportErrorForNode(
+            HintCode.STRICT_RAW_TYPE_IN_AS, node, [node.type]);
+      } else if (unwrappedParent is IsExpression) {
+        _errorReporter.reportErrorForNode(
+            HintCode.STRICT_RAW_TYPE_IN_IS, node, [node.type]);
+      } else {
+        _errorReporter
+            .reportErrorForNode(HintCode.STRICT_RAW_TYPE, node, [node.type]);
+      }
+    }
+  }
+
+  /**
+   * Verify that the type arguments in the given [typeName] are all within
+   * their bounds.
+   */
+  void _checkForTypeArgumentNotMatchingBounds(TypeName typeName) {
+    // prepare Type
+    DartType type = typeName.type;
+    if (type == null) {
+      return;
+    }
+    if (type is ParameterizedType) {
+      var element = typeName.name.staticElement;
+      // prepare type parameters
+      List<TypeParameterElement> parameterElements;
+      if (element is ClassElement) {
+        parameterElements = element.typeParameters;
+      } else if (element is GenericTypeAliasElement) {
+        parameterElements = element.typeParameters;
+      } else if (element is GenericFunctionTypeElement) {
+        // TODO(paulberry): it seems like either this case or the one above
+        // should be unnecessary.
+        FunctionTypeAliasElement typedefElement = element.enclosingElement;
+        parameterElements = typedefElement.typeParameters;
+      } else if (type is FunctionType) {
+        parameterElements = type.typeFormals;
+      } else {
+        // There are no other kinds of parameterized types.
+        throw new UnimplementedError(
+            'Unexpected element associated with parameterized type: '
+            '${element.runtimeType}');
+      }
+      var parameterTypes =
+          parameterElements.map<DartType>((p) => p.type).toList();
+      List<DartType> arguments = type.typeArguments;
+      // iterate over each bounded type parameter and corresponding argument
+      NodeList<TypeAnnotation> argumentNodes =
+          typeName.typeArguments?.arguments;
+      var typeArguments = type.typeArguments;
+      int loopThroughIndex =
+          math.min(typeArguments.length, parameterElements.length);
+      bool shouldSubstitute =
+          arguments.isNotEmpty && arguments.length == parameterTypes.length;
+      for (int i = 0; i < loopThroughIndex; i++) {
+        DartType argType = typeArguments[i];
+        TypeAnnotation argumentNode =
+            argumentNodes != null && i < argumentNodes.length
+                ? argumentNodes[i]
+                : typeName;
+        if (argType is FunctionType && argType.typeFormals.isNotEmpty) {
+          _errorReporter.reportErrorForNode(
+            CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
+            argumentNode,
+          );
+          continue;
+        }
+        DartType boundType = parameterElements[i].bound;
+        if (argType != null && boundType != null) {
+          if (shouldSubstitute) {
+            boundType = boundType.substitute2(arguments, parameterTypes);
+          }
+
+          if (!_typeSystem.isSubtypeOf(argType, boundType)) {
+            if (_shouldAllowSuperBoundedTypes(typeName)) {
+              var replacedType =
+                  (argType as TypeImpl).replaceTopAndBottom(_typeProvider);
+              if (!identical(replacedType, argType) &&
+                  _typeSystem.isSubtypeOf(replacedType, boundType)) {
+                // Bound is satisfied under super-bounded rules, so we're ok.
+                continue;
+              }
+            }
+            _errorReporter.reportTypeErrorForNode(
+                CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
+                argumentNode,
+                [argType, boundType]);
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * Checks to ensure that the given list of type [arguments] does not have a
+   * type parameter as a type argument. The [errorCode] is either
+   * [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST] or
+   * [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP].
+   */
+  void _checkTypeArgumentConst(
+      NodeList<TypeAnnotation> arguments, ErrorCode errorCode) {
+    for (TypeAnnotation type in arguments) {
+      if (type is TypeName && type.type is TypeParameterType) {
+        _errorReporter.reportErrorForNode(errorCode, type, [type.name]);
+      }
+    }
+  }
+
+  /// Verify that the given list of [typeArguments] contains exactly the
+  /// [expectedCount] of elements, reporting an error with the [errorCode]
+  /// if not.
+  void _checkTypeArgumentCount(
+    TypeArgumentList typeArguments,
+    int expectedCount,
+    ErrorCode errorCode,
+  ) {
+    int actualCount = typeArguments.arguments.length;
+    if (actualCount != expectedCount) {
+      _errorReporter.reportErrorForNode(
+        errorCode,
+        typeArguments,
+        [actualCount],
+      );
+    }
+  }
+
+  /**
+   * Verify that the given [typeArguments] are all within their bounds, as
+   * defined by the given [element].
+   */
+  void _checkTypeArguments(InvocationExpression node) {
+    NodeList<TypeAnnotation> typeArgumentList = node.typeArguments?.arguments;
+    if (typeArgumentList == null) {
+      return;
+    }
+
+    var genericType = node.function.staticType;
+    var instantiatedType = node.staticInvokeType;
+    if (genericType is FunctionType && instantiatedType is FunctionType) {
+      var fnTypeParams =
+          TypeParameterTypeImpl.getTypes(genericType.typeFormals);
+      var typeArgs = typeArgumentList.map((t) => t.type).toList();
+
+      // If the amount mismatches, clean up the lists to be substitutable. The
+      // mismatch in size is reported elsewhere, but we must successfully
+      // perform substitution to validate bounds on mismatched lists.
+      final providedLength = math.min(typeArgs.length, fnTypeParams.length);
+      fnTypeParams = fnTypeParams.sublist(0, providedLength);
+      typeArgs = typeArgs.sublist(0, providedLength);
+
+      for (int i = 0; i < providedLength; i++) {
+        // Check the `extends` clause for the type parameter, if any.
+        //
+        // Also substitute to handle cases like this:
+        //
+        //     <TFrom, TTo extends TFrom>
+        //     <TFrom, TTo extends Iterable<TFrom>>
+        //     <T extends Clonable<T>>
+        //
+        DartType argType = typeArgs[i];
+
+        if (argType is FunctionType && argType.typeFormals.isNotEmpty) {
+          _errorReporter.reportErrorForNode(
+            CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
+            typeArgumentList[i],
+          );
+          continue;
+        }
+
+        DartType bound =
+            fnTypeParams[i].bound.substitute2(typeArgs, fnTypeParams);
+        if (!_typeSystem.isSubtypeOf(argType, bound)) {
+          _errorReporter.reportTypeErrorForNode(
+              CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
+              typeArgumentList[i],
+              [argType, bound]);
+        }
+      }
+    }
+  }
+
+  /// Given a [node] without type arguments that refers to [element], issues
+  /// an error if [type] is a generic type, and the type arguments were not
+  /// supplied from inference or a non-dynamic default instantiation.
+  ///
+  /// This function is used by other node-specific type checking functions, and
+  /// should only be called when [node] has no explicit `typeArguments`.
+  ///
+  /// [inferenceContextNode] is the node that has the downwards context type,
+  /// if any. For example an [InstanceCreationExpression].
+  ///
+  /// This function will return false if any of the following are true:
+  ///
+  /// - [inferenceContextNode] has an inference context type that does not
+  ///   contain `?`
+  /// - [type] does not have any `dynamic` type arguments.
+  /// - the element is marked with `@optionalTypeArgs` from "package:meta".
+  bool _isMissingTypeArguments(AstNode node, DartType type, Element element,
+      Expression inferenceContextNode) {
+    // Check if this type has type arguments and at least one is dynamic.
+    // If so, we may need to issue a strict-raw-types error.
+    if (type is ParameterizedType &&
+        type.typeArguments.any((t) => t.isDynamic)) {
+      // If we have an inference context node, check if the type was inferred
+      // from it. Some cases will not have a context type, such as the type
+      // annotation `List` in `List list;`
+      if (inferenceContextNode != null) {
+        var contextType = InferenceContext.getContext(inferenceContextNode);
+        if (contextType != null && UnknownInferredType.isKnown(contextType)) {
+          // Type was inferred from downwards context: not an error.
+          return false;
+        }
+      }
+      if (element.hasOptionalTypeArgs) {
+        return false;
+      }
+      return true;
+    }
+    return false;
+  }
+
+  /// Determines if the given [typeName] occurs in a context where super-bounded
+  /// types are allowed.
+  bool _shouldAllowSuperBoundedTypes(TypeName typeName) {
+    var parent = typeName.parent;
+    if (parent is ExtendsClause) return false;
+    if (parent is OnClause) return false;
+    if (parent is ClassTypeAlias) return false;
+    if (parent is WithClause) return false;
+    if (parent is ConstructorName) return false;
+    if (parent is ImplementsClause) return false;
+    return true;
+  }
+}
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index 0baf769..7c64ff0 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -19,10 +19,10 @@
 import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
-import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/resolver/extension_member_resolver.dart';
 import 'package:analyzer/src/dart/resolver/method_invocation_resolver.dart';
+import 'package:analyzer/src/dart/resolver/resolution_result.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
@@ -116,9 +116,10 @@
   /// Whether constant evaluation errors should be reported during resolution.
   final bool reportConstEvaluationErrors;
 
-  final MethodInvocationResolver _methodInvocationResolver;
+  /// Helper for extension method resolution.
+  final ExtensionMemberResolver _extensionResolver;
 
-  final ExtensionMemberResolver _extensionMemberResolver;
+  final MethodInvocationResolver _methodInvocationResolver;
 
   /**
    * Initialize a newly created visitor to work for the given [_resolver] to
@@ -127,7 +128,7 @@
   ElementResolver(this._resolver, {this.reportConstEvaluationErrors: true})
       : _inheritance = _resolver.inheritance,
         _definingLibrary = _resolver.definingLibrary,
-        _extensionMemberResolver = ExtensionMemberResolver(_resolver),
+        _extensionResolver = _resolver.extensionResolver,
         _methodInvocationResolver = new MethodInvocationResolver(_resolver) {
     _dynamicType = _resolver.typeProvider.dynamicType;
     _typeType = _resolver.typeProvider.typeType;
@@ -171,10 +172,10 @@
         String methodName = operatorType.lexeme;
         // TODO(brianwilkerson) Change the [methodNameNode] from the left hand
         //  side to the operator.
-        MethodElement staticMethod =
+        ResolutionResult result =
             _lookUpMethod(leftHandSide, staticType, methodName, leftHandSide);
-        node.staticElement = staticMethod;
-        if (_shouldReportInvalidMember(staticType, staticMethod)) {
+        node.staticElement = result.element;
+        if (_shouldReportInvalidMember(staticType, result)) {
           _recordUndefinedToken(
               staticType.element,
               StaticTypeWarningCode.UNDEFINED_OPERATOR,
@@ -270,7 +271,8 @@
               memberElement = element.getNamedConstructor(name.name);
               if (memberElement == null) {
                 memberElement =
-                    _lookUpSetter(prefix, element.type, name.name, name);
+                    _lookUpSetter(prefix, element.type, name.name, name)
+                        .element;
               }
             }
             if (memberElement == null) {
@@ -403,8 +405,8 @@
     Expression function = node.function;
     DartType functionType;
     if (function is ExtensionOverride) {
-      ExtensionElement element = function.extensionName.staticElement;
-      MethodElement member = element.getMethod('call');
+      var member = _extensionResolver.getOverrideMember(
+          function, 'call', ElementKind.METHOD);
       if (member != null && member.isStatic) {
         _resolver.errorReporter.reportErrorForNode(
             CompileTimeErrorCode.EXTENSION_OVERRIDE_ACCESS_TO_STATIC_MEMBER,
@@ -480,41 +482,41 @@
     bool isInSetterContext = node.inSetterContext();
     if (isInGetterContext && isInSetterContext) {
       // lookup setter
-      MethodElement setterStaticMethod =
+      ResolutionResult setterResult =
           _lookUpMethod(target, staticType, setterMethodName, target);
       // set setter element
-      node.staticElement = setterStaticMethod;
+      node.staticElement = setterResult.element;
       // generate undefined method warning
       _checkForUndefinedIndexOperator(
-          node, target, setterMethodName, setterStaticMethod, staticType);
+          node, target, setterMethodName, setterResult, staticType);
       // lookup getter method
-      MethodElement getterStaticMethod =
+      ResolutionResult getterResult =
           _lookUpMethod(target, staticType, getterMethodName, target);
       // set getter element
       AuxiliaryElements auxiliaryElements =
-          new AuxiliaryElements(getterStaticMethod, null);
+          new AuxiliaryElements(getterResult.element, null);
       node.auxiliaryElements = auxiliaryElements;
       // generate undefined method warning
       _checkForUndefinedIndexOperator(
-          node, target, getterMethodName, getterStaticMethod, staticType);
+          node, target, getterMethodName, getterResult, staticType);
     } else if (isInGetterContext) {
       // lookup getter method
-      MethodElement staticMethod =
+      ResolutionResult methodResult =
           _lookUpMethod(target, staticType, getterMethodName, target);
       // set getter element
-      node.staticElement = staticMethod;
+      node.staticElement = methodResult.element;
       // generate undefined method warning
       _checkForUndefinedIndexOperator(
-          node, target, getterMethodName, staticMethod, staticType);
+          node, target, getterMethodName, methodResult, staticType);
     } else if (isInSetterContext) {
       // lookup setter method
-      MethodElement staticMethod =
+      ResolutionResult methodResult =
           _lookUpMethod(target, staticType, setterMethodName, target);
       // set setter element
-      node.staticElement = staticMethod;
+      node.staticElement = methodResult.element;
       // generate undefined method warning
       _checkForUndefinedIndexOperator(
-          node, target, setterMethodName, staticMethod, staticType);
+          node, target, setterMethodName, methodResult, staticType);
     }
   }
 
@@ -569,10 +571,10 @@
     DartType staticType = _getStaticType(operand);
     // TODO(brianwilkerson) Change the [methodNameNode] from the operand to
     //  the operator.
-    MethodElement staticMethod =
+    ResolutionResult result =
         _lookUpMethod(operand, staticType, methodName, operand);
-    node.staticElement = staticMethod;
-    if (_shouldReportInvalidMember(staticType, staticMethod)) {
+    node.staticElement = result.element;
+    if (_shouldReportInvalidMember(staticType, result)) {
       if (operand is SuperExpression) {
         _recordUndefinedToken(
             staticType.element,
@@ -677,10 +679,10 @@
       DartType staticType = _getStaticType(operand, read: true);
       // TODO(brianwilkerson) Change the [methodNameNode] from the operand to
       //  the operator.
-      MethodElement staticMethod =
+      ResolutionResult result =
           _lookUpMethod(operand, staticType, methodName, operand);
-      node.staticElement = staticMethod;
-      if (_shouldReportInvalidMember(staticType, staticMethod)) {
+      node.staticElement = result.element;
+      if (_shouldReportInvalidMember(staticType, result)) {
         if (operand is SuperExpression) {
           _recordUndefinedToken(
               staticType.element,
@@ -714,7 +716,8 @@
       String memberName = propertyName.name;
       ExecutableElement member;
       if (propertyName.inSetterContext()) {
-        member = element.getSetter(memberName);
+        member = _extensionResolver.getOverrideMember(
+            target, memberName, ElementKind.SETTER);
         if (member == null) {
           _resolver.errorReporter.reportErrorForNode(
               CompileTimeErrorCode.UNDEFINED_EXTENSION_SETTER,
@@ -722,7 +725,8 @@
               [memberName, element.name]);
         }
         if (propertyName.inGetterContext()) {
-          PropertyAccessorElement getter = element.getGetter(memberName);
+          PropertyAccessorElement getter = _extensionResolver.getOverrideMember(
+              target, memberName, ElementKind.GETTER);
           if (getter == null) {
             _resolver.errorReporter.reportErrorForNode(
                 CompileTimeErrorCode.UNDEFINED_EXTENSION_GETTER,
@@ -732,7 +736,10 @@
           propertyName.auxiliaryElements = AuxiliaryElements(getter, null);
         }
       } else if (propertyName.inGetterContext()) {
-        member = element.getGetter(memberName) ?? element.getMethod(memberName);
+        member = _extensionResolver.getOverrideMember(
+                target, memberName, ElementKind.GETTER) ??
+            _extensionResolver.getOverrideMember(
+                target, memberName, ElementKind.METHOD);
         if (member == null) {
           _resolver.errorReporter.reportErrorForNode(
               CompileTimeErrorCode.UNDEFINED_EXTENSION_GETTER,
@@ -746,12 +753,6 @@
             propertyName);
       }
 
-      member = ExecutableMember.from3(
-        member,
-        element.typeParameters,
-        target.typeArgumentTypes,
-      );
-
       propertyName.staticElement = member;
       return;
     }
@@ -877,7 +878,7 @@
         enclosingClass != null) {
       InterfaceType enclosingType = enclosingClass.type;
       AuxiliaryElements auxiliaryElements = new AuxiliaryElements(
-          _lookUpGetter(null, enclosingType, node.name, node), null);
+          _lookUpGetter(null, enclosingType, node.name, node).element, null);
       node.auxiliaryElements = auxiliaryElements;
     }
     //
@@ -978,9 +979,9 @@
       IndexExpression expression,
       Expression target,
       String methodName,
-      MethodElement staticMethod,
+      ResolutionResult result,
       DartType staticType) {
-    if (_shouldReportInvalidMember(staticType, staticMethod)) {
+    if (_shouldReportInvalidMember(staticType, result)) {
       Token leftBracket = expression.leftBracket;
       Token rightBracket = expression.rightBracket;
       ErrorCode errorCode;
@@ -1075,19 +1076,6 @@
    * type analysis.
    */
   DartType _getStaticType(Expression expression, {bool read: false}) {
-    DartType staticType = _getStaticTypeOrFunctionType(expression, read: read);
-    if (staticType is FunctionType) {
-      //
-      // All function types are subtypes of 'Function', which is itself a
-      // subclass of 'Object'.
-      //
-      staticType = _resolver.typeProvider.functionType;
-    }
-    return staticType;
-  }
-
-  DartType _getStaticTypeOrFunctionType(Expression expression,
-      {bool read: false}) {
     if (expression is NullLiteral) {
       return _resolver.typeProvider.nullType;
     }
@@ -1240,13 +1228,13 @@
       return callMethod;
     }
 
-    var result = _extensionMemberResolver.findExtension(
+    var result = _extensionResolver.findExtension(
       type,
       FunctionElement.CALL_METHOD_NAME,
       node,
       ElementKind.METHOD,
     );
-    var instantiatedMember = result.extension?.instantiatedMember;
+    var instantiatedMember = result.element;
     if (instantiatedMember is MethodElement) {
       return instantiatedMember;
     }
@@ -1255,27 +1243,35 @@
   }
 
   /**
-   * Look up the getter with the given [getterName] in the given [type]. Return
-   * the element representing the getter that was found, or `null` if there is
-   * no getter with the given name. The [target] is the target of the
-   * invocation, or `null` if there is no target.
+   * Look up the getter with the given [name] in the given [type]. Return a
+   * result representing the result of that lookup. The [target] is the target
+   * of the invocation, or `null` if there is no target.
    */
-  PropertyAccessorElement _lookUpGetter(
+  ResolutionResult _lookUpGetter(
       Expression target, DartType type, String name, Expression nameNode) {
     type = _resolveTypeParameter(type);
-    if (type is InterfaceType) {
+    ResolutionResult result = ResolutionResult.none;
+
+    void lookupIn(InterfaceType type) {
       var getter = type.lookUpInheritedGetter(name,
           library: _definingLibrary, thisType: target is! SuperExpression);
       if (getter != null) {
-        return getter;
-      }
-      var result = _extensionMemberResolver.findExtension(
-          type, name, nameNode, ElementKind.GETTER);
-      if (result.isSingle) {
-        return result.extension.instantiatedMember;
+        result = ResolutionResult(getter);
       }
     }
-    return null;
+
+    if (type is InterfaceType) {
+      lookupIn(type);
+    } else if (type is FunctionType) {
+      lookupIn(_resolver.typeProvider.functionType);
+    } else {
+      return ResolutionResult.none;
+    }
+    if (result.isNone) {
+      result = _extensionResolver.findExtension(
+          type, name, nameNode, ElementKind.GETTER);
+    }
+    return result;
   }
 
   /**
@@ -1293,51 +1289,67 @@
   }
 
   /**
-   * Look up the method with the given [name] in the given [type]. Return
-   * the element representing the method that was found, or `null` if there is
-   * no method with the given name. The [target] is the target of the
-   * invocation, or `null` if there is no target.
+   * Look up the method with the given [name] in the given [type]. Return a
+   * result representing the result of that lookup. The [target] is the target
+   * of the invocation, or `null` if there is no target.
    */
-  MethodElement _lookUpMethod(
+  ResolutionResult _lookUpMethod(
       Expression target, DartType type, String name, Expression nameNode) {
     type = _resolveTypeParameter(type);
-    if (type is InterfaceType) {
+    ResolutionResult result = ResolutionResult.none;
+
+    void lookupIn(InterfaceType type) {
       var method = type.lookUpInheritedMethod(name,
           library: _definingLibrary, thisType: target is! SuperExpression);
       if (method != null) {
-        return method;
-      }
-      var result = _extensionMemberResolver.findExtension(
-          type, name, nameNode, ElementKind.METHOD);
-      if (result.isSingle) {
-        return result.extension.instantiatedMember;
+        result = ResolutionResult(method);
       }
     }
-    return null;
+
+    if (type is InterfaceType) {
+      lookupIn(type);
+    } else if (type is FunctionType) {
+      lookupIn(_resolver.typeProvider.functionType);
+    } else {
+      return ResolutionResult.none;
+    }
+    if (result.isNone) {
+      result = _extensionResolver.findExtension(
+          type, name, nameNode, ElementKind.METHOD);
+    }
+    return result;
   }
 
   /**
-   * Look up the setter with the given [name] in the given [type]. Return
-   * the element representing the setter that was found, or `null` if there is
-   * no setter with the given name. The [target] is the target of the
-   * invocation, or `null` if there is no target.
+   * Look up the setter with the given [name] in the given [type]. Return a
+   * result representing the result of that lookup. The [target] is the target
+   * of the invocation, or `null` if there is no target.
    */
-  PropertyAccessorElement _lookUpSetter(
+  ResolutionResult _lookUpSetter(
       Expression target, DartType type, String name, Expression nameNode) {
     type = _resolveTypeParameter(type);
-    if (type is InterfaceType) {
+    ResolutionResult result = ResolutionResult.none;
+
+    void lookupIn(InterfaceType type) {
       var setter = type.lookUpInheritedSetter(name,
           library: _definingLibrary, thisType: target is! SuperExpression);
       if (setter != null) {
-        return setter;
-      }
-      var result = _extensionMemberResolver.findExtension(
-          type, name, nameNode, ElementKind.SETTER);
-      if (result.isSingle) {
-        return result.extension.instantiatedMember;
+        result = ResolutionResult(setter);
       }
     }
-    return null;
+
+    if (type is InterfaceType) {
+      lookupIn(type);
+    } else if (type is FunctionType) {
+      lookupIn(_resolver.typeProvider.functionType);
+    } else {
+      return ResolutionResult.none;
+    }
+    if (result.isNone) {
+      result = _extensionResolver.findExtension(
+          type, name, nameNode, ElementKind.SETTER);
+    }
+    return result;
   }
 
   /**
@@ -1580,26 +1592,33 @@
       DartType leftType = _getStaticType(leftOperand);
       var isSuper = leftOperand is SuperExpression;
 
-      ExecutableElement invokeElement;
-      if (leftType is InterfaceType) {
-        invokeElement = _inheritance.getMember(
-          leftType,
+      ResolutionResult result = ResolutionResult.none;
+
+      void lookupIn(InterfaceType type) {
+        ExecutableElement invokeElement = _inheritance.getMember(
+          type,
           new Name(_definingLibrary.source.uri, methodName),
           forSuper: isSuper,
         );
-      }
-
-      if (invokeElement == null && leftType is InterfaceType) {
-        var result = _extensionMemberResolver.findExtension(
-            leftType, methodName, node, ElementKind.METHOD);
-        if (result.isSingle) {
-          invokeElement = result.extension.instantiatedMember;
+        if (invokeElement != null) {
+          result = ResolutionResult(invokeElement);
         }
       }
 
-      node.staticElement = invokeElement;
-      node.staticInvokeType = invokeElement?.type;
-      if (_shouldReportInvalidMember(leftType, invokeElement)) {
+      if (leftType is InterfaceType) {
+        lookupIn(leftType);
+      } else if (leftType is FunctionType) {
+        lookupIn(_resolver.typeProvider.functionType);
+      }
+
+      if (result.isNone) {
+        result = _extensionResolver.findExtension(
+            leftType, methodName, node, ElementKind.METHOD);
+      }
+
+      node.staticElement = result.element;
+      node.staticInvokeType = result.element?.type;
+      if (_shouldReportInvalidMember(leftType, result)) {
         if (isSuper) {
           _recordUndefinedToken(
               leftType.element,
@@ -1691,29 +1710,35 @@
    * given [propertyName], return the element that represents the property. The
    * [target] is the target of the invocation ('e').
    */
-  ExecutableElement _resolveProperty(
+  ResolutionResult _resolveProperty(
       Expression target, DartType targetType, SimpleIdentifier propertyName) {
-    ExecutableElement memberElement = null;
+    ResolutionResult result = ResolutionResult.none;
     if (propertyName.inSetterContext()) {
-      memberElement =
+      result =
           _lookUpSetter(target, targetType, propertyName.name, propertyName);
     }
-    if (memberElement == null) {
-      memberElement =
+    if (result.isNone) {
+      result =
           _lookUpGetter(target, targetType, propertyName.name, propertyName);
     }
-    if (memberElement == null) {
-      memberElement =
+    if (result.isNone) {
+      result =
           _lookUpMethod(target, targetType, propertyName.name, propertyName);
     }
-    return memberElement;
+    return result;
   }
 
   void _resolvePropertyAccess(
       Expression target, SimpleIdentifier propertyName, bool isCascaded) {
     DartType staticType = _getStaticType(target);
-    Element staticElement;
+    //
+    // If this property access is of the form 'E.m' where 'E' is an extension,
+    // then look for the member in the extension. This does not apply to
+    // conditional property accesses (i.e. 'C?.m').
+    //
+    ResolutionResult result = ResolutionResult.none;
     if (target is Identifier && target.staticElement is ExtensionElement) {
+      Element staticElement;
       ExtensionElement extension = target.staticElement;
       String memberName = propertyName.name;
       if (propertyName.inSetterContext()) {
@@ -1727,6 +1752,9 @@
             propertyName,
             [memberName]);
       }
+      if (staticElement != null) {
+        result = ResolutionResult(staticElement);
+      }
     }
     //
     // If this property access is of the form 'C.m' where 'C' is a class,
@@ -1734,13 +1762,17 @@
     // hierarchy, instead we just look for the member in the type only.  This
     // does not apply to conditional property accesses (i.e. 'C?.m').
     //
-    if (staticElement == null) {
+    if (result.isNone) {
+      Element staticElement;
       ClassElement typeReference = getTypeReference(target);
       if (typeReference != null) {
         if (isCascaded) {
           typeReference = _typeType.element;
         }
         staticElement = _resolveElement(typeReference, propertyName);
+        if (staticElement != null) {
+          result = ResolutionResult(staticElement);
+        }
       } else {
         if (target is SuperExpression) {
           if (staticType is InterfaceTypeImpl) {
@@ -1770,21 +1802,28 @@
               }
             }
           }
+          if (staticElement != null) {
+            result = ResolutionResult(staticElement);
+          }
         } else {
-          staticElement = _resolveProperty(target, staticType, propertyName);
+          result = _resolveProperty(target, staticType, propertyName);
         }
       }
     }
-    // May be part of annotation, record property element only if exists.
+    // Might be part of an annotation, record property element only if exists.
     // Error was already reported in validateAnnotationElement().
     if (target.parent.parent is Annotation) {
-      if (staticElement != null) {
-        propertyName.staticElement = staticElement;
+      if (result.isSingle) {
+        propertyName.staticElement = result.element;
       }
       return;
     }
-    propertyName.staticElement = staticElement;
-    if (_shouldReportInvalidMember(staticType, staticElement)) {
+    propertyName.staticElement = result.element;
+    if (_shouldReportInvalidMember(staticType, result)) {
+      if (staticType is FunctionType &&
+          propertyName.name == FunctionElement.CALL_METHOD_NAME) {
+        return;
+      }
       Element enclosingElement = staticType.element;
       bool isStaticProperty = _isStatic(enclosingElement);
       // Special getter cases.
@@ -1865,7 +1904,8 @@
           ClassElement enclosingClass = _resolver.enclosingClass;
           if (enclosingClass != null) {
             setter = _lookUpSetter(
-                null, enclosingClass.type, identifier.name, identifier);
+                    null, enclosingClass.type, identifier.name, identifier)
+                .element;
           }
         }
         if (setter != null) {
@@ -1904,15 +1944,18 @@
             (identifier.inSetterContext() ||
                 identifier.parent is CommentReference)) {
           element =
-              _lookUpSetter(null, enclosingType, identifier.name, identifier);
+              _lookUpSetter(null, enclosingType, identifier.name, identifier)
+                  .element;
         }
         if (element == null && identifier.inGetterContext()) {
           element =
-              _lookUpGetter(null, enclosingType, identifier.name, identifier);
+              _lookUpGetter(null, enclosingType, identifier.name, identifier)
+                  .element;
         }
         if (element == null) {
           element =
-              _lookUpMethod(null, enclosingType, identifier.name, identifier);
+              _lookUpMethod(null, enclosingType, identifier.name, identifier)
+                  .element;
         }
       }
     }
@@ -1930,8 +1973,8 @@
    * Return `true` if we should report an error for a [member] lookup that found
    * no match on the given [type].
    */
-  bool _shouldReportInvalidMember(DartType type, Element member) =>
-      type != null && member == null && !type.isDynamic;
+  bool _shouldReportInvalidMember(DartType type, ResolutionResult result) =>
+      type != null && !type.isDynamic && result.isNone;
 
   /**
    * Checks whether the given [expression] is a reference to a class. If it is
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index c4fb17b..bde9710 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:collection';
-import "dart:math" as math;
 
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
@@ -24,8 +23,10 @@
 import 'package:analyzer/src/dart/resolver/variance.dart';
 import 'package:analyzer/src/diagnostic/diagnostic_factory.dart';
 import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/error/duplicate_definition_verifier.dart';
 import 'package:analyzer/src/error/literal_element_verifier.dart';
 import 'package:analyzer/src/error/required_parameters_verifier.dart';
+import 'package:analyzer/src/error/type_arguments_verifier.dart';
 import 'package:analyzer/src/generated/element_resolver.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
@@ -301,6 +302,8 @@
   FeatureSet _featureSet;
 
   final RequiredParametersVerifier _requiredParametersVerifier;
+  final DuplicateDefinitionVerifier _duplicateDefinitionVerifier;
+  TypeArgumentsVerifier _typeArgumentsVerifier;
 
   /**
    * Initialize a newly created error verifier.
@@ -323,8 +326,9 @@
         _inheritanceManager = inheritanceManager.asInheritanceManager3,
         _uninstantiatedBoundChecker =
             new _UninstantiatedBoundChecker(errorReporter),
-        _requiredParametersVerifier =
-            RequiredParametersVerifier(errorReporter) {
+        _requiredParametersVerifier = RequiredParametersVerifier(errorReporter),
+        _duplicateDefinitionVerifier =
+            DuplicateDefinitionVerifier(_currentLibrary, errorReporter) {
     this._isInSystemLibrary = _currentLibrary.source.isInSystemLibrary;
     this._hasExtUri = _currentLibrary.hasExtUri;
     _isEnclosingConstructorConst = false;
@@ -339,6 +343,8 @@
     _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT = _typeProvider.nonSubtypableTypes;
     _typeSystem = _currentLibrary.context.typeSystem;
     _options = _currentLibrary.context.analysisOptions;
+    _typeArgumentsVerifier =
+        TypeArgumentsVerifier(_options, _typeSystem, _errorReporter);
   }
 
   /**
@@ -460,7 +466,7 @@
   void visitBlock(Block node) {
     _hiddenElements = new HiddenElements(_hiddenElements, node);
     try {
-      _checkDuplicateDeclarationInStatements(node.statements);
+      _duplicateDefinitionVerifier.checkStatements(node.statements);
       super.visitBlock(node);
     } finally {
       _hiddenElements = _hiddenElements.outerElements;
@@ -510,7 +516,7 @@
 
   @override
   void visitCatchClause(CatchClause node) {
-    _checkDuplicateDefinitionInCatchClause(node);
+    _duplicateDefinitionVerifier.checkCatchClause(node);
     bool previousIsInCatchClause = _isInCatchClause;
     try {
       _isInCatchClause = true;
@@ -530,7 +536,7 @@
       _enclosingClass = AbstractClassElementImpl.getImpl(node.declaredElement);
 
       List<ClassMember> members = node.members;
-      _checkDuplicateClassMembers(members);
+      _duplicateDefinitionVerifier.checkClass(node);
       _checkForBuiltInIdentifierAsName(
           node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME);
       _checkForMemberWithClassName();
@@ -588,7 +594,7 @@
   @override
   void visitCompilationUnit(CompilationUnit node) {
     _featureSet = node.featureSet;
-    _checkDuplicateUnitMembers(node);
+    _duplicateDefinitionVerifier.checkUnit(node);
     _checkForDeferredPrefixCollisions(node);
     super.visitCompilationUnit(node);
     _featureSet = null;
@@ -678,7 +684,7 @@
     ClassElement outerEnum = _enclosingEnum;
     try {
       _enclosingEnum = node.declaredElement;
-      _checkDuplicateEnumMembers(node);
+      _duplicateDefinitionVerifier.checkEnum(node);
       super.visitEnumDeclaration(node);
     } finally {
       _enclosingEnum = outerEnum;
@@ -726,6 +732,8 @@
   @override
   void visitExtensionDeclaration(ExtensionDeclaration node) {
     _enclosingExtension = node.declaredElement;
+    _duplicateDefinitionVerifier.checkExtension(node);
+    _checkForMismatchedAccessorTypesInExtension(node);
     super.visitExtensionDeclaration(node);
     _enclosingExtension = null;
   }
@@ -795,7 +803,7 @@
 
   @override
   void visitFormalParameterList(FormalParameterList node) {
-    _checkDuplicateDefinitionInParameterList(node);
+    _duplicateDefinitionVerifier.checkParameters(node);
     _checkUseOfCovariantInParameters(node);
     _checkUseOfDefaultValuesInParameters(node);
     super.visitFormalParameterList(node);
@@ -807,7 +815,7 @@
       _checkForNonBoolCondition(node.condition);
     }
     if (node.variables != null) {
-      _checkDuplicateVariables(node.variables);
+      _duplicateDefinitionVerifier.checkForVariables(node.variables);
     }
     super.visitForPartsWithDeclarations(node);
   }
@@ -880,12 +888,11 @@
   @override
   void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
     Expression functionExpression = node.function;
+
     if (functionExpression is ExtensionOverride) {
-      // TODO(brianwilkerson) Update `_checkTypeArguments` to handle extension
-      //  overrides.
-//      _checkTypeArguments(node);
       return super.visitFunctionExpressionInvocation(node);
     }
+
     DartType expressionType = functionExpression.staticType;
     if (!_checkForNullableDereference(functionExpression) &&
         !_checkForUseOfVoidResult(functionExpression) &&
@@ -896,9 +903,8 @@
           StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION,
           functionExpression);
     } else if (expressionType is FunctionType) {
-      _checkTypeArguments(node);
+      _typeArgumentsVerifier.checkFunctionExpressionInvocation(node);
     }
-    _checkForImplicitDynamicInvoke(node);
     _checkForNullableDereference(functionExpression);
     _requiredParametersVerifier.visitFunctionExpressionInvocation(node);
     super.visitFunctionExpressionInvocation(node);
@@ -1047,19 +1053,7 @@
 
   @override
   void visitListLiteral(ListLiteral node) {
-    TypeArgumentList typeArguments = node.typeArguments;
-    if (typeArguments != null) {
-      if (node.isConst) {
-        NodeList<TypeAnnotation> arguments = typeArguments.arguments;
-        if (arguments.isNotEmpty) {
-          _checkForInvalidTypeArgumentInConstTypedLiteral(arguments,
-              CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST);
-        }
-      }
-      _checkTypeArgumentCount(typeArguments, 1,
-          StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS);
-    }
-    _checkForImplicitDynamicTypedLiteral(node);
+    _typeArgumentsVerifier.checkListLiteral(node);
     _checkForListElementTypeNotAssignable(node);
 
     super.visitListLiteral(node);
@@ -1101,14 +1095,14 @@
     if (target != null) {
       ClassElement typeReference = ElementResolver.getTypeReference(target);
       _checkForStaticAccessToInstanceMember(typeReference, methodName);
-      _checkForInstanceAccessToStaticMember(typeReference, methodName);
+      _checkForInstanceAccessToStaticMember(
+          typeReference, node.target, methodName);
       _checkForUnnecessaryNullAware(target, node.operator);
     } else {
       _checkForUnqualifiedReferenceToNonLocalStaticMember(methodName);
       _checkForNullableDereference(node.function);
     }
-    _checkTypeArguments(node);
-    _checkForImplicitDynamicInvoke(node);
+    _typeArgumentsVerifier.checkMethodInvocation(node);
     _checkForNullableDereference(methodName);
     _requiredParametersVerifier.visitMethodInvocation(node);
     if (node.operator?.type != TokenType.QUESTION_PERIOD &&
@@ -1127,7 +1121,7 @@
       _enclosingClass = AbstractClassElementImpl.getImpl(node.declaredElement);
 
       List<ClassMember> members = node.members;
-      _checkDuplicateClassMembers(members);
+      _duplicateDefinitionVerifier.checkMixin(node);
       _checkForBuiltInIdentifierAsName(
           node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME);
       _checkForMemberWithClassName();
@@ -1189,7 +1183,7 @@
           ElementResolver.getTypeReference(node.prefix);
       SimpleIdentifier name = node.identifier;
       _checkForStaticAccessToInstanceMember(typeReference, name);
-      _checkForInstanceAccessToStaticMember(typeReference, name);
+      _checkForInstanceAccessToStaticMember(typeReference, node.prefix, name);
     }
     String property = node.identifier.name;
     if (node.staticElement is ExecutableElement &&
@@ -1222,7 +1216,8 @@
         ElementResolver.getTypeReference(node.realTarget);
     SimpleIdentifier propertyName = node.propertyName;
     _checkForStaticAccessToInstanceMember(typeReference, propertyName);
-    _checkForInstanceAccessToStaticMember(typeReference, propertyName);
+    _checkForInstanceAccessToStaticMember(
+        typeReference, node.target, propertyName);
     if (node.operator?.type != TokenType.QUESTION_PERIOD &&
         !_objectPropertyNames.contains(propertyName.name)) {
       _checkForNullableDereference(node.target);
@@ -1262,35 +1257,12 @@
 
   @override
   void visitSetOrMapLiteral(SetOrMapLiteral node) {
-    TypeArgumentList typeArguments = node.typeArguments;
     if (node.isMap) {
-      if (typeArguments != null) {
-        NodeList<TypeAnnotation> arguments = typeArguments.arguments;
-        if (node.isConst) {
-          if (arguments.isNotEmpty) {
-            _checkForInvalidTypeArgumentInConstTypedLiteral(arguments,
-                CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP);
-          }
-        }
-        _checkTypeArgumentCount(typeArguments, 2,
-            StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS);
-      }
-      _checkForImplicitDynamicTypedLiteral(node);
+      _typeArgumentsVerifier.checkMapLiteral(node);
       _checkForMapTypeNotAssignable(node);
       _checkForNonConstMapAsExpressionStatement3(node);
     } else if (node.isSet) {
-      if (typeArguments != null) {
-        if (node.isConst) {
-          NodeList<TypeAnnotation> arguments = typeArguments.arguments;
-          if (arguments.isNotEmpty) {
-            _checkForInvalidTypeArgumentInConstTypedLiteral(arguments,
-                CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_SET);
-          }
-        }
-        _checkTypeArgumentCount(typeArguments, 1,
-            StaticTypeWarningCode.EXPECTED_ONE_SET_TYPE_ARGUMENTS);
-      }
-      _checkForImplicitDynamicTypedLiteral(node);
+      _typeArgumentsVerifier.checkSetLiteral(node);
       _checkForSetElementTypeNotAssignable3(node);
     }
     super.visitSetOrMapLiteral(node);
@@ -1348,13 +1320,13 @@
 
   @override
   void visitSwitchCase(SwitchCase node) {
-    _checkDuplicateDeclarationInStatements(node.statements);
+    _duplicateDefinitionVerifier.checkStatements(node.statements);
     super.visitSwitchCase(node);
   }
 
   @override
   void visitSwitchDefault(SwitchDefault node) {
-    _checkDuplicateDeclarationInStatements(node.statements);
+    _duplicateDefinitionVerifier.checkStatements(node.statements);
     super.visitSwitchDefault(node);
   }
 
@@ -1398,13 +1370,7 @@
 
   @override
   void visitTypeName(TypeName node) {
-    _checkForTypeArgumentNotMatchingBounds(node);
-    if (node.parent is ConstructorName &&
-        node.parent.parent is InstanceCreationExpression) {
-      _checkForInferenceFailureOnInstanceCreation(node, node.parent.parent);
-    } else {
-      _checkForRawTypeName(node);
-    }
+    _typeArgumentsVerifier.checkTypeName(node);
     super.visitTypeName(node);
   }
 
@@ -1422,7 +1388,7 @@
 
   @override
   void visitTypeParameterList(TypeParameterList node) {
-    _checkDuplicateDefinitionInTypeParameterList(node);
+    _duplicateDefinitionVerifier.checkTypeParameters(node);
     super.visitTypeParameterList(node);
   }
 
@@ -1554,338 +1520,6 @@
   }
 
   /**
-   * Check that there are no members with the same name.
-   */
-  void _checkDuplicateClassMembers(List<ClassMember> members) {
-    Set<String> constructorNames = new HashSet<String>();
-    Map<String, Element> instanceGetters = new HashMap<String, Element>();
-    Map<String, Element> instanceSetters = new HashMap<String, Element>();
-    Map<String, Element> staticGetters = new HashMap<String, Element>();
-    Map<String, Element> staticSetters = new HashMap<String, Element>();
-
-    for (ClassMember member in members) {
-      if (member is ConstructorDeclaration) {
-        var name = member.name?.name ?? '';
-        if (!constructorNames.add(name)) {
-          if (name.isEmpty) {
-            _errorReporter.reportErrorForNode(
-                CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT, member);
-          } else {
-            _errorReporter.reportErrorForNode(
-                CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME,
-                member,
-                [name]);
-          }
-        }
-      } else if (member is FieldDeclaration) {
-        for (VariableDeclaration field in member.fields.variables) {
-          SimpleIdentifier identifier = field.name;
-          _checkDuplicateIdentifier(
-            member.isStatic ? staticGetters : instanceGetters,
-            identifier,
-            setterScope: member.isStatic ? staticSetters : instanceSetters,
-          );
-        }
-      } else if (member is MethodDeclaration) {
-        _checkDuplicateIdentifier(
-          member.isStatic ? staticGetters : instanceGetters,
-          member.name,
-          setterScope: member.isStatic ? staticSetters : instanceSetters,
-        );
-      }
-    }
-
-    // Check for local static members conflicting with local instance members.
-    for (ClassMember member in members) {
-      if (member is ConstructorDeclaration) {
-        if (member.name != null) {
-          String name = member.name.name;
-          var staticMember = staticGetters[name] ?? staticSetters[name];
-          if (staticMember != null) {
-            if (staticMember is PropertyAccessorElement) {
-              _errorReporter.reportErrorForNode(
-                CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_FIELD,
-                member.name,
-                [name],
-              );
-            } else {
-              _errorReporter.reportErrorForNode(
-                CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_METHOD,
-                member.name,
-                [name],
-              );
-            }
-          }
-        }
-      } else if (member is FieldDeclaration) {
-        if (member.isStatic) {
-          for (VariableDeclaration field in member.fields.variables) {
-            SimpleIdentifier identifier = field.name;
-            String name = identifier.name;
-            if (instanceGetters.containsKey(name) ||
-                instanceSetters.containsKey(name)) {
-              String className = _enclosingClass.displayName;
-              _errorReporter.reportErrorForNode(
-                  CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE,
-                  identifier,
-                  [className, name, className]);
-            }
-          }
-        }
-      } else if (member is MethodDeclaration) {
-        if (member.isStatic) {
-          SimpleIdentifier identifier = member.name;
-          String name = identifier.name;
-          if (instanceGetters.containsKey(name) ||
-              instanceSetters.containsKey(name)) {
-            String className = identifier.staticElement.enclosingElement.name;
-            _errorReporter.reportErrorForNode(
-                CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE,
-                identifier,
-                [className, name, className]);
-          }
-        }
-      }
-    }
-  }
-
-  /**
-   * Check that all of the parameters have unique names.
-   */
-  void _checkDuplicateDeclarationInStatements(List<Statement> statements) {
-    Map<String, Element> definedNames = new HashMap<String, Element>();
-    for (Statement statement in statements) {
-      if (statement is VariableDeclarationStatement) {
-        for (VariableDeclaration variable in statement.variables.variables) {
-          _checkDuplicateIdentifier(definedNames, variable.name);
-        }
-      } else if (statement is FunctionDeclarationStatement) {
-        _checkDuplicateIdentifier(
-            definedNames, statement.functionDeclaration.name);
-      }
-    }
-  }
-
-  /**
-   * Check that the exception and stack trace parameters have different names.
-   */
-  void _checkDuplicateDefinitionInCatchClause(CatchClause node) {
-    SimpleIdentifier exceptionParameter = node.exceptionParameter;
-    SimpleIdentifier stackTraceParameter = node.stackTraceParameter;
-    if (exceptionParameter != null && stackTraceParameter != null) {
-      String exceptionName = exceptionParameter.name;
-      if (exceptionName == stackTraceParameter.name) {
-        _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.DUPLICATE_DEFINITION,
-            stackTraceParameter,
-            [exceptionName]);
-      }
-    }
-  }
-
-  /**
-   * Check that all of the parameters have unique names.
-   */
-  void _checkDuplicateDefinitionInParameterList(FormalParameterList node) {
-    Map<String, Element> definedNames = new HashMap<String, Element>();
-    for (FormalParameter parameter in node.parameters) {
-      SimpleIdentifier identifier = parameter.identifier;
-      if (identifier != null) {
-        // The identifier can be null if this is a parameter list for a generic
-        // function type.
-        _checkDuplicateIdentifier(definedNames, identifier);
-      }
-    }
-  }
-
-  /**
-   * Check that all of the parameters have unique names.
-   */
-  void _checkDuplicateDefinitionInTypeParameterList(TypeParameterList node) {
-    Map<String, Element> definedNames = new HashMap<String, Element>();
-    for (TypeParameter parameter in node.typeParameters) {
-      _checkDuplicateIdentifier(definedNames, parameter.name);
-    }
-  }
-
-  /**
-   * Check that there are no members with the same name.
-   */
-  void _checkDuplicateEnumMembers(EnumDeclaration node) {
-    ClassElement element = node.declaredElement;
-
-    Map<String, Element> instanceGetters = new HashMap<String, Element>();
-    Map<String, Element> staticGetters = new HashMap<String, Element>();
-
-    String indexName = 'index';
-    String valuesName = 'values';
-    instanceGetters[indexName] = element.getGetter(indexName);
-    staticGetters[valuesName] = element.getGetter(valuesName);
-
-    for (EnumConstantDeclaration constant in node.constants) {
-      _checkDuplicateIdentifier(staticGetters, constant.name);
-    }
-
-    for (EnumConstantDeclaration constant in node.constants) {
-      SimpleIdentifier identifier = constant.name;
-      String name = identifier.name;
-      if (instanceGetters.containsKey(name)) {
-        String enumName = element.displayName;
-        _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE,
-            identifier,
-            [enumName, name, enumName]);
-      }
-    }
-  }
-
-  /**
-   * Check whether the given [element] defined by the [identifier] is already
-   * in one of the scopes - [getterScope] or [setterScope], and produce an
-   * error if it is.
-   */
-  void _checkDuplicateIdentifier(
-      Map<String, Element> getterScope, SimpleIdentifier identifier,
-      {Element element, Map<String, Element> setterScope}) {
-    element ??= identifier.staticElement;
-
-    // Fields define getters and setters, so check them separately.
-    if (element is PropertyInducingElement) {
-      _checkDuplicateIdentifier(getterScope, identifier,
-          element: element.getter, setterScope: setterScope);
-      if (!element.isConst && !element.isFinal) {
-        _checkDuplicateIdentifier(getterScope, identifier,
-            element: element.setter, setterScope: setterScope);
-      }
-      return;
-    }
-
-    ErrorCode getError(Element previous, Element current) {
-      if (previous is PrefixElement) {
-        return CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER;
-      }
-      return CompileTimeErrorCode.DUPLICATE_DEFINITION;
-    }
-
-    bool isGetterSetterPair(Element a, Element b) {
-      if (a is PropertyAccessorElement && b is PropertyAccessorElement) {
-        return a.isGetter && b.isSetter || a.isSetter && b.isGetter;
-      }
-      return false;
-    }
-
-    String name = identifier.name;
-    if (element is MethodElement && element.isOperator && name == '-') {
-      if (element.parameters.isEmpty) {
-        name = 'unary-';
-      }
-    }
-
-    Element previous = getterScope[name];
-    if (previous != null) {
-      if (isGetterSetterPair(element, previous)) {
-        // OK
-      } else {
-        _errorReporter.reportErrorForNode(
-          getError(previous, element),
-          identifier,
-          [name],
-        );
-      }
-    } else {
-      getterScope[name] = element;
-    }
-
-    if (element is PropertyAccessorElement && element.isSetter) {
-      previous = setterScope[name];
-      if (previous != null) {
-        _errorReporter.reportErrorForNode(
-          getError(previous, element),
-          identifier,
-          [name],
-        );
-      } else {
-        setterScope[name] = element;
-      }
-    }
-  }
-
-  /**
-   * Check that there are no members with the same name.
-   */
-  void _checkDuplicateUnitMembers(CompilationUnit node) {
-    Map<String, Element> definedGetters = new HashMap<String, Element>();
-    Map<String, Element> definedSetters = new HashMap<String, Element>();
-
-    void addWithoutChecking(CompilationUnitElement element) {
-      for (PropertyAccessorElement accessor in element.accessors) {
-        String name = accessor.name;
-        if (accessor.isSetter) {
-          name += '=';
-        }
-        definedGetters[name] = accessor;
-      }
-      for (ClassElement type in element.enums) {
-        definedGetters[type.name] = type;
-      }
-      for (FunctionElement function in element.functions) {
-        definedGetters[function.name] = function;
-      }
-      for (FunctionTypeAliasElement alias in element.functionTypeAliases) {
-        definedGetters[alias.name] = alias;
-      }
-      for (TopLevelVariableElement variable in element.topLevelVariables) {
-        definedGetters[variable.name] = variable;
-        if (!variable.isFinal && !variable.isConst) {
-          definedGetters[variable.name + '='] = variable;
-        }
-      }
-      for (ClassElement type in element.types) {
-        definedGetters[type.name] = type;
-      }
-    }
-
-    for (ImportElement importElement in _currentLibrary.imports) {
-      PrefixElement prefix = importElement.prefix;
-      if (prefix != null) {
-        definedGetters[prefix.name] = prefix;
-      }
-    }
-    CompilationUnitElement element = node.declaredElement;
-    if (element != _currentLibrary.definingCompilationUnit) {
-      addWithoutChecking(_currentLibrary.definingCompilationUnit);
-      for (CompilationUnitElement part in _currentLibrary.parts) {
-        if (element == part) {
-          break;
-        }
-        addWithoutChecking(part);
-      }
-    }
-    for (CompilationUnitMember member in node.declarations) {
-      if (member is NamedCompilationUnitMember) {
-        _checkDuplicateIdentifier(definedGetters, member.name,
-            setterScope: definedSetters);
-      } else if (member is TopLevelVariableDeclaration) {
-        for (VariableDeclaration variable in member.variables.variables) {
-          _checkDuplicateIdentifier(definedGetters, variable.name,
-              setterScope: definedSetters);
-        }
-      }
-    }
-  }
-
-  /**
-   * Check that the given list of variable declarations does not define multiple
-   * variables of the same name.
-   */
-  void _checkDuplicateVariables(VariableDeclarationList node) {
-    Map<String, Element> definedNames = new HashMap<String, Element>();
-    for (VariableDeclaration variable in node.variables) {
-      _checkDuplicateIdentifier(definedNames, variable.name);
-    }
-  }
-
-  /**
    * Check that return statements without expressions are not in a generative
    * constructor and the return type is not assignable to `null`; that is, we
    * don't have `return;` if the enclosing method has a non-void containing
@@ -3574,50 +3208,6 @@
     }
   }
 
-  void _checkForImplicitDynamicInvoke(InvocationExpression node) {
-    if (_options.implicitDynamic ||
-        node == null ||
-        node.typeArguments != null) {
-      return;
-    }
-    DartType invokeType = node.staticInvokeType;
-    DartType declaredType = node.function.staticType;
-    if (invokeType is FunctionType &&
-        declaredType is FunctionType &&
-        declaredType.typeFormals.isNotEmpty) {
-      List<DartType> typeArgs = node.typeArgumentTypes;
-      if (typeArgs.any((t) => t.isDynamic)) {
-        // Issue an error depending on what we're trying to call.
-        Expression function = node.function;
-        if (function is Identifier) {
-          Element element = function.staticElement;
-          if (element is MethodElement) {
-            _errorReporter.reportErrorForNode(
-                StrongModeCode.IMPLICIT_DYNAMIC_METHOD,
-                node.function,
-                [element.displayName, element.typeParameters.join(', ')]);
-            return;
-          }
-
-          if (element is FunctionElement) {
-            _errorReporter.reportErrorForNode(
-                StrongModeCode.IMPLICIT_DYNAMIC_FUNCTION,
-                node.function,
-                [element.displayName, element.typeParameters.join(', ')]);
-            return;
-          }
-        }
-
-        // The catch all case if neither of those matched.
-        // For example, invoking a function expression.
-        _errorReporter.reportErrorForNode(
-            StrongModeCode.IMPLICIT_DYNAMIC_INVOKE,
-            node.function,
-            [declaredType]);
-      }
-    }
-  }
-
   void _checkForImplicitDynamicReturn(
       AstNode functionName, ExecutableElement element) {
     if (_options.implicitDynamic) {
@@ -3649,21 +3239,6 @@
     }
   }
 
-  void _checkForImplicitDynamicTypedLiteral(TypedLiteral node) {
-    if (_options.implicitDynamic || node.typeArguments != null) {
-      return;
-    }
-    DartType type = node.staticType;
-    // It's an error if either the key or value was inferred as dynamic.
-    if (type is InterfaceType && type.typeArguments.any((t) => t.isDynamic)) {
-      // TODO(brianwilkerson) Add StrongModeCode.IMPLICIT_DYNAMIC_SET_LITERAL
-      ErrorCode errorCode = node is ListLiteral
-          ? StrongModeCode.IMPLICIT_DYNAMIC_LIST_LITERAL
-          : StrongModeCode.IMPLICIT_DYNAMIC_MAP_LITERAL;
-      _errorReporter.reportErrorForNode(errorCode, node);
-    }
-  }
-
   /**
    * Verify that if the given [identifier] is part of a constructor initializer,
    * then it does not implicitly reference 'this' expression.
@@ -3799,27 +3374,6 @@
         [directive.uri.stringValue]);
   }
 
-  /// Checks a type on an instance creation expression for an inference
-  /// failure, and reports the appropriate error if
-  /// [AnalysisOptionsImpl.strictInference] is set.
-  ///
-  /// This checks if [node] refers to a generic type and does not have explicit
-  /// or inferred type arguments. When that happens, it reports a
-  /// HintMode.INFERENCE_FAILURE_ON_INSTANCE_CREATION error.
-  void _checkForInferenceFailureOnInstanceCreation(
-      TypeName node, InstanceCreationExpression inferenceContextNode) {
-    if (!_options.strictInference || node == null) return;
-    if (node.typeArguments != null) {
-      // Type has explicit type arguments.
-      return;
-    }
-    if (_isMissingTypeArguments(
-        node, node.type, node.name.staticElement, inferenceContextNode)) {
-      _errorReporter.reportErrorForNode(
-          HintCode.INFERENCE_FAILURE_ON_INSTANCE_CREATION, node, [node.type]);
-    }
-  }
-
   /**
    * Check that the given [typeReference] is not a type reference and that then
    * the [name] is reference to an instance member.
@@ -3827,25 +3381,39 @@
    * See [StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER].
    */
   void _checkForInstanceAccessToStaticMember(
-      ClassElement typeReference, SimpleIdentifier name) {
-    // OK, in comment
+      ClassElement typeReference, Expression target, SimpleIdentifier name) {
     if (_isInComment) {
-      return;
-    }
-    // OK, target is a type
-    if (typeReference != null) {
+      // OK, in comment
       return;
     }
     // prepare member Element
     Element element = name.staticElement;
     if (element is ExecutableElement) {
-      // OK, top-level element
-      if (element.enclosingElement is! ClassElement) {
+      if (!element.isStatic) {
+        // OK, instance member
         return;
       }
-      // OK, instance member
-      if (!element.isStatic) {
-        return;
+      Element enclosingElement = element.enclosingElement;
+      if (enclosingElement is ExtensionElement) {
+        if (target is ExtensionOverride) {
+          // OK, target is an extension override
+          return;
+        } else if (target is SimpleIdentifier &&
+            target.staticElement is ExtensionElement) {
+          return;
+        } else if (target is PrefixedIdentifier &&
+            target.staticElement is ExtensionElement) {
+          return;
+        }
+      } else {
+        if (typeReference != null) {
+          // OK, target is a type
+          return;
+        }
+        if (enclosingElement is! ClassElement) {
+          // OK, top-level element
+          return;
+        }
       }
       _errorReporter.reportErrorForNode(
           StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER,
@@ -3982,21 +3550,6 @@
     }
   }
 
-  /**
-   * Checks to ensure that the given list of type [arguments] does not have a
-   * type parameter as a type argument. The [errorCode] is either
-   * [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST] or
-   * [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP].
-   */
-  void _checkForInvalidTypeArgumentInConstTypedLiteral(
-      NodeList<TypeAnnotation> arguments, ErrorCode errorCode) {
-    for (TypeAnnotation type in arguments) {
-      if (type is TypeName && type.type is TypeParameterType) {
-        _errorReporter.reportErrorForNode(errorCode, type, [type.name]);
-      }
-    }
-  }
-
   void _checkForListConstructor(
       InstanceCreationExpression node, InterfaceType type) {
     if (!_isNonNullable) return;
@@ -4160,6 +3713,36 @@
   }
 
   /**
+   * Check whether all similarly named accessors have consistent types.
+   */
+  void _checkForMismatchedAccessorTypesInExtension(
+      ExtensionDeclaration extension) {
+    for (ClassMember member in extension.members) {
+      if (member is MethodDeclaration && member.isGetter) {
+        PropertyAccessorElement getterElement =
+            member.declaredElement as PropertyAccessorElement;
+        PropertyAccessorElement setterElement =
+            getterElement.correspondingSetter;
+        if (setterElement != null) {
+          DartType getterType = _getGetterType(getterElement);
+          DartType setterType = _getSetterType(setterElement);
+          if (setterType != null &&
+              getterType != null &&
+              !_typeSystem.isAssignableTo(getterType, setterType,
+                  featureSet: _featureSet)) {
+            SimpleIdentifier nameNode = member.name;
+            String name = nameNode.name;
+            _errorReporter.reportTypeErrorForNode(
+                StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES,
+                nameNode,
+                [name, getterType, setterType, name]);
+          }
+        }
+      }
+    }
+  }
+
+  /**
    * Check to make sure that the given switch [statement] whose static type is
    * an enum type either have a default case or include all of the enum
    * constants.
@@ -4928,45 +4511,6 @@
         CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, parameter);
   }
 
-  /// Checks a type annotation for a raw generic type, and reports the
-  /// appropriate error if [AnalysisOptionsImpl.strictRawTypes] is set.
-  ///
-  /// This checks if [node] refers to a generic type and does not have explicit
-  /// or inferred type arguments. When that happens, it reports error code
-  /// [StrongModeCode.STRICT_RAW_TYPE].
-  void _checkForRawTypeName(TypeName node) {
-    AstNode parentEscapingTypeArguments(TypeName node) {
-      AstNode parent = node.parent;
-      while (parent is TypeArgumentList || parent is TypeName) {
-        if (parent.parent == null) {
-          return parent;
-        }
-        parent = parent.parent;
-      }
-      return parent;
-    }
-
-    if (!_options.strictRawTypes || node == null) return;
-    if (node.typeArguments != null) {
-      // Type has explicit type arguments.
-      return;
-    }
-    if (_isMissingTypeArguments(
-        node, node.type, node.name.staticElement, null)) {
-      AstNode unwrappedParent = parentEscapingTypeArguments(node);
-      if (unwrappedParent is AsExpression) {
-        _errorReporter.reportErrorForNode(
-            HintCode.STRICT_RAW_TYPE_IN_AS, node, [node.type]);
-      } else if (unwrappedParent is IsExpression) {
-        _errorReporter.reportErrorForNode(
-            HintCode.STRICT_RAW_TYPE_IN_IS, node, [node.type]);
-      } else {
-        _errorReporter
-            .reportErrorForNode(HintCode.STRICT_RAW_TYPE, node, [node.type]);
-      }
-    }
-  }
-
   /**
    * Check whether the given constructor [declaration] is the redirecting
    * generative constructor and references itself directly or indirectly. The
@@ -5416,87 +4960,6 @@
     }
   }
 
-  /**
-   * Verify that the type arguments in the given [typeName] are all within
-   * their bounds.
-   */
-  void _checkForTypeArgumentNotMatchingBounds(TypeName typeName) {
-    // prepare Type
-    DartType type = typeName.type;
-    if (type == null) {
-      return;
-    }
-    if (type is ParameterizedType) {
-      var element = typeName.name.staticElement;
-      // prepare type parameters
-      List<TypeParameterElement> parameterElements;
-      if (element is ClassElement) {
-        parameterElements = element.typeParameters;
-      } else if (element is GenericTypeAliasElement) {
-        parameterElements = element.typeParameters;
-      } else if (element is GenericFunctionTypeElement) {
-        // TODO(paulberry): it seems like either this case or the one above
-        // should be unnecessary.
-        FunctionTypeAliasElement typedefElement = element.enclosingElement;
-        parameterElements = typedefElement.typeParameters;
-      } else if (type is FunctionType) {
-        parameterElements = type.typeFormals;
-      } else {
-        // There are no other kinds of parameterized types.
-        throw new UnimplementedError(
-            'Unexpected element associated with parameterized type: '
-            '${element.runtimeType}');
-      }
-      var parameterTypes =
-          parameterElements.map<DartType>((p) => p.type).toList();
-      List<DartType> arguments = type.typeArguments;
-      // iterate over each bounded type parameter and corresponding argument
-      NodeList<TypeAnnotation> argumentNodes =
-          typeName.typeArguments?.arguments;
-      var typeArguments = type.typeArguments;
-      int loopThroughIndex =
-          math.min(typeArguments.length, parameterElements.length);
-      bool shouldSubstitute =
-          arguments.isNotEmpty && arguments.length == parameterTypes.length;
-      for (int i = 0; i < loopThroughIndex; i++) {
-        DartType argType = typeArguments[i];
-        TypeAnnotation argumentNode =
-            argumentNodes != null && i < argumentNodes.length
-                ? argumentNodes[i]
-                : typeName;
-        if (argType is FunctionType && argType.typeFormals.isNotEmpty) {
-          _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
-            argumentNode,
-          );
-          continue;
-        }
-        DartType boundType = parameterElements[i].bound;
-        if (argType != null && boundType != null) {
-          if (shouldSubstitute) {
-            boundType = boundType.substitute2(arguments, parameterTypes);
-          }
-
-          if (!_typeSystem.isSubtypeOf(argType, boundType)) {
-            if (_shouldAllowSuperBoundedTypes(typeName)) {
-              var replacedType =
-                  (argType as TypeImpl).replaceTopAndBottom(_typeProvider);
-              if (!identical(replacedType, argType) &&
-                  _typeSystem.isSubtypeOf(replacedType, boundType)) {
-                // Bound is satisfied under super-bounded rules, so we're ok.
-                continue;
-              }
-            }
-            _errorReporter.reportTypeErrorForNode(
-                CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
-                argumentNode,
-                [argType, boundType]);
-          }
-        }
-      }
-    }
-  }
-
   void _checkForTypeParameterReferencedByStatic(SimpleIdentifier identifier) {
     if (_isInStaticMethod || _isInStaticVariableDeclaration) {
       var element = identifier.staticElement;
@@ -6013,75 +5476,6 @@
     }
   }
 
-  /**
-   * Verify that the given list of [typeArguments] contains exactly the
-   * [expectedCount] of elements, reporting an error with the given [errorCode]
-   * if not.
-   */
-  void _checkTypeArgumentCount(
-      TypeArgumentList typeArguments, int expectedCount, ErrorCode errorCode) {
-    int actualCount = typeArguments.arguments.length;
-    if (actualCount != expectedCount) {
-      _errorReporter
-          .reportErrorForNode(errorCode, typeArguments, [actualCount]);
-    }
-  }
-
-  /**
-   * Verify that the given [typeArguments] are all within their bounds, as
-   * defined by the given [element].
-   */
-  void _checkTypeArguments(InvocationExpression node) {
-    NodeList<TypeAnnotation> typeArgumentList = node.typeArguments?.arguments;
-    if (typeArgumentList == null) {
-      return;
-    }
-
-    var genericType = node.function.staticType;
-    var instantiatedType = node.staticInvokeType;
-    if (genericType is FunctionType && instantiatedType is FunctionType) {
-      var fnTypeParams =
-          TypeParameterTypeImpl.getTypes(genericType.typeFormals);
-      var typeArgs = typeArgumentList.map((t) => t.type).toList();
-
-      // If the amount mismatches, clean up the lists to be substitutable. The
-      // mismatch in size is reported elsewhere, but we must successfully
-      // perform substitution to validate bounds on mismatched lists.
-      final providedLength = math.min(typeArgs.length, fnTypeParams.length);
-      fnTypeParams = fnTypeParams.sublist(0, providedLength);
-      typeArgs = typeArgs.sublist(0, providedLength);
-
-      for (int i = 0; i < providedLength; i++) {
-        // Check the `extends` clause for the type parameter, if any.
-        //
-        // Also substitute to handle cases like this:
-        //
-        //     <TFrom, TTo extends TFrom>
-        //     <TFrom, TTo extends Iterable<TFrom>>
-        //     <T extends Clonable<T>>
-        //
-        DartType argType = typeArgs[i];
-
-        if (argType is FunctionType && argType.typeFormals.isNotEmpty) {
-          _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
-            typeArgumentList[i],
-          );
-          continue;
-        }
-
-        DartType bound =
-            fnTypeParams[i].bound.substitute2(typeArgs, fnTypeParams);
-        if (!_typeSystem.isSubtypeOf(argType, bound)) {
-          _errorReporter.reportTypeErrorForNode(
-              CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
-              typeArgumentList[i],
-              [argType, bound]);
-        }
-      }
-    }
-  }
-
   void _checkUseOfCovariantInParameters(FormalParameterList node) {
     AstNode parent = node.parent;
     if (_enclosingClass != null &&
@@ -6457,46 +5851,6 @@
     return false;
   }
 
-  /// Given a [node] without type arguments that refers to [element], issues
-  /// an error if [type] is a generic type, and the type arguments were not
-  /// supplied from inference or a non-dynamic default instantiation.
-  ///
-  /// This function is used by other node-specific type checking functions, and
-  /// should only be called when [node] has no explicit `typeArguments`.
-  ///
-  /// [inferenceContextNode] is the node that has the downwards context type,
-  /// if any. For example an [InstanceCreationExpression].
-  ///
-  /// This function will return false if any of the following are true:
-  ///
-  /// - [inferenceContextNode] has an inference context type that does not
-  ///   contain `?`
-  /// - [type] does not have any `dynamic` type arguments.
-  /// - the element is marked with `@optionalTypeArgs` from "package:meta".
-  bool _isMissingTypeArguments(AstNode node, DartType type, Element element,
-      Expression inferenceContextNode) {
-    // Check if this type has type arguments and at least one is dynamic.
-    // If so, we may need to issue a strict-raw-types error.
-    if (type is ParameterizedType &&
-        type.typeArguments.any((t) => t.isDynamic)) {
-      // If we have an inference context node, check if the type was inferred
-      // from it. Some cases will not have a context type, such as the type
-      // annotation `List` in `List list;`
-      if (inferenceContextNode != null) {
-        var contextType = InferenceContext.getContext(inferenceContextNode);
-        if (contextType != null && UnknownInferredType.isKnown(contextType)) {
-          // Type was inferred from downwards context: not an error.
-          return false;
-        }
-      }
-      if (element.hasOptionalTypeArgs) {
-        return false;
-      }
-      return true;
-    }
-    return false;
-  }
-
   /**
    * Return `true` if the given 'this' [expression] is in a valid context.
    */
@@ -6567,19 +5921,6 @@
     return null;
   }
 
-  /// Determines if the given [typeName] occurs in a context where super-bounded
-  /// types are allowed.
-  bool _shouldAllowSuperBoundedTypes(TypeName typeName) {
-    var parent = typeName.parent;
-    if (parent is ExtendsClause) return false;
-    if (parent is OnClause) return false;
-    if (parent is ClassTypeAlias) return false;
-    if (parent is WithClause) return false;
-    if (parent is ConstructorName) return false;
-    if (parent is ImplementsClause) return false;
-    return true;
-  }
-
   /**
    * Return [FieldElement]s that are declared in the [ClassDeclaration] with
    * the given [constructor], but are not initialized.
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 0310cdf..93ef44a 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -25,6 +25,7 @@
 import 'package:analyzer/src/dart/element/member.dart' show ConstructorMember;
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/resolver/exit_detector.dart';
+import 'package:analyzer/src/dart/resolver/extension_member_resolver.dart';
 import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart';
 import 'package:analyzer/src/dart/resolver/scope.dart';
 import 'package:analyzer/src/diagnostic/diagnostic_factory.dart';
@@ -3050,6 +3051,9 @@
 
   final bool _uiAsCodeEnabled;
 
+  /// Helper for extension method resolution.
+  ExtensionMemberResolver extensionResolver;
+
   /// The object used to resolve the element associated with the current node.
   ElementResolver elementResolver;
 
@@ -3159,6 +3163,7 @@
             nameScope: nameScope) {
     this.typeSystem = definingLibrary.context.typeSystem;
     this._promoteManager = TypePromotionManager(typeSystem);
+    this.extensionResolver = ExtensionMemberResolver(this);
     this.elementResolver = new ElementResolver(this,
         reportConstEvaluationErrors: reportConstEvaluationErrors);
     bool strongModeHints = false;
@@ -3422,10 +3427,10 @@
       left?.accept(this);
 
       if (_flowAnalysis != null) {
-        flow?.logicalAnd_rightBegin(node, left);
+        flow?.logicalBinaryOp_rightBegin(left, isAnd: true);
         _flowAnalysis.checkUnreachableNode(right);
         right.accept(this);
-        flow?.logicalAnd_end(node, right);
+        flow?.logicalBinaryOp_end(node, right, isAnd: true);
       } else {
         _promoteManager.visitBinaryExpression_and_rhs(
           left,
@@ -3443,10 +3448,10 @@
 
       left?.accept(this);
 
-      flow?.logicalOr_rightBegin(node, left);
+      flow?.logicalBinaryOp_rightBegin(left, isAnd: false);
       _flowAnalysis?.checkUnreachableNode(right);
       right.accept(this);
-      flow?.logicalOr_end(node, right);
+      flow?.logicalBinaryOp_end(node, right, isAnd: false);
 
       node.accept(elementResolver);
     } else if (operator == TokenType.BANG_EQ || operator == TokenType.EQ_EQ) {
@@ -3605,7 +3610,7 @@
 
     if (_flowAnalysis != null) {
       if (flow != null) {
-        flow.conditional_thenBegin(node, condition);
+        flow.conditional_thenBegin(condition);
         _flowAnalysis.checkUnreachableNode(thenExpression);
       }
       thenExpression.accept(this);
@@ -3623,11 +3628,10 @@
     InferenceContext.setTypeFromNode(elseExpression, node);
 
     if (flow != null) {
-      var isBool = thenExpression.staticType.isDartCoreBool;
-      flow.conditional_elseBegin(node, thenExpression, isBool);
+      flow.conditional_elseBegin(thenExpression);
       _flowAnalysis.checkUnreachableNode(elseExpression);
       elseExpression.accept(this);
-      flow.conditional_end(node, elseExpression, isBool);
+      flow.conditional_end(node, elseExpression);
     } else {
       elseExpression.accept(this);
     }
@@ -3739,7 +3743,7 @@
     _flowAnalysis?.flow?.doStatement_conditionBegin();
     condition.accept(this);
 
-    _flowAnalysis?.flow?.doStatement_end(node, node.condition);
+    _flowAnalysis?.flow?.doStatement_end(node.condition);
   }
 
   @override
@@ -3825,6 +3829,18 @@
   }
 
   @override
+  void visitExtensionOverride(ExtensionOverride node) {
+    node.extensionName.accept(this);
+    node.typeArguments?.accept(this);
+
+    ExtensionMemberResolver(this).setOverrideReceiverContextType(node);
+    node.argumentList.accept(this);
+
+    node.accept(elementResolver);
+    node.accept(typeAnalyzer);
+  }
+
+  @override
   void visitForElementInScope(ForElement node) {
     ForLoopParts forLoopParts = node.forLoopParts;
     if (forLoopParts is ForParts) {
@@ -5365,13 +5381,6 @@
           enclosingExtension = extensionElement;
           nameScope = new TypeParameterScope(nameScope, extensionElement);
           visitExtensionDeclarationInScope(node);
-          DartType extendedType = extensionElement.extendedType;
-          if (extendedType is InterfaceType) {
-            nameScope = new ClassScope(nameScope, extendedType.element);
-          } else if (extendedType is FunctionType) {
-            nameScope =
-                new ClassScope(nameScope, typeProvider.functionType.element);
-          }
           nameScope = ExtensionScope(nameScope, extensionElement);
           visitExtensionMembersInScope(node);
         } finally {
@@ -6204,8 +6213,9 @@
       }
     } else {
       if (element is GenericTypeAliasElementImpl) {
+        var ts = typeSystem as Dart2TypeSystem;
         List<DartType> typeArguments =
-            typeSystem.instantiateTypeFormalsToBounds(element.typeParameters);
+            ts.instantiateTypeFormalsToBounds2(element);
         type = GenericTypeAliasElementImpl.typeAfterSubstitution(
                 element, typeArguments) ??
             dynamicType;
@@ -6451,8 +6461,8 @@
       if (redirectedType != null) {
         typeArguments = redirectedType.typeArguments;
       } else {
-        var typeFormals = typeParameters;
-        typeArguments = typeSystem.instantiateTypeFormalsToBounds(typeFormals);
+        var ts = typeSystem as Dart2TypeSystem;
+        typeArguments = ts.instantiateTypeFormalsToBounds2(element);
       }
     }
 
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index c36e138..2dc19dc 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -15,7 +15,6 @@
 import 'package:analyzer/src/dart/element/member.dart' show ConstructorMember;
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_algebra.dart';
-import 'package:analyzer/src/dart/resolver/extension_member_resolver.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
@@ -479,8 +478,7 @@
 
   @override
   void visitExtensionOverride(ExtensionOverride node) {
-    var extensionResolver = ExtensionMemberResolver(_resolver);
-    extensionResolver.resolveOverride(node);
+    _resolver.extensionResolver.resolveOverride(node);
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 6f89335..85a737b 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -475,6 +475,31 @@
     return orderedArguments;
   }
 
+  /// Given the type defining [element], instantiate its type formals to
+  /// their bounds.
+  List<DartType> instantiateTypeFormalsToBounds2(Element element) {
+    List<TypeParameterElement> typeParameters;
+    if (element is ClassElement) {
+      typeParameters = element.typeParameters;
+    } else if (element is GenericTypeAliasElement) {
+      typeParameters = element.typeParameters;
+    } else {
+      throw StateError('Unexpected: $element');
+    }
+
+    if (typeParameters.isEmpty) {
+      return const <DartType>[];
+    }
+
+    if (AnalysisDriver.useSummary2) {
+      return typeParameters
+          .map((p) => (p as TypeParameterElementImpl).defaultType)
+          .toList();
+    } else {
+      return instantiateTypeFormalsToBounds(typeParameters);
+    }
+  }
+
   @override
   bool isAssignableTo(DartType fromType, DartType toType,
       {FeatureSet featureSet}) {
@@ -1081,8 +1106,9 @@
       var newTypeArgs = _transformList(
           type.typeArguments, (t) => _substituteType(t, lowerBound, visitType));
       if (identical(type.typeArguments, newTypeArgs)) return type;
-      return new InterfaceTypeImpl(
-          type.element, type.prunedTypedefs, type.nullabilitySuffix)
+      return new InterfaceTypeImpl(type.element,
+          prunedTypedefs: type.prunedTypedefs,
+          nullabilitySuffix: type.nullabilitySuffix)
         ..typeArguments = newTypeArgs;
     }
     if (type is FunctionType) {
@@ -1514,7 +1540,7 @@
   ///   - `GLB(FutureOr<A>, FutureOr<B>) == FutureOr<GLB(A, B)>`
   ///   - `GLB(FutureOr<A>, Future<B>) == Future<GLB(A, B)>`
   ///   - else `GLB(FutureOr<A>, B) == GLB(A, B)`
-  /// - `GLB(A, FutureOr<B>) ==  GLB(FutureOr<A>, B)` (defined above),
+  /// - `GLB(A, FutureOr<B>) ==  GLB(FutureOr<B>, A)` (defined above),
   /// - else `GLB(A, B) == Null`
   DartType _getGreatestLowerBound(DartType t1, DartType t2) {
     var result = _typeSystem.getGreatestLowerBound(t1, t2);
@@ -1540,7 +1566,7 @@
         return _getGreatestLowerBound(t1TypeArg, t2);
       }
       if (t2 is InterfaceType && t2.isDartAsyncFutureOr) {
-        // GLB(A, FutureOr<B>) ==  GLB(FutureOr<A>, B)
+        // GLB(A, FutureOr<B>) ==  GLB(FutureOr<B>, A)
         return _getGreatestLowerBound(t2, t1);
       }
       return typeProvider.nullType;
diff --git a/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart b/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart
index 33dee1e..9a559a5 100644
--- a/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart
+++ b/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart
@@ -81,6 +81,12 @@
   bool get checkConstantUpdate2018 => _checkConstantUpdate2018 ??=
       !before_2_5_0.intersect(_versionConstraint).isEmpty;
 
+  /// Return `true` if references to the extension method features need to
+  /// be checked.
+  // TODO(brianwilkerson) Implement this as a version check when a version has
+  //  been selected.
+  bool get checkExtensionMethods => true;
+
   /// Return `true` if references to Future and Stream need to be checked.
   bool get checkFutureAndStream => _checkFutureAndStream ??=
       !before_2_1_0.intersect(_versionConstraint).isEmpty;
@@ -122,8 +128,10 @@
               operatorType == TokenType.CARET) &&
           (node as BinaryExpressionImpl).inConstantContext) {
         if (node.leftOperand.staticType.isDartCoreBool) {
-          _errorReporter.reportErrorForToken(HintCode.SDK_VERSION_BOOL_OPERATOR,
-              node.operator, [node.operator.lexeme]);
+          _errorReporter.reportErrorForToken(
+              HintCode.SDK_VERSION_BOOL_OPERATOR_IN_CONST_CONTEXT,
+              node.operator,
+              [node.operator.lexeme]);
         }
       } else if (operatorType == TokenType.EQ_EQ &&
           (node as BinaryExpressionImpl).inConstantContext) {
@@ -147,6 +155,24 @@
   }
 
   @override
+  void visitExtensionDeclaration(ExtensionDeclaration node) {
+    if (checkExtensionMethods) {
+      _errorReporter.reportErrorForToken(
+          HintCode.SDK_VERSION_EXTENSION_METHODS, node.extensionKeyword);
+    }
+    super.visitExtensionDeclaration(node);
+  }
+
+  @override
+  void visitExtensionOverride(ExtensionOverride node) {
+    if (checkExtensionMethods) {
+      _errorReporter.reportErrorForNode(
+          HintCode.SDK_VERSION_EXTENSION_METHODS, node.extensionName);
+    }
+    super.visitExtensionOverride(node);
+  }
+
+  @override
   void visitForElement(ForElement node) {
     _validateUiAsCode(node);
     _validateUiAsCodeInConstContext(node);
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index 3b231d7..2ac377b 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -23598,6 +23598,7 @@
   List<int> _variantField_7;
   int _variantField_6;
   int _variantField_5;
+  String _variantField_10;
   int _variantField_1;
   List<String> _variantField_4;
   idl.LinkedNodeKind _kind;
@@ -23768,6 +23769,19 @@
   }
 
   @override
+  String get defaultFormalParameter_defaultValueCode {
+    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
+    return _variantField_10 ??= '';
+  }
+
+  /// If the parameter has a default value, the source text of the constant
+  /// expression in the default value.  Otherwise the empty string.
+  set defaultFormalParameter_defaultValueCode(String value) {
+    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
+    _variantField_10 = value;
+  }
+
+  @override
   int get directiveKeywordOffset {
     assert(kind == idl.LinkedNodeKind.exportDirective ||
         kind == idl.LinkedNodeKind.importDirective ||
@@ -23923,9 +23937,11 @@
   UnlinkedInformativeDataBuilder.defaultFormalParameter({
     int codeLength,
     int codeOffset,
+    String defaultFormalParameter_defaultValueCode,
   })  : _kind = idl.LinkedNodeKind.defaultFormalParameter,
         _variantField_2 = codeLength,
-        _variantField_3 = codeOffset;
+        _variantField_3 = codeOffset,
+        _variantField_10 = defaultFormalParameter_defaultValueCode;
 
   UnlinkedInformativeDataBuilder.enumConstantDeclaration({
     int nameOffset,
@@ -24199,6 +24215,7 @@
       signature.addInt(this.kind == null ? 0 : this.kind.index);
       signature.addInt(this.codeLength ?? 0);
       signature.addInt(this.codeOffset ?? 0);
+      signature.addString(this.defaultFormalParameter_defaultValueCode ?? '');
     } else if (kind == idl.LinkedNodeKind.enumConstantDeclaration) {
       signature.addInt(this.kind == null ? 0 : this.kind.index);
       signature.addInt(this.nameOffset ?? 0);
@@ -24383,10 +24400,14 @@
 
   fb.Offset finish(fb.Builder fbBuilder) {
     fb.Offset offset_variantField_7;
+    fb.Offset offset_variantField_10;
     fb.Offset offset_variantField_4;
     if (!(_variantField_7 == null || _variantField_7.isEmpty)) {
       offset_variantField_7 = fbBuilder.writeListUint32(_variantField_7);
     }
+    if (_variantField_10 != null) {
+      offset_variantField_10 = fbBuilder.writeString(_variantField_10);
+    }
     if (!(_variantField_4 == null || _variantField_4.isEmpty)) {
       offset_variantField_4 = fbBuilder.writeList(
           _variantField_4.map((b) => fbBuilder.writeString(b)).toList());
@@ -24413,6 +24434,9 @@
     if (_variantField_5 != null && _variantField_5 != 0) {
       fbBuilder.addUint32(5, _variantField_5);
     }
+    if (offset_variantField_10 != null) {
+      fbBuilder.addOffset(10, offset_variantField_10);
+    }
     if (_variantField_1 != null && _variantField_1 != 0) {
       fbBuilder.addUint32(1, _variantField_1);
     }
@@ -24450,6 +24474,7 @@
   List<int> _variantField_7;
   int _variantField_6;
   int _variantField_5;
+  String _variantField_10;
   int _variantField_1;
   List<String> _variantField_4;
   idl.LinkedNodeKind _kind;
@@ -24546,6 +24571,14 @@
   }
 
   @override
+  String get defaultFormalParameter_defaultValueCode {
+    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
+    _variantField_10 ??=
+        const fb.StringReader().vTableGet(_bc, _bcOffset, 10, '');
+    return _variantField_10;
+  }
+
+  @override
   int get directiveKeywordOffset {
     assert(kind == idl.LinkedNodeKind.exportDirective ||
         kind == idl.LinkedNodeKind.importDirective ||
@@ -24650,6 +24683,9 @@
     if (kind == idl.LinkedNodeKind.defaultFormalParameter) {
       if (codeLength != 0) _result["codeLength"] = codeLength;
       if (codeOffset != 0) _result["codeOffset"] = codeOffset;
+      if (defaultFormalParameter_defaultValueCode != '')
+        _result["defaultFormalParameter_defaultValueCode"] =
+            defaultFormalParameter_defaultValueCode;
     }
     if (kind == idl.LinkedNodeKind.enumConstantDeclaration) {
       if (nameOffset != 0) _result["nameOffset"] = nameOffset;
@@ -24820,6 +24856,8 @@
       return {
         "codeLength": codeLength,
         "codeOffset": codeOffset,
+        "defaultFormalParameter_defaultValueCode":
+            defaultFormalParameter_defaultValueCode,
         "kind": kind,
       };
     }
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index cfb2b67..4ce0eca 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -2837,6 +2837,10 @@
 
   variantField_5:uint (id: 5);
 
+  /// If the parameter has a default value, the source text of the constant
+  /// expression in the default value.  Otherwise the empty string.
+  variantField_10:string (id: 10);
+
   variantField_1:uint (id: 1);
 
   variantField_4:[string] (id: 4);
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index 42e5b1f..5e71b0e 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -3703,6 +3703,11 @@
   @VariantId(5, variant: LinkedNodeKind.constructorDeclaration)
   int get constructorDeclaration_returnTypeOffset;
 
+  /// If the parameter has a default value, the source text of the constant
+  /// expression in the default value.  Otherwise the empty string.
+  @VariantId(10, variant: LinkedNodeKind.defaultFormalParameter)
+  String get defaultFormalParameter_defaultValueCode;
+
   @VariantId(1, variantList: [
     LinkedNodeKind.exportDirective,
     LinkedNodeKind.importDirective,
diff --git a/pkg/analyzer/lib/src/summary/summary_file_builder.dart b/pkg/analyzer/lib/src/summary/summary_file_builder.dart
index 62f79f8..9068bfd 100644
--- a/pkg/analyzer/lib/src/summary/summary_file_builder.dart
+++ b/pkg/analyzer/lib/src/summary/summary_file_builder.dart
@@ -11,6 +11,7 @@
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/scanner/reader.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart';
 import 'package:analyzer/src/dart/sdk/sdk.dart';
@@ -88,16 +89,22 @@
   List<int> build() {
     librarySources.forEach(_addLibrary);
 
-    Map<String, LinkedLibraryBuilder> map = link(libraryUris, (uri) {
-      throw new StateError('Unexpected call to GetDependencyCallback($uri).');
-    }, (uri) {
-      UnlinkedUnit unlinked = unlinkedMap[uri];
-      if (unlinked == null) {
-        throw new StateError('Unable to find unresolved unit $uri.');
-      }
-      return unlinked;
-    }, DeclaredVariables(), context.analysisOptions);
-    map.forEach(bundleAssembler.addLinkedLibrary);
+    var useSummary2 = AnalysisDriver.useSummary2;
+    try {
+      AnalysisDriver.useSummary2 = false;
+      Map<String, LinkedLibraryBuilder> map = link(libraryUris, (uri) {
+        throw new StateError('Unexpected call to GetDependencyCallback($uri).');
+      }, (uri) {
+        UnlinkedUnit unlinked = unlinkedMap[uri];
+        if (unlinked == null) {
+          throw new StateError('Unable to find unresolved unit $uri.');
+        }
+        return unlinked;
+      }, DeclaredVariables(), context.analysisOptions);
+      map.forEach(bundleAssembler.addLinkedLibrary);
+    } finally {
+      AnalysisDriver.useSummary2 = useSummary2;
+    }
 
     _link2();
 
diff --git a/pkg/analyzer/lib/src/summary2/informative_data.dart b/pkg/analyzer/lib/src/summary2/informative_data.dart
index 121c99f..1bf085d 100644
--- a/pkg/analyzer/lib/src/summary2/informative_data.dart
+++ b/pkg/analyzer/lib/src/summary2/informative_data.dart
@@ -98,11 +98,13 @@
 
   @override
   void visitDefaultFormalParameter(DefaultFormalParameter node) {
+    var defaultValueCode = node.defaultValue?.toSource();
     setData(
       node,
       UnlinkedInformativeDataBuilder.defaultFormalParameter(
         codeOffset: node.offset,
         codeLength: node.length,
+        defaultFormalParameter_defaultValueCode: defaultValueCode,
       ),
     );
 
diff --git a/pkg/analyzer/lib/src/summary2/lazy_ast.dart b/pkg/analyzer/lib/src/summary2/lazy_ast.dart
index 4bea1b2..97fd87a 100644
--- a/pkg/analyzer/lib/src/summary2/lazy_ast.dart
+++ b/pkg/analyzer/lib/src/summary2/lazy_ast.dart
@@ -890,6 +890,21 @@
     return node.offset;
   }
 
+  static String getDefaultValueCode(
+    LinkedUnitContext context,
+    DefaultFormalParameter node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null) {
+      if (lazy.data.defaultFormalParameter_defaultValue == null) {
+        return null;
+      }
+      return context.getDefaultValueCodeData(lazy.data);
+    } else {
+      return node.defaultValue?.toSource();
+    }
+  }
+
   static DartType getType(
     AstBinaryReader reader,
     FormalParameter node,
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
index 15c7bf2..25e5b7f 100644
--- a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
@@ -76,6 +76,14 @@
     var library = libraryMap[uriStr];
     if (library == null) return const [];
 
+    // Ask for source to trigger dependency tracking.
+    //
+    // Usually we record a dependency because we request an element from a
+    // library, so we build its library element, so request its source.
+    // However if a library is just exported, and the exporting library is not
+    // imported itself, we just copy references, without computing elements.
+    analysisContext.sourceFactory.forUri(uriStr);
+
     var exportIndexList = library.node.exports;
     var exportReferences = List<Reference>(exportIndexList.length);
     for (var i = 0; i < exportIndexList.length; ++i) {
@@ -293,7 +301,7 @@
       elementFactory.analysisSession,
       libraryNode.name,
       hasName ? libraryNode.nameOffset : -1,
-      libraryNode.name.length,
+      libraryNode.nameLength,
       definingUnitContext,
       reference,
       definingUnitContext.unit_withDeclarations,
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index cc0ae97..2b30438 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -238,12 +238,16 @@
 
   String getDefaultValueCode(AstNode node) {
     if (node is DefaultFormalParameter) {
-      LazyFormalParameter.readDefaultValue(_astReader, node);
-      return node.defaultValue?.toString();
+      return LazyFormalParameter.getDefaultValueCode(this, node);
     }
     return null;
   }
 
+  String getDefaultValueCodeData(LinkedNode data) {
+    var informativeData = getInformativeData(data);
+    return informativeData?.defaultFormalParameter_defaultValueCode;
+  }
+
   int getDirectiveOffset(Directive node) {
     return node.keyword.offset;
   }
@@ -998,11 +1002,17 @@
       VariableDeclarationList variableList = node.parent;
       if (variableList.isConst) return true;
 
+      FieldDeclaration fieldDeclaration = variableList.parent;
+      if (fieldDeclaration.staticKeyword != null) return false;
+
       if (variableList.isFinal) {
-        ClassOrMixinDeclaration class_ = variableList.parent.parent;
-        for (var member in class_.members) {
-          if (member is ConstructorDeclaration && member.constKeyword != null) {
-            return true;
+        var class_ = fieldDeclaration.parent;
+        if (class_ is ClassOrMixinDeclaration) {
+          for (var member in class_.members) {
+            if (member is ConstructorDeclaration &&
+                member.constKeyword != null) {
+              return true;
+            }
           }
         }
       }
diff --git a/pkg/analyzer/lib/src/summary2/top_level_inference.dart b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
index 8187614..8516655 100644
--- a/pkg/analyzer/lib/src/summary2/top_level_inference.dart
+++ b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
@@ -203,13 +203,17 @@
 
   @override
   void visitInstanceCreationExpression(InstanceCreationExpression node) {
-    super.visitInstanceCreationExpression(node);
     var element = node.staticElement;
+    if (element == null) return;
+
     if (element is ConstructorMember) {
       element = (element as ConstructorMember).baseElement;
     }
-    if (element != null) {
-      _set.add(element);
+
+    _set.add(element);
+
+    if (element.enclosingElement.typeParameters.isNotEmpty) {
+      node.argumentList.accept(this);
     }
   }
 
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 8491beb..c5ed643 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 0.37.1-dev
+version: 0.38.0
 author: Dart Team <misc@dartlang.org>
 description: This package provides a library that performs static analysis of Dart code.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
@@ -13,10 +13,10 @@
   collection: ^1.10.1
   convert: ^2.0.0
   crypto: '>=1.1.1 <3.0.0'
-  front_end: 0.1.20
+  front_end: 0.1.22
   glob: ^1.0.3
   html: '>=0.13.4+1 <0.15.0'
-  kernel: 0.3.20
+  kernel: 0.3.22
   meta: ^1.0.2
   package_config: '>=0.1.5 <2.0.0'
   path: '>=0.9.0 <2.0.0'
diff --git a/pkg/analyzer/test/generated/compile_time_error_code.dart b/pkg/analyzer/test/generated/compile_time_error_code.dart
index ed10771..e011614 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code.dart
@@ -1097,186 +1097,6 @@
     ]);
   }
 
-  test_duplicateDefinition_acrossLibraries() async {
-    var libFile = newFile('/test/lib/lib.dart', content: '''
-library lib;
-
-part 'a.dart';
-part 'test.dart';
-''');
-    newFile('/test/lib/a.dart', content: '''
-part of lib;
-
-class A {}
-''');
-    String partContent = '''
-part of lib;
-
-class A {}
-''';
-    newFile('/test/lib/test.dart', content: partContent);
-    await resolveFile(libFile.path);
-    await assertErrorsInCode(partContent, [
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 20, 1),
-    ]);
-  }
-
-  test_duplicateDefinition_catch() async {
-    await assertErrorsInCode(r'''
-main() {
-  try {} catch (e, e) {}
-}''', [
-      error(HintCode.UNUSED_CATCH_STACK, 28, 1),
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 28, 1),
-    ]);
-  }
-
-  test_duplicateDefinition_inPart() async {
-    var libFile = newFile('/test/lib/lib1.dart', content: '''
-library test;
-part 'test.dart';
-class A {}
-''');
-    String partContent = '''
-part of test;
-class A {}
-''';
-    newFile('/test/lib/test.dart', content: partContent);
-    await resolveFile(libFile.path);
-    await assertErrorsInCode(partContent, [
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 20, 1),
-    ]);
-  }
-
-  test_duplicateDefinition_locals_inCase() async {
-    await assertErrorsInCode(r'''
-main() {
-  switch(1) {
-    case 1:
-      var a;
-      var a;
-  }
-}
-''', [
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 45, 1),
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 58, 1),
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 58, 1),
-    ]);
-  }
-
-  test_duplicateDefinition_locals_inFunctionBlock() async {
-    await assertErrorsInCode(r'''
-main() {
-  int m = 0;
-  m(a) {}
-}
-''', [
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 15, 1),
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 24, 1),
-      error(HintCode.UNUSED_ELEMENT, 24, 1),
-    ]);
-  }
-
-  test_duplicateDefinition_locals_inIf() async {
-    await assertErrorsInCode(r'''
-main(int p) {
-  if (p != 0) {
-    var a;
-    var a;
-  }
-}
-''', [
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 38, 1),
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 49, 1),
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 49, 1),
-    ]);
-  }
-
-  test_duplicateDefinition_locals_inMethodBlock() async {
-    await assertErrorsInCode(r'''
-class A {
-  m() {
-    int a;
-    int a;
-  }
-}
-''', [
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 26, 1),
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 37, 1),
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 37, 1),
-    ]);
-  }
-
-  test_duplicateDefinition_notInDefiningUnit() async {
-    newFile('/test/lib/a.dart', content: '''
-part of test;
-class A {}
-''');
-    await assertNoErrorsInCode('''
-library test;
-part 'a.dart';
-class A {}
-''');
-  }
-
-  test_duplicateDefinition_parameters_inConstructor() async {
-    await assertErrorsInCode(r'''
-class A {
-  int a;
-  A(int a, this.a);
-}
-''', [
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 35, 1),
-    ]);
-  }
-
-  test_duplicateDefinition_parameters_inFunctionTypeAlias() async {
-    await assertErrorsInCode(r'''
-typedef F(int a, double a);
-''', [
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 24, 1),
-    ]);
-  }
-
-  test_duplicateDefinition_parameters_inLocalFunction() async {
-    await assertErrorsInCode(r'''
-main() {
-  f(int a, double a) {
-  };
-}
-''', [
-      error(HintCode.UNUSED_ELEMENT, 11, 1),
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 27, 1),
-    ]);
-  }
-
-  test_duplicateDefinition_parameters_inMethod() async {
-    await assertErrorsInCode(r'''
-class A {
-  m(int a, double a) {
-  }
-}
-''', [
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 28, 1),
-    ]);
-  }
-
-  test_duplicateDefinition_parameters_inTopLevelFunction() async {
-    await assertErrorsInCode(r'''
-f(int a, double a) {}
-''', [
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 16, 1),
-    ]);
-  }
-
-  test_duplicateDefinition_typeParameters() async {
-    await assertErrorsInCode(r'''
-class A<T, T> {}
-''', [
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 11, 1),
-    ]);
-  }
-
   test_duplicateNamedArgument() async {
     await assertErrorsInCode(r'''
 f({a, b}) {}
@@ -5061,19 +4881,6 @@
     ]);
   }
 
-  test_typeArgumentNotMatchingBounds_const() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {
-  const G();
-}
-f() { return const G<B>(); }
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 81, 1),
-    ]);
-  }
-
   test_typedef_infiniteParameterBoundCycle() async {
     await assertErrorsInCode(r'''
 typedef F<X extends F> = F Function();
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
index 7346b25..ba715e5 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
@@ -138,17 +138,6 @@
     ]);
   }
 
-  test_duplicateDefinition_for_initializers() async {
-    await assertErrorsInCode(r'''
-f() {
-  for (int i = 0, i = 0; i < 5;) {}
-}
-''', [
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 24, 1),
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 24, 1),
-    ]);
-  }
-
   test_expectedOneListTypeArgument() async {
     await assertErrorsInCode(r'''
 main() {
diff --git a/pkg/analyzer/test/generated/invalid_code_test.dart b/pkg/analyzer/test/generated/invalid_code_test.dart
index 778ecc8..33617ea 100644
--- a/pkg/analyzer/test/generated/invalid_code_test.dart
+++ b/pkg/analyzer/test/generated/invalid_code_test.dart
@@ -48,7 +48,6 @@
 ''');
   }
 
-  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/37733')
   test_fuzz_01() async {
     await _assertCanBeAnalyzed(r'''
 typedef K=Function(<>($
@@ -61,7 +60,6 @@
 ''');
   }
 
-  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/37735')
   test_fuzz_03() async {
     await _assertCanBeAnalyzed('''
 class{const():super.{n
@@ -89,6 +87,38 @@
 ''');
   }
 
+  test_keywordInConstructorInitializer_assert() async {
+    await _assertCanBeAnalyzed('''
+class C {
+  C() : assert = 0;
+}
+''');
+  }
+
+  test_keywordInConstructorInitializer_null() async {
+    await _assertCanBeAnalyzed('''
+class C {
+  C() : null = 0;
+}
+''');
+  }
+
+  test_keywordInConstructorInitializer_super() async {
+    await _assertCanBeAnalyzed('''
+class C {
+  C() : super = 0;
+}
+''');
+  }
+
+  test_keywordInConstructorInitializer_this() async {
+    await _assertCanBeAnalyzed('''
+class C {
+  C() : this = 0;
+}
+''');
+  }
+
   Future<void> _assertCanBeAnalyzed(String text) async {
     addTestFile(text);
     await resolveTestFile();
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index 9873beb..383986c 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -97,6 +97,24 @@
     expect(rightHandSide.name, 'value');
   }
 
+  void test_parseConstructor_nullSuperArgList_openBrace_37735() {
+    // https://github.com/dart-lang/sdk/issues/37735
+    var unit = parseCompilationUnit('class{const():super.{n', errors: [
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 5, 1),
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 11, 1),
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 20, 1),
+      expectedError(ParserErrorCode.EXPECTED_TOKEN, 20, 1),
+      expectedError(ParserErrorCode.CONST_CONSTRUCTOR_WITH_BODY, 20, 1),
+      expectedError(ParserErrorCode.EXPECTED_TOKEN, 21, 1),
+      expectedError(ScannerErrorCode.EXPECTED_TOKEN, 22, 1),
+      expectedError(ScannerErrorCode.EXPECTED_TOKEN, 22, 1),
+    ]);
+    var classDeclaration = unit.declarations[0] as ClassDeclaration;
+    var constructor = classDeclaration.members[0] as ConstructorDeclaration;
+    var invocation = constructor.initializers[0] as SuperConstructorInvocation;
+    expect(invocation.argumentList.arguments, hasLength(0));
+  }
+
   void test_parseField_const_late() {
     createParser('const late T f = 0;', featureSet: nonNullable);
     ClassMember member = parser.parseClassMember('C');
@@ -1024,8 +1042,6 @@
       expectedError(ParserErrorCode.INVALID_SUPER_IN_INITIALIZER, 25, 5),
       expectedError(ParserErrorCode.EXPECTED_TOKEN, 30, 2),
       expectedError(ParserErrorCode.MISSING_IDENTIFIER, 33, 1),
-      expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 34, 1),
-      expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 36, 1),
     ]);
   }
 
@@ -1068,8 +1084,6 @@
       expectedError(ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER, 25, 4),
       expectedError(ParserErrorCode.EXPECTED_TOKEN, 29, 2),
       expectedError(ParserErrorCode.MISSING_IDENTIFIER, 32, 1),
-      expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 33, 1),
-      expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 35, 1),
     ]);
   }
 
@@ -1209,16 +1223,13 @@
 
   void test_listLiteral_invalid_assert() {
     // https://github.com/dart-lang/sdk/issues/37674
-    parseExpression('n=<.["\$assert',
-        errors: [
-          expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 3, 1),
-          expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 4, 1),
-          expectedError(ParserErrorCode.MISSING_IDENTIFIER, 7, 6),
-          expectedError(ParserErrorCode.EXPECTED_STRING_LITERAL, 7, 6),
-          expectedError(ScannerErrorCode.EXPECTED_TOKEN, 7, 1),
-          expectedError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 12, 1),
-        ],
-        expectedEndOffset: 7);
+    parseExpression('n=<.["\$assert', errors: [
+      expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 3, 1),
+      expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 4, 1),
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 7, 6),
+      expectedError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 12, 1),
+      expectedError(ScannerErrorCode.EXPECTED_TOKEN, 13, 1),
+    ]);
   }
 
   void test_listLiteral_spread_disabled() {
@@ -1394,6 +1405,22 @@
     expect(map.elements, hasLength(0));
   }
 
+  void test_parseStringLiteral_interpolated_void() {
+    Expression expression = parseStringLiteral(r"'<html>$void</html>'");
+    expect(expression, isNotNull);
+    assertErrors(
+        errors: [expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 4)]);
+    expect(expression, isStringInterpolation);
+    StringInterpolation literal = expression;
+    NodeList<InterpolationElement> elements = literal.elements;
+    expect(elements, hasLength(3));
+    expect(elements[0] is InterpolationString, isTrue);
+    expect(elements[1] is InterpolationExpression, isTrue);
+    expect(elements[2] is InterpolationString, isTrue);
+    expect((elements[1] as InterpolationExpression).leftBracket.lexeme, '\$');
+    expect((elements[1] as InterpolationExpression).rightBracket, isNull);
+  }
+
   @override
   @failingTest
   void test_parseUnaryExpression_decrement_super() {
@@ -3159,6 +3186,19 @@
 @reflectiveTest
 class SimpleParserTest_Fasta extends FastaParserTestCase
     with SimpleParserTestMixin {
+  void test_method_name_notNull_37733() {
+    // https://github.com/dart-lang/sdk/issues/37733
+    var unit = parseCompilationUnit(r'class C { f(<T>()); }', errors: [
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 12, 1),
+    ]);
+    var classDeclaration = unit.declarations[0] as ClassDeclaration;
+    var method = classDeclaration.members[0] as MethodDeclaration;
+    expect(method.parameters.parameters, hasLength(1));
+    var parameter =
+        method.parameters.parameters[0] as FunctionTypedFormalParameter;
+    expect(parameter.identifier, isNotNull);
+  }
+
   test_parseArgument() {
     Expression result = parseArgument('3');
     expect(result, const TypeMatcher<IntegerLiteral>());
@@ -3235,6 +3275,38 @@
     expect(declarationList.type, isNotNull);
     expect(declarationList.variables, hasLength(1));
   }
+
+  void test_typeAlias_37733() {
+    // https://github.com/dart-lang/sdk/issues/37733
+    var unit = parseCompilationUnit(r'typedef K=Function(<>($', errors: [
+      expectedError(CompileTimeErrorCode.INVALID_INLINE_FUNCTION_TYPE, 19, 1),
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 19, 1),
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 20, 1),
+      expectedError(ParserErrorCode.EXPECTED_TOKEN, 22, 1),
+      expectedError(ScannerErrorCode.EXPECTED_TOKEN, 23, 1),
+      expectedError(ScannerErrorCode.EXPECTED_TOKEN, 23, 1),
+    ]);
+    var typeAlias = unit.declarations[0] as GenericTypeAlias;
+    expect(typeAlias.name.toSource(), 'K');
+    var functionType = typeAlias.functionType;
+    expect(functionType.parameters.parameters, hasLength(1));
+    var parameter = functionType.parameters.parameters[0];
+    expect(parameter.identifier, isNotNull);
+  }
+
+  void test_typeAlias_parameter_missingIdentifier_37733() {
+    // https://github.com/dart-lang/sdk/issues/37733
+    var unit = parseCompilationUnit(r'typedef T=Function(<S>());', errors: [
+      expectedError(CompileTimeErrorCode.INVALID_INLINE_FUNCTION_TYPE, 19, 1),
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 19, 1),
+    ]);
+    var typeAlias = unit.declarations[0] as GenericTypeAlias;
+    expect(typeAlias.name.toSource(), 'T');
+    var functionType = typeAlias.functionType;
+    expect(functionType.parameters.parameters, hasLength(1));
+    var parameter = functionType.parameters.parameters[0];
+    expect(parameter.identifier, isNotNull);
+  }
 }
 
 /**
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index 1e77ec8..663ec18 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -2307,7 +2307,11 @@
   }
 
   test_visitTypeName_parameters_noArguments() async {
-    ClassElement classA = ElementFactory.classElement2("A", ["E"]);
+    var tpE = ElementFactory.typeParameterElement('E');
+    tpE.defaultType = DynamicTypeImpl.instance;
+
+    ClassElement classA =
+        ElementFactory.classElement3(name: 'A', typeParameters: [tpE]);
     TypeName typeName = AstTestFactory.typeName(classA);
     typeName.type = null;
     _resolveNode(typeName, [classA]);
diff --git a/pkg/analyzer/test/generated/static_type_warning_code_test.dart b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
index 6b2cfd5..b9c570d 100644
--- a/pkg/analyzer/test/generated/static_type_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
@@ -1063,281 +1063,6 @@
     ]);
   }
 
-  test_typeArgumentNotMatchingBounds_classTypeAlias() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class C {}
-class G<E extends A> {}
-class D = G<B> with C;
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 69, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_extends() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-class C extends G<B>{}
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 64, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_extends_regressionInIssue18468Fix() async {
-    // https://code.google.com/p/dart/issues/detail?id=18628
-    await assertErrorsInCode(r'''
-class X<T extends Type> {}
-class Y<U> extends X<U> {}
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 48, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_fieldFormalParameter() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-class C {
-  var f;
-  C(G<B> this.f) {}
-}
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 71, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_functionReturnType() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-G<B> f() { return null; }
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 48, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_functionTypeAlias() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-typedef G<B> f();
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 56, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_functionTypedFormalParameter() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-f(G<B> h()) {}
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 50, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_implements() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-class C implements G<B>{}
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 67, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_is() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-var b = 1 is G<B>;
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 61, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_methodInvocation_localFunction() async {
-    await assertErrorsInCode(r'''
-class Point<T extends num> {
-  Point(T x, T y);
-}
-
-main() {
-  Point<T> f<T extends num>(T x, T y) {
-    return new Point<T>(x, y);
-  }
-  print(f<String>('hello', 'world'));
-}
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 145, 6),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_methodInvocation_method() async {
-    await assertErrorsInCode(r'''
-class Point<T extends num> {
-  Point(T x, T y);
-}
-
-class PointFactory {
-  Point<T> point<T extends num>(T x, T y) {
-    return new Point<T>(x, y);
-  }
-}
-
-f(PointFactory factory) {
-  print(factory.point<String>('hello', 'world'));
-}
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 202, 6),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_methodInvocation_topLevelFunction() async {
-    await assertErrorsInCode(r'''
-class Point<T extends num> {
-  Point(T x, T y);
-}
-
-Point<T> f<T extends num>(T x, T y) {
-  return new Point<T>(x, y);
-}
-
-main() {
-  print(f<String>('hello', 'world'));
-}
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 140, 6),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_methodReturnType() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-class C {
-  G<B> m() { return null; }
-}
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 60, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_new() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-f() { return new G<B>(); }
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 65, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_new_superTypeOfUpperBound() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B extends A {}
-class C extends B {}
-class G<E extends B> {}
-f() { return new G<A>(); }
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 96, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_ofFunctionTypeAlias() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-typedef F<T extends A>();
-F<B> fff;
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 50, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_parameter() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-f(G<B> g) {}
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 50, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_redirectingConstructor() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class X<T extends A> {
-  X(int x, int y) {}
-  factory X.name(int x, int y) = X<B>;
-}
-''', [
-      error(StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE, 99, 4),
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 101, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_typeArgumentList() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class C<E> {}
-class D<E extends A> {}
-C<D<B>> Var;
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 64, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_typeParameter() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class C {}
-class G<E extends A> {}
-class D<F extends G<B>> {}
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 77, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_variableDeclaration() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-G<B> g;
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 48, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_with() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-class C extends Object with G<B>{}
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 76, 1),
-    ]);
-  }
-
   test_typeParameterSupertypeOfItsBound() async {
     await assertErrorsInCode(r'''
 class A<T extends T> {
diff --git a/pkg/analyzer/test/generated/type_system_test.dart b/pkg/analyzer/test/generated/type_system_test.dart
index 815c659..16f0d8d 100644
--- a/pkg/analyzer/test/generated/type_system_test.dart
+++ b/pkg/analyzer/test/generated/type_system_test.dart
@@ -48,17 +48,29 @@
   Dart2TypeSystem typeSystem;
 
   DartType get bottomType => typeProvider.bottomType;
+
   InterfaceType get doubleType => typeProvider.doubleType;
+
   DartType get dynamicType => typeProvider.dynamicType;
+
   InterfaceType get functionType => typeProvider.functionType;
+
   InterfaceType get intType => typeProvider.intType;
+
   InterfaceType get iterableType => typeProvider.iterableType;
+
   InterfaceType get listType => typeProvider.listType;
+
   DartType get neverType => typeProvider.neverType;
+
   DartType get nullType => typeProvider.nullType;
+
   InterfaceType get numType => typeProvider.numType;
+
   InterfaceType get objectType => typeProvider.objectType;
+
   InterfaceType get stringType => typeProvider.stringType;
+
   DartType get voidType => VoidTypeImpl.instance;
 
   void setUp() {
@@ -342,16 +354,27 @@
   FunctionType simpleFunctionType;
 
   DartType get bottomType => typeProvider.bottomType;
+
   InterfaceType get doubleType => typeProvider.doubleType;
+
   DartType get dynamicType => typeProvider.dynamicType;
+
   InterfaceType get functionType => typeProvider.functionType;
+
   InterfaceType get futureOrType => typeProvider.futureOrType;
+
   InterfaceType get intType => typeProvider.intType;
+
   InterfaceType get iterableType => typeProvider.iterableType;
+
   InterfaceType get listType => typeProvider.listType;
+
   InterfaceType get nullType => typeProvider.nullType;
+
   InterfaceType get numType => typeProvider.numType;
+
   InterfaceType get objectType => typeProvider.objectType;
+
   InterfaceType get stringType => typeProvider.stringType;
 
   DartType get voidType => VoidTypeImpl.instance;
@@ -2673,7 +2696,7 @@
     ]);
 
     // Create a non-identical but equal copy of Function, and verify subtyping
-    var copyOfFunction = new InterfaceTypeImpl(functionType.element, null);
+    var copyOfFunction = new InterfaceTypeImpl(functionType.element);
     _checkEquivalent(functionType, copyOfFunction);
   }
 
@@ -2907,16 +2930,27 @@
   TypeSystem typeSystem;
 
   DartType get bottomType => typeProvider.bottomType;
+
   InterfaceType get doubleType => typeProvider.doubleType;
+
   DartType get dynamicType => typeProvider.dynamicType;
+
   InterfaceType get functionType => typeProvider.functionType;
+
   InterfaceType get futureOrType => typeProvider.futureOrType;
+
   InterfaceType get intType => typeProvider.intType;
+
   InterfaceType get listType => typeProvider.listType;
+
   DartType get nullType => typeProvider.nullType;
+
   InterfaceType get numType => typeProvider.numType;
+
   InterfaceType get objectType => typeProvider.objectType;
+
   InterfaceType get stringType => typeProvider.stringType;
+
   DartType get voidType => VoidTypeImpl.instance;
 
   void setUp() {
diff --git a/pkg/analyzer/test/src/dart/analysis/index_test.dart b/pkg/analyzer/test/src/dart/analysis/index_test.dart
index df9540b..38f6ff8 100644
--- a/pkg/analyzer/test/src/dart/analysis/index_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/index_test.dart
@@ -5,10 +5,12 @@
 import 'dart:async';
 import 'dart:convert';
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/dart/analysis/index.dart';
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:test/test.dart';
@@ -19,6 +21,7 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(IndexTest);
+    defineReflectiveTests(IndexWithExtensionMethodsTest);
   });
 }
 
@@ -1286,7 +1289,8 @@
       }
     }
     for (Element e = element; e != null; e = e.enclosingElement) {
-      if (e.enclosingElement is ClassElement) {
+      if (e.enclosingElement is ClassElement ||
+          e.enclosingElement is ExtensionElement) {
         classMemberId = _getStringId(e.name);
         break;
       }
@@ -1370,6 +1374,112 @@
   }
 }
 
+@reflectiveTest
+class IndexWithExtensionMethodsTest extends IndexTest {
+  @override
+  AnalysisOptionsImpl createAnalysisOptions() => AnalysisOptionsImpl()
+    ..contextFeatures = new FeatureSet.forTesting(
+        sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
+
+  test_isInvokedBy_MethodElement_ofExtension_instance() async {
+    await _indexTestUnit('''
+class A {}
+
+extension E on A {
+  void foo() {}
+}
+
+main(A a) {
+  a.foo();
+}
+''');
+    MethodElement element = findElement('foo');
+    assertThat(element)..isInvokedAt('foo();', true);
+  }
+
+  test_isInvokedBy_MethodElement_ofExtension_static() async {
+    await _indexTestUnit('''
+class A {}
+
+extension E on A {
+  static void foo() {}
+}
+
+main(A a) {
+  E.foo();
+}
+''');
+    MethodElement element = findElement('foo');
+    assertThat(element)..isInvokedAt('foo();', true);
+  }
+
+  test_isReferencedBy_ClassElement_fromExtension() async {
+    await _indexTestUnit('''
+class A<T> {}
+
+extension E on A<int> {}
+''');
+    ClassElement element = findElement('A');
+    assertThat(element)..isReferencedAt('A<int>', false);
+  }
+
+  test_isReferencedBy_ExtensionElement() async {
+    await _indexTestUnit('''
+class A {}
+
+extension E on A {
+  void foo() {}
+}
+
+main(A a) {
+  E(a).foo();
+}
+''');
+    ExtensionElement element = findElement('E');
+    assertThat(element)..isReferencedAt('E(a).foo()', false);
+  }
+
+  test_isReferencedBy_PropertyAccessor_ofExtension_instance() async {
+    await _indexTestUnit('''
+class A {}
+
+extension E on A {
+  int get foo => 0;
+  void set foo(int _) {}
+}
+
+main(A a) {
+  a.foo;
+  a.foo = 0;
+}
+''');
+    PropertyAccessorElement getter = findElement('foo', ElementKind.GETTER);
+    PropertyAccessorElement setter = findElement('foo=');
+    assertThat(getter)..isReferencedAt('foo;', true);
+    assertThat(setter)..isReferencedAt('foo = 0;', true);
+  }
+
+  test_isReferencedBy_PropertyAccessor_ofExtension_static() async {
+    await _indexTestUnit('''
+class A {}
+
+extension E on A {
+  static int get foo => 0;
+  static void set foo(int _) {}
+}
+
+main(A a) {
+  a.foo;
+  a.foo = 0;
+}
+''');
+    PropertyAccessorElement getter = findElement('foo', ElementKind.GETTER);
+    PropertyAccessorElement setter = findElement('foo=');
+    assertThat(getter)..isReferencedAt('foo;', true);
+    assertThat(setter)..isReferencedAt('foo = 0;', true);
+  }
+}
+
 class _ElementIndexAssert {
   final IndexTest test;
   final Element element;
diff --git a/pkg/analyzer/test/src/dart/analysis/search_test.dart b/pkg/analyzer/test/src/dart/analysis/search_test.dart
index ac142d0..fb4a4ef 100644
--- a/pkg/analyzer/test/src/dart/analysis/search_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/search_test.dart
@@ -4,6 +4,7 @@
 
 import 'dart:async';
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/ast/ast.dart' hide Declaration;
 import 'package:analyzer/dart/ast/standard_resolution_map.dart';
@@ -12,6 +13,7 @@
 import 'package:analyzer/src/dart/ast/element_locator.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/testing/element_search.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -21,6 +23,7 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(SearchTest);
+    defineReflectiveTests(SearchWithExtensionMethodsTest);
   });
 }
 
@@ -1636,3 +1639,152 @@
     expect(matches, unorderedEquals(expectedMatches));
   }
 }
+
+@reflectiveTest
+class SearchWithExtensionMethodsTest extends SearchTest {
+  @override
+  AnalysisOptionsImpl createAnalysisOptions() => AnalysisOptionsImpl()
+    ..contextFeatures = new FeatureSet.forTesting(
+        sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
+
+  test_searchReferences_ExtensionElement() async {
+    await _resolveTestUnit('''
+extension E on int {
+  void foo() {}
+  static void bar() {}
+}
+
+main() {
+  E(0).foo();
+  E.bar();
+}
+''');
+    var element = _findElement('E');
+    var main = _findElement('main');
+    var expected = [
+      _expectId(main, SearchResultKind.REFERENCE, 'E(0)'),
+      _expectId(main, SearchResultKind.REFERENCE, 'E.bar()'),
+    ];
+    await _verifyReferences(element, expected);
+  }
+
+  test_searchReferences_MethodElement_ofExtension_instance() async {
+    await _resolveTestUnit('''
+extension E on int {
+  void foo() {}
+
+  void bar() {
+    foo(); // 1
+    this.foo(); // 2
+    foo; // 3
+    this.foo; // 4
+  }
+}
+
+main() {
+  E(0).foo(); // 5
+  0.foo(); // 6
+  E(0).foo; // 7
+  0.foo; // 8
+}
+''');
+    var element = _findElement('foo');
+    var bar = _findElement('bar');
+    var main = _findElement('main');
+    var expected = [
+      _expectId(bar, SearchResultKind.INVOCATION, 'foo(); // 1'),
+      _expectIdQ(bar, SearchResultKind.INVOCATION, 'foo(); // 2'),
+      _expectId(bar, SearchResultKind.REFERENCE, 'foo; // 3'),
+      _expectIdQ(bar, SearchResultKind.REFERENCE, 'foo; // 4'),
+      _expectIdQ(main, SearchResultKind.INVOCATION, 'foo(); // 5'),
+      _expectIdQ(main, SearchResultKind.INVOCATION, 'foo(); // 6'),
+      _expectIdQ(main, SearchResultKind.REFERENCE, 'foo; // 7'),
+      _expectIdQ(main, SearchResultKind.REFERENCE, 'foo; // 8'),
+    ];
+    await _verifyReferences(element, expected);
+  }
+
+  test_searchReferences_MethodElement_ofExtension_static() async {
+    await _resolveTestUnit('''
+extension E on int {
+  static void foo() {}
+
+  static void bar() {
+    foo(); // 1
+    foo; // 2
+  }
+}
+
+main() {
+  E.foo(); // 3
+  E.foo; // 4
+}
+''');
+    var element = _findElement('foo');
+    var bar = _findElement('bar');
+    var main = _findElement('main');
+    var expected = [
+      _expectId(bar, SearchResultKind.INVOCATION, 'foo(); // 1'),
+      _expectId(bar, SearchResultKind.REFERENCE, 'foo; // 2'),
+      _expectIdQ(main, SearchResultKind.INVOCATION, 'foo(); // 3'),
+      _expectIdQ(main, SearchResultKind.REFERENCE, 'foo; // 4'),
+    ];
+    await _verifyReferences(element, expected);
+  }
+
+  test_searchReferences_PropertyAccessor_getter_ofExtension_instance() async {
+    await _resolveTestUnit('''
+extension E on int {
+  int get foo => 0;
+
+  void bar() {
+    foo; // 1
+    this.foo; // 2
+  }
+}
+
+main() {
+  E(0).foo; // 3
+  0.foo; // 4
+}
+''');
+    var element = _findElement('foo', ElementKind.GETTER);
+    var bar = _findElement('bar');
+    var main = _findElement('main');
+    var expected = [
+      _expectId(bar, SearchResultKind.REFERENCE, 'foo; // 1'),
+      _expectIdQ(bar, SearchResultKind.REFERENCE, 'foo; // 2'),
+      _expectIdQ(main, SearchResultKind.REFERENCE, 'foo; // 3'),
+      _expectIdQ(main, SearchResultKind.REFERENCE, 'foo; // 4'),
+    ];
+    await _verifyReferences(element, expected);
+  }
+
+  test_searchReferences_PropertyAccessor_setter_ofExtension_instance() async {
+    await _resolveTestUnit('''
+extension E on int {
+  set foo(int _) {}
+
+  void bar() {
+    foo = 1;
+    this.foo = 2;
+  }
+}
+
+main() {
+  E(0).foo = 3;
+  0.foo = 4;
+}
+''');
+    var element = _findElement('foo=');
+    var bar = _findElement('bar');
+    var main = _findElement('main');
+    var expected = [
+      _expectId(bar, SearchResultKind.REFERENCE, 'foo = 1;'),
+      _expectIdQ(bar, SearchResultKind.REFERENCE, 'foo = 2;'),
+      _expectIdQ(main, SearchResultKind.REFERENCE, 'foo = 3;'),
+      _expectIdQ(main, SearchResultKind.REFERENCE, 'foo = 4;'),
+    ];
+    await _verifyReferences(element, expected);
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/ast_rewrite_test.dart b/pkg/analyzer/test/src/dart/resolution/ast_rewrite_test.dart
new file mode 100644
index 0000000..73316d2
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/ast_rewrite_test.dart
@@ -0,0 +1,394 @@
+// 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.
+
+import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:meta/meta.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(AstRewriteMethodInvocationTest);
+    defineReflectiveTests(AstRewriteMethodInvocationWithExtensionMethodsTest);
+  });
+}
+
+@reflectiveTest
+class AstRewriteMethodInvocationTest extends DriverResolutionTest {
+  test_targetNull_cascade() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  void foo() {}
+}
+
+f(A a) {
+  a..foo();
+}
+''');
+
+    var invocation = findNode.methodInvocation('foo();');
+    assertElement(invocation, findElement.method('foo'));
+  }
+
+  test_targetNull_class() async {
+    await assertNoErrorsInCode(r'''
+class A<T, U> {
+  A(int a);
+}
+
+f() {
+  A<int, String>(0);
+}
+''');
+
+    var creation = findNode.instanceCreation('A<int, String>(0);');
+    assertInstanceCreation(
+      creation,
+      findElement.class_('A'),
+      'A<int, String>',
+      expectedConstructorMember: true,
+      expectedSubstitution: {'T': 'int', 'U': 'String'},
+    );
+    _assertArgumentList(creation.argumentList, ['0']);
+  }
+
+  test_targetNull_function() async {
+    await assertNoErrorsInCode(r'''
+void A<T, U>(int a) {}
+
+f() {
+  A<int, String>(0);
+}
+''');
+
+    var invocation = findNode.methodInvocation('A<int, String>(0);');
+    assertElement(invocation, findElement.topFunction('A'));
+    assertInvokeType(invocation, 'void Function(int)');
+    _assertArgumentList(invocation.argumentList, ['0']);
+  }
+
+  test_targetPrefixedIdentifier_prefix_class_constructor() async {
+    newFile('/test/lib/a.dart', content: r'''
+class A<T> {
+  A.named(T a);
+}
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'a.dart' as prefix;
+
+f() {
+  prefix.A.named(0);
+}
+''');
+
+    var importFind = findElement.importFind('package:test/a.dart');
+
+    var creation = findNode.instanceCreation('A.named(0);');
+    assertInstanceCreation(
+      creation,
+      importFind.class_('A'),
+      'A<int>',
+      constructorName: 'named',
+      expectedPrefix: importFind.prefix,
+      expectedConstructorMember: true,
+      expectedSubstitution: {'T': 'int'},
+    );
+    _assertArgumentList(creation.argumentList, ['0']);
+  }
+
+  test_targetPrefixedIdentifier_prefix_class_constructor_typeArguments() async {
+    newFile('/test/lib/a.dart', content: r'''
+class A<T> {
+  A.named(int a);
+}
+''');
+
+    await assertErrorsInCode(r'''
+import 'a.dart' as prefix;
+
+f() {
+  prefix.A.named<int>(0);
+}
+''', [
+      error(StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
+          50, 5),
+    ]);
+
+    var importFind = findElement.importFind('package:test/a.dart');
+
+    var creation = findNode.instanceCreation('named<int>(0);');
+    assertInstanceCreation(
+      creation,
+      importFind.class_('A'),
+      'A<int>',
+      constructorName: 'named',
+      expectedPrefix: importFind.prefix,
+      expectedConstructorMember: true,
+      expectedSubstitution: {'T': 'int'},
+    );
+    _assertTypeArgumentList(
+      creation.constructorName.type.typeArguments,
+      ['int'],
+    );
+    expect((creation as InstanceCreationExpressionImpl).typeArguments, isNull);
+    _assertArgumentList(creation.argumentList, ['0']);
+  }
+
+  test_targetPrefixedIdentifier_prefix_getter_method() async {
+    newFile('/test/lib/a.dart', content: r'''
+A get foo => A();
+
+class A {
+  void bar(int a) {}
+}
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'a.dart' as prefix;
+
+f() {
+  prefix.foo.bar(0);
+}
+''');
+
+    var importFind = findElement.importFind('package:test/a.dart');
+
+    var invocation = findNode.methodInvocation('bar(0);');
+    assertElement(invocation, importFind.class_('A').getMethod('bar'));
+    assertInvokeType(invocation, 'void Function(int)');
+    _assertArgumentList(invocation.argumentList, ['0']);
+  }
+
+  test_targetSimpleIdentifier_class_constructor() async {
+    await assertNoErrorsInCode(r'''
+class A<T> {
+  A.named(T a);
+}
+
+f() {
+  A.named(0);
+}
+''');
+
+    var creation = findNode.instanceCreation('A.named(0);');
+    assertInstanceCreation(
+      creation,
+      findElement.class_('A'),
+      'A<int>',
+      constructorName: 'named',
+      expectedConstructorMember: true,
+      expectedSubstitution: {'T': 'int'},
+    );
+    _assertArgumentList(creation.argumentList, ['0']);
+  }
+
+  test_targetSimpleIdentifier_class_constructor_typeArguments() async {
+    await assertErrorsInCode(r'''
+class A<T, U> {
+  A.named(int a);
+}
+
+f() {
+  A.named<int, String>(0);
+}
+''', [
+      error(StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
+          52, 13),
+    ]);
+
+    var creation = findNode.instanceCreation('named<int, String>(0);');
+    assertInstanceCreation(
+      creation,
+      findElement.class_('A'),
+      // TODO(scheglov) Move type arguments
+      'A<dynamic, dynamic>',
+//      'A<int, String>',
+      constructorName: 'named',
+      expectedConstructorMember: true,
+      // TODO(scheglov) Move type arguments
+      expectedSubstitution: {'T': 'dynamic', 'U': 'dynamic'},
+//      expectedSubstitution: {'T': 'int', 'U': 'String'},
+    );
+    // TODO(scheglov) Move type arguments
+//    _assertTypeArgumentList(
+//      creation.constructorName.type.typeArguments,
+//      ['int', 'String'],
+//    );
+    // TODO(scheglov) Fix and uncomment.
+//    expect((creation as InstanceCreationExpressionImpl).typeArguments, isNull);
+    _assertArgumentList(creation.argumentList, ['0']);
+  }
+
+  test_targetSimpleIdentifier_class_staticMethod() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  static void foo(int a) {}
+}
+
+f() {
+  A.foo(0);
+}
+''');
+
+    var invocation = findNode.methodInvocation('foo(0);');
+    assertElement(invocation, findElement.method('foo'));
+  }
+
+  test_targetSimpleIdentifier_prefix_class() async {
+    newFile('/test/lib/a.dart', content: r'''
+class A<T, U> {
+  A(int a);
+}
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'a.dart' as prefix;
+
+f() {
+  prefix.A<int, String>(0);
+}
+''');
+
+    var importFind = findElement.importFind('package:test/a.dart');
+
+    var creation = findNode.instanceCreation('A<int, String>(0);');
+    assertInstanceCreation(
+      creation,
+      importFind.class_('A'),
+      'A<int, String>',
+      expectedPrefix: importFind.prefix,
+      expectedConstructorMember: true,
+      expectedSubstitution: {'T': 'int', 'U': 'String'},
+    );
+    _assertArgumentList(creation.argumentList, ['0']);
+  }
+
+  test_targetSimpleIdentifier_prefix_function() async {
+    newFile('/test/lib/a.dart', content: r'''
+void A<T, U>(int a) {}
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'a.dart' as prefix;
+
+f() {
+  prefix.A<int, String>(0);
+}
+''');
+
+    var importFind = findElement.importFind('package:test/a.dart');
+
+    var invocation = findNode.methodInvocation('A<int, String>(0);');
+    assertElement(invocation, importFind.topFunction('A'));
+    assertInvokeType(invocation, 'void Function(int)');
+    _assertArgumentList(invocation.argumentList, ['0']);
+  }
+
+  void _assertArgumentList(
+    ArgumentList argumentList,
+    List<String> expectedArguments,
+  ) {
+    var argumentStrings = argumentList.arguments
+        .map((e) => result.content.substring(e.offset, e.end))
+        .toList();
+    expect(argumentStrings, expectedArguments);
+  }
+
+  void _assertTypeArgumentList(
+    TypeArgumentList argumentList,
+    List<String> expectedArguments,
+  ) {
+    var argumentStrings = argumentList.arguments
+        .map((e) => result.content.substring(e.offset, e.end))
+        .toList();
+    expect(argumentStrings, expectedArguments);
+  }
+}
+
+@reflectiveTest
+class AstRewriteMethodInvocationWithExtensionMethodsTest
+    extends AstRewriteMethodInvocationTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = FeatureSet.forTesting(
+      sdkVersion: '2.3.0',
+      additionalFeatures: [Feature.extension_methods],
+    );
+
+  test_targetNull_extension() async {
+    await assertNoErrorsInCode(r'''
+class A {}
+
+extension E<T> on A {
+  void foo() {}
+}
+
+f(A a) {
+  E<int>(a).foo();
+}
+''');
+
+    var override = findNode.extensionOverride('E<int>(a)');
+    _assertExtensionOverride(
+      override,
+      expectedElement: findElement.extension_('E'),
+      expectedTypeArguments: ['int'],
+      expectedExtendedType: 'A',
+    );
+  }
+
+  test_targetSimpleIdentifier_prefix_extension() async {
+    newFile('/test/lib/a.dart', content: r'''
+class A {}
+
+extension E<T> on A {
+  void foo() {}
+}
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'a.dart' as prefix;
+
+f(prefix.A a) {
+  prefix.E<int>(a).foo();
+}
+''');
+
+    var importFind = findElement.importFind('package:test/a.dart');
+
+    var override = findNode.extensionOverride('E<int>(a)');
+    _assertExtensionOverride(
+      override,
+      expectedElement: importFind.extension_('E'),
+      expectedTypeArguments: ['int'],
+      expectedExtendedType: 'A',
+    );
+    assertImportPrefix(findNode.simple('prefix.E'), importFind.prefix);
+  }
+
+  void _assertExtensionOverride(
+    ExtensionOverride override, {
+    @required ExtensionElement expectedElement,
+    @required List<String> expectedTypeArguments,
+    @required String expectedExtendedType,
+  }) {
+    expect(override.staticElement, expectedElement);
+    assertElementTypeStrings(
+      override.typeArgumentTypes,
+      expectedTypeArguments,
+    );
+    assertElementTypeString(
+      override.extendedType,
+      expectedExtendedType,
+    );
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/class_test.dart b/pkg/analyzer/test/src/dart/resolution/class_test.dart
index f384b0d..53ff0e9 100644
--- a/pkg/analyzer/test/src/dart/resolution/class_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/class_test.dart
@@ -478,450 +478,6 @@
         [CompileTimeErrorCode.CONFLICTING_METHOD_AND_FIELD]);
   }
 
-  test_error_conflictingStaticAndInstance_inClass_getter_getter() async {
-    addTestFile(r'''
-class C {
-  static int get foo => 0;
-  int get foo => 0;
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_getter_method() async {
-    addTestFile(r'''
-class C {
-  static int get foo => 0;
-  void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_getter_setter() async {
-    addTestFile(r'''
-class C {
-  static int get foo => 0;
-  set foo(_) {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_method_getter() async {
-    addTestFile(r'''
-class C {
-  static void foo() {}
-  int get foo => 0;
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_method_method() async {
-    addTestFile(r'''
-class C {
-  static void foo() {}
-  void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_method_setter() async {
-    addTestFile(r'''
-class C {
-  static void foo() {}
-  set foo(_) {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_setter_getter() async {
-    addTestFile(r'''
-class C {
-  static set foo(_) {}
-  int get foo => 0;
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_setter_method() async {
-    addTestFile(r'''
-class C {
-  static set foo(_) {}
-  void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_setter_setter() async {
-    addTestFile(r'''
-class C {
-  static set foo(_) {}
-  set foo(_) {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_getter_getter() async {
-    addTestFile(r'''
-class A {
-  int get foo => 0;
-}
-abstract class B implements A {
-  static int get foo => 0;
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_getter_method() async {
-    addTestFile(r'''
-class A {
-  int get foo => 0;
-}
-abstract class B implements A {
-  static void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_getter_setter() async {
-    addTestFile(r'''
-class A {
-  set foo(_) {}
-}
-abstract class B implements A {
-  static int get foo => 0;
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_method_getter() async {
-    addTestFile(r'''
-class A {
-  int get foo => 0;
-}
-abstract class B implements A {
-  static void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_method_method() async {
-    addTestFile(r'''
-class A {
-  void foo() {}
-}
-abstract class B implements A {
-  static void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_method_setter() async {
-    addTestFile(r'''
-class A {
-  set foo(_) {}
-}
-abstract class B implements A {
-  static void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_setter_method() async {
-    addTestFile(r'''
-class A {
-  void foo() {}
-}
-abstract class B implements A {
-  static set foo(_) {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_setter_setter() async {
-    addTestFile(r'''
-class A {
-  set foo(_) {}
-}
-abstract class B implements A {
-  static set foo(_) {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inMixin_getter_getter() async {
-    addTestFile(r'''
-class A {
-  int get foo => 0;
-}
-class B extends Object with A {
-  static int get foo => 0;
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inMixin_getter_method() async {
-    addTestFile(r'''
-class A {
-  int get foo => 0;
-}
-class B extends Object with A {
-  static void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inMixin_getter_setter() async {
-    addTestFile(r'''
-class A {
-  set foo(_) {}
-}
-class B extends Object with A {
-  static int get foo => 0;
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inMixin_method_getter() async {
-    addTestFile(r'''
-class A {
-  int get foo => 0;
-}
-class B extends Object with A {
-  static void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inMixin_method_method() async {
-    addTestFile(r'''
-class A {
-  void foo() {}
-}
-class B extends Object with A {
-  static void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inMixin_method_setter() async {
-    addTestFile(r'''
-class A {
-  set foo(_) {}
-}
-class B extends Object with A {
-  static void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inMixin_setter_method() async {
-    addTestFile(r'''
-class A {
-  void foo() {}
-}
-class B extends Object with A {
-  static set foo(_) {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inMixin_setter_setter() async {
-    addTestFile(r'''
-class A {
-  set foo(_) {}
-}
-class B extends Object with A {
-  static set foo(_) {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inSuper_getter_getter() async {
-    addTestFile(r'''
-class A {
-  int get foo => 0;
-}
-class B extends A {
-  static int get foo => 0;
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inSuper_getter_method() async {
-    addTestFile(r'''
-class A {
-  int get foo => 0;
-}
-class B extends A {
-  static void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inSuper_getter_setter() async {
-    addTestFile(r'''
-class A {
-  set foo(_) {}
-}
-class B extends A {
-  static int get foo => 0;
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inSuper_method_getter() async {
-    addTestFile(r'''
-class A {
-  int get foo => 0;
-}
-class B extends A {
-  static void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inSuper_method_method() async {
-    addTestFile(r'''
-class A {
-  void foo() {}
-}
-class B extends A {
-  static void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inSuper_method_setter() async {
-    addTestFile(r'''
-class A {
-  set foo(_) {}
-}
-class B extends A {
-  static void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inSuper_setter_method() async {
-    addTestFile(r'''
-class A {
-  void foo() {}
-}
-class B extends A {
-  static set foo(_) {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inSuper_setter_setter() async {
-    addTestFile(r'''
-class A {
-  set foo(_) {}
-}
-class B extends A {
-  static set foo(_) {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
   test_error_duplicateConstructorDefault() async {
     addTestFile(r'''
 class C {
@@ -948,160 +504,6 @@
     ]);
   }
 
-  test_error_duplicateDefinition_field_field() async {
-    addTestFile(r'''
-class C {
-  int foo;
-  int foo;
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-  }
-
-  test_error_duplicateDefinition_field_field_static() async {
-    addTestFile(r'''
-class C {
-  static int foo;
-  static int foo;
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-  }
-
-  test_error_duplicateDefinition_field_getter() async {
-    addTestFile(r'''
-class C {
-  int foo;
-  int get foo => 0;
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-  }
-
-  test_error_duplicateDefinition_field_method() async {
-    addTestFile(r'''
-class C {
-  int foo;
-  void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-  }
-
-  test_error_duplicateDefinition_getter_getter() async {
-    addTestFile(r'''
-class C {
-  int get foo => 0;
-  int get foo => 0;
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-  }
-
-  test_error_duplicateDefinition_getter_method() async {
-    addTestFile(r'''
-class C {
-  int get foo => 0;
-  void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-  }
-
-  test_error_duplicateDefinition_method_getter() async {
-    addTestFile(r'''
-class C {
-  void foo() {}
-  int get foo => 0;
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-  }
-
-  test_error_duplicateDefinition_method_method() async {
-    addTestFile(r'''
-class C {
-  void foo() {}
-  void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-  }
-
-  test_error_duplicateDefinition_method_setter() async {
-    addTestFile(r'''
-class C {
-  void foo() {}
-  set foo(_) {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-  }
-
-  test_error_duplicateDefinition_OK_fieldFinal_setter() async {
-    addTestFile(r'''
-class C {
-  final int foo = 0;
-  set foo(int x) {}
-}
-''');
-    await resolveTestFile();
-    assertNoTestErrors();
-  }
-
-  test_error_duplicateDefinition_OK_getter_setter() async {
-    addTestFile(r'''
-class C {
-  int get foo => 0;
-  set foo(_) {}
-}
-''');
-    await resolveTestFile();
-    assertNoTestErrors();
-  }
-
-  test_error_duplicateDefinition_OK_setter_getter() async {
-    addTestFile(r'''
-class C {
-  set foo(_) {}
-  int get foo => 0;
-}
-''');
-    await resolveTestFile();
-    assertNoTestErrors();
-  }
-
-  test_error_duplicateDefinition_setter_method() async {
-    addTestFile(r'''
-class C {
-  set foo(_) {}
-  void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-  }
-
-  test_error_duplicateDefinition_setter_setter() async {
-    addTestFile(r'''
-class C {
-  void set foo(_) {}
-  void set foo(_) {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-  }
-
   test_error_extendsNonClass_dynamic() async {
     addTestFile(r'''
 class A extends dynamic {}
diff --git a/pkg/analyzer/test/src/dart/resolution/enum_test.dart b/pkg/analyzer/test/src/dart/resolution/enum_test.dart
index c731596..8e9b10b 100644
--- a/pkg/analyzer/test/src/dart/resolution/enum_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/enum_test.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:analyzer/src/error/codes.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -20,17 +19,6 @@
     with EnumResolutionMixin {}
 
 mixin EnumResolutionMixin implements ResolutionTest {
-  test_error_conflictingStaticAndInstance_index() async {
-    addTestFile(r'''
-enum E {
-  a, index
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
   test_inference_listLiteral() async {
     addTestFile(r'''
 enum E1 {a, b}
diff --git a/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart b/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart
index b6633c9..40f8562 100644
--- a/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart
@@ -363,6 +363,20 @@
     assertType(identifier, 'int');
   }
 
+  test_instance_getter_fromExtension_functionType() async {
+    await assertNoErrorsInCode('''
+extension E on int Function(int) {
+  int get a => 1;
+}
+g(int Function(int) f) {
+  f.a;
+}
+''');
+    var access = findNode.prefixed('f.a');
+    assertElement(access, findElement.getter('a'));
+    assertType(access, 'int');
+  }
+
   test_instance_getter_fromInstance() async {
     await assertNoErrorsInCode('''
 class C {}
@@ -443,6 +457,20 @@
     assertType(access, 'int');
   }
 
+  test_instance_getterInvoked_fromExtension_functionType() async {
+    await assertNoErrorsInCode('''
+extension E on int Function(int) {
+  String Function() get a => () => 'a';
+}
+g(int Function(int) f) {
+  f.a();
+}
+''');
+    var invocation = findNode.methodInvocation('f.a()');
+    assertElement(invocation, findElement.getter('a'));
+    assertType(invocation, 'String');
+  }
+
   test_instance_method_fromDifferentExtension_usingBounds() async {
     await assertNoErrorsInCode('''
 class B {}
@@ -509,6 +537,20 @@
     assertInvokeType(invocation, 'void Function()');
   }
 
+  test_instance_method_fromExtension_functionType() async {
+    await assertNoErrorsInCode('''
+extension E on int Function(int) {
+  void a() {}
+}
+g(int Function(int) f) {
+  f.a();
+}
+''');
+    var invocation = findNode.methodInvocation('f.a()');
+    assertElement(invocation, findElement.method('a'));
+    assertInvokeType(invocation, 'void Function()');
+  }
+
   test_instance_method_fromInstance() async {
     await assertNoErrorsInCode('''
 class B {}
@@ -584,7 +626,6 @@
     assertInvokeType(invocation, 'void Function()');
   }
 
-  @failingTest
   test_instance_method_specificSubtypeMatchLocalGenerics() async {
     await assertNoErrorsInCode('''
 class A<T> {}
@@ -606,8 +647,12 @@
 }
 ''');
     var invocation = findNode.methodInvocation('x.f(o)');
-    assertElement(invocation, findElement.method('f', of: 'B_Ext'));
-    assertInvokeType(invocation, 'void Function(T)');
+    assertMember(
+      invocation,
+      findElement.method('f', of: 'B_Ext'),
+      {'T': 'C'},
+    );
+    assertInvokeType(invocation, 'void Function(C)');
   }
 
   test_instance_method_specificSubtypeMatchPlatform() async {
@@ -654,7 +699,20 @@
     assertElement(binary, findElement.method('+', of: 'C'));
   }
 
-  test_instance_operator_binary_fromExtension() async {
+  test_instance_operator_binary_fromExtension_functionType() async {
+    await assertNoErrorsInCode('''
+extension E on int Function(int) {
+  void operator +(int i) {}
+}
+g(int Function(int) f) {
+  f + 2;
+}
+''');
+    var binary = findNode.binary('+ ');
+    assertElement(binary, findElement.method('+', of: 'E'));
+  }
+
+  test_instance_operator_binary_fromExtension_interfaceType() async {
     await assertNoErrorsInCode('''
 class C {}
 extension E on C {
@@ -684,7 +742,20 @@
     assertElement(index, findElement.method('[]', of: 'C'));
   }
 
-  test_instance_operator_index_fromExtension() async {
+  test_instance_operator_index_fromExtension_functionType() async {
+    await assertNoErrorsInCode('''
+extension E on int Function(int) {
+  void operator [](int index) {}
+}
+g(int Function(int) f) {
+  f[2];
+}
+''');
+    var index = findNode.index('f[2]');
+    assertElement(index, findElement.method('[]', of: 'E'));
+  }
+
+  test_instance_operator_index_fromExtension_interfaceType() async {
     await assertNoErrorsInCode('''
 class C {}
 extension E on C {
@@ -714,7 +785,20 @@
     assertElement(index, findElement.method('[]=', of: 'C'));
   }
 
-  test_instance_operator_indexEquals_fromExtension() async {
+  test_instance_operator_indexEquals_fromExtension_functionType() async {
+    await assertNoErrorsInCode('''
+extension E on int Function(int) {
+  void operator []=(int index, int value) {}
+}
+g(int Function(int) f) {
+  f[2] = 3;
+}
+''');
+    var index = findNode.index('f[2]');
+    assertElement(index, findElement.method('[]=', of: 'E'));
+  }
+
+  test_instance_operator_indexEquals_fromExtension_interfaceType() async {
     await assertNoErrorsInCode('''
 class C {}
 extension E on C {
@@ -744,7 +828,20 @@
     assertElement(postfix, findElement.method('+', of: 'C'));
   }
 
-  test_instance_operator_postfix_fromExtension() async {
+  test_instance_operator_postfix_fromExtension_functionType() async {
+    await assertNoErrorsInCode('''
+extension E on int Function(int) {
+  void operator +(int i) {}
+}
+g(int Function(int) f) {
+  f++;
+}
+''');
+    var postfix = findNode.postfix('++');
+    assertElement(postfix, findElement.method('+', of: 'E'));
+  }
+
+  test_instance_operator_postfix_fromExtension_interfaceType() async {
     await assertNoErrorsInCode('''
 class C {}
 extension E on C {
@@ -774,7 +871,20 @@
     assertElement(prefix, findElement.method('+', of: 'C'));
   }
 
-  test_instance_operator_prefix_fromExtension() async {
+  test_instance_operator_prefix_fromExtension_functionType() async {
+    await assertNoErrorsInCode('''
+extension E on int Function(int) {
+  void operator +(int i) {}
+}
+g(int Function(int) f) {
+  ++f;
+}
+''');
+    var prefix = findNode.prefix('++');
+    assertElement(prefix, findElement.method('+', of: 'E'));
+  }
+
+  test_instance_operator_prefix_fromExtension_interfaceType() async {
     await assertNoErrorsInCode('''
 class C {}
 extension E on C {
@@ -804,7 +914,20 @@
     assertElement(prefix, findElement.method('unary-', of: 'C'));
   }
 
-  test_instance_operator_unary_fromExtension() async {
+  test_instance_operator_unary_fromExtension_functionType() async {
+    await assertNoErrorsInCode('''
+extension E on int Function(int) {
+  void operator -() {}
+}
+g(int Function(int) f) {
+  -f;
+}
+''');
+    var prefix = findNode.prefix('-f');
+    assertElement(prefix, findElement.method('unary-', of: 'E'));
+  }
+
+  test_instance_operator_unary_fromExtension_interfaceType() async {
     await assertNoErrorsInCode('''
 class C {}
 extension E on C {
@@ -818,6 +941,19 @@
     assertElement(prefix, findElement.method('unary-', of: 'E'));
   }
 
+  test_instance_setter_fromExtension_functionType() async {
+    await assertNoErrorsInCode('''
+extension E on int Function(int) {
+  set a(int x) {}
+}
+g(int Function(int) f) {
+  f.a = 1;
+}
+''');
+    var access = findNode.prefixed('f.a');
+    assertElement(access, findElement.setter('a'));
+  }
+
   test_instance_setter_oneMatch() async {
     await assertNoErrorsInCode('''
 class C {}
@@ -855,7 +991,19 @@
     assertType(access, 'int');
   }
 
-  test_instance_tearoff() async {
+  test_instance_tearoff_fromExtension_functionType() async {
+    await assertNoErrorsInCode('''
+extension E on int Function(int) {
+  void a(int x) {}
+}
+g(int Function(int) f) => f.a;
+''');
+    var identifier = findNode.simple('a;');
+    assertElement(identifier, findElement.method('a'));
+    assertType(identifier, 'void Function(int)');
+  }
+
+  test_instance_tearoff_fromExtension_interfaceType() async {
     await assertNoErrorsInCode('''
 class C {}
 
@@ -1490,4 +1638,116 @@
     assertElement(identifier, findElement.method('a'));
     assertType(identifier, 'void Function(int)');
   }
+
+  test_topLevel_function_fromInstance() async {
+    await assertNoErrorsInCode('''
+class C {
+  void a() {}
+}
+
+void a() {}
+
+extension E on C {
+  void b() {
+    a();
+  }
+}
+''');
+    var invocation = findNode.methodInvocation('a();');
+    assertElement(invocation, findElement.topFunction('a'));
+    assertInvokeType(invocation, 'void Function()');
+  }
+
+  test_topLevel_function_fromStatic() async {
+    await assertNoErrorsInCode('''
+class C {
+  void a() {}
+}
+
+void a() {}
+
+extension E on C {
+  static void b() {
+    a();
+  }
+}
+''');
+    var invocation = findNode.methodInvocation('a();');
+    assertElement(invocation, findElement.topFunction('a'));
+    assertInvokeType(invocation, 'void Function()');
+  }
+
+  test_topLevel_getter_fromInstance() async {
+    await assertNoErrorsInCode('''
+class C {
+  int get a => 0;
+}
+
+int get a => 0;
+
+extension E on C {
+  void b() {
+    a;
+  }
+}
+''');
+    var identifier = findNode.simple('a;');
+    assertElement(identifier, findElement.topGet('a'));
+    assertType(identifier, 'int');
+  }
+
+  test_topLevel_getter_fromStatic() async {
+    await assertNoErrorsInCode('''
+class C {
+  int get a => 0;
+}
+
+int get a => 0;
+
+extension E on C {
+  static void b() {
+    a;
+  }
+}
+''');
+    var identifier = findNode.simple('a;');
+    assertElement(identifier, findElement.topGet('a'));
+    assertType(identifier, 'int');
+  }
+
+  test_topLevel_setter_fromInstance() async {
+    await assertNoErrorsInCode('''
+class C {
+  set a(int _) {}
+}
+
+set a(int _) {}
+
+extension E on C {
+  void b() {
+    a = 0;
+  }
+}
+''');
+    var identifier = findNode.simple('a = 0;');
+    assertElement(identifier, findElement.topSet('a'));
+  }
+
+  test_topLevel_setter_fromStatic() async {
+    await assertNoErrorsInCode('''
+class C {
+  set a(int _) {}
+}
+
+set a(int _) {}
+
+extension E on C {
+  static void b() {
+    a = 0;
+  }
+}
+''');
+    var identifier = findNode.simple('a = 0;');
+    assertElement(identifier, findElement.topSet('a'));
+  }
 }
diff --git a/pkg/analyzer/test/src/dart/resolution/extension_override_test.dart b/pkg/analyzer/test/src/dart/resolution/extension_override_test.dart
index 77c2a17..cb1bd80 100644
--- a/pkg/analyzer/test/src/dart/resolution/extension_override_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/extension_override_test.dart
@@ -59,7 +59,6 @@
     validateCall();
   }
 
-  @failingTest
   test_call_noPrefix_typeArguments() async {
     // The test is failing because we're not yet doing type inference.
     await assertNoErrorsInCode('''
@@ -97,7 +96,6 @@
     validateCall();
   }
 
-  @failingTest
   test_call_prefix_typeArguments() async {
     // The test is failing because we're not yet doing type inference.
     newFile('/test/lib/lib.dart', content: '''
diff --git a/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart b/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
index 57179a1..2a5fd62 100644
--- a/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
@@ -114,10 +114,14 @@
     assertInstanceCreation(
       creation,
       findElement.class_('Foo'),
+      // TODO(scheglov) Move type arguments
       'Foo<dynamic>',
+//      'Foo<int>',
       constructorName: 'bar',
       expectedConstructorMember: true,
+      // TODO(scheglov) Move type arguments
       expectedSubstitution: {'X': 'dynamic'},
+//      expectedSubstitution: {'X': 'int'},
     );
   }
 
diff --git a/pkg/analyzer/test/src/dart/resolution/mixin_test.dart b/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
index 100d12e..827c61b 100644
--- a/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
@@ -234,313 +234,6 @@
 ''');
   }
 
-  test_error_conflictingStaticAndInstance_inClass_getter_getter() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  static int get foo => 0;
-  int get foo => 0;
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 27, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_getter_method() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  static int get foo => 0;
-  void foo() {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 27, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_getter_setter() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  static int get foo => 0;
-  set foo(_) {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 27, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_method_getter() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  static void foo() {}
-  int get foo => 0;
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 24, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_method_method() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  static void foo() {}
-  void foo() {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 24, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_method_setter() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  static void foo() {}
-  set foo(_) {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 24, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_setter_getter() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  static set foo(_) {}
-  int get foo => 0;
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 23, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_setter_method() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  static set foo(_) {}
-  void foo() {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 23, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_setter_setter() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  static set foo(_) {}
-  set foo(_) {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 23, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inConstraint_getter_getter() async {
-    await assertErrorsInCode(r'''
-class A {
-  int get foo => 0;
-}
-mixin M on A {
-  static int get foo => 0;
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 64, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inConstraint_getter_method() async {
-    await assertErrorsInCode(r'''
-class A {
-  int get foo => 0;
-}
-mixin M on A {
-  static void foo() {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 61, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inConstraint_getter_setter() async {
-    await assertErrorsInCode(r'''
-class A {
-  set foo(_) {}
-}
-mixin M on A {
-  static int get foo => 0;
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 60, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inConstraint_method_getter() async {
-    await assertErrorsInCode(r'''
-class A {
-  int get foo => 0;
-}
-mixin M on A {
-  static void foo() {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 61, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inConstraint_method_method() async {
-    await assertErrorsInCode(r'''
-class A {
-  void foo() {}
-}
-mixin M on A {
-  static void foo() {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 57, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inConstraint_method_setter() async {
-    await assertErrorsInCode(r'''
-class A {
-  set foo(_) {}
-}
-mixin M on A {
-  static void foo() {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 57, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inConstraint_setter_method() async {
-    await assertErrorsInCode(r'''
-class A {
-  void foo() {}
-}
-mixin M on A {
-  static set foo(_) {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 56, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inConstraint_setter_setter() async {
-    await assertErrorsInCode(r'''
-class A {
-  set foo(_) {}
-}
-mixin M on A {
-  static set foo(_) {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 56, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_getter_getter() async {
-    await assertErrorsInCode(r'''
-class A {
-  int get foo => 0;
-}
-mixin M implements A {
-  static int get foo => 0;
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 72, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_getter_method() async {
-    await assertErrorsInCode(r'''
-class A {
-  int get foo => 0;
-}
-mixin M implements A {
-  static void foo() {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 69, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_getter_setter() async {
-    await assertErrorsInCode(r'''
-class A {
-  set foo(_) {}
-}
-mixin M implements A {
-  static int get foo => 0;
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 68, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_method_getter() async {
-    await assertErrorsInCode(r'''
-class A {
-  int get foo => 0;
-}
-mixin M implements A {
-  static void foo() {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 69, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_method_method() async {
-    await assertErrorsInCode(r'''
-class A {
-  void foo() {}
-}
-mixin M implements A {
-  static void foo() {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 65, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_method_setter() async {
-    await assertErrorsInCode(r'''
-class A {
-  set foo(_) {}
-}
-mixin M implements A {
-  static void foo() {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 65, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_setter_method() async {
-    await assertErrorsInCode(r'''
-class A {
-  void foo() {}
-}
-mixin M implements A {
-  static set foo(_) {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 64, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_setter_setter() async {
-    await assertErrorsInCode(r'''
-class A {
-  set foo(_) {}
-}
-mixin M implements A {
-  static set foo(_) {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 64, 3),
-    ]);
-  }
-
   test_error_conflictingTypeVariableAndClass() async {
     await assertErrorsInCode(r'''
 mixin M<M> {}
@@ -599,83 +292,6 @@
     ]);
   }
 
-  test_error_duplicateDefinition_field() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  int t;
-  int t;
-}
-''', [
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 25, 1),
-    ]);
-  }
-
-  test_error_duplicateDefinition_field_method() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  int t;
-  void t() {}
-}
-''', [
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 26, 1),
-    ]);
-  }
-
-  test_error_duplicateDefinition_getter() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  int get t => 0;
-  int get t => 0;
-}
-''', [
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 38, 1),
-    ]);
-  }
-
-  test_error_duplicateDefinition_getter_method() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  int get foo => 0;
-  void foo() {}
-}
-''', [
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 37, 3),
-    ]);
-  }
-
-  test_error_duplicateDefinition_method() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  void t() {}
-  void t() {}
-}
-''', [
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 31, 1),
-    ]);
-  }
-
-  test_error_duplicateDefinition_method_getter() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  void foo() {}
-  int get foo => 0;
-}
-''', [
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 36, 3),
-    ]);
-  }
-
-  test_error_duplicateDefinition_setter() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  void set t(_) {}
-  void set t(_) {}
-}
-''', [
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 40, 1),
-    ]);
-  }
-
   test_error_finalNotInitialized() async {
     await assertErrorsInCode(r'''
 mixin M {
diff --git a/pkg/analyzer/test/src/dart/resolution/resolution.dart b/pkg/analyzer/test/src/dart/resolution/resolution.dart
index bd793ba..3fd1ab2 100644
--- a/pkg/analyzer/test/src/dart/resolution/resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/resolution.dart
@@ -413,13 +413,10 @@
       var name = node.name as SimpleIdentifier;
       assertElement(name, expectedElement);
       // TODO(scheglov) Should this be null?
-      assertType(name, expectedType);
+//      assertType(name, expectedType);
     } else {
       var name = node.name as PrefixedIdentifier;
-
-      assertElement(name.prefix, expectedPrefix);
-      expect(name.prefix.staticType, isNull);
-
+      assertImportPrefix(name.prefix, expectedPrefix);
       assertElement(name.identifier, expectedElement);
 
       // TODO(scheglov) This should be null, but it is not.
diff --git a/pkg/analyzer/test/src/dart/resolution/test_all.dart b/pkg/analyzer/test/src/dart/resolution/test_all.dart
index 243bad8..8261f8b 100644
--- a/pkg/analyzer/test/src/dart/resolution/test_all.dart
+++ b/pkg/analyzer/test/src/dart/resolution/test_all.dart
@@ -5,6 +5,7 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'assignment_test.dart' as assignment;
+import 'ast_rewrite_test.dart' as ast_rewrite;
 import 'class_alias_test.dart' as class_alias;
 import 'class_test.dart' as class_resolution;
 import 'comment_test.dart' as comment;
@@ -41,6 +42,7 @@
 main() {
   defineReflectiveSuite(() {
     assignment.main();
+    ast_rewrite.main();
     class_alias.main();
     class_resolution.main();
     comment.main();
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/extension_methods_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/extension_methods_test.dart
index 410fc08..dfbb4ac 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/extension_methods_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/extension_methods_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -137,6 +138,48 @@
     );
   }
 
+  test_override_downward_hasTypeArguments() async {
+    await assertNoErrorsInCode('''
+extension E<T> on Set<T> {
+  void foo() {}
+}
+
+main() {
+  E<int>({}).foo();
+}
+''');
+    var literal = findNode.setOrMapLiteral('{}).');
+    assertType(literal, 'Set<int>');
+  }
+
+  test_override_downward_hasTypeArguments_wrongNumber() async {
+    await assertNoErrorsInCode('''
+extension E<T> on Set<T> {
+  void foo() {}
+}
+
+main() {
+  E<int, bool>({}).foo();
+}
+''');
+    var literal = findNode.setOrMapLiteral('{}).');
+    assertType(literal, 'Set<dynamic>');
+  }
+
+  test_override_downward_noTypeArguments() async {
+    await assertNoErrorsInCode('''
+extension E<T> on Set<T> {
+  void foo() {}
+}
+
+main() {
+  E({}).foo();
+}
+''');
+    var literal = findNode.setOrMapLiteral('{}).');
+    assertType(literal, 'Set<dynamic>');
+  }
+
   test_override_hasTypeArguments_getter() async {
     await assertNoErrorsInCode('''
 class A<T> {}
@@ -241,6 +284,23 @@
     );
   }
 
+  test_override_inferTypeArguments_error_couldNotInfer() async {
+    await assertErrorsInCode('''
+extension E<T extends num> on T {
+  void foo() {}
+}
+
+f(String s) {
+  E(s).foo();
+}
+''', [
+      error(StrongModeCode.COULD_NOT_INFER, 69, 1),
+    ]);
+    var override = findNode.extensionOverride('E(s)');
+    assertElementTypeStrings(override.typeArgumentTypes, ['String']);
+    assertElementTypeString(override.extendedType, 'String');
+  }
+
   test_override_inferTypeArguments_getter() async {
     await assertNoErrorsInCode('''
 class A<T> {}
diff --git a/pkg/analyzer/test/src/diagnostics/access_static_extension_member_test.dart b/pkg/analyzer/test/src/diagnostics/access_static_extension_member_test.dart
deleted file mode 100644
index deb739c..0000000
--- a/pkg/analyzer/test/src/diagnostics/access_static_extension_member_test.dart
+++ /dev/null
@@ -1,74 +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.
-
-import 'package:analyzer/dart/analysis/features.dart';
-import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../dart/resolution/driver_resolution.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(AccessStaticExtensionMemberTest);
-  });
-}
-
-@reflectiveTest
-class AccessStaticExtensionMemberTest extends DriverResolutionTest {
-  @override
-  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
-    ..contextFeatures = new FeatureSet.forTesting(
-        sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
-
-  @failingTest
-  test_getter() async {
-    await assertErrorsInCode('''
-class C {}
-
-extension E on C {
-  static int get a => 0;
-}
-
-f(C c) {
-  c.a;
-}
-''', [
-      error(CompileTimeErrorCode.ACCESS_STATIC_EXTENSION_MEMBER, 72, 1),
-    ]);
-  }
-
-  test_method() async {
-    await assertErrorsInCode('''
-class C {}
-
-extension E on C {
-  static void a() {}
-}
-
-f(C c) {
-  c.a();
-}
-''', [
-      error(CompileTimeErrorCode.ACCESS_STATIC_EXTENSION_MEMBER, 68, 1),
-    ]);
-  }
-
-  @failingTest
-  test_setter() async {
-    await assertErrorsInCode('''
-class C {}
-
-extension E on C {
-  static set a(v) {}}
-}
-
-f(C c) {
-  c.a = 2;
-}
-''', [
-      error(CompileTimeErrorCode.ACCESS_STATIC_EXTENSION_MEMBER, 69, 1),
-    ]);
-  }
-}
diff --git a/pkg/analyzer/test/src/diagnostics/ambiguous_export_test.dart b/pkg/analyzer/test/src/diagnostics/ambiguous_export_test.dart
index 02dc727..bf7926d 100644
--- a/pkg/analyzer/test/src/diagnostics/ambiguous_export_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/ambiguous_export_test.dart
@@ -41,7 +41,7 @@
     ..contextFeatures = new FeatureSet.forTesting(
         sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
 
-  test_extension() async {
+  test_extensions_bothExported() async {
     newFile('/test/lib/lib1.dart', content: r'''
 extension E on String {}
 ''');
@@ -55,4 +55,15 @@
       error(CompileTimeErrorCode.AMBIGUOUS_EXPORT, 20, 19),
     ]);
   }
+
+  test_extensions_localAndExported() async {
+    newFile('/test/lib/lib1.dart', content: r'''
+extension E on String {}
+''');
+    await assertNoErrorsInCode(r'''
+export 'lib1.dart';
+
+extension E on String {}
+''');
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/ambiguous_extension_method_access_test.dart b/pkg/analyzer/test/src/diagnostics/ambiguous_extension_method_access_test.dart
index cc03f82..21ffe97 100644
--- a/pkg/analyzer/test/src/diagnostics/ambiguous_extension_method_access_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/ambiguous_extension_method_access_test.dart
@@ -22,16 +22,33 @@
     ..contextFeatures = new FeatureSet.forTesting(
         sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
 
-  test_getter() async {
-    // TODO(brianwilkerson) Ensure that only one diagnostic is produced.
+  test_call() async {
     await assertErrorsInCode('''
 class A {}
 
-extension A1_Ext on A {
+extension E1 on A {
+  int call() => 0;
+}
+
+extension E2 on A {
+  int call() => 0;
+}
+
+int f(A a) => a();
+''', [
+      error(CompileTimeErrorCode.AMBIGUOUS_EXTENSION_METHOD_ACCESS, 110, 1),
+    ]);
+  }
+
+  test_getter() async {
+    await assertErrorsInCode('''
+class A {}
+
+extension E1 on A {
   void get a => 1;
 }
 
-extension A2_Ext on A {
+extension E2 on A {
   void get a => 2;
 }
 
@@ -39,8 +56,7 @@
   a.a;
 }
 ''', [
-      error(StaticTypeWarningCode.UNDEFINED_GETTER, 117, 1),
-      error(CompileTimeErrorCode.AMBIGUOUS_EXTENSION_METHOD_ACCESS, 117, 1),
+      error(CompileTimeErrorCode.AMBIGUOUS_EXTENSION_METHOD_ACCESS, 109, 1),
     ]);
   }
 
@@ -48,11 +64,11 @@
     await assertErrorsInCode('''
 class A {}
 
-extension A1_Ext on A {
+extension E1 on A {
   void a() {}
 }
 
-extension A2_Ext on A {
+extension E2 on A {
   void a() {}
 }
 
@@ -60,20 +76,74 @@
   a.a();
 }
 ''', [
-      error(CompileTimeErrorCode.AMBIGUOUS_EXTENSION_METHOD_ACCESS, 107, 1),
+      error(CompileTimeErrorCode.AMBIGUOUS_EXTENSION_METHOD_ACCESS, 99, 1),
+    ]);
+  }
+
+  test_operator_binary() async {
+    // There is no error reported.
+    await assertErrorsInCode('''
+class A {}
+
+extension E1 on A {
+  A operator +(A a) => a;
+}
+
+extension E2 on A {
+  A operator +(A a) => a;
+}
+
+A f(A a) => a + a;
+''', [
+      error(CompileTimeErrorCode.AMBIGUOUS_EXTENSION_METHOD_ACCESS, 122, 5),
+    ]);
+  }
+
+  test_operator_index() async {
+    await assertErrorsInCode('''
+class A {}
+
+extension E1 on A {
+  int operator [](int i) => 0;
+}
+
+extension E2 on A {
+  int operator [](int i) => 0;
+}
+
+int f(A a) => a[0];
+''', [
+      error(CompileTimeErrorCode.AMBIGUOUS_EXTENSION_METHOD_ACCESS, 134, 1),
+    ]);
+  }
+
+  test_operator_unary() async {
+    await assertErrorsInCode('''
+class A {}
+
+extension E1 on A {
+  int operator -() => 0;
+}
+
+extension E2 on A {
+  int operator -() => 0;
+}
+
+int f(A a) => -a;
+''', [
+      error(CompileTimeErrorCode.AMBIGUOUS_EXTENSION_METHOD_ACCESS, 123, 1),
     ]);
   }
 
   test_setter() async {
-    // TODO(brianwilkerson) Ensure that only one diagnostic is produced.
     await assertErrorsInCode('''
 class A {}
 
-extension A1_Ext on A {
+extension E1 on A {
   set a(x) {}
 }
 
-extension A2_Ext on A {
+extension E2 on A {
   set a(x) {}
 }
 
@@ -81,8 +151,7 @@
   a.a = 3;
 }
 ''', [
-      error(StaticTypeWarningCode.UNDEFINED_SETTER, 107, 1),
-      error(CompileTimeErrorCode.AMBIGUOUS_EXTENSION_METHOD_ACCESS, 107, 1),
+      error(CompileTimeErrorCode.AMBIGUOUS_EXTENSION_METHOD_ACCESS, 99, 1),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/conflicting_static_and_instance_test.dart b/pkg/analyzer/test/src/diagnostics/conflicting_static_and_instance_test.dart
new file mode 100644
index 0000000..d7ac1a6
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/conflicting_static_and_instance_test.dart
@@ -0,0 +1,753 @@
+// 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.
+
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ConflictingStaticAndInstanceClassTest);
+    defineReflectiveTests(ConflictingStaticAndInstanceEnumTest);
+    defineReflectiveTests(ConflictingStaticAndInstanceMixinTest);
+  });
+}
+
+@reflectiveTest
+class ConflictingStaticAndInstanceClassTest extends DriverResolutionTest {
+  test_inClass_getter_getter() async {
+    await assertErrorsInCode(r'''
+class C {
+  static int get foo => 0;
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 27, 3),
+    ]);
+  }
+
+  test_inClass_getter_method() async {
+    await assertErrorsInCode(r'''
+class C {
+  static int get foo => 0;
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 27, 3),
+    ]);
+  }
+
+  test_inClass_getter_setter() async {
+    await assertErrorsInCode(r'''
+class C {
+  static int get foo => 0;
+  set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 27, 3),
+    ]);
+  }
+
+  test_inClass_method_getter() async {
+    await assertErrorsInCode(r'''
+class C {
+  static void foo() {}
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 24, 3),
+    ]);
+  }
+
+  test_inClass_method_method() async {
+    await assertErrorsInCode(r'''
+class C {
+  static void foo() {}
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 24, 3),
+    ]);
+  }
+
+  test_inClass_method_setter() async {
+    await assertErrorsInCode(r'''
+class C {
+  static void foo() {}
+  set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 24, 3),
+    ]);
+  }
+
+  test_inClass_setter_getter() async {
+    await assertErrorsInCode(r'''
+class C {
+  static set foo(_) {}
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 23, 3),
+    ]);
+  }
+
+  test_inClass_setter_method() async {
+    await assertErrorsInCode(r'''
+class C {
+  static set foo(_) {}
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 23, 3),
+    ]);
+  }
+
+  test_inClass_setter_setter() async {
+    await assertErrorsInCode(r'''
+class C {
+  static set foo(_) {}
+  set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 23, 3),
+    ]);
+  }
+
+  test_inInterface_getter_getter() async {
+    await assertErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+abstract class B implements A {
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 81, 3),
+    ]);
+  }
+
+  test_inInterface_getter_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+abstract class B implements A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 78, 3),
+    ]);
+  }
+
+  test_inInterface_getter_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  set foo(_) {}
+}
+abstract class B implements A {
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 77, 3),
+    ]);
+  }
+
+  test_inInterface_method_getter() async {
+    await assertErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+abstract class B implements A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 78, 3),
+    ]);
+  }
+
+  test_inInterface_method_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  void foo() {}
+}
+abstract class B implements A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 74, 3),
+    ]);
+  }
+
+  test_inInterface_method_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  set foo(_) {}
+}
+abstract class B implements A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 74, 3),
+    ]);
+  }
+
+  test_inInterface_setter_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  void foo() {}
+}
+abstract class B implements A {
+  static set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 73, 3),
+    ]);
+  }
+
+  test_inInterface_setter_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  set foo(_) {}
+}
+abstract class B implements A {
+  static set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 73, 3),
+    ]);
+  }
+
+  test_inMixin_getter_getter() async {
+    await assertErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+class B extends Object with A {
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 81, 3),
+    ]);
+  }
+
+  test_inMixin_getter_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+class B extends Object with A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 78, 3),
+    ]);
+  }
+
+  test_inMixin_getter_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  set foo(_) {}
+}
+class B extends Object with A {
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 77, 3),
+    ]);
+  }
+
+  test_inMixin_method_getter() async {
+    await assertErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+class B extends Object with A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 78, 3),
+    ]);
+  }
+
+  test_inMixin_method_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  void foo() {}
+}
+class B extends Object with A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 74, 3),
+    ]);
+  }
+
+  test_inMixin_method_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  set foo(_) {}
+}
+class B extends Object with A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 74, 3),
+    ]);
+  }
+
+  test_inMixin_setter_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  void foo() {}
+}
+class B extends Object with A {
+  static set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 73, 3),
+    ]);
+  }
+
+  test_inMixin_setter_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  set foo(_) {}
+}
+class B extends Object with A {
+  static set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 73, 3),
+    ]);
+  }
+
+  test_inSuper_getter_getter() async {
+    await assertErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+class B extends A {
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 69, 3),
+    ]);
+  }
+
+  test_inSuper_getter_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+class B extends A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 66, 3),
+    ]);
+  }
+
+  test_inSuper_getter_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  set foo(_) {}
+}
+class B extends A {
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 65, 3),
+    ]);
+  }
+
+  test_inSuper_method_getter() async {
+    await assertErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+class B extends A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 66, 3),
+    ]);
+  }
+
+  test_inSuper_method_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  void foo() {}
+}
+class B extends A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 62, 3),
+    ]);
+  }
+
+  test_inSuper_method_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  set foo(_) {}
+}
+class B extends A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 62, 3),
+    ]);
+  }
+
+  test_inSuper_setter_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  void foo() {}
+}
+class B extends A {
+  static set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 61, 3),
+    ]);
+  }
+
+  test_inSuper_setter_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  set foo(_) {}
+}
+class B extends A {
+  static set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 61, 3),
+    ]);
+  }
+}
+
+@reflectiveTest
+class ConflictingStaticAndInstanceEnumTest extends DriverResolutionTest {
+  test_index() async {
+    await assertErrorsInCode(r'''
+enum E {
+  a, index
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 14, 5),
+    ]);
+  }
+}
+
+@reflectiveTest
+class ConflictingStaticAndInstanceMixinTest extends DriverResolutionTest {
+  test_inConstraint_getter_getter() async {
+    await assertErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+mixin M on A {
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 64, 3),
+    ]);
+  }
+
+  test_inConstraint_getter_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+mixin M on A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 61, 3),
+    ]);
+  }
+
+  test_inConstraint_getter_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  set foo(_) {}
+}
+mixin M on A {
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 60, 3),
+    ]);
+  }
+
+  test_inConstraint_method_getter() async {
+    await assertErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+mixin M on A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 61, 3),
+    ]);
+  }
+
+  test_inConstraint_method_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  void foo() {}
+}
+mixin M on A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 57, 3),
+    ]);
+  }
+
+  test_inConstraint_method_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  set foo(_) {}
+}
+mixin M on A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 57, 3),
+    ]);
+  }
+
+  test_inConstraint_setter_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  void foo() {}
+}
+mixin M on A {
+  static set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 56, 3),
+    ]);
+  }
+
+  test_inConstraint_setter_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  set foo(_) {}
+}
+mixin M on A {
+  static set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 56, 3),
+    ]);
+  }
+
+  test_inInterface_getter_getter() async {
+    await assertErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+mixin M implements A {
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 72, 3),
+    ]);
+  }
+
+  test_inInterface_getter_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+mixin M implements A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 69, 3),
+    ]);
+  }
+
+  test_inInterface_getter_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  set foo(_) {}
+}
+mixin M implements A {
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 68, 3),
+    ]);
+  }
+
+  test_inInterface_method_getter() async {
+    await assertErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+mixin M implements A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 69, 3),
+    ]);
+  }
+
+  test_inInterface_method_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  void foo() {}
+}
+mixin M implements A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 65, 3),
+    ]);
+  }
+
+  test_inInterface_method_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  set foo(_) {}
+}
+mixin M implements A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 65, 3),
+    ]);
+  }
+
+  test_inInterface_setter_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  void foo() {}
+}
+mixin M implements A {
+  static set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 64, 3),
+    ]);
+  }
+
+  test_inInterface_setter_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  set foo(_) {}
+}
+mixin M implements A {
+  static set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 64, 3),
+    ]);
+  }
+
+  test_inMixin_getter_getter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static int get foo => 0;
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 27, 3),
+    ]);
+  }
+
+  test_inMixin_getter_method() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static int get foo => 0;
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 27, 3),
+    ]);
+  }
+
+  test_inMixin_getter_setter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static int get foo => 0;
+  set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 27, 3),
+    ]);
+  }
+
+  test_inMixin_method_getter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static void foo() {}
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 24, 3),
+    ]);
+  }
+
+  test_inMixin_method_method() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static void foo() {}
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 24, 3),
+    ]);
+  }
+
+  test_inMixin_method_setter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static void foo() {}
+  set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 24, 3),
+    ]);
+  }
+
+  test_inMixin_setter_getter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static set foo(_) {}
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 23, 3),
+    ]);
+  }
+
+  test_inMixin_setter_method() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static set foo(_) {}
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 23, 3),
+    ]);
+  }
+
+  test_inMixin_setter_setter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static set foo(_) {}
+  set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 23, 3),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/duplicate_definition_test.dart b/pkg/analyzer/test/src/diagnostics/duplicate_definition_test.dart
new file mode 100644
index 0000000..8fa1978
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/duplicate_definition_test.dart
@@ -0,0 +1,1184 @@
+// 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.
+
+import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../generated/test_support.dart';
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(DuplicateDefinitionTest);
+    defineReflectiveTests(DuplicateDefinitionClassTest);
+    defineReflectiveTests(DuplicateDefinitionExtensionTest);
+    defineReflectiveTests(DuplicateDefinitionMixinTest);
+  });
+}
+
+@reflectiveTest
+class DuplicateDefinitionClassTest extends DriverResolutionTest {
+  test_instance_field_field() async {
+    await assertErrorsInCode(r'''
+class C {
+  int foo;
+  int foo;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 27, 3),
+    ]);
+  }
+
+  test_instance_field_getter() async {
+    await assertErrorsInCode(r'''
+class C {
+  int foo;
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 31, 3),
+    ]);
+  }
+
+  test_instance_field_method() async {
+    await assertErrorsInCode(r'''
+class C {
+  int foo;
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 28, 3),
+    ]);
+  }
+
+  test_instance_fieldFinal_getter() async {
+    await assertErrorsInCode(r'''
+class C {
+  final int foo = 0;
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 41, 3),
+    ]);
+  }
+
+  test_instance_fieldFinal_setter() async {
+    await assertNoErrorsInCode(r'''
+class C {
+  final int foo = 0;
+  set foo(int x) {}
+}
+''');
+  }
+
+  test_instance_getter_getter() async {
+    await assertErrorsInCode(r'''
+class C {
+  int get foo => 0;
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 40, 3),
+    ]);
+  }
+
+  test_instance_getter_method() async {
+    await assertErrorsInCode(r'''
+class C {
+  int get foo => 0;
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 37, 3),
+    ]);
+  }
+
+  test_instance_getter_setter() async {
+    await assertNoErrorsInCode(r'''
+class C {
+  int get foo => 0;
+  set foo(_) {}
+}
+''');
+  }
+
+  test_instance_method_getter() async {
+    await assertErrorsInCode(r'''
+class C {
+  void foo() {}
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 36, 3),
+    ]);
+  }
+
+  test_instance_method_method() async {
+    await assertErrorsInCode(r'''
+class C {
+  void foo() {}
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 33, 3),
+    ]);
+  }
+
+  test_instance_method_setter() async {
+    await assertErrorsInCode(r'''
+class C {
+  void foo() {}
+  set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 32, 3),
+    ]);
+  }
+
+  test_instance_setter_getter() async {
+    await assertNoErrorsInCode(r'''
+class C {
+  set foo(_) {}
+  int get foo => 0;
+}
+''');
+  }
+
+  test_instance_setter_method() async {
+    await assertErrorsInCode(r'''
+class C {
+  set foo(_) {}
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 33, 3),
+    ]);
+  }
+
+  test_instance_setter_setter() async {
+    await assertErrorsInCode(r'''
+class C {
+  void set foo(_) {}
+  void set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 42, 3),
+    ]);
+  }
+
+  test_static_field_field() async {
+    await assertErrorsInCode(r'''
+class C {
+  static int foo;
+  static int foo;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 41, 3),
+    ]);
+  }
+
+  test_static_field_getter() async {
+    await assertErrorsInCode(r'''
+class C {
+  static int foo;
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 45, 3),
+    ]);
+  }
+
+  test_static_field_method() async {
+    await assertErrorsInCode(r'''
+class C {
+  static int foo;
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 42, 3),
+    ]);
+  }
+
+  test_static_fieldFinal_getter() async {
+    await assertErrorsInCode(r'''
+class C {
+  static final int foo = 0;
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 55, 3),
+    ]);
+  }
+
+  test_static_fieldFinal_setter() async {
+    await assertNoErrorsInCode(r'''
+class C {
+  static final int foo = 0;
+  static set foo(int x) {}
+}
+''');
+  }
+
+  test_static_getter_getter() async {
+    await assertErrorsInCode(r'''
+class C {
+  static int get foo => 0;
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 54, 3),
+    ]);
+  }
+
+  test_static_getter_method() async {
+    await assertErrorsInCode(r'''
+class C {
+  static int get foo => 0;
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 51, 3),
+    ]);
+  }
+
+  test_static_getter_setter() async {
+    await assertNoErrorsInCode(r'''
+class C {
+  static int get foo => 0;
+  static set foo(_) {}
+}
+''');
+  }
+
+  test_static_method_getter() async {
+    await assertErrorsInCode(r'''
+class C {
+  static void foo() {}
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 50, 3),
+    ]);
+  }
+
+  test_static_method_method() async {
+    await assertErrorsInCode(r'''
+class C {
+  static void foo() {}
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 47, 3),
+    ]);
+  }
+
+  test_static_method_setter() async {
+    await assertErrorsInCode(r'''
+class C {
+  static void foo() {}
+  static set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 46, 3),
+    ]);
+  }
+
+  test_static_setter_getter() async {
+    await assertNoErrorsInCode(r'''
+class C {
+  static set foo(_) {}
+  static int get foo => 0;
+}
+''');
+  }
+
+  test_static_setter_method() async {
+    await assertErrorsInCode(r'''
+class C {
+  static set foo(_) {}
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 47, 3),
+    ]);
+  }
+
+  test_static_setter_setter() async {
+    await assertErrorsInCode(r'''
+class C {
+  static void set foo(_) {}
+  static void set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 56, 3),
+    ]);
+  }
+}
+
+@reflectiveTest
+class DuplicateDefinitionExtensionTest extends DriverResolutionTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = new FeatureSet.forTesting(
+        sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
+
+  test_extendedType_instance() async {
+    await assertNoErrorsInCode('''
+class A {
+  int get foo => 0;
+  set foo(_) {}
+  void bar() {}
+}
+
+extension E on A {
+  int get foo => 0;
+  set foo(_) {}
+  void bar() {}
+}
+''');
+  }
+
+  test_extendedType_static() async {
+    await assertNoErrorsInCode('''
+class A {
+  static int get foo => 0;
+  static set foo(_) {}
+  static void bar() {}
+}
+
+extension E on A {
+  static int get foo => 0;
+  static set foo(_) {}
+  static void bar() {}
+}
+''');
+  }
+
+  test_instance_getter_getter() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  int get foo => 0;
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 60, 3),
+    ]);
+  }
+
+  test_instance_getter_method() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  int get foo => 0;
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 57, 3),
+    ]);
+  }
+
+  test_instance_getter_setter() async {
+    await assertNoErrorsInCode(r'''
+class A {}
+extension E on A {
+  int get foo => 0;
+  set foo(_) {}
+}
+''');
+  }
+
+  test_instance_method_getter() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  void foo() {}
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 56, 3),
+    ]);
+  }
+
+  test_instance_method_method() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  void foo() {}
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 53, 3),
+    ]);
+  }
+
+  test_instance_method_setter() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  void foo() {}
+  set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 52, 3),
+    ]);
+  }
+
+  test_instance_setter_getter() async {
+    await assertNoErrorsInCode(r'''
+class A {}
+extension E on A {
+  set foo(_) {}
+  int get foo => 0;
+}
+''');
+  }
+
+  test_instance_setter_method() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  set foo(_) {}
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 53, 3),
+    ]);
+  }
+
+  test_instance_setter_setter() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  void set foo(_) {}
+  void set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 62, 3),
+    ]);
+  }
+
+  test_static_field_field() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  static int foo;
+  static int foo;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 61, 3),
+    ]);
+  }
+
+  test_static_field_getter() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  static int foo;
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 65, 3),
+    ]);
+  }
+
+  test_static_field_method() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  static int foo;
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 62, 3),
+    ]);
+  }
+
+  test_static_fieldFinal_getter() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  static final int foo = 0;
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 75, 3),
+    ]);
+  }
+
+  test_static_fieldFinal_setter() async {
+    await assertNoErrorsInCode(r'''
+class A {}
+extension E on A {
+  static final int foo = 0;
+  static set foo(int x) {}
+}
+''');
+  }
+
+  test_static_getter_getter() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  static int get foo => 0;
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 74, 3),
+    ]);
+  }
+
+  test_static_getter_method() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  static int get foo => 0;
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 71, 3),
+    ]);
+  }
+
+  test_static_getter_setter() async {
+    await assertNoErrorsInCode(r'''
+class A {}
+extension E on A {
+  static int get foo => 0;
+  static set foo(_) {}
+}
+''');
+  }
+
+  test_static_method_getter() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  static void foo() {}
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 70, 3),
+    ]);
+  }
+
+  test_static_method_method() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  static void foo() {}
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 67, 3),
+    ]);
+  }
+
+  test_static_method_setter() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  static void foo() {}
+  static set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 66, 3),
+    ]);
+  }
+
+  test_static_setter_getter() async {
+    await assertNoErrorsInCode(r'''
+mixin M {
+  static set foo(_) {}
+  static int get foo => 0;
+}
+''');
+  }
+
+  test_static_setter_method() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  static set foo(_) {}
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 67, 3),
+    ]);
+  }
+
+  test_static_setter_setter() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  static void set foo(_) {}
+  static void set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 76, 3),
+    ]);
+  }
+
+  test_unitMembers_extension() async {
+    await assertErrorsInCode('''
+class A {}
+extension E on A {}
+extension E on A {}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 41, 1),
+    ]);
+  }
+}
+
+@reflectiveTest
+class DuplicateDefinitionMixinTest extends DriverResolutionTest {
+  test_instance_field_field() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  int foo;
+  int foo;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 27, 3),
+    ]);
+  }
+
+  test_instance_field_getter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  int foo;
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 31, 3),
+    ]);
+  }
+
+  test_instance_field_method() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  int foo;
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 28, 3),
+    ]);
+  }
+
+  test_instance_fieldFinal_getter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  final int foo = 0;
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 41, 3),
+    ]);
+  }
+
+  test_instance_fieldFinal_setter() async {
+    await assertNoErrorsInCode(r'''
+mixin M {
+  final int foo = 0;
+  set foo(int x) {}
+}
+''');
+  }
+
+  test_instance_getter_getter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  int get foo => 0;
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 40, 3),
+    ]);
+  }
+
+  test_instance_getter_method() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  int get foo => 0;
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 37, 3),
+    ]);
+  }
+
+  test_instance_getter_setter() async {
+    await assertNoErrorsInCode(r'''
+mixin M {
+  int get foo => 0;
+  set foo(_) {}
+}
+''');
+  }
+
+  test_instance_method_getter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  void foo() {}
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 36, 3),
+    ]);
+  }
+
+  test_instance_method_method() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  void foo() {}
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 33, 3),
+    ]);
+  }
+
+  test_instance_method_setter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  void foo() {}
+  set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 32, 3),
+    ]);
+  }
+
+  test_instance_setter_getter() async {
+    await assertNoErrorsInCode(r'''
+mixin M {
+  set foo(_) {}
+  int get foo => 0;
+}
+''');
+  }
+
+  test_instance_setter_method() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  set foo(_) {}
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 33, 3),
+    ]);
+  }
+
+  test_instance_setter_setter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  void set foo(_) {}
+  void set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 42, 3),
+    ]);
+  }
+
+  test_static_field_field() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static int foo;
+  static int foo;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 41, 3),
+    ]);
+  }
+
+  test_static_field_getter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static int foo;
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 45, 3),
+    ]);
+  }
+
+  test_static_field_method() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static int foo;
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 42, 3),
+    ]);
+  }
+
+  test_static_fieldFinal_getter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static final int foo = 0;
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 55, 3),
+    ]);
+  }
+
+  test_static_fieldFinal_setter() async {
+    await assertNoErrorsInCode(r'''
+mixin M {
+  static final int foo = 0;
+  static set foo(int x) {}
+}
+''');
+  }
+
+  test_static_getter_getter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static int get foo => 0;
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 54, 3),
+    ]);
+  }
+
+  test_static_getter_method() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static int get foo => 0;
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 51, 3),
+    ]);
+  }
+
+  test_static_getter_setter() async {
+    await assertNoErrorsInCode(r'''
+mixin M {
+  static int get foo => 0;
+  static set foo(_) {}
+}
+''');
+  }
+
+  test_static_method_getter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static void foo() {}
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 50, 3),
+    ]);
+  }
+
+  test_static_method_method() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static void foo() {}
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 47, 3),
+    ]);
+  }
+
+  test_static_method_setter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static void foo() {}
+  static set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 46, 3),
+    ]);
+  }
+
+  test_static_setter_getter() async {
+    await assertNoErrorsInCode(r'''
+mixin M {
+  static set foo(_) {}
+  static int get foo => 0;
+}
+''');
+  }
+
+  test_static_setter_method() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static set foo(_) {}
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 47, 3),
+    ]);
+  }
+
+  test_static_setter_setter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static void set foo(_) {}
+  static void set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 56, 3),
+    ]);
+  }
+}
+
+@reflectiveTest
+class DuplicateDefinitionTest extends DriverResolutionTest {
+  test_catch() async {
+    await assertErrorsInCode(r'''
+main() {
+  try {} catch (e, e) {}
+}''', [
+      error(HintCode.UNUSED_CATCH_STACK, 28, 1),
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 28, 1),
+    ]);
+  }
+
+  test_for_initializers() async {
+    await assertErrorsInCode(r'''
+f() {
+  for (int i = 0, i = 0; i < 5;) {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 24, 1),
+      error(HintCode.UNUSED_LOCAL_VARIABLE, 24, 1),
+    ]);
+  }
+
+  test_locals_block_if() async {
+    await assertErrorsInCode(r'''
+main(int p) {
+  if (p != 0) {
+    var a;
+    var a;
+  }
+}
+''', [
+      error(HintCode.UNUSED_LOCAL_VARIABLE, 38, 1),
+      error(HintCode.UNUSED_LOCAL_VARIABLE, 49, 1),
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 49, 1),
+    ]);
+  }
+
+  test_locals_block_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  m() {
+    int a;
+    int a;
+  }
+}
+''', [
+      error(HintCode.UNUSED_LOCAL_VARIABLE, 26, 1),
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 37, 1),
+      error(HintCode.UNUSED_LOCAL_VARIABLE, 37, 1),
+    ]);
+  }
+
+  test_locals_block_switchCase() async {
+    await assertErrorsInCode(r'''
+main() {
+  switch(1) {
+    case 1:
+      var a;
+      var a;
+  }
+}
+''', [
+      error(HintCode.UNUSED_LOCAL_VARIABLE, 45, 1),
+      error(HintCode.UNUSED_LOCAL_VARIABLE, 58, 1),
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 58, 1),
+    ]);
+  }
+
+  test_locals_block_topLevelFunction() async {
+    await assertErrorsInCode(r'''
+main() {
+  int m = 0;
+  m(a) {}
+}
+''', [
+      error(HintCode.UNUSED_LOCAL_VARIABLE, 15, 1),
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 24, 1),
+      error(HintCode.UNUSED_ELEMENT, 24, 1),
+    ]);
+  }
+
+  test_parameters_constructor() async {
+    await assertErrorsInCode(r'''
+class A {
+  int a;
+  A(int a, this.a);
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 35, 1),
+    ]);
+  }
+
+  test_parameters_functionTypeAlias() async {
+    await assertErrorsInCode(r'''
+typedef void F(int a, double a);
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 29, 1),
+    ]);
+  }
+
+  test_parameters_genericFunction() async {
+    await assertErrorsInCode(r'''
+typedef F = void Function(int a, double a);
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 40, 1),
+    ]);
+  }
+
+  test_parameters_localFunction() async {
+    await assertErrorsInCode(r'''
+main() {
+  f(int a, double a) {
+  };
+}
+''', [
+      error(HintCode.UNUSED_ELEMENT, 11, 1),
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 27, 1),
+    ]);
+  }
+
+  test_parameters_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  m(int a, double a) {
+  }
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 28, 1),
+    ]);
+  }
+
+  test_parameters_topLevelFunction() async {
+    await assertErrorsInCode(r'''
+f(int a, double a) {}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 16, 1),
+    ]);
+  }
+
+  test_typeParameters_class() async {
+    await assertErrorsInCode(r'''
+class A<T, T> {}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 11, 1),
+    ]);
+  }
+
+  test_typeParameters_functionTypeAlias() async {
+    await assertErrorsInCode(r'''
+typedef void F<T, T>();
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 18, 1),
+    ]);
+  }
+
+  test_typeParameters_genericFunction() async {
+    await assertErrorsInCode(r'''
+typedef F = void Function<T, T>();
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 29, 1),
+    ]);
+  }
+
+  test_typeParameters_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  void m<T, T>() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 22, 1),
+    ]);
+  }
+
+  test_typeParameters_topLevelFunction() async {
+    await assertErrorsInCode(r'''
+void f<T, T>() {}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 10, 1),
+    ]);
+  }
+
+  test_unitMembers_class() async {
+    await assertErrorsInCode('''
+class A {}
+class B {}
+class A {}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 28, 1),
+    ]);
+  }
+
+  test_unitMembers_part_library() async {
+    var libPath = convertPath('/test/lib/lib.dart');
+    var aPath = convertPath('/test/lib/a.dart');
+    newFile(libPath, content: '''
+part 'a.dart';
+
+class A {}
+''');
+    newFile(aPath, content: '''
+part of 'lib.dart';
+
+class A {}
+''');
+
+    await resolveFile(libPath);
+
+    var aResult = await resolveFile(aPath);
+    GatheringErrorListener()
+      ..addAll(aResult.errors)
+      ..assertErrors([
+        error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 27, 1),
+      ]);
+  }
+
+  test_unitMembers_part_part() async {
+    var libPath = convertPath('/test/lib/lib.dart');
+    var aPath = convertPath('/test/lib/a.dart');
+    var bPath = convertPath('/test/lib/b.dart');
+    newFile(libPath, content: '''
+part 'a.dart';
+part 'b.dart';
+''');
+    newFile(aPath, content: '''
+part of 'lib.dart';
+
+class A {}
+''');
+    newFile(bPath, content: '''
+part of 'lib.dart';
+
+class A {}
+''');
+
+    await resolveFile(libPath);
+
+    var aResult = await resolveFile(aPath);
+    GatheringErrorListener()
+      ..addAll(aResult.errors)
+      ..assertNoErrors();
+
+    var bResult = await resolveFile(bPath);
+    GatheringErrorListener()
+      ..addAll(bResult.errors)
+      ..assertErrors([
+        error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 27, 1),
+      ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/extension_conflicting_static_and_instance_test.dart b/pkg/analyzer/test/src/diagnostics/extension_conflicting_static_and_instance_test.dart
new file mode 100644
index 0000000..10df3869
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/extension_conflicting_static_and_instance_test.dart
@@ -0,0 +1,215 @@
+// 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.
+
+import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ExtensionConflictingStaticAndInstanceTest);
+  });
+}
+
+@reflectiveTest
+class ExtensionConflictingStaticAndInstanceTest extends DriverResolutionTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = new FeatureSet.forTesting(
+        sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
+
+  CompileTimeErrorCode get _errorCode =>
+      CompileTimeErrorCode.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE;
+
+  test_extendedType_field() async {
+    await assertNoErrorsInCode('''
+class A {
+  static int foo = 0;
+  int bar = 0;
+}
+
+extension E on A {
+  int get foo => 0;
+  static int get bar => 0;
+}
+''');
+  }
+
+  test_extendedType_getter() async {
+    await assertNoErrorsInCode('''
+class A {
+  static int get foo => 0;
+  int get bar => 0;
+}
+
+extension E on A {
+  int get foo => 0;
+  static int get bar => 0;
+}
+''');
+  }
+
+  test_extendedType_method() async {
+    await assertNoErrorsInCode('''
+class A {
+  static void foo() {}
+  void bar() {}
+}
+
+extension E on A {
+  void foo() {}
+  static void bar() {}
+}
+''');
+  }
+
+  test_extendedType_setter() async {
+    await assertNoErrorsInCode('''
+class A {
+  static set foo(_) {}
+  set bar(_) {}
+}
+
+extension E on A {
+  set foo(_) {}
+  static set bar(_) {}
+}
+''');
+  }
+
+  test_field_getter() async {
+    await assertErrorsInCode('''
+extension E on String {
+  static int foo = 0;
+  int get foo => 0;
+}
+''', [
+      error(_errorCode, 37, 3),
+    ]);
+  }
+
+  test_field_method() async {
+    await assertErrorsInCode('''
+extension E on String {
+  static int foo = 0;
+  void foo() {}
+}
+''', [
+      error(_errorCode, 37, 3),
+    ]);
+  }
+
+  test_field_setter() async {
+    await assertErrorsInCode('''
+extension E on String {
+  static int foo = 0;
+  set foo(_) {}
+}
+''', [
+      error(_errorCode, 37, 3),
+    ]);
+  }
+
+  test_getter_getter() async {
+    await assertErrorsInCode('''
+extension E on String {
+  static int get foo => 0;
+  int get foo => 0;
+}
+''', [
+      error(_errorCode, 41, 3),
+    ]);
+  }
+
+  test_getter_method() async {
+    await assertErrorsInCode('''
+extension E on String {
+  static int get foo => 0;
+  void foo() {}
+}
+''', [
+      error(_errorCode, 41, 3),
+    ]);
+  }
+
+  test_getter_setter() async {
+    await assertErrorsInCode('''
+extension E on String {
+  static int get foo => 0;
+  set foo(_) {}
+}
+''', [
+      error(_errorCode, 41, 3),
+    ]);
+  }
+
+  test_method_getter() async {
+    await assertErrorsInCode('''
+extension E on String {
+  static void foo() {}
+  int get foo => 0;
+}
+''', [
+      error(_errorCode, 38, 3),
+    ]);
+  }
+
+  test_method_method() async {
+    await assertErrorsInCode('''
+extension E on String {
+  static void foo() {}
+  void foo() {}
+}
+''', [
+      error(_errorCode, 38, 3),
+    ]);
+  }
+
+  test_method_setter() async {
+    await assertErrorsInCode('''
+extension E on String {
+  static void foo() {}
+  set foo(_) {}
+}
+''', [
+      error(_errorCode, 38, 3),
+    ]);
+  }
+
+  test_setter_getter() async {
+    await assertErrorsInCode('''
+extension E on String {
+  static set foo(_) {}
+  int get foo => 0;
+}
+''', [
+      error(_errorCode, 37, 3),
+    ]);
+  }
+
+  test_setter_method() async {
+    await assertErrorsInCode('''
+extension E on String {
+  static set foo(_) {}
+  void foo() {}
+}
+''', [
+      error(_errorCode, 37, 3),
+    ]);
+  }
+
+  test_setter_setter() async {
+    await assertErrorsInCode('''
+extension E on String {
+  static set foo(_) {}
+  set foo(_) {}
+}
+''', [
+      error(_errorCode, 37, 3),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/non_constant_if_element_condition_from_deferred_library_test.dart b/pkg/analyzer/test/src/diagnostics/if_element_condition_from_deferred_library_test.dart
similarity index 87%
rename from pkg/analyzer/test/src/diagnostics/non_constant_if_element_condition_from_deferred_library_test.dart
rename to pkg/analyzer/test/src/diagnostics/if_element_condition_from_deferred_library_test.dart
index 7f85015..a717195 100644
--- a/pkg/analyzer/test/src/diagnostics/non_constant_if_element_condition_from_deferred_library_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/if_element_condition_from_deferred_library_test.dart
@@ -11,15 +11,14 @@
 
 main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(NonConstantIfElementConditionFromDeferredLibraryTest);
+    defineReflectiveTests(IfElementConditionFromDeferredLibraryTest);
     defineReflectiveTests(
-        NonConstantIfElementConditionFromDeferredLibraryWithConstantsTest);
+        IfElementConditionFromDeferredLibraryWithConstantsTest);
   });
 }
 
 @reflectiveTest
-class NonConstantIfElementConditionFromDeferredLibraryTest
-    extends DriverResolutionTest {
+class IfElementConditionFromDeferredLibraryTest extends DriverResolutionTest {
   test_inList_deferred() async {
     newFile(convertPath('/test/lib/lib1.dart'), content: r'''
 const bool c = true;''');
@@ -33,7 +32,7 @@
             ? [
                 error(
                     CompileTimeErrorCode
-                        .NON_CONSTANT_IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY,
+                        .IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY,
                     59,
                     3),
               ]
@@ -81,7 +80,7 @@
             ? [
                 error(
                     CompileTimeErrorCode
-                        .NON_CONSTANT_IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY,
+                        .IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY,
                     59,
                     3),
               ]
@@ -129,7 +128,7 @@
             ? [
                 error(
                     CompileTimeErrorCode
-                        .NON_CONSTANT_IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY,
+                        .IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY,
                     59,
                     3),
               ]
@@ -166,8 +165,8 @@
 }
 
 @reflectiveTest
-class NonConstantIfElementConditionFromDeferredLibraryWithConstantsTest
-    extends NonConstantIfElementConditionFromDeferredLibraryTest {
+class IfElementConditionFromDeferredLibraryWithConstantsTest
+    extends IfElementConditionFromDeferredLibraryTest {
   @override
   AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
     ..enabledExperiments = [EnableString.constant_update_2018];
diff --git a/pkg/analyzer/test/src/diagnostics/instance_access_to_static_member_test.dart b/pkg/analyzer/test/src/diagnostics/instance_access_to_static_member_test.dart
new file mode 100644
index 0000000..cd3cb61
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/instance_access_to_static_member_test.dart
@@ -0,0 +1,90 @@
+// 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.
+
+import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(InstanceAccessToStaticMemberTest);
+    defineReflectiveTests(InstanceAccessToStaticMemberWithExtensionMethodsTest);
+  });
+}
+
+@reflectiveTest
+class InstanceAccessToStaticMemberTest extends DriverResolutionTest {}
+
+@reflectiveTest
+class InstanceAccessToStaticMemberWithExtensionMethodsTest
+    extends InstanceAccessToStaticMemberTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = new FeatureSet.forTesting(
+        sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
+
+  test_getter() async {
+    await assertErrorsInCode('''
+class C {}
+
+extension E on C {
+  static int get a => 0;
+}
+
+C g(C c) => null;
+f(C c) {
+  g(c).a;
+}
+''', [
+      error(StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, 93, 1),
+    ]);
+    assertElement(
+      findNode.simple('a;'),
+      findElement.getter('a'),
+    );
+  }
+
+  test_method() async {
+    await assertErrorsInCode('''
+class C {}
+
+extension E on C {
+  static void a() {}
+}
+
+f(C c) {
+  c.a();
+}
+''', [
+      error(StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, 68, 1),
+    ]);
+    assertElement(
+      findNode.methodInvocation('a();'),
+      findElement.method('a'),
+    );
+  }
+
+  test_setter() async {
+    await assertErrorsInCode('''
+class C {}
+
+extension E on C {
+  static set a(v) {}
+}
+
+f(C c) {
+  c.a = 2;
+}
+''', [
+      error(StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, 68, 1),
+    ]);
+    assertElement(
+      findNode.simple('a = 2;'),
+      findElement.setter('a'),
+    );
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/mismatched_getter_and_setter_types_test.dart b/pkg/analyzer/test/src/diagnostics/mismatched_getter_and_setter_types_test.dart
index ec3b2bc..d4c8ccd 100644
--- a/pkg/analyzer/test/src/diagnostics/mismatched_getter_and_setter_types_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/mismatched_getter_and_setter_types_test.dart
@@ -2,7 +2,9 @@
 // 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/analysis/features.dart';
 import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../dart/resolution/driver_resolution.dart';
@@ -10,6 +12,9 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(MismatchedGetterAndSetterTypesTest);
+    defineReflectiveTests(
+        MismatchedGetterAndSetterTypesWithExtensionMethodsTest);
+    defineReflectiveTests(MismatchedGetterAndSetterTypesWithNNBDTest);
   });
 }
 
@@ -23,3 +28,66 @@
     ]);
   }
 }
+
+@reflectiveTest
+class MismatchedGetterAndSetterTypesWithExtensionMethodsTest
+    extends MismatchedGetterAndSetterTypesTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = new FeatureSet.forTesting(
+        sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
+
+  test_extensionMembers_instance() async {
+    await assertErrorsInCode('''
+extension E on Object {
+  int get g { return 0; }
+  set g(String v) {}
+}
+''', [
+      error(StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES, 34, 1),
+    ]);
+  }
+
+  test_extensionMembers_static() async {
+    await assertErrorsInCode('''
+extension E on Object {
+  static int get g { return 0; }
+  static set g(String v) {}
+}
+''', [
+      error(StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES, 41, 1),
+    ]);
+  }
+}
+
+@reflectiveTest
+class MismatchedGetterAndSetterTypesWithNNBDTest
+    extends MismatchedGetterAndSetterTypesTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = new FeatureSet.forTesting(
+        sdkVersion: '2.3.0', additionalFeatures: [Feature.non_nullable]);
+
+  test_classMembers_instance() async {
+    await assertErrorsInCode('''
+class C {
+  num get g { return 0; }
+  set g(int v) {}
+}
+''', [
+      error(StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES, 20, 1),
+    ]);
+  }
+
+  @failingTest
+  test_classMembers_static() async {
+    await assertErrorsInCode('''
+class C {
+  static num get g { return 0; }
+  static set g(int v) {}
+}
+''', [
+      error(StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES, 12, 30),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/sdk_constraint_verifier_support.dart b/pkg/analyzer/test/src/diagnostics/sdk_constraint_verifier_support.dart
index 8bd294a..ee4c362 100644
--- a/pkg/analyzer/test/src/diagnostics/sdk_constraint_verifier_support.dart
+++ b/pkg/analyzer/test/src/diagnostics/sdk_constraint_verifier_support.dart
@@ -4,15 +4,15 @@
 
 import 'package:pub_semver/pub_semver.dart';
 
-import '../dart/resolution/driver_resolution.dart';
 import '../../generated/test_support.dart';
+import '../dart/resolution/driver_resolution.dart';
 
 /// A base class designed to be used by tests of the hints produced by the
 /// SdkConstraintVerifier.
 class SdkConstraintVerifierTest extends DriverResolutionTest {
   /// Verify that the [errorCodes] are produced if the [source] is analyzed in
   /// a context that specifies the minimum SDK version to be [version].
-  verifyVersion(String version, String source,
+  Future<void> verifyVersion(String version, String source,
       {List<ExpectedError> expectedErrors}) async {
     driver.configure(
         analysisOptions: analysisOptions
diff --git a/pkg/analyzer/test/src/diagnostics/sdk_version_as_expression_in_const_context_test.dart b/pkg/analyzer/test/src/diagnostics/sdk_version_as_expression_in_const_context_test.dart
index d7f2330..095a6a2 100644
--- a/pkg/analyzer/test/src/diagnostics/sdk_version_as_expression_in_const_context_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/sdk_version_as_expression_in_const_context_test.dart
@@ -22,15 +22,15 @@
   AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
     ..enabledExperiments = [EnableString.constant_update_2018];
 
-  test_equals() {
-    verifyVersion('2.5.0', '''
+  test_equals() async {
+    await verifyVersion('2.5.0', '''
 const dynamic a = 2;
 const c = (a as int) + 2;
 ''');
   }
 
-  test_lessThan() {
-    verifyVersion('2.2.0', '''
+  test_lessThan() async {
+    await verifyVersion('2.2.0', '''
 const dynamic a = 2;
 const c = (a as int) + 2;
 ''', expectedErrors: [
diff --git a/pkg/analyzer/test/src/diagnostics/sdk_version_bool_operator_in_const_context_test.dart b/pkg/analyzer/test/src/diagnostics/sdk_version_bool_operator_in_const_context_test.dart
new file mode 100644
index 0000000..32adcd5
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/sdk_version_bool_operator_in_const_context_test.dart
@@ -0,0 +1,102 @@
+// 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.
+
+import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'sdk_constraint_verifier_support.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(SdkVersionBoolOperatorInConstContextTest);
+  });
+}
+
+@reflectiveTest
+class SdkVersionBoolOperatorInConstContextTest
+    extends SdkConstraintVerifierTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..enabledExperiments = [EnableString.constant_update_2018];
+
+  test_and_const_equals() async {
+    await verifyVersion('2.5.0', '''
+const c = true & false;
+''');
+  }
+
+  test_and_const_lessThan() async {
+    await verifyVersion('2.2.0', '''
+const c = true & false;
+''', expectedErrors: [
+      error(HintCode.SDK_VERSION_BOOL_OPERATOR_IN_CONST_CONTEXT, 15, 1),
+    ]);
+  }
+
+  test_and_nonConst_equals() async {
+    await verifyVersion('2.5.0', '''
+var c = true & false;
+''');
+  }
+
+  test_and_nonConst_lessThan() async {
+    await verifyVersion('2.2.0', '''
+var c = true & false;
+''');
+  }
+
+  test_or_const_equals() async {
+    await verifyVersion('2.5.0', '''
+const c = true | false;
+''');
+  }
+
+  test_or_const_lessThan() async {
+    await verifyVersion('2.2.0', '''
+const c = true | false;
+''', expectedErrors: [
+      error(HintCode.SDK_VERSION_BOOL_OPERATOR_IN_CONST_CONTEXT, 15, 1),
+    ]);
+  }
+
+  test_or_nonConst_equals() async {
+    await verifyVersion('2.5.0', '''
+var c = true | false;
+''');
+  }
+
+  test_or_nonConst_lessThan() async {
+    await verifyVersion('2.2.0', '''
+var c = true | false;
+''');
+  }
+
+  test_xor_const_equals() async {
+    await verifyVersion('2.5.0', '''
+const c = true ^ false;
+''');
+  }
+
+  test_xor_const_lessThan() async {
+    await verifyVersion('2.2.0', '''
+const c = true ^ false;
+''', expectedErrors: [
+      error(HintCode.SDK_VERSION_BOOL_OPERATOR_IN_CONST_CONTEXT, 15, 1),
+    ]);
+  }
+
+  test_xor_nonConst_equals() async {
+    await verifyVersion('2.5.0', '''
+var c = true ^ false;
+''');
+  }
+
+  test_xor_nonConst_lessThan() async {
+    await verifyVersion('2.2.0', '''
+var c = true ^ false;
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/sdk_version_bool_operator_test.dart b/pkg/analyzer/test/src/diagnostics/sdk_version_bool_operator_test.dart
deleted file mode 100644
index 6cd9411..0000000
--- a/pkg/analyzer/test/src/diagnostics/sdk_version_bool_operator_test.dart
+++ /dev/null
@@ -1,101 +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.
-
-import 'package:analyzer/src/dart/analysis/experiments.dart';
-import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import 'sdk_constraint_verifier_support.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(SdkVersionBoolOperatorTest);
-  });
-}
-
-@reflectiveTest
-class SdkVersionBoolOperatorTest extends SdkConstraintVerifierTest {
-  @override
-  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
-    ..enabledExperiments = [EnableString.constant_update_2018];
-
-  test_and_const_equals() {
-    verifyVersion('2.5.0', '''
-const c = true & false;
-''');
-  }
-
-  test_and_const_lessThan() {
-    verifyVersion('2.2.0', '''
-const c = true & false;
-''', expectedErrors: [
-      error(HintCode.SDK_VERSION_BOOL_OPERATOR, 15, 1),
-    ]);
-  }
-
-  test_and_nonConst_equals() {
-    verifyVersion('2.5.0', '''
-var c = true & false;
-''');
-  }
-
-  test_and_nonConst_lessThan() {
-    verifyVersion('2.2.0', '''
-var c = true & false;
-''');
-  }
-
-  test_or_const_equals() {
-    verifyVersion('2.5.0', '''
-const c = true | false;
-''');
-  }
-
-  test_or_const_lessThan() {
-    verifyVersion('2.2.0', '''
-const c = true | false;
-''', expectedErrors: [
-      error(HintCode.SDK_VERSION_BOOL_OPERATOR, 15, 1),
-    ]);
-  }
-
-  test_or_nonConst_equals() {
-    verifyVersion('2.5.0', '''
-var c = true | false;
-''');
-  }
-
-  test_or_nonConst_lessThan() {
-    verifyVersion('2.2.0', '''
-var c = true | false;
-''');
-  }
-
-  test_xor_const_equals() {
-    verifyVersion('2.5.0', '''
-const c = true ^ false;
-''');
-  }
-
-  test_xor_const_lessThan() {
-    verifyVersion('2.2.0', '''
-const c = true ^ false;
-''', expectedErrors: [
-      error(HintCode.SDK_VERSION_BOOL_OPERATOR, 15, 1),
-    ]);
-  }
-
-  test_xor_nonConst_equals() {
-    verifyVersion('2.5.0', '''
-var c = true ^ false;
-''');
-  }
-
-  test_xor_nonConst_lessThan() {
-    verifyVersion('2.2.0', '''
-var c = true ^ false;
-''');
-  }
-}
diff --git a/pkg/analyzer/test/src/diagnostics/sdk_version_eq_eq_operator_test.dart b/pkg/analyzer/test/src/diagnostics/sdk_version_eq_eq_operator_test.dart
index a173f44..4e7d20b 100644
--- a/pkg/analyzer/test/src/diagnostics/sdk_version_eq_eq_operator_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/sdk_version_eq_eq_operator_test.dart
@@ -21,8 +21,8 @@
   AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
     ..enabledExperiments = [EnableString.constant_update_2018];
 
-  test_left_equals() {
-    verifyVersion('2.5.0', '''
+  test_left_equals() async {
+    await verifyVersion('2.5.0', '''
 class A {
   const A();
 }
@@ -31,8 +31,8 @@
 ''');
   }
 
-  test_left_lessThan() {
-    verifyVersion('2.2.0', '''
+  test_left_lessThan() async {
+    await verifyVersion('2.2.0', '''
 class A {
   const A();
 }
@@ -43,8 +43,8 @@
     ]);
   }
 
-  test_right_equals() {
-    verifyVersion('2.5.0', '''
+  test_right_equals() async {
+    await verifyVersion('2.5.0', '''
 class A {
   const A();
 }
@@ -53,8 +53,8 @@
 ''');
   }
 
-  test_right_lessThan() {
-    verifyVersion('2.2.0', '''
+  test_right_lessThan() async {
+    await verifyVersion('2.2.0', '''
 class A {
   const A();
 }
diff --git a/pkg/analyzer/test/src/diagnostics/sdk_version_extension_methods_test.dart b/pkg/analyzer/test/src/diagnostics/sdk_version_extension_methods_test.dart
new file mode 100644
index 0000000..9afa451
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/sdk_version_extension_methods_test.dart
@@ -0,0 +1,64 @@
+// 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.
+
+import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'sdk_constraint_verifier_support.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(SdkVersionExtensionMethodsTest);
+  });
+}
+
+@reflectiveTest
+class SdkVersionExtensionMethodsTest extends SdkConstraintVerifierTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..enabledExperiments = [EnableString.extension_methods];
+
+  @failingTest
+  test_extension_equals() async {
+    await verifyVersion('2.6.0', '''
+extension E on int {}
+''');
+  }
+
+  test_extension_lessThan() async {
+    await verifyVersion('2.2.0', '''
+extension E on int {}
+''', expectedErrors: [
+      error(HintCode.SDK_VERSION_EXTENSION_METHODS, 0, 9),
+    ]);
+  }
+
+  @failingTest
+  test_extensionOverride_equals() async {
+    await verifyVersion('2.6.0', '''
+extension E on int {
+  int get a => 0;
+}
+void f() {
+  E(0).a;
+}
+''');
+  }
+
+  test_extensionOverride_lessThan() async {
+    await verifyVersion('2.2.0', '''
+extension E on int {
+  int get a => 0;
+}
+void f() {
+  E(0).a;
+}
+''', expectedErrors: [
+      error(HintCode.SDK_VERSION_EXTENSION_METHODS, 0, 9),
+      error(HintCode.SDK_VERSION_EXTENSION_METHODS, 54, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/sdk_version_gt_gt_gt_operator_test.dart b/pkg/analyzer/test/src/diagnostics/sdk_version_gt_gt_gt_operator_test.dart
index 416079f..d73c523 100644
--- a/pkg/analyzer/test/src/diagnostics/sdk_version_gt_gt_gt_operator_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/sdk_version_gt_gt_gt_operator_test.dart
@@ -21,20 +21,20 @@
   AnalysisOptionsImpl get analysisOptions =>
       AnalysisOptionsImpl()..enabledExperiments = [EnableString.triple_shift];
 
-  test_const_equals() {
+  test_const_equals() async {
     // TODO(brianwilkerson) Add '>>>' to MockSdk and remove the code
     //  UNDEFINED_OPERATOR when triple_shift is enabled by default.
-    verifyVersion('2.5.0', '''
+    await verifyVersion('2.5.0', '''
 const a = 42 >>> 3;
 ''', expectedErrors: [
       error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 13, 3),
     ]);
   }
 
-  test_const_lessThan() {
+  test_const_lessThan() async {
     // TODO(brianwilkerson) Add '>>>' to MockSdk and remove the code
     //  UNDEFINED_OPERATOR when triple_shift is enabled by default.
-    verifyVersion('2.2.0', '''
+    await verifyVersion('2.2.0', '''
 const a = 42 >>> 3;
 ''', expectedErrors: [
       error(HintCode.SDK_VERSION_GT_GT_GT_OPERATOR, 13, 3),
@@ -42,16 +42,16 @@
     ]);
   }
 
-  test_declaration_equals() {
-    verifyVersion('2.5.0', '''
+  test_declaration_equals() async {
+    await verifyVersion('2.5.0', '''
 class A {
   A operator >>>(A a) => this;
 }
 ''');
   }
 
-  test_declaration_lessThan() {
-    verifyVersion('2.2.0', '''
+  test_declaration_lessThan() async {
+    await verifyVersion('2.2.0', '''
 class A {
   A operator >>>(A a) => this;
 }
@@ -60,20 +60,20 @@
     ]);
   }
 
-  test_nonConst_equals() {
+  test_nonConst_equals() async {
     // TODO(brianwilkerson) Add '>>>' to MockSdk and remove the code
     //  UNDEFINED_OPERATOR when constant update is enabled by default.
-    verifyVersion('2.5.0', '''
+    await verifyVersion('2.5.0', '''
 var a = 42 >>> 3;
 ''', expectedErrors: [
       error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 11, 3),
     ]);
   }
 
-  test_nonConst_lessThan() {
+  test_nonConst_lessThan() async {
     // TODO(brianwilkerson) Add '>>>' to MockSdk and remove the code
     //  UNDEFINED_OPERATOR when constant update is enabled by default.
-    verifyVersion('2.2.0', '''
+    await verifyVersion('2.2.0', '''
 var a = 42 >>> 3;
 ''', expectedErrors: [
       error(HintCode.SDK_VERSION_GT_GT_GT_OPERATOR, 11, 3),
diff --git a/pkg/analyzer/test/src/diagnostics/sdk_version_is_expression_in_const_context_test.dart b/pkg/analyzer/test/src/diagnostics/sdk_version_is_expression_in_const_context_test.dart
index ab7ff21..517982f 100644
--- a/pkg/analyzer/test/src/diagnostics/sdk_version_is_expression_in_const_context_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/sdk_version_is_expression_in_const_context_test.dart
@@ -22,15 +22,15 @@
   AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
     ..enabledExperiments = [EnableString.constant_update_2018];
 
-  test_equals() {
-    verifyVersion('2.5.0', '''
+  test_equals() async {
+    await verifyVersion('2.5.0', '''
 const dynamic a = 2;
 const c = a is int;
 ''');
   }
 
-  test_lessThan() {
-    verifyVersion('2.2.0', '''
+  test_lessThan() async {
+    await verifyVersion('2.2.0', '''
 const dynamic a = 2;
 const c = a is int;
 ''', expectedErrors: [
diff --git a/pkg/analyzer/test/src/diagnostics/non_constant_set_element_from_deferred_library_test.dart b/pkg/analyzer/test/src/diagnostics/set_element_from_deferred_library_test.dart
similarity index 70%
rename from pkg/analyzer/test/src/diagnostics/non_constant_set_element_from_deferred_library_test.dart
rename to pkg/analyzer/test/src/diagnostics/set_element_from_deferred_library_test.dart
index 7dd39c4..ff2ce80 100644
--- a/pkg/analyzer/test/src/diagnostics/non_constant_set_element_from_deferred_library_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/set_element_from_deferred_library_test.dart
@@ -11,15 +11,13 @@
 
 main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(NonConstantSetElementFromDeferredLibraryTest);
-    defineReflectiveTests(
-        NonConstantSetElementFromDeferredLibraryWithConstantsTest);
+    defineReflectiveTests(SetElementFromDeferredLibraryTest);
+    defineReflectiveTests(SetElementFromDeferredLibraryWithConstantsTest);
   });
 }
 
 @reflectiveTest
-class NonConstantSetElementFromDeferredLibraryTest
-    extends DriverResolutionTest {
+class SetElementFromDeferredLibraryTest extends DriverResolutionTest {
   @failingTest
   test_const_ifElement_thenTrue_elseDeferred() async {
     // reports wrong error code
@@ -30,8 +28,7 @@
 const cond = true;
 var v = const {if (cond) null else a.c};
 ''', [
-      error(CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY,
-          88, 3),
+      error(CompileTimeErrorCode.SET_ELEMENT_FROM_DEFERRED_LIBRARY, 88, 3),
     ]);
   }
 
@@ -46,11 +43,8 @@
 ''',
         analysisOptions.experimentStatus.constant_update_2018
             ? [
-                error(
-                    CompileTimeErrorCode
-                        .NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY,
-                    78,
-                    3),
+                error(CompileTimeErrorCode.SET_ELEMENT_FROM_DEFERRED_LIBRARY,
+                    78, 3),
               ]
             : [
                 error(CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT, 68, 13),
@@ -64,8 +58,7 @@
 import 'lib1.dart' deferred as a;
 var v = const {a.c};
 ''', [
-      error(CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY,
-          49, 3),
+      error(CompileTimeErrorCode.SET_ELEMENT_FROM_DEFERRED_LIBRARY, 49, 3),
     ]);
   }
 
@@ -76,15 +69,14 @@
 import 'lib1.dart' deferred as a;
 var v = const {a.c + 1};
 ''', [
-      error(CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY,
-          49, 7),
+      error(CompileTimeErrorCode.SET_ELEMENT_FROM_DEFERRED_LIBRARY, 49, 7),
     ]);
   }
 }
 
 @reflectiveTest
-class NonConstantSetElementFromDeferredLibraryWithConstantsTest
-    extends NonConstantSetElementFromDeferredLibraryTest {
+class SetElementFromDeferredLibraryWithConstantsTest
+    extends SetElementFromDeferredLibraryTest {
   @override
   AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
     ..enabledExperiments = [EnableString.constant_update_2018];
diff --git a/pkg/analyzer/test/src/diagnostics/non_constant_spread_expression_from_deferred_library_test.dart b/pkg/analyzer/test/src/diagnostics/spread_expression_from_deferred_library_test.dart
similarity index 87%
rename from pkg/analyzer/test/src/diagnostics/non_constant_spread_expression_from_deferred_library_test.dart
rename to pkg/analyzer/test/src/diagnostics/spread_expression_from_deferred_library_test.dart
index b8ad8b4..88274ec 100644
--- a/pkg/analyzer/test/src/diagnostics/non_constant_spread_expression_from_deferred_library_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/spread_expression_from_deferred_library_test.dart
@@ -11,15 +11,13 @@
 
 main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(NonConstantSpreadExpressionFromDeferredLibraryTest);
-    defineReflectiveTests(
-        NonConstantSpreadExpressionFromDeferredLibraryWithConstantsTest);
+    defineReflectiveTests(SpreadExpressionFromDeferredLibraryTest);
+    defineReflectiveTests(SpreadExpressionFromDeferredLibraryWithConstantsTest);
   });
 }
 
 @reflectiveTest
-class NonConstantSpreadExpressionFromDeferredLibraryTest
-    extends DriverResolutionTest {
+class SpreadExpressionFromDeferredLibraryTest extends DriverResolutionTest {
   test_inList_deferred() async {
     newFile(convertPath('/test/lib/lib1.dart'), content: r'''
 const List c = [];''');
@@ -33,7 +31,7 @@
             ? [
                 error(
                     CompileTimeErrorCode
-                        .NON_CONSTANT_SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY,
+                        .SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY,
                     59,
                     3),
               ]
@@ -81,7 +79,7 @@
             ? [
                 error(
                     CompileTimeErrorCode
-                        .NON_CONSTANT_SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY,
+                        .SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY,
                     59,
                     3),
               ]
@@ -129,7 +127,7 @@
             ? [
                 error(
                     CompileTimeErrorCode
-                        .NON_CONSTANT_SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY,
+                        .SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY,
                     59,
                     3),
               ]
@@ -166,8 +164,8 @@
 }
 
 @reflectiveTest
-class NonConstantSpreadExpressionFromDeferredLibraryWithConstantsTest
-    extends NonConstantSpreadExpressionFromDeferredLibraryTest {
+class SpreadExpressionFromDeferredLibraryWithConstantsTest
+    extends SpreadExpressionFromDeferredLibraryTest {
   @override
   AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
     ..enabledExperiments = [EnableString.constant_update_2018];
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 3f0007b..0d182ed 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -4,8 +4,6 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'access_static_extension_member_test.dart'
-    as access_static_extension_member;
 import 'ambiguous_export_test.dart' as ambiguous_export;
 import 'ambiguous_extension_method_access_test.dart'
     as ambiguous_extension_method_access;
@@ -27,6 +25,8 @@
 import 'cast_to_non_type_test.dart' as cast_to_non_type;
 import 'concrete_class_with_abstract_member_test.dart'
     as concrete_class_with_abstract_member;
+import 'conflicting_static_and_instance_test.dart'
+    as conflicting_static_and_instance;
 import 'const_constructor_param_type_mismatch_test.dart'
     as const_constructor_param_type_mismatch;
 import 'const_constructor_with_mixin_with_field_test.dart'
@@ -52,6 +52,7 @@
 import 'deprecated_mixin_function_test.dart' as deprecated_mixin_function;
 import 'division_optimization_test.dart' as division_optimization;
 import 'down_cast_composite_test.dart' as down_cast_composite;
+import 'duplicate_definition_test.dart' as duplicate_definition;
 import 'duplicate_hidden_name_test.dart' as duplicate_hidden_name;
 import 'duplicate_import_test.dart' as duplicate_import;
 import 'duplicate_shown_name_test.dart' as duplicate_shown_name;
@@ -61,6 +62,8 @@
     as export_suplicated_library_named;
 import 'expression_in_map_test.dart' as expression_in_map;
 import 'extends_non_class_test.dart' as extends_non_class;
+import 'extension_conflicting_static_and_instance_test.dart'
+    as extension_conflicting_static_and_instance;
 import 'extension_declares_abstract_method_test.dart'
     as extension_declares_abstract_method;
 import 'extension_declares_constructor_test.dart'
@@ -86,6 +89,8 @@
 import 'final_not_initialized_constructor_test.dart'
     as final_not_initialized_constructor;
 import 'final_not_initialized_test.dart' as final_not_initialized;
+import 'if_element_condition_from_deferred_library_test.dart'
+    as if_element_condition_from_deferred_library;
 import 'implements_non_class_test.dart' as implements_non_class;
 import 'implicit_this_reference_in_initializer_test.dart'
     as implicit_this_reference_in_initializer;
@@ -94,6 +99,8 @@
 import 'import_duplicated_library_named_test.dart'
     as import_duplicated_library_named;
 import 'import_of_non_library_test.dart' as import_of_non_library;
+import 'instance_access_to_static_member_test.dart'
+    as instance_access_to_static_member;
 import 'invalid_assignment_test.dart' as invalid_assignment;
 import 'invalid_cast_new_expr_test.dart' as invalid_cast_new_expr;
 import 'invalid_extension_argument_count_test.dart'
@@ -160,8 +167,6 @@
 import 'non_bool_condition_test.dart' as non_bool_condition;
 import 'non_bool_negation_expression_test.dart' as non_bool_negation_expression;
 import 'non_bool_operand_test.dart' as non_bool_operand;
-import 'non_constant_if_element_condition_from_deferred_library_test.dart'
-    as non_constant_if_element_condition_from_deferred_library;
 import 'non_constant_list_element_from_deferred_library_test.dart'
     as non_constant_list_element_from_deferred_library;
 import 'non_constant_list_element_test.dart' as non_constant_list_element;
@@ -172,11 +177,7 @@
 import 'non_constant_map_value_from_deferred_library_test.dart'
     as non_constant_map_value_from_deferred_library;
 import 'non_constant_map_value_test.dart' as non_constant_map_value;
-import 'non_constant_set_element_from_deferred_library_test.dart'
-    as non_constant_set_element_from_deferred_library;
 import 'non_constant_set_element_test.dart' as non_constant_set_element;
-import 'non_constant_spread_expression_from_deferred_library_test.dart'
-    as non_constant_spread_expression_from_deferred_library;
 import 'non_null_opt_out_test.dart' as non_null_opt_out;
 import 'non_type_in_catch_clause_test.dart' as non_type_in_catch_clause;
 import 'non_void_return_for_operator_test.dart' as non_void_return_for_operator;
@@ -228,8 +229,11 @@
     as sdk_version_as_expression_in_const_context;
 import 'sdk_version_async_exported_from_core_test.dart'
     as sdk_version_async_exported_from_core;
-import 'sdk_version_bool_operator_test.dart' as sdk_version_bool_operator;
+import 'sdk_version_bool_operator_in_const_context_test.dart'
+    as sdk_version_bool_operator_in_const_context;
 import 'sdk_version_eq_eq_operator_test.dart' as sdk_version_eq_eq_operator;
+import 'sdk_version_extension_methods_test.dart'
+    as sdk_version_extension_methods;
 import 'sdk_version_gt_gt_gt_operator_test.dart'
     as sdk_version_gt_gt_gt_operator;
 import 'sdk_version_is_expression_in_const_context_test.dart'
@@ -239,14 +243,20 @@
 import 'sdk_version_ui_as_code_in_const_context_test.dart'
     as sdk_version_ui_as_code_in_const_context;
 import 'sdk_version_ui_as_code_test.dart' as sdk_version_ui_as_code;
+import 'set_element_from_deferred_library_test.dart'
+    as set_element_from_deferred_library;
 import 'set_element_type_not_assignable_test.dart'
     as set_element_type_not_assignable;
+import 'spread_expression_from_deferred_library_test.dart'
+    as spread_expression_from_deferred_library;
 import 'static_access_to_instance_member_test.dart'
     as static_access_to_instance_member;
 import 'subtype_of_sealed_class_test.dart' as subtype_of_sealed_class;
 import 'super_in_extension_test.dart' as super_in_extension;
 import 'top_level_instance_getter_test.dart' as top_level_instance_getter;
 import 'top_level_instance_method_test.dart' as top_level_instance_method;
+import 'type_argument_not_matching_bounds_test.dart'
+    as type_argument_not_matching_bounds;
 import 'type_check_is_not_null_test.dart' as type_check_is_not_null;
 import 'type_check_is_null_test.dart' as type_check_is_null;
 import 'unchecked_use_of_nullable_value_test.dart'
@@ -286,7 +296,6 @@
 
 main() {
   defineReflectiveSuite(() {
-    access_static_extension_member.main();
     ambiguous_export.main();
     ambiguous_extension_method_access.main();
     ambiguous_import.main();
@@ -304,6 +313,7 @@
     case_block_not_terminated.main();
     cast_to_non_type.main();
     concrete_class_with_abstract_member.main();
+    conflicting_static_and_instance.main();
     const_constructor_param_type_mismatch.main();
     const_constructor_with_mixin_with_field.main();
     const_eval_throws_exception.main();
@@ -321,6 +331,7 @@
     deprecated_mixin_function.main();
     division_optimization.main();
     down_cast_composite.main();
+    duplicate_definition.main();
     duplicate_hidden_name.main();
     duplicate_import.main();
     duplicate_shown_name.main();
@@ -329,6 +340,7 @@
     export_suplicated_library_named.main();
     expression_in_map.main();
     extends_non_class.main();
+    extension_conflicting_static_and_instance.main();
     extension_declares_abstract_method.main();
     extension_declares_constructor.main();
     extension_declares_field.main();
@@ -343,11 +355,13 @@
     final_initialized_in_delcaration_and_constructor.main();
     final_not_initialized_constructor.main();
     final_not_initialized.main();
+    if_element_condition_from_deferred_library.main();
     implements_non_class.main();
     implicit_this_reference_in_initializer.main();
     import_deferred_library_with_load_function.main();
     import_duplicated_library_named.main();
     import_of_non_library.main();
+    instance_access_to_static_member.main();
     invalid_assignment.main();
     invalid_cast_new_expr.main();
     invalid_extension_argument_count.main();
@@ -397,7 +411,6 @@
     non_bool_condition.main();
     non_bool_negation_expression.main();
     non_bool_operand.main();
-    non_constant_if_element_condition_from_deferred_library.main();
     non_constant_list_element.main();
     non_constant_list_element_from_deferred_library.main();
     non_constant_map_key.main();
@@ -406,8 +419,6 @@
     non_constant_map_value.main();
     non_constant_map_value_from_deferred_library.main();
     non_constant_set_element.main();
-    non_constant_set_element_from_deferred_library.main();
-    non_constant_spread_expression_from_deferred_library.main();
     non_null_opt_out.main();
     non_type_in_catch_clause.main();
     non_void_return_for_operator.main();
@@ -439,10 +450,12 @@
     redirect_to_missing_constructor.main();
     redirect_to_non_class.main();
     return_without_value.main();
+    set_element_from_deferred_library.main();
     sdk_version_as_expression_in_const_context.main();
     sdk_version_async_exported_from_core.main();
-    sdk_version_bool_operator.main();
+    sdk_version_bool_operator_in_const_context.main();
     sdk_version_eq_eq_operator.main();
+    sdk_version_extension_methods.main();
     sdk_version_gt_gt_gt_operator.main();
     sdk_version_is_expression_in_const_context.main();
     sdk_version_never.main();
@@ -450,11 +463,13 @@
     sdk_version_ui_as_code.main();
     sdk_version_ui_as_code_in_const_context.main();
     set_element_type_not_assignable.main();
+    spread_expression_from_deferred_library.main();
     static_access_to_instance_member.main();
     subtype_of_sealed_class.main();
     super_in_extension.main();
     top_level_instance_getter.main();
     top_level_instance_method.main();
+    type_argument_not_matching_bounds.main();
     type_check_is_not_null.main();
     type_check_is_null.main();
     unchecked_use_of_nullable_value.main();
diff --git a/pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart b/pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart
new file mode 100644
index 0000000..e1c52d5
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart
@@ -0,0 +1,347 @@
+// 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.
+
+import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(TypeArgumentNotMatchingBoundsTest);
+    defineReflectiveTests(
+      TypeArgumentNotMatchingBoundsWithExtensionMethodsTest,
+    );
+  });
+}
+
+@reflectiveTest
+class TypeArgumentNotMatchingBoundsTest extends DriverResolutionTest {
+  test_classTypeAlias() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class C {}
+class G<E extends A> {}
+class D = G<B> with C;
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 69, 1),
+    ]);
+  }
+
+  test_const() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {
+  const G();
+}
+f() { return const G<B>(); }
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 81, 1),
+    ]);
+  }
+
+  test_extends() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+class C extends G<B>{}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 64, 1),
+    ]);
+  }
+
+  test_extends_regressionInIssue18468Fix() async {
+    // https://code.google.com/p/dart/issues/detail?id=18628
+    await assertErrorsInCode(r'''
+class X<T extends Type> {}
+class Y<U> extends X<U> {}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 48, 1),
+    ]);
+  }
+
+  test_fieldFormalParameter() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+class C {
+  var f;
+  C(G<B> this.f) {}
+}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 71, 1),
+    ]);
+  }
+
+  test_functionReturnType() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+G<B> f() { return null; }
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 48, 1),
+    ]);
+  }
+
+  test_functionTypeAlias() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+typedef G<B> f();
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 56, 1),
+    ]);
+  }
+
+  test_functionTypedFormalParameter() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+f(G<B> h()) {}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 50, 1),
+    ]);
+  }
+
+  test_implements() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+class C implements G<B>{}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 67, 1),
+    ]);
+  }
+
+  test_is() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+var b = 1 is G<B>;
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 61, 1),
+    ]);
+  }
+
+  test_methodInvocation_localFunction() async {
+    await assertErrorsInCode(r'''
+class Point<T extends num> {
+  Point(T x, T y);
+}
+
+main() {
+  Point<T> f<T extends num>(T x, T y) {
+    return new Point<T>(x, y);
+  }
+  print(f<String>('hello', 'world'));
+}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 145, 6),
+    ]);
+  }
+
+  test_methodInvocation_method() async {
+    await assertErrorsInCode(r'''
+class Point<T extends num> {
+  Point(T x, T y);
+}
+
+class PointFactory {
+  Point<T> point<T extends num>(T x, T y) {
+    return new Point<T>(x, y);
+  }
+}
+
+f(PointFactory factory) {
+  print(factory.point<String>('hello', 'world'));
+}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 202, 6),
+    ]);
+  }
+
+  test_methodInvocation_topLevelFunction() async {
+    await assertErrorsInCode(r'''
+class Point<T extends num> {
+  Point(T x, T y);
+}
+
+Point<T> f<T extends num>(T x, T y) {
+  return new Point<T>(x, y);
+}
+
+main() {
+  print(f<String>('hello', 'world'));
+}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 140, 6),
+    ]);
+  }
+
+  test_methodReturnType() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+class C {
+  G<B> m() { return null; }
+}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 60, 1),
+    ]);
+  }
+
+  test_new() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+f() { return new G<B>(); }
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 65, 1),
+    ]);
+  }
+
+  test_new_superTypeOfUpperBound() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B extends A {}
+class C extends B {}
+class G<E extends B> {}
+f() { return new G<A>(); }
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 96, 1),
+    ]);
+  }
+
+  test_ofFunctionTypeAlias() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+typedef F<T extends A>();
+F<B> fff;
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 50, 1),
+    ]);
+  }
+
+  test_parameter() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+f(G<B> g) {}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 50, 1),
+    ]);
+  }
+
+  test_redirectingConstructor() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class X<T extends A> {
+  X(int x, int y) {}
+  factory X.name(int x, int y) = X<B>;
+}
+''', [
+      error(StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE, 99, 4),
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 101, 1),
+    ]);
+  }
+
+  test_typeArgumentList() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class C<E> {}
+class D<E extends A> {}
+C<D<B>> Var;
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 64, 1),
+    ]);
+  }
+
+  test_typeParameter() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class C {}
+class G<E extends A> {}
+class D<F extends G<B>> {}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 77, 1),
+    ]);
+  }
+
+  test_variableDeclaration() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+G<B> g;
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 48, 1),
+    ]);
+  }
+
+  test_with() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+class C extends Object with G<B>{}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 76, 1),
+    ]);
+  }
+}
+
+@reflectiveTest
+class TypeArgumentNotMatchingBoundsWithExtensionMethodsTest
+    extends DriverResolutionTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = new FeatureSet.forTesting(
+        sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
+
+  test_extensionOverride_hasTypeArguments() async {
+    await assertErrorsInCode(r'''
+extension E<T extends num> on int {
+  void foo() {}
+}
+
+void f() {
+  E<String>(0).foo();
+}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 70, 6),
+    ]);
+  }
+
+  test_extensionOverride_hasTypeArguments_call() async {
+    await assertErrorsInCode(r'''
+extension E<T extends num> on int {
+  void call() {}
+}
+
+void f() {
+  E<String>(0)();
+}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 71, 6),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/summary/expr_builder_test.dart b/pkg/analyzer/test/src/summary/expr_builder_test.dart
index 385c03e..fcdb51f3 100644
--- a/pkg/analyzer/test/src/summary/expr_builder_test.dart
+++ b/pkg/analyzer/test/src/summary/expr_builder_test.dart
@@ -6,6 +6,7 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/scanner/reader.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart';
@@ -22,6 +23,7 @@
 import 'test_strategies.dart';
 
 main() {
+  if (AnalysisDriver.useSummary2) return;
   defineReflectiveSuite(() {
     defineReflectiveTests(ExprBuilderTest);
     defineReflectiveTests(ExprBuilderWithConstantUpdateTest);
diff --git a/pkg/analyzer/test/src/summary/prelinker_test.dart b/pkg/analyzer/test/src/summary/prelinker_test.dart
index 59d8a62..6e932bd 100644
--- a/pkg/analyzer/test/src/summary/prelinker_test.dart
+++ b/pkg/analyzer/test/src/summary/prelinker_test.dart
@@ -2,12 +2,14 @@
 // 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/src/dart/analysis/driver.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'summary_common.dart';
 import 'test_strategies.dart';
 
 main() {
+  if (AnalysisDriver.useSummary2) return;
   defineReflectiveSuite(() {
     defineReflectiveTests(PrelinkerTest);
   });
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index ff7f676..8745996 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -10093,6 +10093,35 @@
 ''');
   }
 
+  test_type_inference_instanceCreation_notGeneric() async {
+    var library = await checkLibrary('''
+class A {
+  A(_);
+}
+var a = A(() => b);
+var b = A(() => a);
+''');
+    if (isAstBasedSummary) {
+      // There is no cycle with `a` and `b`, because `A` is not generic,
+      // so the type of `new A(...)` does not depend on its arguments.
+      checkElementText(library, '''
+class A {
+  A(dynamic _);
+}
+A a;
+A b;
+''');
+    } else {
+      checkElementText(library, '''
+class A {
+  A(dynamic _);
+}
+dynamic a/*error: dependencyCycle*/;
+dynamic b/*error: dependencyCycle*/;
+''');
+    }
+  }
+
   test_type_inference_multiplyDefinedElement() async {
     addLibrarySource('/a.dart', 'class C {}');
     addLibrarySource('/b.dart', 'class C {}');
diff --git a/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart b/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
index 7a9c6bf..3911aab 100644
--- a/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
+++ b/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
@@ -2,12 +2,14 @@
 // 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/src/dart/analysis/driver.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'summary_common.dart';
 import 'test_strategies.dart';
 
 main() {
+  if (AnalysisDriver.useSummary2) return;
   defineReflectiveSuite(() {
     defineReflectiveTests(LinkedSummarizeAstStrongTest);
   });
diff --git a/pkg/analyzer/test/util/id_testing_helper.dart b/pkg/analyzer/test/util/id_testing_helper.dart
index 7002715..28fa311 100644
--- a/pkg/analyzer/test/util/id_testing_helper.dart
+++ b/pkg/analyzer/test/util/id_testing_helper.dart
@@ -56,16 +56,15 @@
   computeExpectedMap(testFileUri, testFileName, code, expectedMaps,
       onFailure: onFailure);
   Map<Uri, AnnotatedCode> codeMap = {testFileUri: code};
-  var libFileNames = <String>[];
-  var testData = TestData(testFileUri, testFileUri, memorySourceFiles, codeMap,
-      expectedMaps, libFileNames);
+  var testData = TestData(testFileName, testFileUri, testFileUri,
+      memorySourceFiles, codeMap, expectedMaps);
   var config =
       TestConfig(marker, 'provisional test config', featureSet: featureSet);
   return runTestForConfig<T>(testData, dataComputer, config);
 }
 
 /// Creates the testing URI used for [fileName] in annotated tests.
-Uri createUriForFileName(String fileName, {bool isLib}) => _toTestUri(fileName);
+Uri createUriForFileName(String fileName) => _toTestUri(fileName);
 
 void onFailure(String message) {
   throw StateError(message);
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
index 287af32..52a0e77 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
@@ -1060,8 +1060,8 @@
 
     Element element = type.element;
 
-    // No element, e.g. "void".
-    if (element == null) {
+    // The type `void` does not have an element.
+    if (type is VoidType) {
       write(type.displayName);
       return true;
     }
@@ -1074,14 +1074,12 @@
     }
 
     // Just a Function, not FunctionTypeAliasElement.
-    if (type is FunctionType &&
-        element is FunctionTypedElement &&
-        element is! FunctionTypeAliasElement) {
+    if (type is FunctionType && element is! FunctionTypeAliasElement) {
       if (_writeType(type.returnType, methodBeingCopied: methodBeingCopied)) {
         write(' ');
       }
       write('Function');
-      writeTypeParameters(element.typeParameters,
+      writeTypeParameters(type.typeFormals,
           methodBeingCopied: methodBeingCopied);
       writeParameters(type.parameters, methodBeingCopied: methodBeingCopied);
       return true;
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
index 9e50791..2b22b737 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
@@ -616,6 +616,14 @@
   }
 
   @override
+  void visitExtensionDeclaration(ExtensionDeclaration node) {
+    // Make suggestions in the body of the extension declaration
+    if (node.members.contains(entity) || identical(entity, node.rightBracket)) {
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
   visitFieldDeclaration(FieldDeclaration node) {
     if (offset <= node.semicolon.offset) {
       optype.includeVarNameSuggestions = true;
@@ -877,6 +885,14 @@
   }
 
   @override
+  visitMixinDeclaration(MixinDeclaration node) {
+    // Make suggestions in the body of the mixin declaration
+    if (node.members.contains(entity) || identical(entity, node.rightBracket)) {
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
   void visitNamedExpression(NamedExpression node) {
     if (identical(entity, node.expression)) {
       optype.includeReturnValueSuggestions = true;
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
index ff2cb12..abf151b 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
@@ -9,6 +9,7 @@
 import 'package:analyzer/dart/ast/standard_resolution_map.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -1135,9 +1136,10 @@
     await _assertWriteType('int Function(double a, String b)');
   }
 
-  @failingTest
   test_writeType_function_generic() async {
     // TODO(scheglov) Fails because T/U are considered invisible.
+    if (!AnalysisDriver.useSummary2) return;
+
     await _assertWriteType('T Function<T, U>(T a, U b)');
   }
 
diff --git a/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart b/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
index 186cfa7..024a5e1 100644
--- a/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
@@ -5,6 +5,7 @@
 import 'dart:async';
 
 import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
 import 'package:analyzer_plugin/src/utilities/completion/optype.dart';
@@ -17,6 +18,7 @@
   defineReflectiveSuite(() {
     defineReflectiveTests(OpTypeTest);
     defineReflectiveTests(OpTypeDart1OnlyTest);
+    defineReflectiveTests(OpTypeTestWithExtensionMethods);
   });
 }
 
@@ -1950,19 +1952,19 @@
     await assertOpType(methodBody: true);
   }
 
-  test_MethodDeclaration1() async {
+  test_MethodDeclaration_inClass1() async {
     // SimpleIdentifier  MethodDeclaration  ClassDeclaration
     addTestSource('class Bar {const ^Fara();}');
     await assertOpType(typeNames: true);
   }
 
-  test_MethodDeclaration2() async {
+  test_MethodDeclaration_inClass2() async {
     // SimpleIdentifier  MethodDeclaration  ClassDeclaration
     addTestSource('class Bar {const F^ara();}');
     await assertOpType(typeNames: true);
   }
 
-  test_MethodDeclaration_inLineComment() async {
+  test_MethodDeclaration_inClass_inLineComment() async {
     // Comment  ClassDeclaration  CompilationUnit
     addTestSource('''
       class C2 {
@@ -1971,7 +1973,7 @@
     await assertOpType();
   }
 
-  test_MethodDeclaration_inLineComment2() async {
+  test_MethodDeclaration_inClass_inLineComment2() async {
     // Comment  ClassDeclaration  CompilationUnit
     addTestSource('''
       class C2 {
@@ -1980,7 +1982,7 @@
     await assertOpType();
   }
 
-  test_MethodDeclaration_inLineComment3() async {
+  test_MethodDeclaration_inClass_inLineComment3() async {
     // Comment  ClassDeclaration  CompilationUnit
     addTestSource('''
       class C2 {
@@ -1990,7 +1992,7 @@
     await assertOpType();
   }
 
-  test_MethodDeclaration_inLineDocComment() async {
+  test_MethodDeclaration_inClass_inLineDocComment() async {
     // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
     addTestSource('''
       class C2 {
@@ -1999,7 +2001,7 @@
     await assertOpType();
   }
 
-  test_MethodDeclaration_inLineDocComment2() async {
+  test_MethodDeclaration_inClass_inLineDocComment2() async {
     // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
     addTestSource('''
       class C2 {
@@ -2008,37 +2010,37 @@
     await assertOpType();
   }
 
-  test_MethodDeclaration_inStarComment() async {
+  test_MethodDeclaration_inClass_inStarComment() async {
     // Comment  ClassDeclaration  CompilationUnit
     addTestSource('class C2 {/* ^ */ zoo(z) {} String name;}');
     await assertOpType();
   }
 
-  test_MethodDeclaration_inStarComment2() async {
+  test_MethodDeclaration_inClass_inStarComment2() async {
     // Comment  ClassDeclaration  CompilationUnit
     addTestSource('class C2 {/*  *^/ zoo(z) {} String name;}');
     await assertOpType();
   }
 
-  test_MethodDeclaration_inStarDocComment() async {
+  test_MethodDeclaration_inClass_inStarDocComment() async {
     // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
     addTestSource('class C2 {/** ^ */ zoo(z) { } String name; }');
     await assertOpType();
   }
 
-  test_MethodDeclaration_inStarDocComment2() async {
+  test_MethodDeclaration_inClass_inStarDocComment2() async {
     // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
     addTestSource('class C2 {/**  *^/ zoo(z) { } String name; }');
     await assertOpType();
   }
 
-  test_MethodDeclaration_returnType() async {
+  test_MethodDeclaration_inClass_returnType() async {
     // ClassDeclaration  CompilationUnit
     addTestSource('class C2 {^ zoo(z) { } String name; }');
     await assertOpType(typeNames: true);
   }
 
-  test_MethodDeclaration_returnType_afterLineComment() async {
+  test_MethodDeclaration_inClass_returnType_afterLineComment() async {
     // MethodDeclaration  ClassDeclaration  CompilationUnit
     addTestSource('''
       class C2 {
@@ -2047,7 +2049,7 @@
     await assertOpType(typeNames: true);
   }
 
-  test_MethodDeclaration_returnType_afterLineComment2() async {
+  test_MethodDeclaration_inClass_returnType_afterLineComment2() async {
     // MethodDeclaration  ClassDeclaration  CompilationUnit
     // TOD(danrubel) left align all test source
     addTestSource('''
@@ -2057,7 +2059,7 @@
     await assertOpType(typeNames: true);
   }
 
-  test_MethodDeclaration_returnType_afterLineDocComment() async {
+  test_MethodDeclaration_inClass_returnType_afterLineDocComment() async {
     // SimpleIdentifier  MethodDeclaration  ClassDeclaration  CompilationUnit
     addTestSource('''
       class C2 {
@@ -2066,7 +2068,7 @@
     await assertOpType(typeNames: true);
   }
 
-  test_MethodDeclaration_returnType_afterLineDocComment2() async {
+  test_MethodDeclaration_inClass_returnType_afterLineDocComment2() async {
     // SimpleIdentifier  MethodDeclaration  ClassDeclaration  CompilationUnit
     addTestSource('''
 class C2 {
@@ -2075,30 +2077,60 @@
     await assertOpType(typeNames: true);
   }
 
-  test_MethodDeclaration_returnType_afterStarComment() async {
+  test_MethodDeclaration_inClass_returnType_afterStarComment() async {
     // ClassDeclaration  CompilationUnit
     addTestSource('class C2 {/* */ ^ zoo(z) { } String name; }');
     await assertOpType(typeNames: true);
   }
 
-  test_MethodDeclaration_returnType_afterStarComment2() async {
+  test_MethodDeclaration_inClass_returnType_afterStarComment2() async {
     // ClassDeclaration  CompilationUnit
     addTestSource('class C2 {/* */^ zoo(z) { } String name; }');
     await assertOpType(typeNames: true);
   }
 
-  test_MethodDeclaration_returnType_afterStarDocComment() async {
+  test_MethodDeclaration_inClass_returnType_afterStarDocComment() async {
     // MethodDeclaration  ClassDeclaration  CompilationUnit
     addTestSource('class C2 {/** */ ^ zoo(z) { } String name; }');
     await assertOpType(typeNames: true);
   }
 
-  test_MethodDeclaration_returnType_afterStarDocComment2() async {
+  test_MethodDeclaration_inClass_returnType_afterStarDocComment2() async {
     // MethodDeclaration  ClassDeclaration  CompilationUnit
     addTestSource('class C2 {/** */^ zoo(z) { } String name; }');
     await assertOpType(typeNames: true);
   }
 
+  test_methodDeclaration_inMixin1() async {
+    // SimpleIdentifier  MethodDeclaration  MixinDeclaration
+    addTestSource('mixin M {const ^Fara();}');
+    await assertOpType(typeNames: true);
+  }
+
+  test_methodDeclaration_inMixin2() async {
+    // SimpleIdentifier  MethodDeclaration  MixinDeclaration
+    addTestSource('mixin M {const F^ara();}');
+    await assertOpType(typeNames: true);
+  }
+
+  test_methodDeclaration_inMixin_returnType() async {
+    // MixinDeclaration  CompilationUnit
+    addTestSource('mixin M {^ zoo(z) { } String name; }');
+    await assertOpType(typeNames: true);
+  }
+
+  test_mixinDeclaration_body() async {
+    // MixinDeclaration  CompilationUnit
+    addTestSource('mixin M {^}');
+    await assertOpType(typeNames: true);
+  }
+
+  test_mixinDeclaration_body2() async {
+    // SimpleIdentifier  MethodDeclaration  MixinDeclaration
+    addTestSource('mixin M {^mth() {}}');
+    await assertOpType(typeNames: true);
+  }
+
   test_NamedExpression() async {
     addTestSource('''
 main() { f(3, ^); }
@@ -2401,3 +2433,46 @@
     testPath = convertPath('/completionTest.dart');
   }
 }
+
+@reflectiveTest
+class OpTypeTestWithExtensionMethods extends OpTypeTestCommon {
+  @override
+  void setUp() {
+    createAnalysisOptionsFile(
+      experiments: [
+        EnableString.extension_methods,
+      ],
+    );
+    super.setUp();
+  }
+
+  test_extensionDeclaration_body() async {
+    // ExtensionDeclaration  CompilationUnit
+    addTestSource('extension E on int {^}');
+    await assertOpType(typeNames: true);
+  }
+
+  test_extensionDeclaration_body2() async {
+    // SimpleIdentifier  MethodDeclaration  ExtensionDeclaration
+    addTestSource('extension E on int {^mth() {}}');
+    await assertOpType(typeNames: true);
+  }
+
+  test_methodDeclaration_inExtension1() async {
+    // SimpleIdentifier  ExtensionDeclaration  MixinDeclaration
+    addTestSource('extension E on int {const ^Fara();}');
+    await assertOpType(typeNames: true);
+  }
+
+  test_methodDeclaration_inExtension2() async {
+    // SimpleIdentifier  ExtensionDeclaration  MixinDeclaration
+    addTestSource('extension E on int {const F^ara();}');
+    await assertOpType(typeNames: true);
+  }
+
+  test_methodDeclaration_inExtension_returnType() async {
+    // ExtensionDeclaration  CompilationUnit
+    addTestSource('extension E on int {^ zoo(z) { } String name; }');
+    await assertOpType(typeNames: true);
+  }
+}
diff --git a/pkg/compiler/lib/src/common_elements.dart b/pkg/compiler/lib/src/common_elements.dart
index 4d53d40..3dab917 100644
--- a/pkg/compiler/lib/src/common_elements.dart
+++ b/pkg/compiler/lib/src/common_elements.dart
@@ -483,11 +483,14 @@
 
   FunctionEntity get findType;
   FunctionEntity get instanceType;
+  FunctionEntity get arrayInstanceType;
+  FunctionEntity get simpleInstanceType;
   FunctionEntity get typeLiteralMaker;
   FunctionEntity get checkTypeBound;
   FieldEntity get rtiAsField;
   FieldEntity get rtiCheckField;
   FieldEntity get rtiIsField;
+  FieldEntity get rtiRestField;
   FunctionEntity get rtiEvalMethod;
   FunctionEntity get rtiBindMethod;
   FunctionEntity get rtiAddRulesMethod;
@@ -511,6 +514,9 @@
   FunctionEntity get specializedAsStringNullable;
   FunctionEntity get specializedCheckStringNullable;
 
+  FunctionEntity get instantiatedGenericFunctionTypeNewRti;
+  FunctionEntity get closureFunctionType;
+
   // From dart:_internal
 
   ClassEntity get symbolImplementationClass;
@@ -1757,7 +1763,7 @@
 
   @override
   FunctionEntity get createRuntimeType => _options.experimentNewRti
-      ? _findRtiFunction('_createRuntimeType')
+      ? _findRtiFunction('createRuntimeType')
       : _findHelperFunction('createRuntimeType');
 
   @override
@@ -1846,6 +1852,16 @@
   FunctionEntity get instanceType =>
       _instanceType ??= _findRtiFunction('instanceType');
 
+  FunctionEntity _arrayInstanceType;
+  @override
+  FunctionEntity get arrayInstanceType =>
+      _arrayInstanceType ??= _findRtiFunction('_arrayInstanceType');
+
+  FunctionEntity _simpleInstanceType;
+  @override
+  FunctionEntity get simpleInstanceType =>
+      _simpleInstanceType ??= _findRtiFunction('_instanceType');
+
   FunctionEntity _typeLiteralMaker;
   @override
   FunctionEntity get typeLiteralMaker =>
@@ -1874,6 +1890,10 @@
   FieldEntity get rtiCheckField =>
       _rtiCheckField ??= _findRtiClassField('_check');
 
+  FieldEntity _rtiRestField;
+  @override
+  FieldEntity get rtiRestField => _rtiRestField ??= _findRtiClassField('_rest');
+
   FunctionEntity _rtiEvalMethod;
   @override
   FunctionEntity get rtiEvalMethod =>
@@ -1959,6 +1979,14 @@
   FunctionEntity get specializedCheckStringNullable =>
       _findRtiFunction('_checkStringNullable');
 
+  @override
+  FunctionEntity get instantiatedGenericFunctionTypeNewRti =>
+      _findRtiFunction('instantiatedGenericFunctionType');
+
+  @override
+  FunctionEntity get closureFunctionType =>
+      _findRtiFunction('closureFunctionType');
+
   // From dart:_internal
 
   ClassEntity _symbolImplementationClass;
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index 67332be..8864815 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -356,6 +356,7 @@
               break;
             case TypeUseKind.RTI_VALUE:
             case TypeUseKind.TYPE_ARGUMENT:
+            case TypeUseKind.NAMED_TYPE_VARIABLE_NEW_RTI:
               failedAt(element, "Unexpected type use: $typeUse.");
               break;
           }
diff --git a/pkg/compiler/lib/src/elements/types.dart b/pkg/compiler/lib/src/elements/types.dart
index ef7c2f8..d793fe9 100644
--- a/pkg/compiler/lib/src/elements/types.dart
+++ b/pkg/compiler/lib/src/elements/types.dart
@@ -75,7 +75,8 @@
   /// variable.
   // TODO(sra): Review uses of [containsTypeVariables] for update with
   // [containsFreeTypeVariables].
-  bool get containsFreeTypeVariables => _containsFreeTypeVariables(null);
+  bool get containsFreeTypeVariables =>
+      _ContainsFreeTypeVariablesVisitor().run(this);
 
   /// Is `true` if this type is the 'Object' type defined in 'dart:core'.
   bool get isObject => false;
@@ -93,14 +94,20 @@
   /// See [TypeVariableType] for a motivation for this method.
   ///
   /// Invariant: There must be the same number of [arguments] and [parameters].
-  DartType subst(List<DartType> arguments, List<DartType> parameters);
+  DartType subst(List<DartType> arguments, List<DartType> parameters) {
+    assert(arguments.length == parameters.length);
+    if (parameters.isEmpty) return this;
+    return SimpleDartTypeSubstitutionVisitor(arguments, parameters)
+        .substitute(this);
+  }
 
   /// Calls the visit method on [visitor] corresponding to this type.
   R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument);
 
   bool _equals(DartType other, _Assumptions assumptions);
 
-  bool _containsFreeTypeVariables(List<FunctionTypeVariable> bindings) => false;
+  @override
+  String toString() => _DartTypeToStringVisitor().run(this);
 }
 
 /// Pairs of [FunctionTypeVariable]s that are currently assumed to be
@@ -185,32 +192,6 @@
   }
 
   @override
-  bool _containsFreeTypeVariables(List<FunctionTypeVariable> bindings) {
-    return typeArguments
-        .any((type) => type._containsFreeTypeVariables(bindings));
-  }
-
-  @override
-  InterfaceType subst(List<DartType> arguments, List<DartType> parameters) {
-    if (typeArguments.isEmpty) {
-      // Return fast on non-generic types.
-      return this;
-    }
-    if (parameters.isEmpty) {
-      assert(arguments.isEmpty);
-      // Return fast on empty substitutions.
-      return this;
-    }
-    List<DartType> newTypeArguments =
-        _substTypes(typeArguments, arguments, parameters);
-    if (!identical(typeArguments, newTypeArguments)) {
-      // Create a new type only if necessary.
-      return new InterfaceType(element, newTypeArguments);
-    }
-    return this;
-  }
-
-  @override
   bool get treatAsRaw {
     for (DartType type in typeArguments) {
       if (!type.treatAsDynamic) return false;
@@ -250,25 +231,6 @@
     return identical(element, other.element) &&
         _equalTypes(typeArguments, other.typeArguments, assumptions);
   }
-
-  @override
-  String toString() {
-    StringBuffer sb = new StringBuffer();
-    sb.write(element.name);
-    if (typeArguments.isNotEmpty) {
-      sb.write('<');
-      bool needsComma = false;
-      for (DartType typeArgument in typeArguments) {
-        if (needsComma) {
-          sb.write(',');
-        }
-        sb.write(typeArgument);
-        needsComma = true;
-      }
-      sb.write('>');
-    }
-    return sb.toString();
-  }
 }
 
 class TypedefType extends DartType {
@@ -292,32 +254,6 @@
   }
 
   @override
-  bool _containsFreeTypeVariables(List<FunctionTypeVariable> bindings) =>
-      typeArguments.any((type) => type._containsFreeTypeVariables(bindings));
-
-  @override
-  TypedefType subst(List<DartType> arguments, List<DartType> parameters) {
-    if (typeArguments.isEmpty) {
-      // Return fast on non-generic types.
-      return this;
-    }
-    if (parameters.isEmpty) {
-      assert(arguments.isEmpty);
-      // Return fast on empty substitutions.
-      return this;
-    }
-    List<DartType> newTypeArguments =
-        _substTypes(typeArguments, arguments, parameters);
-    FunctionType newUnaliased = unaliased.subst(arguments, parameters);
-    if (!identical(typeArguments, newTypeArguments) ||
-        !identical(unaliased, newUnaliased)) {
-      // Create a new type only if necessary.
-      return new TypedefType(element, newTypeArguments, newUnaliased);
-    }
-    return this;
-  }
-
-  @override
   bool get treatAsRaw {
     for (DartType type in typeArguments) {
       if (!type.treatAsDynamic) return false;
@@ -357,25 +293,6 @@
     return identical(element, other.element) &&
         _equalTypes(typeArguments, other.typeArguments, assumptions);
   }
-
-  @override
-  String toString() {
-    StringBuffer sb = new StringBuffer();
-    sb.write(element.name);
-    if (typeArguments.isNotEmpty) {
-      sb.write('<');
-      bool needsComma = false;
-      for (DartType typeArgument in typeArguments) {
-        if (needsComma) {
-          sb.write(',');
-        }
-        sb.write(typeArgument);
-        needsComma = true;
-      }
-      sb.write('>');
-    }
-    return sb.toString();
-  }
 }
 
 class TypeVariableType extends DartType {
@@ -395,24 +312,6 @@
   }
 
   @override
-  bool _containsFreeTypeVariables(List<FunctionTypeVariable> bindings) => true;
-
-  @override
-  DartType subst(List<DartType> arguments, List<DartType> parameters) {
-    assert(arguments.length == parameters.length);
-    if (parameters.isEmpty) {
-      // Return fast on empty substitutions.
-      return this;
-    }
-    int index = parameters.indexOf(this);
-    if (index != -1) {
-      return arguments[index];
-    }
-    // The type variable was not substituted.
-    return this;
-  }
-
-  @override
   R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
       visitor.visitTypeVariableType(this, argument);
 
@@ -432,9 +331,6 @@
     }
     return false;
   }
-
-  @override
-  String toString() => '${element.typeDeclaration.name}.${element.name}';
 }
 
 /// A type variable declared on a function type.
@@ -457,7 +353,7 @@
   FunctionTypeVariable(this.index);
 
   DartType get bound {
-    assert(_bound != null, "Bound hasn't been set.");
+    assert(_bound != null, "Bound has not been set.");
     return _bound;
   }
 
@@ -470,28 +366,6 @@
   bool get isFunctionTypeVariable => true;
 
   @override
-  bool _containsFreeTypeVariables(List<FunctionTypeVariable> bindings) {
-    if (bindings == null) return true;
-    if (bindings.indexOf(this) >= 0) return false;
-    return true;
-  }
-
-  @override
-  DartType subst(List<DartType> arguments, List<DartType> parameters) {
-    assert(arguments.length == parameters.length);
-    if (parameters.isEmpty) {
-      // Return fast on empty substitutions.
-      return this;
-    }
-    int index = parameters.indexOf(this);
-    if (index != -1) {
-      return arguments[index];
-    }
-    // The function type variable was not substituted.
-    return this;
-  }
-
-  @override
   int get hashCode => index.hashCode * 19;
 
   @override
@@ -512,9 +386,6 @@
   @override
   R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
       visitor.visitFunctionTypeVariable(this, argument);
-
-  @override
-  String toString() => '#${new String.fromCharCode(0x41 + index)}';
 }
 
 class VoidType extends DartType {
@@ -524,12 +395,6 @@
   bool get isVoid => true;
 
   @override
-  DartType subst(List<DartType> arguments, List<DartType> parameters) {
-    // `void` cannot be substituted.
-    return this;
-  }
-
-  @override
   R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
       visitor.visitVoidType(this, argument);
 
@@ -540,9 +405,6 @@
   bool _equals(DartType other, _Assumptions assumptions) {
     return identical(this, other);
   }
-
-  @override
-  String toString() => 'void';
 }
 
 class DynamicType extends DartType {
@@ -555,12 +417,6 @@
   bool get treatAsDynamic => true;
 
   @override
-  DartType subst(List<DartType> arguments, List<DartType> parameters) {
-    // `dynamic` cannot be substituted.
-    return this;
-  }
-
-  @override
   R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
       visitor.visitDynamicType(this, argument);
 
@@ -571,9 +427,6 @@
   bool _equals(DartType other, _Assumptions assumptions) {
     return identical(this, other);
   }
-
-  @override
-  String toString() => 'dynamic';
 }
 
 class FunctionType extends DartType {
@@ -627,88 +480,8 @@
   }
 
   @override
-  bool _containsFreeTypeVariables(List<FunctionTypeVariable> bindings) {
-    int restore;
-    if (typeVariables.isNotEmpty) {
-      if (bindings == null) {
-        bindings = <FunctionTypeVariable>[];
-      } else {
-        restore = bindings.length;
-      }
-      bindings.addAll(typeVariables);
-    }
-
-    bool hasFree(DartType type) => type._containsFreeTypeVariables(bindings);
-
-    bool result = hasFree(returnType) ||
-        typeVariables.any((type) => hasFree(type.bound)) ||
-        parameterTypes.any(hasFree) ||
-        optionalParameterTypes.any(hasFree) ||
-        namedParameterTypes.any(hasFree);
-
-    if (restore != null) bindings.length = restore;
-    return result;
-  }
-
-  @override
   bool get isFunctionType => true;
 
-  @override
-  DartType subst(List<DartType> arguments, List<DartType> parameters) {
-    if (parameters.isEmpty) {
-      assert(arguments.isEmpty);
-      // Return fast on empty substitutions.
-      return this;
-    }
-    DartType newReturnType = returnType.subst(arguments, parameters);
-    bool changed = !identical(newReturnType, returnType);
-    List<DartType> newParameterTypes =
-        _substTypes(parameterTypes, arguments, parameters);
-    List<DartType> newOptionalParameterTypes =
-        _substTypes(optionalParameterTypes, arguments, parameters);
-    List<DartType> newNamedParameterTypes =
-        _substTypes(namedParameterTypes, arguments, parameters);
-    if (!changed &&
-        (!identical(parameterTypes, newParameterTypes) ||
-            !identical(optionalParameterTypes, newOptionalParameterTypes) ||
-            !identical(namedParameterTypes, newNamedParameterTypes))) {
-      changed = true;
-    }
-    List<FunctionTypeVariable> newTypeVariables;
-    if (typeVariables.isNotEmpty) {
-      if (parameters == typeVariables) {
-        newTypeVariables = const <FunctionTypeVariable>[];
-        changed = true;
-      } else {
-        int index = 0;
-        for (FunctionTypeVariable typeVariable in typeVariables) {
-          DartType newBound = typeVariable.bound.subst(arguments, parameters);
-          if (!identical(typeVariable.bound, newBound)) {
-            newTypeVariables ??= typeVariables.sublist(0, index);
-            changed = true;
-          } else {
-            newTypeVariables?.add(typeVariable);
-          }
-          index++;
-        }
-        newTypeVariables ??= typeVariables;
-      }
-    } else {
-      newTypeVariables = typeVariables;
-    }
-    if (changed) {
-      // Create a new type only if necessary.
-      return new FunctionType(
-          newReturnType,
-          newParameterTypes,
-          newOptionalParameterTypes,
-          namedParameters,
-          newNamedParameterTypes,
-          newTypeVariables);
-    }
-    return this;
-  }
-
   FunctionType instantiate(List<DartType> arguments) {
     return subst(arguments, typeVariables);
   }
@@ -778,74 +551,6 @@
     }
     return result;
   }
-
-  @override
-  String toString() {
-    StringBuffer sb = new StringBuffer();
-    sb.write(returnType);
-    sb.write(' Function');
-    if (typeVariables.isNotEmpty) {
-      sb.write('<');
-      bool needsComma = false;
-      for (FunctionTypeVariable typeVariable in typeVariables) {
-        if (needsComma) {
-          sb.write(',');
-        }
-        sb.write(typeVariable);
-        DartType bound = typeVariable.bound;
-        if (!bound.isObject) {
-          sb.write(' extends ');
-          sb.write(typeVariable.bound);
-        }
-        needsComma = true;
-      }
-      sb.write('>');
-    }
-    sb.write('(');
-    bool needsComma = false;
-    for (DartType parameterType in parameterTypes) {
-      if (needsComma) {
-        sb.write(',');
-      }
-      sb.write(parameterType);
-      needsComma = true;
-    }
-    if (optionalParameterTypes.isNotEmpty) {
-      if (needsComma) {
-        sb.write(',');
-      }
-      sb.write('[');
-      bool needsOptionalComma = false;
-      for (DartType typeArgument in optionalParameterTypes) {
-        if (needsOptionalComma) {
-          sb.write(',');
-        }
-        sb.write(typeArgument);
-        needsOptionalComma = true;
-      }
-      sb.write(']');
-      needsComma = true;
-    }
-    if (namedParameters.isNotEmpty) {
-      if (needsComma) {
-        sb.write(',');
-      }
-      sb.write('{');
-      bool needsNamedComma = false;
-      for (int index = 0; index < namedParameters.length; index++) {
-        if (needsNamedComma) {
-          sb.write(',');
-        }
-        sb.write(namedParameterTypes[index]);
-        sb.write(' ');
-        sb.write(namedParameters[index]);
-        needsNamedComma = true;
-      }
-      sb.write('}');
-    }
-    sb.write(')');
-    return sb.toString();
-  }
 }
 
 class FutureOrType extends DartType {
@@ -857,13 +562,6 @@
   bool get isFutureOr => true;
 
   @override
-  DartType subst(List<DartType> arguments, List<DartType> parameters) {
-    DartType newTypeArgument = typeArgument.subst(arguments, parameters);
-    if (identical(typeArgument, newTypeArgument)) return this;
-    return new FutureOrType(newTypeArgument);
-  }
-
-  @override
   bool get containsTypeVariables => typeArgument.containsTypeVariables;
 
   @override
@@ -872,10 +570,6 @@
   }
 
   @override
-  bool _containsFreeTypeVariables(List<FunctionTypeVariable> bindings) =>
-      typeArgument._containsFreeTypeVariables(bindings);
-
-  @override
   R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
       visitor.visitFutureOrType(this, argument);
 
@@ -899,36 +593,6 @@
   bool _equalsInternal(FutureOrType other, _Assumptions assumptions) {
     return typeArgument._equals(other.typeArgument, assumptions);
   }
-
-  @override
-  String toString() {
-    StringBuffer sb = new StringBuffer();
-    sb.write('FutureOr');
-    sb.write('<');
-    sb.write(typeArgument);
-    sb.write('>');
-    return sb.toString();
-  }
-}
-
-/// Helper method for performing substitution of a list of types.
-///
-/// If no types are changed by the substitution, the [types] is returned
-/// instead of a newly created list.
-List<DartType> _substTypes(
-    List<DartType> types, List<DartType> arguments, List<DartType> parameters) {
-  bool changed = false;
-  List<DartType> result =
-      new List<DartType>.generate(types.length, (int index) {
-    DartType type = types[index];
-    DartType argument = type.subst(arguments, parameters);
-    if (!changed && !identical(argument, type)) {
-      changed = true;
-    }
-    return argument;
-  });
-  // Use the new List only if necessary.
-  return changed ? result : types;
 }
 
 bool _equalTypes(List<DartType> a, List<DartType> b, _Assumptions assumptions) {
@@ -1000,6 +664,579 @@
       visitType(type, argument);
 }
 
+abstract class DartTypeSubstitutionVisitor<A>
+    extends DartTypeVisitor<DartType, A> {
+  // The input type is a DAG and we must preserve the sharing.
+  Map<DartType, DartType> _map = Map.identity();
+
+  DartType _mapped(DartType oldType, DartType newType) {
+    assert(_map[oldType] == null);
+    return _map[oldType] = newType;
+  }
+
+  /// Returns the replacement for the type variable [type]. Returns the original
+  /// [type] if not substituted. The substitution algorithm sometimes visits the
+  /// same subterm more than once. When this happens, [freshReference] is `true`
+  /// on only one visit. This allows the substitution visitor to count the
+  /// number of times the replacement term occurs in the final term.
+  DartType substituteTypeVariableType(
+      TypeVariableType type, A argument, bool freshReference);
+
+  /// Returns the replacement for the function type variable [type]. Returns the
+  /// original [type] if not substituted. The substitution algorithm sometimes
+  /// visits the same subterm more than once. When this happens,
+  /// [freshReference] is `true` on only one visit. This allows the substitution
+  /// visitor to count the number of times the replacement term occurs in the
+  /// final term.
+  DartType substituteFunctionTypeVariable(
+          FunctionTypeVariable type, A argument, bool freshReference) =>
+      type;
+
+  @override
+  DartType visitTypeVariableType(covariant TypeVariableType type, A argument) {
+    return substituteTypeVariableType(type, argument, true);
+  }
+
+  @override
+  DartType visitFunctionTypeVariable(
+      covariant FunctionTypeVariable type, A argument) {
+    // Function type variables are added to the map only for type variables that
+    // need to be replaced with updated bounds.
+    DartType seen = _map[type];
+    if (seen != null) return seen;
+    return substituteFunctionTypeVariable(type, argument, true);
+  }
+
+  @override
+  DartType visitVoidType(covariant VoidType type, A argument) => type;
+
+  @override
+  DartType visitFunctionType(covariant FunctionType type, A argument) {
+    DartType seen = _map[type];
+    if (seen != null) return seen;
+
+    List<FunctionTypeVariable> newTypeVariables =
+        _handleFunctionTypeVariables(type.typeVariables, argument);
+
+    DartType newReturnType = visit(type.returnType, argument);
+    List<DartType> newParameterTypes =
+        _substTypes(type.parameterTypes, argument);
+    List<DartType> newOptionalParameterTypes =
+        _substTypes(type.optionalParameterTypes, argument);
+    List<DartType> newNamedParameterTypes =
+        _substTypes(type.namedParameterTypes, argument);
+
+    // Create a new type only if necessary.
+    if (identical(type.typeVariables, newTypeVariables) &&
+        identical(type.returnType, newReturnType) &&
+        identical(type.parameterTypes, newParameterTypes) &&
+        identical(type.optionalParameterTypes, newOptionalParameterTypes) &&
+        identical(type.namedParameterTypes, newNamedParameterTypes)) {
+      return _mapped(type, type);
+    }
+
+    return _mapped(
+        type,
+        FunctionType(
+            newReturnType,
+            newParameterTypes,
+            newOptionalParameterTypes,
+            type.namedParameters,
+            newNamedParameterTypes,
+            newTypeVariables));
+  }
+
+  List<FunctionTypeVariable> _handleFunctionTypeVariables(
+      List<FunctionTypeVariable> variables, A argument) {
+    if (variables.isEmpty) return variables;
+
+    // Are the function type variables being substituted (i.e. generic function
+    // type instantiation).
+    // TODO(sra): This should happen only from via
+    // [FunctionType.instantiate]. Perhaps it would be handled better there.
+    int count = 0;
+    for (int i = 0; i < variables.length; i++) {
+      FunctionTypeVariable variable = variables[i];
+      if (variable !=
+          substituteFunctionTypeVariable(variable, argument, false)) {
+        count++;
+      }
+    }
+    if (count == variables.length) return const <FunctionTypeVariable>[];
+    assert(count == 0, 'Generic function type instantiation is all-or-none');
+
+    // Type variables may depend on each other. Consider:
+    //
+    //     <A extends List<B>,
+    //      B extends Set<A>,
+    //      C extends D,
+    //      D extends Map<B, F>>(){}
+    //
+    // A and B have a cycle but are not changed by the subsitution of F->G. C is
+    // indirectly changed by the substitution of F. When D is replaced by `D2
+    // extends Map<B,G>`, C must be replaced by `C2 extends D2`.
+
+    List<FunctionTypeVariable> undecided = variables.toList();
+    List<FunctionTypeVariable> newVariables;
+
+    _DependencyCheck<A> dependencyCheck = _DependencyCheck<A>(this, argument);
+
+    bool changed = true;
+    while (changed) {
+      changed = false;
+      for (int i = 0; i < undecided.length; i++) {
+        FunctionTypeVariable variable = undecided[i];
+        if (variable == null) continue;
+        if (dependencyCheck.run(variable.bound)) {
+          changed = true;
+          undecided[i] = null;
+          newVariables ??= variables.toList();
+          FunctionTypeVariable newVariable =
+              FunctionTypeVariable(variable.index);
+          newVariables[i] = newVariable;
+          _mapped(variable, newVariable);
+        }
+      }
+    }
+    if (newVariables == null) return variables;
+
+    // Substitute the bounds of the new variables;
+    for (int i = 0; i < newVariables.length; i++) {
+      FunctionTypeVariable oldVariable = variables[i];
+      FunctionTypeVariable newVariable = newVariables[i];
+      if (identical(oldVariable, newVariable)) continue;
+      newVariable.bound = visit(oldVariable.bound, argument);
+    }
+    return newVariables;
+  }
+
+  @override
+  DartType visitInterfaceType(covariant InterfaceType type, A argument) {
+    List<DartType> typeArguments = type.typeArguments;
+    if (typeArguments.isEmpty) {
+      // Return fast on non-generic types.
+      return type;
+    }
+
+    DartType seen = _map[type];
+    if (seen != null) return seen;
+
+    List<DartType> newTypeArguments = _substTypes(typeArguments, argument);
+    // Create a new type only if necessary.
+    if (identical(typeArguments, newTypeArguments)) {
+      return _mapped(type, type);
+    }
+    return _mapped(type, InterfaceType(type.element, newTypeArguments));
+  }
+
+  @override
+  DartType visitTypedefType(covariant TypedefType type, A argument) {
+    DartType seen = _map[type];
+    if (seen != null) return seen;
+
+    List<DartType> newTypeArguments = _substTypes(type.typeArguments, argument);
+    FunctionType newUnaliased = visit(type.unaliased, argument);
+    // Create a new type only if necessary.
+    if (identical(type.typeArguments, newTypeArguments) &&
+        identical(type.unaliased, newUnaliased)) {
+      return _mapped(type, type);
+    }
+    return _mapped(
+        type, TypedefType(type.element, newTypeArguments, newUnaliased));
+  }
+
+  @override
+  DartType visitDynamicType(covariant DynamicType type, A argument) => type;
+
+  @override
+  DartType visitFutureOrType(covariant FutureOrType type, A argument) {
+    DartType seen = _map[type];
+    if (seen != null) return seen;
+
+    DartType newTypeArgument = visit(type.typeArgument, argument);
+    // Create a new type only if necessary.
+    if (identical(type.typeArgument, newTypeArgument)) {
+      return _mapped(type, type);
+    }
+    return _mapped(type, FutureOrType(newTypeArgument));
+  }
+
+  List<DartType> _substTypes(List<DartType> types, A argument) {
+    List<DartType> result;
+    for (int i = 0; i < types.length; i++) {
+      DartType oldType = types[i];
+      DartType newType = visit(oldType, argument);
+      if (!identical(newType, oldType)) {
+        result ??= types.sublist(0, i);
+      }
+      result?.add(newType);
+    }
+    return result ?? types;
+  }
+}
+
+class _DependencyCheck<A> extends DartTypeStructuralPredicateVisitor {
+  final DartTypeSubstitutionVisitor<A> _substitutionVisitor;
+  final A argument;
+
+  _DependencyCheck(this._substitutionVisitor, this.argument);
+
+  @override
+  bool handleTypeVariableType(TypeVariableType type) {
+    return !identical(type,
+        _substitutionVisitor.substituteTypeVariableType(type, argument, false));
+  }
+
+  @override
+  bool handleFreeFunctionTypeVariable(FunctionTypeVariable type) {
+    // Function type variables are added to the map for type variables that need
+    // to be replaced with updated bounds.
+    DartType seen = _substitutionVisitor._map[type];
+    if (seen != null) return seen != type;
+    return !identical(
+        type,
+        _substitutionVisitor.substituteFunctionTypeVariable(
+            type, argument, false));
+  }
+}
+
+/// A visitor that by default visits the substructure of the type until some
+/// visit returns`true`.  The default handers return `false` which will search
+/// the whole structure unless overridden.
+abstract class DartTypeStructuralPredicateVisitor
+    extends DartTypeVisitor<bool, List<FunctionTypeVariable>> {
+  const DartTypeStructuralPredicateVisitor();
+
+  bool run(DartType type) => visit(type, null);
+
+  bool handleVoidType(VoidType type) => false;
+  bool handleTypeVariableType(TypeVariableType type) => false;
+  bool handleBoundFunctionTypeVariable(FunctionTypeVariable type) => false;
+  bool handleFreeFunctionTypeVariable(FunctionTypeVariable type) => false;
+  bool handleFunctionType(FunctionType type) => false;
+  bool handleInterfaceType(InterfaceType type) => false;
+  bool handleTypedefType(TypedefType type) => false;
+  bool handleDynamicType(DynamicType type) => false;
+  bool handleFutureOrType(FutureOrType type) => false;
+
+  @override
+  bool visitVoidType(VoidType type, List<FunctionTypeVariable> bindings) =>
+      handleVoidType(type);
+
+  @override
+  bool visitTypeVariableType(
+          TypeVariableType type, List<FunctionTypeVariable> bindings) =>
+      handleTypeVariableType(type);
+
+  @override
+  bool visitFunctionTypeVariable(
+      FunctionTypeVariable type, List<FunctionTypeVariable> bindings) {
+    return bindings != null && bindings.indexOf(type) >= 0
+        ? handleBoundFunctionTypeVariable(type)
+        : handleFreeFunctionTypeVariable(type);
+  }
+
+  @override
+  bool visitFunctionType(
+      FunctionType type, List<FunctionTypeVariable> bindings) {
+    if (handleFunctionType(type)) return true;
+    List<FunctionTypeVariable> typeVariables = type.typeVariables;
+    if (typeVariables.isNotEmpty) {
+      bindings ??= <FunctionTypeVariable>[];
+      bindings.addAll(typeVariables);
+    }
+
+    bool result = visit(type.returnType, bindings);
+    result = result ||
+        _visitAll(type.typeVariables.map((variable) => variable.bound).toList(),
+            bindings);
+    result = result || _visitAll(type.parameterTypes, bindings);
+    result = result || _visitAll(type.optionalParameterTypes, bindings);
+    result = result || _visitAll(type.namedParameterTypes, bindings);
+
+    bindings?.length -= typeVariables.length;
+    return result;
+  }
+
+  @override
+  bool visitInterfaceType(
+      InterfaceType type, List<FunctionTypeVariable> bindings) {
+    if (handleInterfaceType(type)) return true;
+    return _visitAll(type.typeArguments, bindings);
+  }
+
+  @override
+  bool visitTypedefType(TypedefType type, List<FunctionTypeVariable> bindings) {
+    if (handleTypedefType(type)) return true;
+    if (_visitAll(type.typeArguments, bindings)) return true;
+    return visit(type.unaliased, bindings);
+  }
+
+  @override
+  bool visitDynamicType(
+          DynamicType type, List<FunctionTypeVariable> bindings) =>
+      handleDynamicType(type);
+
+  @override
+  bool visitFutureOrType(
+      FutureOrType type, List<FunctionTypeVariable> bindings) {
+    if (handleFutureOrType(type)) return true;
+    return visit(type.typeArgument, bindings);
+  }
+
+  bool _visitAll(List<DartType> types, List<FunctionTypeVariable> bindings) {
+    for (DartType type in types) {
+      if (visit(type, bindings)) return true;
+    }
+    return false;
+  }
+}
+
+class _ContainsFreeTypeVariablesVisitor
+    extends DartTypeStructuralPredicateVisitor {
+  @override
+  bool handleTypeVariableType(TypeVariableType type) => true;
+
+  @override
+  bool handleFreeFunctionTypeVariable(FunctionTypeVariable type) => true;
+}
+
+class SimpleDartTypeSubstitutionVisitor
+    extends DartTypeSubstitutionVisitor<Null> {
+  final List<DartType> arguments;
+  final List<DartType> parameters;
+
+  SimpleDartTypeSubstitutionVisitor(this.arguments, this.parameters);
+
+  DartType substitute(DartType input) => visit(input, null);
+
+  @override
+  DartType substituteTypeVariableType(
+      TypeVariableType type, Null _, bool freshReference) {
+    int index = this.parameters.indexOf(type);
+    if (index != -1) {
+      return this.arguments[index];
+    }
+    // The type variable was not substituted.
+    return type;
+  }
+
+  @override
+  DartType substituteFunctionTypeVariable(
+      covariant FunctionTypeVariable type, Null _, bool freshReference) {
+    int index = this.parameters.indexOf(type);
+    if (index != -1) {
+      return this.arguments[index];
+    }
+    // The function type variable was not substituted.
+    return type;
+  }
+}
+
+class _DeferredName {
+  String name;
+  _DeferredName();
+  @override
+  String toString() => name;
+}
+
+class _DartTypeToStringVisitor extends DartTypeVisitor<void, void> {
+  final List _fragments = []; // Strings and _DeferredNames
+  bool _lastIsIdentifier = false;
+  List<FunctionTypeVariable> _boundVariables;
+  Map<FunctionTypeVariable, _DeferredName> _variableToName;
+  Set<FunctionType> _genericFunctions;
+
+  String run(DartType type) {
+    _visit(type);
+    if (_variableToName != null &&
+        _variableToName.values.any((deferred) => deferred.name == null)) {
+      // Assign names to _DeferredNames that were not assigned while visiting a
+      // generic function type.
+      Set<String> usedNames =
+          _variableToName.values.map((deferred) => deferred.name).toSet();
+      int startGroup = (_genericFunctions?.length ?? 0) + 1;
+      for (var entry in _variableToName.entries) {
+        if (entry.value.name != null) continue;
+        for (int group = startGroup;; group++) {
+          String name = _functionTypeVariableName(entry.key, group);
+          if (!usedNames.add(name)) continue;
+          entry.value.name = name;
+          break;
+        }
+      }
+    }
+    return _fragments.join();
+  }
+
+  String _functionTypeVariableName(FunctionTypeVariable variable, int group) {
+    String prefix = String.fromCharCode(0x41 + variable.index);
+    String suffix = group == 1 ? '' : '$group';
+    return prefix + suffix;
+  }
+
+  void _identifier(String text) {
+    if (_lastIsIdentifier) _fragments.add(' ');
+    _fragments.add(text);
+    _lastIsIdentifier = true;
+  }
+
+  void _deferredNameIdentifier(_DeferredName name) {
+    if (_lastIsIdentifier) _fragments.add(' ');
+    _fragments.add(name);
+    _lastIsIdentifier = true;
+  }
+
+  void _token(String text) {
+    _fragments.add(text);
+    _lastIsIdentifier = false;
+  }
+
+  bool _comma(bool needsComma) {
+    if (needsComma) _token(',');
+    return true;
+  }
+
+  void _visit(DartType type) {
+    type.accept(this, null);
+  }
+
+  @override
+  void visitVoidType(covariant VoidType type, _) {
+    _identifier('void');
+  }
+
+  @override
+  void visitDynamicType(covariant DynamicType type, _) {
+    _identifier('dynamic');
+  }
+
+  @override
+  void visitTypeVariableType(covariant TypeVariableType type, _) {
+    _identifier(type.element.typeDeclaration.name);
+    _token('.');
+    _identifier(type.element.name);
+  }
+
+  _DeferredName _nameFor(FunctionTypeVariable type) {
+    _variableToName ??= Map.identity();
+    return _variableToName[type] ??= _DeferredName();
+  }
+
+  @override
+  void visitFunctionTypeVariable(covariant FunctionTypeVariable type, _) {
+    // The first letter of the variable name indicates the 'index'.  Names have
+    // suffixes corresponding to the different generic function types (A, A2,
+    // A3, etc).
+    _token('#');
+    _deferredNameIdentifier(_nameFor(type));
+    if (_boundVariables == null || !_boundVariables.contains(type)) {
+      _token('/*free*/');
+    }
+  }
+
+  @override
+  void visitFunctionType(covariant FunctionType type, _) {
+    if (type.typeVariables.isNotEmpty) {
+      // Enter function type variable scope.
+      _boundVariables ??= [];
+      _boundVariables.addAll(type.typeVariables);
+      // Assign names for the function type variables. We could have already
+      // assigned names for this node if we are printing a DAG.
+      _genericFunctions ??= Set.identity();
+      if (_genericFunctions.add(type)) {
+        int group = _genericFunctions.length;
+        for (FunctionTypeVariable variable in type.typeVariables) {
+          _DeferredName deferredName = _nameFor(variable);
+          // If there is a structural error where one FunctionTypeVariable is
+          // used in two [FunctionType]s it might already have a name.
+          deferredName.name ??= _functionTypeVariableName(variable, group);
+        }
+      }
+    }
+    _visit(type.returnType);
+    _token(' ');
+    _identifier('Function');
+    if (type.typeVariables.isNotEmpty) {
+      _token('<');
+      bool needsComma = false;
+      for (FunctionTypeVariable typeVariable in type.typeVariables) {
+        needsComma = _comma(needsComma);
+        _visit(typeVariable);
+        DartType bound = typeVariable.bound;
+        if (!bound.isObject) {
+          _token(' extends ');
+          _visit(typeVariable.bound);
+        }
+      }
+      _token('>');
+    }
+    _token('(');
+    bool needsComma = false;
+    for (DartType parameterType in type.parameterTypes) {
+      needsComma = _comma(needsComma);
+      _visit(parameterType);
+    }
+    if (type.optionalParameterTypes.isNotEmpty) {
+      needsComma = _comma(needsComma);
+      _token('[');
+      bool needsOptionalComma = false;
+      for (DartType typeArgument in type.optionalParameterTypes) {
+        needsOptionalComma = _comma(needsOptionalComma);
+        _visit(typeArgument);
+      }
+      _token(']');
+    }
+    if (type.namedParameters.isNotEmpty) {
+      needsComma = _comma(needsComma);
+      _token('{');
+      bool needsNamedComma = false;
+      for (int index = 0; index < type.namedParameters.length; index++) {
+        needsNamedComma = _comma(needsNamedComma);
+        _visit(type.namedParameterTypes[index]);
+        _token(' ');
+        _identifier(type.namedParameters[index]);
+      }
+      _token('}');
+    }
+    _token(')');
+    // Exit function type variable scope.
+    _boundVariables?.length -= type.typeVariables.length;
+  }
+
+  @override
+  void visitInterfaceType(covariant InterfaceType type, _) {
+    _identifier(type.element.name);
+    _optionalTypeArguments(type.typeArguments);
+  }
+
+  @override
+  void visitTypedefType(covariant TypedefType type, _) {
+    _identifier(type.element.name);
+    _optionalTypeArguments(type.typeArguments);
+  }
+
+  void _optionalTypeArguments(List<DartType> types) {
+    if (types.isNotEmpty) {
+      _token('<');
+      bool needsComma = false;
+      for (DartType typeArgument in types) {
+        needsComma = _comma(needsComma);
+        _visit(typeArgument);
+      }
+      _token('>');
+    }
+  }
+
+  @override
+  void visitFutureOrType(covariant FutureOrType type, _) {
+    _identifier('FutureOr');
+    _token('<');
+    _visit(type.typeArgument);
+    _token('>');
+  }
+}
+
 /// Abstract visitor for determining relations between types.
 abstract class AbstractTypeRelation<T extends DartType>
     extends BaseDartTypeVisitor<bool, T> {
diff --git a/pkg/compiler/lib/src/enqueue.dart b/pkg/compiler/lib/src/enqueue.dart
index 5dbbef9..4c06e53 100644
--- a/pkg/compiler/lib/src/enqueue.dart
+++ b/pkg/compiler/lib/src/enqueue.dart
@@ -422,6 +422,10 @@
       case TypeUseKind.TYPE_ARGUMENT:
         failedAt(CURRENT_ELEMENT_SPANNABLE, "Unexpected type use: $typeUse.");
         break;
+      case TypeUseKind.NAMED_TYPE_VARIABLE_NEW_RTI:
+        assert(type is TypeVariableType);
+        _registerNamedTypeVariableNewRti(type);
+        break;
     }
   }
 
@@ -429,6 +433,10 @@
     _worldBuilder.registerIsCheck(type);
   }
 
+  void _registerNamedTypeVariableNewRti(TypeVariableType type) {
+    _worldBuilder.registerNamedTypeVariableNewRti(type);
+  }
+
   void _registerClosurizedMember(MemberEntity element) {
     assert(element.isInstanceMember);
     applyImpact(listener.registerClosurizedMember(element),
diff --git a/pkg/compiler/lib/src/inferrer/abstract_value_domain.dart b/pkg/compiler/lib/src/inferrer/abstract_value_domain.dart
index b4ba15b..28fbbb1 100644
--- a/pkg/compiler/lib/src/inferrer/abstract_value_domain.dart
+++ b/pkg/compiler/lib/src/inferrer/abstract_value_domain.dart
@@ -207,7 +207,7 @@
   /// reasoning, for example, that a dominating check uses the same type
   /// expression.
   AbstractValueWithPrecision createFromStaticType(DartType type,
-      [ClassRelation classRelation = ClassRelation.subtype]);
+      {ClassRelation classRelation = ClassRelation.subtype, bool nullable});
 
   /// Creates an [AbstractValue] for a non-null exact instance of [cls].
   AbstractValue createNonNullExact(ClassEntity cls);
diff --git a/pkg/compiler/lib/src/inferrer/trivial.dart b/pkg/compiler/lib/src/inferrer/trivial.dart
index 218962b..07c10d4 100644
--- a/pkg/compiler/lib/src/inferrer/trivial.dart
+++ b/pkg/compiler/lib/src/inferrer/trivial.dart
@@ -360,8 +360,11 @@
 
   @override
   AbstractValueWithPrecision createFromStaticType(DartType type,
-          [ClassRelation classRelation = ClassRelation.subtype]) =>
-      const AbstractValueWithPrecision(const TrivialAbstractValue(), false);
+      {ClassRelation classRelation = ClassRelation.subtype, bool nullable}) {
+    assert(nullable != null);
+    return const AbstractValueWithPrecision(
+        const TrivialAbstractValue(), false);
+  }
 
   @override
   AbstractValue get asyncStarStreamType => const TrivialAbstractValue();
diff --git a/pkg/compiler/lib/src/inferrer/typemasks/masks.dart b/pkg/compiler/lib/src/inferrer/typemasks/masks.dart
index a24356a..d7717bf 100644
--- a/pkg/compiler/lib/src/inferrer/typemasks/masks.dart
+++ b/pkg/compiler/lib/src/inferrer/typemasks/masks.dart
@@ -265,7 +265,13 @@
 
   @override
   AbstractValueWithPrecision createFromStaticType(DartType type,
-      [ClassRelation classRelation = ClassRelation.subtype]) {
+      {ClassRelation classRelation = ClassRelation.subtype, bool nullable}) {
+    assert(nullable != null);
+    AbstractValueWithPrecision finish(TypeMask value, bool isPrecise) {
+      return AbstractValueWithPrecision(
+          nullable ? value : value.nonNullable(), isPrecise);
+    }
+
     bool isPrecise = true;
     while (type is TypeVariableType) {
       TypeVariableType typeVariable = type;
@@ -274,6 +280,7 @@
       classRelation = ClassRelation.subtype;
       isPrecise = false;
     }
+
     if (type is InterfaceType) {
       if (isPrecise) {
         // TODO(sra): Could be precise if instantiated-to-bounds.
@@ -284,24 +291,24 @@
       }
       switch (classRelation) {
         case ClassRelation.exact:
-          return AbstractValueWithPrecision(
-              TypeMask.exact(type.element, _closedWorld), isPrecise);
+          return finish(TypeMask.exact(type.element, _closedWorld), isPrecise);
         case ClassRelation.thisExpression:
           if (!_closedWorld.isUsedAsMixin(type.element)) {
-            return AbstractValueWithPrecision(
+            return finish(
                 TypeMask.subclass(type.element, _closedWorld), isPrecise);
           }
           break;
         case ClassRelation.subtype:
           break;
       }
-      return AbstractValueWithPrecision(
-          TypeMask.subtype(type.element, _closedWorld), isPrecise);
+      return finish(TypeMask.subtype(type.element, _closedWorld), isPrecise);
     } else if (type is FunctionType) {
-      return AbstractValueWithPrecision(
+      return finish(
           TypeMask.subtype(commonElements.functionClass, _closedWorld), false);
+    } else if (type is DynamicType) {
+      return AbstractValueWithPrecision(dynamicType, true);
     } else {
-      return AbstractValueWithPrecision(dynamicType, false);
+      return finish(dynamicType, false);
     }
   }
 
diff --git a/pkg/compiler/lib/src/js_backend/backend_impact.dart b/pkg/compiler/lib/src/js_backend/backend_impact.dart
index 50f7e16..7742425 100644
--- a/pkg/compiler/lib/src/js_backend/backend_impact.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_impact.dart
@@ -760,8 +760,15 @@
       _genericInstantiation[typeArgumentCount] ??=
           new BackendImpact(staticUses: [
         _commonElements.getInstantiateFunction(typeArgumentCount),
-        _commonElements.instantiatedGenericFunctionType,
-        _commonElements.extractFunctionTypeObjectFromInternal,
+        ..._newRti
+            ? [
+                _commonElements.instantiatedGenericFunctionTypeNewRti,
+                _commonElements.closureFunctionType
+              ]
+            : [
+                _commonElements.instantiatedGenericFunctionType,
+                _commonElements.extractFunctionTypeObjectFromInternal
+              ],
       ], instantiatedClasses: [
         _commonElements.getInstantiationClass(typeArgumentCount),
       ]);
@@ -774,6 +781,8 @@
       BackendImpact(staticUses: [
         _commonElements.findType,
         _commonElements.instanceType,
+        _commonElements.arrayInstanceType,
+        _commonElements.simpleInstanceType,
         _commonElements.rtiEvalMethod,
         _commonElements.rtiBindMethod,
         _commonElements.generalIsTestImplementation,
diff --git a/pkg/compiler/lib/src/js_backend/codegen_listener.dart b/pkg/compiler/lib/src/js_backend/codegen_listener.dart
index f8554ec..62e9fa0 100644
--- a/pkg/compiler/lib/src/js_backend/codegen_listener.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen_listener.dart
@@ -181,12 +181,21 @@
       impactBuilder.registerTypeUse(new TypeUse.instantiation(
           _elementEnvironment.getThisType(_commonElements
               .getInstantiationClass(constant.typeArguments.length))));
-      impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
-          _commonElements.instantiatedGenericFunctionType,
-          CallStructure.TWO_ARGS));
-      impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
-          _commonElements.extractFunctionTypeObjectFromInternal,
-          CallStructure.ONE_ARG));
+
+      if (_options.experimentNewRti) {
+        impactBuilder.registerStaticUse(StaticUse.staticInvoke(
+            _commonElements.instantiatedGenericFunctionTypeNewRti,
+            CallStructure.TWO_ARGS));
+        impactBuilder.registerStaticUse(StaticUse.staticInvoke(
+            _commonElements.closureFunctionType, CallStructure.ONE_ARG));
+      } else {
+        impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
+            _commonElements.instantiatedGenericFunctionType,
+            CallStructure.TWO_ARGS));
+        impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
+            _commonElements.extractFunctionTypeObjectFromInternal,
+            CallStructure.ONE_ARG));
+      }
     }
   }
 
diff --git a/pkg/compiler/lib/src/js_backend/enqueuer.dart b/pkg/compiler/lib/src/js_backend/enqueuer.dart
index 4e2c957..77dceec 100644
--- a/pkg/compiler/lib/src/js_backend/enqueuer.dart
+++ b/pkg/compiler/lib/src/js_backend/enqueuer.dart
@@ -226,6 +226,10 @@
         break;
       case TypeUseKind.CONST_INSTANTIATION:
         failedAt(CURRENT_ELEMENT_SPANNABLE, "Unexpected type use: $typeUse.");
+        break;
+      case TypeUseKind.NAMED_TYPE_VARIABLE_NEW_RTI:
+        assert(type is TypeVariableType);
+        _registerNamedTypeVariableNewRti(type);
     }
   }
 
@@ -243,6 +247,10 @@
     _worldBuilder.registerIsCheck(type);
   }
 
+  void _registerNamedTypeVariableNewRti(TypeVariableType type) {
+    _worldBuilder.registerNamedTypeVariableNewRti(type);
+  }
+
   void _registerClosurizedMember(FunctionEntity element) {
     assert(element.isInstanceMember);
     applyImpact(listener.registerClosurizedMember(element));
diff --git a/pkg/compiler/lib/src/js_backend/impact_transformer.dart b/pkg/compiler/lib/src/js_backend/impact_transformer.dart
index c684fb7..7c2177a 100644
--- a/pkg/compiler/lib/src/js_backend/impact_transformer.dart
+++ b/pkg/compiler/lib/src/js_backend/impact_transformer.dart
@@ -204,6 +204,7 @@
           break;
         case TypeUseKind.RTI_VALUE:
         case TypeUseKind.TYPE_ARGUMENT:
+        case TypeUseKind.NAMED_TYPE_VARIABLE_NEW_RTI:
           failedAt(CURRENT_ELEMENT_SPANNABLE, "Unexpected type use: $typeUse.");
           break;
       }
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types_new.dart b/pkg/compiler/lib/src/js_backend/runtime_types_new.dart
index 426d5b9..c544c21 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types_new.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types_new.dart
@@ -21,10 +21,17 @@
 import 'runtime_types_codegen.dart' show RuntimeTypesSubstitutions;
 import 'runtime_types_resolution.dart' show RuntimeTypesNeed;
 
+class RecipeEncoding {
+  final jsAst.Literal recipe;
+  final Set<TypeVariableType> typeVariables;
+
+  const RecipeEncoding(this.recipe, this.typeVariables);
+}
+
 abstract class RecipeEncoder {
-  /// Returns a [jsAst.Literal] representing the given [recipe] to be
+  /// Returns a [RecipeEncoding] representing the given [recipe] to be
   /// evaluated against a type environment with shape [structure].
-  jsAst.Literal encodeRecipe(ModularEmitter emitter,
+  RecipeEncoding encodeRecipe(ModularEmitter emitter,
       TypeEnvironmentStructure environmentStructure, TypeRecipe recipe);
 
   jsAst.Literal encodeGroundRecipe(ModularEmitter emitter, TypeRecipe recipe);
@@ -67,14 +74,14 @@
       this._elementEnvironment, this.commonElements, this._rtiNeed);
 
   @override
-  jsAst.Literal encodeRecipe(ModularEmitter emitter,
+  RecipeEncoding encodeRecipe(ModularEmitter emitter,
       TypeEnvironmentStructure environmentStructure, TypeRecipe recipe) {
     return _RecipeGenerator(this, emitter, environmentStructure, recipe).run();
   }
 
   @override
   jsAst.Literal encodeGroundRecipe(ModularEmitter emitter, TypeRecipe recipe) {
-    return _RecipeGenerator(this, emitter, null, recipe).run();
+    return _RecipeGenerator(this, emitter, null, recipe).run().recipe;
   }
 
   @override
@@ -82,7 +89,8 @@
       ModularEmitter emitter, DartType dartType) {
     return _RecipeGenerator(this, emitter, null, TypeExpressionRecipe(dartType),
             hackTypeVariablesToAny: true)
-        .run();
+        .run()
+        .recipe;
   }
 
   @override
@@ -94,7 +102,8 @@
             FullTypeEnvironmentStructure(classType: declaringType),
             TypeExpressionRecipe(supertypeArgument),
             indexTypeVariablesOnDeclaringClass: true)
-        .run();
+        .run()
+        .recipe;
   }
 
   @override
@@ -125,6 +134,7 @@
   final bool hackTypeVariablesToAny;
 
   final List<FunctionTypeVariable> functionTypeVariables = [];
+  final Set<TypeVariableType> typeVariables = {};
 
   // Accumulated recipe.
   final List<jsAst.Literal> _fragments = [];
@@ -139,15 +149,19 @@
   NativeBasicData get _nativeData => _encoder._nativeData;
   RuntimeTypesSubstitutions get _rtiSubstitutions => _encoder._rtiSubstitutions;
 
-  jsAst.Literal run() {
+  RecipeEncoding _finishEncoding(jsAst.Literal literal) =>
+      RecipeEncoding(literal, typeVariables);
+
+  RecipeEncoding run() {
     _start(_recipe);
     assert(functionTypeVariables.isEmpty);
     if (_fragments.isEmpty) {
-      return js.string(String.fromCharCodes(_codes));
+      return _finishEncoding(js.string(String.fromCharCodes(_codes)));
     }
     _flushCodes();
     jsAst.LiteralString quote = jsAst.LiteralString('"');
-    return jsAst.StringConcatenation([quote, ..._fragments, quote]);
+    return _finishEncoding(
+        jsAst.StringConcatenation([quote, ..._fragments, quote]));
   }
 
   void _start(TypeRecipe recipe) {
@@ -261,6 +275,7 @@
       }
       jsAst.Name name = _emitter.typeVariableAccessNewRti(type.element);
       _emitName(name);
+      typeVariables.add(type);
       return;
     }
     // TODO(sra): Handle missing cases. This just emits some readable junk. The
@@ -286,8 +301,12 @@
 
     if (_closedWorld.isUsedAsMixin(cls)) return null;
 
+    // TODO(fishythefish): We should only check strict subclasses for
+    // non-trivial substitutions in the general case. We should check all strict
+    // subtypes only when [cls] is a mixin (above) or when [cls] is a type
+    // argument to `extractTypeArguments`.
     ClassHierarchy classHierarchy = _closedWorld.classHierarchy;
-    if (classHierarchy.anyStrictSubclassOf(cls, (ClassEntity subclass) {
+    if (classHierarchy.anyStrictSubtypeOf(cls, (ClassEntity subclass) {
       return !_rtiSubstitutions.isTrivialSubstitution(subclass, cls);
     })) {
       return null;
@@ -449,9 +468,10 @@
 class _RulesetEntry {
   final InterfaceType _targetType;
   List<InterfaceType> _supertypes;
-  Map<TypeVariableType, DartType> _typeVariables = {};
+  Map<TypeVariableType, DartType> _typeVariables;
 
-  _RulesetEntry(this._targetType, Iterable<InterfaceType> supertypes)
+  _RulesetEntry(
+      this._targetType, Iterable<InterfaceType> supertypes, this._typeVariables)
       : _supertypes = supertypes.toList();
 
   bool get isEmpty => _supertypes.isEmpty && _typeVariables.isEmpty;
@@ -463,8 +483,9 @@
   Ruleset(this._entries);
   Ruleset.empty() : this([]);
 
-  void add(InterfaceType targetType, Iterable<InterfaceType> supertypes) =>
-      _entries.add(_RulesetEntry(targetType, supertypes));
+  void add(InterfaceType targetType, Iterable<InterfaceType> supertypes,
+          Map<TypeVariableType, DartType> typeVariables) =>
+      _entries.add(_RulesetEntry(targetType, supertypes, typeVariables));
 }
 
 class RulesetEncoder {
@@ -487,23 +508,9 @@
 
   bool _isObject(InterfaceType type) => identical(type.element, _objectClass);
 
-  void _preprocessSupertype(_RulesetEntry entry, InterfaceType supertype) {
-    InterfaceType thisSupertype = _dartTypes.getThisType(supertype.element);
-    List<DartType> typeVariables = thisSupertype.typeArguments;
-    List<DartType> supertypeArguments = supertype.typeArguments;
-    int length = typeVariables.length;
-    assert(supertypeArguments.length == length);
-    for (int i = 0; i < length; i++) {
-      entry._typeVariables[typeVariables[i]] = supertypeArguments[i];
-    }
-  }
-
   void _preprocessEntry(_RulesetEntry entry) {
-    entry._supertypes.removeWhere(_isObject);
-    entry._supertypes.forEach(
-        (InterfaceType supertype) => _preprocessSupertype(entry, supertype));
-    entry._supertypes.removeWhere(
-        (InterfaceType supertype) => identical(entry._targetType, supertype));
+    entry._supertypes.removeWhere((InterfaceType supertype) =>
+        _isObject(supertype) || identical(entry._targetType, supertype));
   }
 
   void _preprocessRuleset(Ruleset ruleset) {
diff --git a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
index 58e2b6c..5bdac89 100644
--- a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
+++ b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
@@ -15,6 +15,7 @@
 import '../js_backend/inferred_data.dart';
 import '../js_backend/namer.dart' show Namer;
 import '../js_model/js_strategy.dart';
+import '../options.dart';
 import '../universe/codegen_world_builder.dart';
 import '../world.dart' show JClosedWorld;
 import 'program_builder/program_builder.dart';
@@ -39,6 +40,8 @@
 
   JsBackendStrategy get _backendStrategy => _compiler.backendStrategy;
 
+  CompilerOptions get options => _compiler.options;
+
   @deprecated
   // This field should be removed. It's currently only needed for dump-info and
   // tests.
diff --git a/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart
index 7a13db6..4e5547f 100644
--- a/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart
@@ -10,6 +10,7 @@
 import '../js/js.dart' as jsAst;
 import '../js/js.dart' show js;
 import '../js_backend/namer.dart' show Namer;
+import '../options.dart';
 import '../universe/call_structure.dart' show CallStructure;
 import '../universe/codegen_world_builder.dart';
 import '../universe/selector.dart' show Selector;
@@ -38,6 +39,8 @@
   JElementEnvironment get _elementEnvironment =>
       _closedWorld.elementEnvironment;
 
+  CompilerOptions get _options => _emitterTask.options;
+
   /// Generates a stub to forward a call selector with no type arguments to a
   /// call selector with stored types.
   ///
@@ -78,8 +81,18 @@
       parameters.add(new jsAst.Parameter(jsName));
     }
 
-    for (int i = 0; i < targetSelector.typeArgumentCount; i++) {
-      arguments.add(js('this.#[#]', [_namer.rtiFieldJsName, js.number(i)]));
+    if (_options.experimentNewRti) {
+      for (int i = 0; i < targetSelector.typeArgumentCount; i++) {
+        arguments.add(js('this.#.#[#]', [
+          _namer.rtiFieldJsName,
+          _namer.fieldPropertyName(_commonElements.rtiRestField),
+          js.number(i)
+        ]));
+      }
+    } else {
+      for (int i = 0; i < targetSelector.typeArgumentCount; i++) {
+        arguments.add(js('this.#[#]', [_namer.rtiFieldJsName, js.number(i)]));
+      }
     }
 
     jsAst.Fun function = js('function(#) { return this.#.#(#); }', [
@@ -109,20 +122,35 @@
     jsAst.Name operatorSignature =
         _namer.asName(_namer.fixedNames.operatorSignature);
 
-    jsAst.Fun function = js('function() { return #(#(this.#), this.#); }', [
-      _emitter.staticFunctionAccess(
-          _commonElements.instantiatedGenericFunctionType),
-      _emitter.staticFunctionAccess(
-          _commonElements.extractFunctionTypeObjectFromInternal),
-      _namer.fieldPropertyName(functionField),
-      _namer.rtiFieldJsName,
-    ]);
+    jsAst.Fun function = _options.experimentNewRti
+        ? _generateSignatureNewRti(functionField)
+        : _generateSignatureLegacy(functionField);
+
     // TODO(sra): Generate source information for stub that has no member.
     // TODO(sra): .withSourceInformation(sourceInformation);
 
     return new ParameterStubMethod(operatorSignature, null, function);
   }
 
+  jsAst.Fun _generateSignatureLegacy(FieldEntity functionField) =>
+      js('function() { return #(#(this.#), this.#); }', [
+        _emitter.staticFunctionAccess(
+            _commonElements.instantiatedGenericFunctionType),
+        _emitter.staticFunctionAccess(
+            _commonElements.extractFunctionTypeObjectFromInternal),
+        _namer.fieldPropertyName(functionField),
+        _namer.rtiFieldJsName,
+      ]);
+
+  jsAst.Fun _generateSignatureNewRti(FieldEntity functionField) =>
+      js('function() { return #(#(this.#), this.#); }', [
+        _emitter.staticFunctionAccess(
+            _commonElements.instantiatedGenericFunctionTypeNewRti),
+        _emitter.staticFunctionAccess(_commonElements.closureFunctionType),
+        _namer.fieldPropertyName(functionField),
+        _namer.rtiFieldJsName,
+      ]);
+
   // Returns all stubs for an instantiation class.
   //
   List<StubMethod> generateStubs(
diff --git a/pkg/compiler/lib/src/js_emitter/model.dart b/pkg/compiler/lib/src/js_emitter/model.dart
index c43eebb..ab1ee4f 100644
--- a/pkg/compiler/lib/src/js_emitter/model.dart
+++ b/pkg/compiler/lib/src/js_emitter/model.dart
@@ -7,6 +7,7 @@
 import '../constants/values.dart' show ConstantValue;
 import '../deferred_load.dart' show OutputUnit;
 import '../elements/entities.dart';
+import '../elements/types.dart';
 import '../js/js.dart' as js show Expression, Name, Statement, TokenFinalizer;
 import '../js/js_debug.dart' as js show nodeToString;
 import '../js_backend/runtime_types_codegen.dart';
@@ -233,6 +234,7 @@
   }
 }
 
+// TODO(fishythefish, sra): Split type information into separate model object.
 class Class implements FieldContainer {
   /// The element should only be used during the transition to the new model.
   /// Uses indicate missing information in the model.
@@ -246,6 +248,7 @@
   final List<Field> fields;
   final List<StubMethod> isChecks;
   final ClassChecks classChecksNewRti;
+  final Set<TypeVariableType> namedTypeVariablesNewRti = {};
   final List<StubMethod> checkedSetters;
 
   /// Stub methods for this class that are call stubs for getters.
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
index e9decf2..e5a9ca3 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
@@ -28,13 +28,15 @@
 import '../../js_backend/native_data.dart';
 import '../../js_backend/runtime_types.dart'
     show RuntimeTypesChecks, RuntimeTypesEncoder;
-import '../../js_backend/runtime_types_new.dart' show RecipeEncoder;
+import '../../js_backend/runtime_types_new.dart'
+    show RecipeEncoder, RecipeEncoding;
 import '../../js_backend/runtime_types_resolution.dart' show RuntimeTypesNeed;
 import '../../js_model/elements.dart' show JGeneratorBody, JSignatureMethod;
 import '../../js_model/type_recipe.dart'
     show FullTypeEnvironmentStructure, TypeExpressionRecipe;
 import '../../native/enqueue.dart' show NativeCodegenEnqueuer;
 import '../../options.dart';
+import '../../universe/class_hierarchy.dart';
 import '../../universe/codegen_world_builder.dart';
 import '../../universe/selector.dart' show Selector;
 import '../../universe/world_builder.dart' show SelectorConstraints;
@@ -102,6 +104,10 @@
   /// True if the program should store function types in the metadata.
   bool _storeFunctionTypesInMetadata = false;
 
+  final Set<TypeVariableType> _lateNamedTypeVariablesNewRti = {};
+
+  ClassHierarchy get _classHierarchy => _closedWorld.classHierarchy;
+
   ProgramBuilder(
       this._options,
       this._reporter,
@@ -241,6 +247,10 @@
 
     _markEagerClasses();
 
+    if (_options.experimentNewRti) {
+      associateNamedTypeVariablesNewRti();
+    }
+
     List<Holder> holders = _registry.holders.toList(growable: false);
 
     bool needsNativeSupport =
@@ -838,6 +848,18 @@
     return result;
   }
 
+  void associateNamedTypeVariablesNewRti() {
+    for (TypeVariableType typeVariable in _codegenWorld.namedTypeVariablesNewRti
+        .union(_lateNamedTypeVariablesNewRti)) {
+      for (ClassEntity entity
+          in _classHierarchy.subtypesOf(typeVariable.element.typeDeclaration)) {
+        Class cls = _classes[entity];
+        if (cls == null) continue;
+        cls.namedTypeVariablesNewRti.add(typeVariable);
+      }
+    }
+  }
+
   bool _methodNeedsStubs(FunctionEntity method) {
     if (method is JGeneratorBody) return false;
     if (method is ConstructorBodyEntity) return false;
@@ -962,13 +984,13 @@
       FunctionType type, OutputUnit outputUnit) {
     if (type.containsTypeVariables) {
       if (_options.experimentNewRti) {
-        // TODO(sra): The recipe might reference class type variables. Collect
-        // these for the type metadata.
-        return _rtiRecipeEncoder.encodeRecipe(
+        RecipeEncoding encoding = _rtiRecipeEncoder.encodeRecipe(
             _task.emitter,
             FullTypeEnvironmentStructure(
                 classType: _elementEnvironment.getThisType(enclosingClass)),
             TypeExpressionRecipe(type));
+        _lateNamedTypeVariablesNewRti.addAll(encoding.typeVariables);
+        return encoding.recipe;
       } else {
         js.Expression thisAccess = js.js(r'this.$receiver');
         return _rtiEncoder.getSignatureEncoding(
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
index 5882777..adf8d1c 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
@@ -1950,7 +1950,15 @@
       InterfaceType targetType = _elementEnvironment.getThisType(cls.element);
       Iterable<InterfaceType> supertypes = cls.classChecksNewRti.checks.map(
           (TypeCheck check) => _dartTypes.asInstanceOf(targetType, check.cls));
-      ruleset.add(targetType, supertypes);
+      Map<TypeVariableType, DartType> typeVariables = {};
+      for (TypeVariableType typeVariable in cls.namedTypeVariablesNewRti) {
+        TypeVariableEntity element = typeVariable.element;
+        InterfaceType supertype =
+            _dartTypes.asInstanceOf(targetType, element.typeDeclaration);
+        List<DartType> supertypeArguments = supertype.typeArguments;
+        typeVariables[typeVariable] = supertypeArguments[element.index];
+      }
+      ruleset.add(targetType, supertypes, typeVariables);
     });
 
     FunctionEntity method = _closedWorld.commonElements.rtiAddRulesMethod;
diff --git a/pkg/compiler/lib/src/kernel/kernel_world.dart b/pkg/compiler/lib/src/kernel/kernel_world.dart
index f9b990d..f7fab57 100644
--- a/pkg/compiler/lib/src/kernel/kernel_world.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_world.dart
@@ -79,6 +79,9 @@
   @override
   final Set<DartType> isChecks;
 
+  @override
+  final Set<TypeVariableType> namedTypeVariablesNewRti;
+
   final Map<Entity, Set<DartType>> staticTypeArgumentDependencies;
 
   final Map<Selector, Set<DartType>> dynamicTypeArgumentDependencies;
@@ -122,6 +125,7 @@
       this.classHierarchy,
       this.annotationsData,
       this.isChecks,
+      this.namedTypeVariablesNewRti,
       this.staticTypeArgumentDependencies,
       this.dynamicTypeArgumentDependencies,
       this.typeVariableTypeLiterals,
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index a7fea25..af985cd 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -39,6 +39,7 @@
 import '../js_model/elements.dart' show JGeneratorBody;
 import '../js_model/element_map.dart';
 import '../js_model/js_strategy.dart';
+import '../js_model/type_recipe.dart';
 import '../kernel/invocation_mirror_constants.dart';
 import '../native/behavior.dart';
 import '../native/js.dart';
@@ -4038,14 +4039,32 @@
     List<HInstruction> inputs = <HInstruction>[closure];
     List<DartType> typeArguments = <DartType>[];
 
-    thisType.typeArguments.forEach((_typeVariable) {
-      TypeVariableType variable = _typeVariable;
-      typeArguments.add(variable);
-      HInstruction readType = new HTypeInfoReadVariable.intercepted(
-          variable, interceptor, object, _abstractValueDomain.dynamicType);
-      add(readType);
-      inputs.add(readType);
-    });
+    if (options.experimentNewRti) {
+      HInstruction instanceType =
+          HInstanceEnvironment(object, _abstractValueDomain.dynamicType);
+      add(instanceType);
+      TypeEnvironmentStructure envStructure =
+          FullTypeEnvironmentStructure(classType: thisType);
+
+      thisType.typeArguments.forEach((_typeVariable) {
+        TypeVariableType variable = _typeVariable;
+        typeArguments.add(variable);
+        TypeRecipe recipe = TypeExpressionRecipe(variable);
+        HInstruction typeEval = new HTypeEval(instanceType, envStructure,
+            recipe, _abstractValueDomain.dynamicType);
+        add(typeEval);
+        inputs.add(typeEval);
+      });
+    } else {
+      thisType.typeArguments.forEach((_typeVariable) {
+        TypeVariableType variable = _typeVariable;
+        typeArguments.add(variable);
+        HInstruction readType = new HTypeInfoReadVariable.intercepted(
+            variable, interceptor, object, _abstractValueDomain.dynamicType);
+        add(readType);
+        inputs.add(readType);
+      });
+    }
 
     // TODO(sra): In compliance mode, insert a check that [closure] is a
     // function of N type arguments.
@@ -4055,8 +4074,8 @@
     StaticType receiverStaticType =
         _getStaticType(invocation.arguments.positional[1]);
     AbstractValue receiverType = _abstractValueDomain
-        .createFromStaticType(
-            receiverStaticType.type, receiverStaticType.relation)
+        .createFromStaticType(receiverStaticType.type,
+            classRelation: receiverStaticType.relation, nullable: true)
         .abstractValue;
     push(new HInvokeClosure(selector, receiverType, inputs,
         _abstractValueDomain.dynamicType, typeArguments));
@@ -4811,8 +4830,8 @@
       List<DartType> typeArguments,
       SourceInformation sourceInformation) {
     AbstractValue typeBound = _abstractValueDomain
-        .createFromStaticType(
-            staticReceiverType.type, staticReceiverType.relation)
+        .createFromStaticType(staticReceiverType.type,
+            classRelation: staticReceiverType.relation, nullable: true)
         .abstractValue;
     receiverType = receiverType == null
         ? typeBound
@@ -5404,7 +5423,11 @@
     if (options.experimentNewRti) {
       HInstruction rti =
           _typeBuilder.analyzeTypeArgumentNewRti(typeValue, sourceElement);
-      push(HIsTest(typeValue, expression, rti, _abstractValueDomain.boolType));
+      AbstractValueWithPrecision checkedType =
+          _abstractValueDomain.createFromStaticType(typeValue, nullable: false);
+
+      push(HIsTest(typeValue, checkedType, expression, rti,
+          _abstractValueDomain.boolType));
       return;
     }
 
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index 4dfc69b..7147b77 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -27,7 +27,8 @@
 import '../js_backend/namer.dart' show ModularNamer;
 import '../js_backend/runtime_types.dart';
 import '../js_backend/runtime_types_codegen.dart';
-import '../js_backend/runtime_types_new.dart' show RecipeEncoder;
+import '../js_backend/runtime_types_new.dart'
+    show RecipeEncoder, RecipeEncoding;
 import '../js_emitter/code_emitter_task.dart' show ModularEmitter;
 import '../js_model/elements.dart' show JGeneratorBody;
 import '../js_model/type_recipe.dart' show TypeExpressionRecipe;
@@ -3404,18 +3405,63 @@
 
   @override
   visitInstanceEnvironment(HInstanceEnvironment node) {
-    use(node.inputs.single);
+    HInstruction input = node.inputs.single;
+    use(input);
     js.Expression receiver = pop();
-    // TODO(sra): Optimize to direct field access where possible.
-    //
-    //    push(js.js(r'#.#', [receiver, _namer.rtiFieldJsName]));
 
-    FunctionEntity helperElement = _commonElements.instanceType;
-    _registry.registerStaticUse(
-        new StaticUse.staticInvoke(helperElement, CallStructure.ONE_ARG));
-    js.Expression helper = _emitter.staticFunctionAccess(helperElement);
-    push(js.js(r'#(#)', [helper, receiver]).withSourceInformation(
-        node.sourceInformation));
+    void useRtiField() {
+      push(js.js(r'#.#', [receiver, _namer.rtiFieldJsName]));
+    }
+
+    void useHelper(FunctionEntity helper) {
+      _registry.registerStaticUse(
+          new StaticUse.staticInvoke(helper, CallStructure.ONE_ARG));
+      js.Expression helperAccess = _emitter.staticFunctionAccess(helper);
+      push(js.js(r'#(#)', [helperAccess, receiver]).withSourceInformation(
+          node.sourceInformation));
+    }
+
+    // Try to use the 'rti' field, or a specialization of 'instanceType'.
+    AbstractValue receiverMask = input.instructionType;
+
+    AbstractBool isArray = _abstractValueDomain.isInstanceOf(
+        receiverMask, _commonElements.jsArrayClass);
+
+    if (isArray.isDefinitelyTrue) {
+      useHelper(_commonElements.arrayInstanceType);
+      return;
+    }
+
+    if (isArray.isDefinitelyFalse) {
+      // See if the receiver type narrows the set of classes to ones that all
+      // have a stored type field.
+      // TODO(sra): Currently the only convenient query is [getExactClass]. We
+      // should have a (cached) query to iterate over all the concrete classes
+      // in [receiverMask].
+      // TODO(sra): Store the context class on the HInstanceEnvironment. This
+      // would allow the subtype classes to be iterated.
+      ClassEntity receiverClass =
+          _abstractValueDomain.getExactClass(receiverMask);
+      if (receiverClass != null) {
+        if (_closedWorld.rtiNeed.classNeedsTypeArguments(receiverClass)) {
+          useRtiField();
+          return;
+        }
+      }
+
+      // If the type is not intercepted and is not a closure, use the 'simple'
+      // helper.
+      if (_abstractValueDomain.isInterceptor(receiverMask).isDefinitelyFalse) {
+        if (_abstractValueDomain
+            .isInstanceOf(receiverMask, _commonElements.closureClass)
+            .isDefinitelyFalse) {
+          useHelper(_commonElements.simpleInstanceType);
+          return;
+        }
+      }
+    }
+
+    useHelper(_commonElements.instanceType);
   }
 
   @override
@@ -3423,8 +3469,15 @@
     // Call `env._eval("recipe")`.
     use(node.inputs[0]);
     js.Expression environment = pop();
-    js.Expression recipe = _rtiRecipeEncoder.encodeRecipe(
+    RecipeEncoding encoding = _rtiRecipeEncoder.encodeRecipe(
         _emitter, node.envStructure, node.typeExpression);
+    js.Expression recipe = encoding.recipe;
+
+    for (TypeVariableType typeVariable in encoding.typeVariables) {
+      // TODO(fishythefish): Constraint the type variable to only be emitted on
+      // (subtypes of) the environment type.
+      _registry.registerTypeUse(TypeUse.namedTypeVariableNewRti(typeVariable));
+    }
 
     MemberEntity method = _commonElements.rtiEvalMethod;
     Selector selector = Selector.fromElement(method);
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index 89a7adf..495f629 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -4352,10 +4352,11 @@
 /// lowered to other instructions, so this instruction remains for types that
 /// depend on type variables and complex types.
 class HIsTest extends HInstruction {
+  final AbstractValueWithPrecision checkedAbstractValue;
   final DartType dartType;
 
-  HIsTest(
-      this.dartType, HInstruction checked, HInstruction rti, AbstractValue type)
+  HIsTest(this.dartType, this.checkedAbstractValue, HInstruction checked,
+      HInstruction rti, AbstractValue type)
       : super([rti, checked], type) {
     setUseGvn();
   }
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index ee39ddb..8eb2043 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -761,7 +761,9 @@
             _closedWorld.elementEnvironment.getFieldType(field);
         HInstruction closureCall = new HInvokeClosure(
             callSelector,
-            _abstractValueDomain.createFromStaticType(fieldType).abstractValue,
+            _abstractValueDomain
+                .createFromStaticType(fieldType, nullable: true)
+                .abstractValue,
             inputs,
             node.instructionType,
             node.typeArguments)
@@ -1333,41 +1335,64 @@
     // Use `node.inputs.last` in case the call follows the interceptor calling
     // convention, but is not a call on an interceptor.
     HInstruction value = node.inputs.last;
-    if (_closedWorld.annotationsData.getParameterCheckPolicy(field).isEmitted) {
-      if (_options.experimentNewRti) {
-        // TODO(sra): Implement inlining of setters with checks for new rti.
-        node.needsCheck = true;
-        return node;
-      }
-      DartType type = _closedWorld.elementEnvironment.getFieldType(field);
-      if (!type.treatAsRaw ||
-          type.isTypeVariable ||
-          type.unaliased.isFunctionType ||
-          type.unaliased.isFutureOr) {
-        // We cannot generate the correct type representation here, so don't
-        // inline this access.
-        // TODO(sra): If the input is such that we don't need a type check, we
-        // can skip the test an generate the HFieldSet.
-        node.needsCheck = true;
-        return node;
-      }
-      HInstruction other =
-          value.convertType(_closedWorld, type, HTypeConversion.TYPE_CHECK);
-      if (other != value) {
-        node.block.addBefore(node, other);
-        value = other;
+
+    HInstruction assignField() {
+      if (_closedWorld.fieldAnalysis.getFieldData(field).isElided) {
+        _log?.registerFieldSet(node);
+        return value;
+      } else {
+        HFieldSet result =
+            new HFieldSet(_abstractValueDomain, field, receiver, value)
+              ..sourceInformation = node.sourceInformation;
+        _log?.registerFieldSet(node, result);
+        return result;
       }
     }
-    if (_closedWorld.fieldAnalysis.getFieldData(field).isElided) {
-      _log?.registerFieldSet(node);
-      return value;
-    } else {
-      HFieldSet result =
-          new HFieldSet(_abstractValueDomain, field, receiver, value)
-            ..sourceInformation = node.sourceInformation;
-      _log?.registerFieldSet(node, result);
-      return result;
+
+    if (!_closedWorld.annotationsData
+        .getParameterCheckPolicy(field)
+        .isEmitted) {
+      return assignField();
     }
+
+    DartType fieldType = _closedWorld.elementEnvironment.getFieldType(field);
+
+    if (_options.experimentNewRti) {
+      AbstractValueWithPrecision checkedType =
+          _abstractValueDomain.createFromStaticType(fieldType, nullable: true);
+      if (checkedType.isPrecise &&
+          _abstractValueDomain
+              .isIn(value.instructionType, checkedType.abstractValue)
+              .isDefinitelyTrue) {
+        return assignField();
+      }
+      // TODO(sra): Implement inlining of setters with checks for new rti. The
+      // check and field assignmeny for the setter should inlined if this is the
+      // only call to the setter, or the current function already computes the
+      // type of the field.
+      node.needsCheck = true;
+      return node;
+    }
+
+    if (!fieldType.treatAsRaw ||
+        fieldType.isTypeVariable ||
+        fieldType.unaliased.isFunctionType ||
+        fieldType.unaliased.isFutureOr) {
+      // We cannot generate the correct type representation here, so don't
+      // inline this access.
+      // TODO(sra): If the input is such that we don't need a type check, we
+      // can skip the test an generate the HFieldSet.
+      node.needsCheck = true;
+      return node;
+    }
+    HInstruction other =
+        value.convertType(_closedWorld, fieldType, HTypeConversion.TYPE_CHECK);
+    if (other != value) {
+      node.block.addBefore(node, other);
+      value = other;
+    }
+
+    return assignField();
   }
 
   @override
@@ -1877,7 +1902,7 @@
           dartType, node.isTypeError, _closedWorld.commonElements);
       if (specializedCheck != null) {
         AbstractValueWithPrecision checkedType =
-            _abstractValueDomain.createFromStaticType(dartType);
+            _abstractValueDomain.createFromStaticType(dartType, nullable: true);
         return HAsCheckSimple(node.checkedInput, dartType, checkedType,
             node.isTypeError, specializedCheck, node.instructionType);
       }
@@ -1892,6 +1917,27 @@
   }
 
   @override
+  HInstruction visitIsTest(HIsTest node) {
+    AbstractValueWithPrecision checkedAbstractValue = node.checkedAbstractValue;
+    HInstruction checkedInput = node.checkedInput;
+    AbstractValue inputType = checkedInput.instructionType;
+
+    AbstractBool isIn = _abstractValueDomain.isIn(
+        inputType, checkedAbstractValue.abstractValue);
+
+    if (isIn.isDefinitelyFalse) {
+      return _graph.addConstantBool(false, _closedWorld);
+    }
+    if (!checkedAbstractValue.isPrecise) return node;
+
+    if (isIn.isDefinitelyTrue) {
+      return _graph.addConstantBool(true, _closedWorld);
+    }
+
+    return node;
+  }
+
+  @override
   HInstruction visitInstanceEnvironment(HInstanceEnvironment node) {
     HInstruction instance = node.inputs.single;
 
@@ -2955,6 +3001,27 @@
   }
 
   @override
+  void visitIsTest(HIsTest instruction) {
+    List<HBasicBlock> trueTargets = <HBasicBlock>[];
+    List<HBasicBlock> falseTargets = <HBasicBlock>[];
+
+    collectTargets(instruction, trueTargets, falseTargets);
+
+    if (trueTargets.isEmpty && falseTargets.isEmpty) return;
+
+    AbstractValue convertedType =
+        instruction.checkedAbstractValue.abstractValue;
+    HInstruction input = instruction.checkedInput;
+
+    for (HBasicBlock block in trueTargets) {
+      insertTypePropagationForDominatedUsers(block, input, convertedType);
+    }
+    // TODO(sra): Also strengthen uses for when the condition is precise and
+    // known false (e.g. int? x; ... if (x is! int) use(x)). Avoid strengthening
+    // to `null`.
+  }
+
+  @override
   void visitIdentity(HIdentity instruction) {
     // At HIf(HIdentity(x, null)) strengthens x to non-null on else branch.
     HInstruction left = instruction.left;
diff --git a/pkg/compiler/lib/src/ssa/type_builder.dart b/pkg/compiler/lib/src/ssa/type_builder.dart
index 7a0eaed..aac509a 100644
--- a/pkg/compiler/lib/src/ssa/type_builder.dart
+++ b/pkg/compiler/lib/src/ssa/type_builder.dart
@@ -480,7 +480,7 @@
         type, builder.sourceElement,
         sourceInformation: sourceInformation);
     AbstractValueWithPrecision checkedType =
-        _abstractValueDomain.createFromStaticType(type);
+        _abstractValueDomain.createFromStaticType(type, nullable: true);
     AbstractValue instructionType = _abstractValueDomain.intersection(
         original.instructionType, checkedType.abstractValue);
     return HAsCheck(
diff --git a/pkg/compiler/lib/src/ssa/validate.dart b/pkg/compiler/lib/src/ssa/validate.dart
index 74a852a..f53f94f 100644
--- a/pkg/compiler/lib/src/ssa/validate.dart
+++ b/pkg/compiler/lib/src/ssa/validate.dart
@@ -133,20 +133,30 @@
     super.visitBasicBlock(block);
   }
 
-  /// Returns how often [instruction] is contained in [instructions].
-  static int countInstruction(
-      List<HInstruction> instructions, HInstruction instruction) {
+  // Limit for the size of `inputs` and `usedBy` lists. We assume lists longer
+  // than this are OK in order to avoid the O(N^2) validation getting out of
+  // hand.
+  //
+  // Poster child: corelib_2/regexp/pcre_test.dart, which has a 7KLOC main().
+  static const int kMaxValidatedInstructionListLength = 1000;
+
+  /// Verifies [instruction] is contained in [instructions] [count] times.
+  static bool checkInstructionCount(
+      List<HInstruction> instructions, HInstruction instruction, int count) {
+    if (instructions.length > kMaxValidatedInstructionListLength) return true;
     int result = 0;
     for (int i = 0; i < instructions.length; i++) {
       if (identical(instructions[i], instruction)) result++;
     }
-    return result;
+    return result == count;
   }
 
   /// Returns true if the predicate returns true for every instruction in the
   /// list. The argument to [f] is an instruction with the count of how often
   /// it appeared in the list [instructions].
-  static bool everyInstruction(List<HInstruction> instructions, Function f) {
+  static bool everyInstruction(
+      List<HInstruction> instructions, bool Function(HInstruction, int) f) {
+    if (instructions.length > kMaxValidatedInstructionListLength) return true;
     var copy = new List<HInstruction>.from(instructions);
     // TODO(floitsch): there is currently no way to sort HInstructions before
     // we have assigned an ID. The loop is therefore O(n^2) for now.
@@ -173,9 +183,9 @@
       return everyInstruction(instruction.inputs, (input, count) {
         if (inBasicBlock) {
           return input.isInBasicBlock() &&
-              countInstruction(input.usedBy, instruction) == count;
+              checkInstructionCount(input.usedBy, instruction, count);
         } else {
-          return countInstruction(input.usedBy, instruction) == 0;
+          return checkInstructionCount(input.usedBy, instruction, 0);
         }
       });
     }
@@ -185,7 +195,7 @@
       if (!instruction.isInBasicBlock()) return true;
       return everyInstruction(instruction.usedBy, (use, count) {
         return use.isInBasicBlock() &&
-            countInstruction(use.inputs, instruction) == count;
+            checkInstructionCount(use.inputs, instruction, count);
       });
     }
 
diff --git a/pkg/compiler/lib/src/universe/codegen_world_builder.dart b/pkg/compiler/lib/src/universe/codegen_world_builder.dart
index afe16e0..64e22df 100644
--- a/pkg/compiler/lib/src/universe/codegen_world_builder.dart
+++ b/pkg/compiler/lib/src/universe/codegen_world_builder.dart
@@ -160,6 +160,7 @@
 
   final Set<DartType> _constTypeLiterals = new Set<DartType>();
   final Set<DartType> _liveTypeArguments = new Set<DartType>();
+  final Set<TypeVariableType> _namedTypeVariablesNewRti = {};
 
   CodegenWorldBuilderImpl(this._closedWorld, this._selectorConstraintsStrategy,
       this._oneShotInterceptorData);
@@ -324,6 +325,10 @@
     _isChecks.add(type.unaliased);
   }
 
+  void registerNamedTypeVariableNewRti(TypeVariableType type) {
+    _namedTypeVariablesNewRti.add(type);
+  }
+
   void registerStaticUse(StaticUse staticUse, MemberUsedCallback memberUsed) {
     MemberEntity element = staticUse.element;
     EnumSet<MemberUse> useSet = new EnumSet<MemberUse>();
@@ -583,6 +588,7 @@
         typeVariableTypeLiterals: typeVariableTypeLiterals,
         instantiatedClasses: instantiatedClasses,
         isChecks: _isChecks,
+        namedTypeVariablesNewRti: _namedTypeVariablesNewRti,
         instantiatedTypes: _instantiatedTypes,
         liveTypeArguments: _liveTypeArguments,
         compiledConstants: _compiledConstants,
@@ -616,6 +622,9 @@
   final Iterable<DartType> isChecks;
 
   @override
+  final Set<TypeVariableType> namedTypeVariablesNewRti;
+
+  @override
   final Iterable<InterfaceType> instantiatedTypes;
 
   @override
@@ -642,6 +651,7 @@
       this.typeVariableTypeLiterals,
       this.instantiatedClasses,
       this.isChecks,
+      this.namedTypeVariablesNewRti,
       this.instantiatedTypes,
       this.liveTypeArguments,
       Iterable<ConstantValue> compiledConstants,
diff --git a/pkg/compiler/lib/src/universe/resolution_world_builder.dart b/pkg/compiler/lib/src/universe/resolution_world_builder.dart
index 19d9461..3ac96ab 100644
--- a/pkg/compiler/lib/src/universe/resolution_world_builder.dart
+++ b/pkg/compiler/lib/src/universe/resolution_world_builder.dart
@@ -93,6 +93,8 @@
   /// is returned.
   void registerIsCheck(DartType type);
 
+  void registerNamedTypeVariableNewRti(TypeVariableType typeVariable);
+
   void registerTypeVariableTypeLiteral(TypeVariableType typeVariable);
 }
 
@@ -313,6 +315,7 @@
   final Set<FieldEntity> _fieldSetters = new Set<FieldEntity>();
 
   final Set<DartType> _isChecks = new Set<DartType>();
+  final Set<TypeVariableType> _namedTypeVariablesNewRti = {};
 
   /// Set of all closures in the program. Used by the mirror tracking system
   /// to find all live closure instances.
@@ -593,6 +596,11 @@
   }
 
   @override
+  void registerNamedTypeVariableNewRti(TypeVariableType type) {
+    _namedTypeVariablesNewRti.add(type);
+  }
+
+  @override
   bool registerConstantUse(ConstantUse use) {
     return _constantValues.add(use.value);
   }
diff --git a/pkg/compiler/lib/src/universe/use.dart b/pkg/compiler/lib/src/universe/use.dart
index 5e124f3..8b4255a 100644
--- a/pkg/compiler/lib/src/universe/use.dart
+++ b/pkg/compiler/lib/src/universe/use.dart
@@ -702,6 +702,7 @@
   PARAMETER_CHECK,
   RTI_VALUE,
   TYPE_ARGUMENT,
+  NAMED_TYPE_VARIABLE_NEW_RTI,
 }
 
 /// Use of a [DartType].
@@ -773,6 +774,9 @@
       case TypeUseKind.TYPE_ARGUMENT:
         sb.write('typeArg:');
         break;
+      case TypeUseKind.NAMED_TYPE_VARIABLE_NEW_RTI:
+        sb.write('named:');
+        break;
     }
     sb.write(type);
     if (deferredImport != null) {
@@ -858,6 +862,10 @@
     return new TypeUse.internal(type, TypeUseKind.TYPE_ARGUMENT);
   }
 
+  /// [type] used as a named type variable in a recipe.
+  factory TypeUse.namedTypeVariableNewRti(TypeVariableType type) =>
+      TypeUse.internal(type, TypeUseKind.NAMED_TYPE_VARIABLE_NEW_RTI);
+
   @override
   bool operator ==(other) {
     if (identical(this, other)) return true;
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index 046be4f..e7f5930 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -237,6 +237,9 @@
   /// All types that are checked either through is, as or checked mode checks.
   Iterable<DartType> get isChecks;
 
+  /// All type variables named in recipes.
+  Set<TypeVariableType> get namedTypeVariablesNewRti;
+
   /// All directly instantiated types, that is, the types of
   /// [directlyInstantiatedClasses].
   // TODO(johnniwinther): Improve semantic precision.
diff --git a/pkg/dart_internal/pubspec.yaml b/pkg/dart_internal/pubspec.yaml
index 89bb3d6..2ffe0ee 100644
--- a/pkg/dart_internal/pubspec.yaml
+++ b/pkg/dart_internal/pubspec.yaml
@@ -1,5 +1,5 @@
 name: dart_internal
-version: 0.1.5
+version: 0.1.6
 author: "Dart Team <misc@dartlang.org>"
 homepage: http://www.dartlang.org
 description: >
@@ -16,4 +16,4 @@
 environment:
   # Restrict the upper bound so that we can remove support for this in a later
   # version of the SDK without it being a breaking change.
-  sdk: ">=2.0.0-dev.12.0 <2.5.0"
+  sdk: ">=2.0.0-dev.12.0 <2.6.0"
diff --git a/pkg/dartfix/analysis_options.yaml b/pkg/dartfix/analysis_options.yaml
index 63d1935..1d96fdd 100644
--- a/pkg/dartfix/analysis_options.yaml
+++ b/pkg/dartfix/analysis_options.yaml
@@ -1,5 +1,9 @@
 include: package:pedantic/analysis_options.1.8.0.yaml
 
+analyzer:
+  strong-mode:
+    implicit-casts: false
+
 linter:
   rules:
     directives_ordering: true
diff --git a/pkg/dartfix/lib/src/options.dart b/pkg/dartfix/lib/src/options.dart
index 9aba6fa..545196a 100644
--- a/pkg/dartfix/lib/src/options.dart
+++ b/pkg/dartfix/lib/src/options.dart
@@ -52,7 +52,7 @@
         pedanticFixes = results[pedanticOption] as bool,
         requiredFixes = results[requiredOption] as bool,
         sdkPath = _getSdkPath(),
-        serverSnapshot = results[_serverSnapshot],
+        serverSnapshot = results[_serverSnapshot] as String,
         showHelp = results[_helpOption] as bool || results.arguments.isEmpty,
         targets = results.rest,
         useColor = results.wasParsed(_colorOption)
diff --git a/pkg/dev_compiler/lib/src/kernel/command.dart b/pkg/dev_compiler/lib/src/kernel/command.dart
index 72912de..c4ab9cf 100644
--- a/pkg/dev_compiler/lib/src/kernel/command.dart
+++ b/pkg/dev_compiler/lib/src/kernel/command.dart
@@ -101,7 +101,9 @@
     ..addFlag('compile-sdk',
         help: 'Build an SDK module.', defaultsTo: false, hide: true)
     ..addOption('libraries-file',
-        help: 'The path to the libraries.json file for the sdk.');
+        help: 'The path to the libraries.json file for the sdk.')
+    ..addOption('used-inputs-file',
+        help: 'If set, the file to record inputs used.', hide: true);
   SharedCompilerOptions.addArguments(argParser);
 
   var declaredVariables = parseAndRemoveDeclaredVariables(args);
@@ -237,6 +239,7 @@
   List<Component> doneInputSummaries;
   fe.IncrementalCompiler incrementalCompiler;
   fe.WorkerInputComponent cachedSdkInput;
+  bool recordUsedInputs = argResults['used-inputs-file'] != null;
   if (useAnalyzer || !useIncrementalCompiler) {
     compilerState = await fe.initializeCompiler(
         oldCompilerState,
@@ -267,7 +270,8 @@
             TargetFlags(trackWidgetCreation: trackWidgetCreation)),
         fileSystem: fileSystem,
         experiments: experiments,
-        environmentDefines: declaredVariables);
+        environmentDefines: declaredVariables,
+        trackNeededDillLibraries: recordUsedInputs);
     incrementalCompiler = compilerState.incrementalCompiler;
     cachedSdkInput =
         compilerState.workerInputCache[sourcePathToUri(sdkSummaryPath)];
@@ -386,6 +390,31 @@
     }
   }
 
+  if (recordUsedInputs) {
+    Set<Uri> usedOutlines = Set<Uri>();
+    if (!useAnalyzer && useIncrementalCompiler) {
+      compilerState.incrementalCompiler
+          .updateNeededDillLibrariesWithHierarchy(result.classHierarchy, null);
+      for (Library lib
+          in compilerState.incrementalCompiler.neededDillLibraries) {
+        if (lib.importUri.scheme == "dart") continue;
+        Uri uri = compilerState.libraryToInputDill[lib.importUri];
+        if (uri == null) {
+          throw StateError("Library ${lib.importUri} was recorded as used, "
+              "but was not in the list of known libraries.");
+        }
+        usedOutlines.add(uri);
+      }
+    } else {
+      // Used inputs wasn't recorded: Say we used everything.
+      usedOutlines.addAll(summaryModules.keys);
+    }
+
+    var outputUsedFile = File(argResults['used-inputs-file'] as String);
+    outputUsedFile.createSync(recursive: true);
+    outputUsedFile.writeAsStringSync(usedOutlines.join("\n"));
+  }
+
   await Future.wait(outFiles);
   return CompilerResult(0, kernelState: compilerState);
 }
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index fb8f432..0cd7d86 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -362,7 +362,8 @@
       segments = uri.pathSegments;
     }
 
-    var qualifiedPath = pathToJSIdentifier(p.withoutExtension(segments.join('/')));
+    var qualifiedPath =
+        pathToJSIdentifier(p.withoutExtension(segments.join('/')));
     return qualifiedPath == jsLibraryName(library) ? null : qualifiedPath;
   }
 
@@ -5339,8 +5340,9 @@
   @override
   js_ast.Expression visitConstant(Constant node) {
     if (node is TearOffConstant) {
-      // JS() or JS interop functions should not be lazily loaded.
-      if (node.procedure.isExternal || _isInForeignJS) {
+      // JS() or external JS consts should not be lazily loaded.
+      var isSdk = node.procedure.enclosingLibrary.importUri.scheme == "dart";
+      if ((node.procedure.isExternal && !isSdk) || _isInForeignJS) {
         return _emitStaticTarget(node.procedure);
       }
     }
@@ -5451,7 +5453,8 @@
     var prototype = js.call("#.prototype", [type]);
     var properties = [
       js_ast.Property(propertyName("__proto__"), prototype),
-      for (var e in node.fieldValues.entries) entryToProperty(e),
+      for (var e in node.fieldValues.entries.toList().reversed)
+        entryToProperty(e),
     ];
     return canonicalizeConstObject(
         js_ast.ObjectInitializer(properties, multiline: true));
diff --git a/pkg/dev_compiler/lib/src/kernel/property_model.dart b/pkg/dev_compiler/lib/src/kernel/property_model.dart
index 7c5bcee..5eca899 100644
--- a/pkg/dev_compiler/lib/src/kernel/property_model.dart
+++ b/pkg/dev_compiler/lib/src/kernel/property_model.dart
@@ -203,8 +203,18 @@
       VirtualFieldModel fieldModel, Class class_) {
     // Visit superclasses to collect information about their fields/accessors.
     // This is expensive so we try to collect everything in one pass.
-    for (var base in getSuperclasses(class_)) {
+    var superclasses = [class_, ...getSuperclasses(class_)];
+    for (var base in superclasses) {
       for (var member in base.members) {
+        // Note, we treat noSuchMethodForwarders in the current class as
+        // inherited / potentially virtual.  Skip all other members of the
+        // current class.
+        if (base == class_ &&
+            (member is Field ||
+                (member is Procedure && !member.isNoSuchMethodForwarder))) {
+          continue;
+        }
+
         if (member is Constructor ||
             member is Procedure && (!member.isAccessor || member.isStatic)) {
           continue;
diff --git a/pkg/dev_compiler/tool/ddb b/pkg/dev_compiler/tool/ddb
index 7ce2e26..17d5704 100755
--- a/pkg/dev_compiler/tool/ddb
+++ b/pkg/dev_compiler/tool/ddb
@@ -236,7 +236,7 @@
       if (!source_maps) {
         console.log('For Dart source maps: npm install source-map-support');
       }
-      console.error(e);
+      sdk.core.print(sdk.dart.stackTrace(e));
       process.exit(1);
     }
     ''';
@@ -258,7 +258,7 @@
 
     var runjs = '''
     import { dart, _isolate_helper } from '$sdkJsPath/dart_sdk.js';
-    import { $basename } from '$basename.js';
+    import { $libname } from '$basename.js';
     let main = $libname.main;
     try {
       _isolate_helper.startRootIsolate(() => {}, []);
diff --git a/pkg/front_end/PRESUBMIT.py b/pkg/front_end/PRESUBMIT.py
new file mode 100644
index 0000000..8f25cd2
--- /dev/null
+++ b/pkg/front_end/PRESUBMIT.py
@@ -0,0 +1,61 @@
+# 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.
+"""Front-end specific presubmit script.
+
+See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
+for more details about the presubmit API built into gcl.
+"""
+
+import imp
+import os.path
+import subprocess
+
+
+def runSmokeTest(input_api, output_api):
+    hasChangedFiles = False
+    for git_file in input_api.AffectedTextFiles():
+        filename = git_file.AbsoluteLocalPath()
+        if filename.endswith(".dart") or filename.endswith("messages.yaml"):
+            hasChangedFiles = True
+            break
+
+    if hasChangedFiles:
+        local_root = input_api.change.RepositoryRoot()
+        utils = imp.load_source('utils',
+                        os.path.join(local_root, 'tools', 'utils.py'))
+        dart = os.path.join(utils.CheckedInSdkPath(), 'bin', 'dart')
+        smoke_test = os.path.join(local_root, 'pkg', 'front_end', 'tool',
+                                  'smoke_test_quick.dart')
+
+        windows = utils.GuessOS() == 'win32'
+        if windows:
+            dart += '.exe'
+
+        if not os.path.isfile(dart):
+            print('WARNING: dart not found: %s' % dart)
+            return []
+
+        if not os.path.isfile(smoke_test):
+            print('WARNING: Front-end smoke test not found: %s' % smoke_test)
+            return []
+
+        args = [dart, smoke_test]
+        process = subprocess.Popen(
+            args, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
+        outs, _ = process.communicate()
+
+        if process.returncode != 0:
+            return [output_api.PresubmitError(
+                    'Front-end smoke test failure(s):',
+                    long_text=outs)]
+
+    return []
+
+
+def CheckChangeOnCommit(input_api, output_api):
+    return runSmokeTest(input_api, output_api)
+
+
+def CheckChangeOnUpload(input_api, output_api):
+    return runSmokeTest(input_api, output_api)
diff --git a/pkg/front_end/analysis_options.yaml b/pkg/front_end/analysis_options.yaml
index 63c5c24..9021253 100644
--- a/pkg/front_end/analysis_options.yaml
+++ b/pkg/front_end/analysis_options.yaml
@@ -1,17 +1,20 @@
-# Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+# 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.
 
-analyzer:
-  exclude:
-    - test/extensions/data/**
-    - test/flow_analysis/definite_assignment/data/**
-    - test/flow_analysis/nullability/data/**
-    - test/flow_analysis/reachability/data/**
-    - test/flow_analysis/type_promotion/data/**
-    - testcases/**
-    - test/id_testing/data/**
-    - test/language_versioning/data/**
-  errors:
-    # Allow having TODOs in the code
-    todo: ignore
+include: analysis_options_no_lints.yaml
+
+linter:
+  rules:
+    - curly_braces_in_flow_control_structures
+    - prefer_adjacent_string_concatenation
+    - unawaited_futures
+    - recursive_getters
+    - avoid_empty_else
+    - empty_statements
+    - list_remove_unrelated_type
+    - iterable_contains_unrelated_type
+    - valid_regexps
+    - package_api_docs
+    - lines_longer_than_80_chars
+    # - always_specify_types
diff --git a/pkg/front_end/analysis_options_no_lints.yaml b/pkg/front_end/analysis_options_no_lints.yaml
new file mode 100644
index 0000000..63c5c24
--- /dev/null
+++ b/pkg/front_end/analysis_options_no_lints.yaml
@@ -0,0 +1,17 @@
+# Copyright (c) 2017, 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.
+
+analyzer:
+  exclude:
+    - test/extensions/data/**
+    - test/flow_analysis/definite_assignment/data/**
+    - test/flow_analysis/nullability/data/**
+    - test/flow_analysis/reachability/data/**
+    - test/flow_analysis/type_promotion/data/**
+    - testcases/**
+    - test/id_testing/data/**
+    - test/language_versioning/data/**
+  errors:
+    # Allow having TODOs in the code
+    todo: ignore
diff --git a/pkg/front_end/lib/src/api_prototype/compiler_options.dart b/pkg/front_end/lib/src/api_prototype/compiler_options.dart
index e6616203..bd628d8 100644
--- a/pkg/front_end/lib/src/api_prototype/compiler_options.dart
+++ b/pkg/front_end/lib/src/api_prototype/compiler_options.dart
@@ -222,8 +222,8 @@
 Map<String, bool> parseExperimentalArguments(List<String> arguments) {
   Map<String, bool> result = {};
   if (arguments != null) {
-    for (var argument in arguments) {
-      for (var feature in argument.split(',')) {
+    for (String argument in arguments) {
+      for (String feature in argument.split(',')) {
         if (feature.startsWith('no-')) {
           result[feature.substring(3)] = false;
         } else {
diff --git a/pkg/front_end/lib/src/api_prototype/experimental_flags.dart b/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
index 466a1ff..0bfe1a9 100644
--- a/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
+++ b/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
@@ -48,7 +48,7 @@
 };
 
 const Map<ExperimentalFlag, bool> expiredExperimentalFlags = {
-  ExperimentalFlag.constantUpdate2018: false,
+  ExperimentalFlag.constantUpdate2018: true,
   ExperimentalFlag.controlFlowCollections: false,
   ExperimentalFlag.extensionMethods: false,
   ExperimentalFlag.nonNullable: false,
diff --git a/pkg/front_end/lib/src/api_prototype/kernel_generator.dart b/pkg/front_end/lib/src/api_prototype/kernel_generator.dart
index b83bdd4..7c5e1b5 100644
--- a/pkg/front_end/lib/src/api_prototype/kernel_generator.dart
+++ b/pkg/front_end/lib/src/api_prototype/kernel_generator.dart
@@ -54,12 +54,13 @@
 Future<CompilerResult> kernelForProgramInternal(
     Uri source, CompilerOptions options,
     {bool retainDataForTesting: false}) async {
-  var pOptions = new ProcessedOptions(options: options, inputs: [source]);
+  ProcessedOptions pOptions =
+      new ProcessedOptions(options: options, inputs: [source]);
   return await CompilerContext.runWithOptions(pOptions, (context) async {
     CompilerResult result = await generateKernelInternal(
         includeHierarchyAndCoreTypes: true,
         retainDataForTesting: retainDataForTesting);
-    var component = result?.component;
+    Component component = result?.component;
     if (component == null) return null;
 
     if (component.mainMethod == null) {
diff --git a/pkg/front_end/lib/src/api_prototype/memory_file_system.dart b/pkg/front_end/lib/src/api_prototype/memory_file_system.dart
index 62ec112..fd091bb 100644
--- a/pkg/front_end/lib/src/api_prototype/memory_file_system.dart
+++ b/pkg/front_end/lib/src/api_prototype/memory_file_system.dart
@@ -35,7 +35,7 @@
   }
 
   String get debugString {
-    var sb = new StringBuffer();
+    StringBuffer sb = new StringBuffer();
     _files.forEach((uri, _) => sb.write("- $uri\n"));
     _directories.forEach((uri) => sb.write("- $uri\n"));
     return '$sb';
diff --git a/pkg/front_end/lib/src/api_unstable/bazel_worker.dart b/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
index e9f9dda..1473017 100644
--- a/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
+++ b/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
@@ -8,7 +8,8 @@
 import 'dart:async' show Future;
 
 import 'package:front_end/src/api_prototype/compiler_options.dart';
-import 'package:kernel/kernel.dart' show Component, CanonicalName;
+
+import 'package:kernel/kernel.dart' show Component, CanonicalName, Library;
 
 import 'package:kernel/target/targets.dart' show Target;
 
@@ -63,7 +64,8 @@
     Target target,
     FileSystem fileSystem,
     Iterable<String> experiments,
-    bool outlineOnly) async {
+    bool outlineOnly,
+    {bool trackNeededDillLibraries: false}) async {
   final List<int> sdkDigest = workerInputDigests[sdkSummary];
   if (sdkDigest == null) {
     throw new StateError("Expected to get digest for $sdkSummary");
@@ -121,12 +123,13 @@
         new CompilerContext(processedOpts),
         cachedSdkInput.component,
         outlineOnly);
+    incrementalCompiler.trackNeededDillLibraries = trackNeededDillLibraries;
   } else {
     options = oldState.options;
     processedOpts = oldState.processedOpts;
-    var sdkComponent = cachedSdkInput.component;
+    Component sdkComponent = cachedSdkInput.component;
     // Reset the state of the component.
-    for (var lib in sdkComponent.libraries) {
+    for (Library lib in sdkComponent.libraries) {
       lib.isExternal = cachedSdkInput.externalLibs.contains(lib.importUri);
     }
 
@@ -147,6 +150,7 @@
     // Reuse the incremental compiler, but reset as needed.
     incrementalCompiler = oldState.incrementalCompiler;
     incrementalCompiler.invalidateAllSources();
+    incrementalCompiler.trackNeededDillLibraries = trackNeededDillLibraries;
     options.packagesFileUri = packagesFile;
     options.fileSystem = fileSystem;
     processedOpts.clearFileSystemCache();
@@ -154,11 +158,15 @@
 
   // Then read all the input summary components.
   CanonicalName nameRoot = cachedSdkInput.component.root;
-  final inputSummaries = <Component>[];
+  final List<Component> inputSummaries = <Component>[];
+  Map<Uri, Uri> libraryToInputDill;
+  if (trackNeededDillLibraries) {
+    libraryToInputDill = new Map<Uri, Uri>();
+  }
   List<Uri> loadFromDill = new List<Uri>();
   for (Uri summary in summaryInputs) {
-    var cachedInput = workerInputCache[summary];
-    var summaryDigest = workerInputDigests[summary];
+    WorkerInputComponent cachedInput = workerInputCache[summary];
+    List<int> summaryDigest = workerInputDigests[summary];
     if (summaryDigest == null) {
       throw new StateError("Expected to get digest for $summary");
     }
@@ -168,9 +176,12 @@
       loadFromDill.add(summary);
     } else {
       // Need to reset cached components so they are usable again.
-      var component = cachedInput.component;
-      for (var lib in component.libraries) {
+      Component component = cachedInput.component;
+      for (Library lib in component.libraries) {
         lib.isExternal = cachedInput.externalLibs.contains(lib.importUri);
+        if (trackNeededDillLibraries) {
+          libraryToInputDill[lib.importUri] = summary;
+        }
       }
       inputSummaries.add(component);
     }
@@ -189,13 +200,19 @@
             alwaysCreateNewNamedNodes: true));
     workerInputCache[summary] = cachedInput;
     inputSummaries.add(cachedInput.component);
+    if (trackNeededDillLibraries) {
+      for (Library lib in cachedInput.component.libraries) {
+        libraryToInputDill[lib.importUri] = summary;
+      }
+    }
   }
 
   incrementalCompiler.setModulesToLoadOnNextComputeDelta(inputSummaries);
 
   return new InitializedCompilerState(options, processedOpts,
       workerInputCache: workerInputCache,
-      incrementalCompiler: incrementalCompiler);
+      incrementalCompiler: incrementalCompiler,
+      libraryToInputDill: libraryToInputDill);
 }
 
 Future<InitializedCompilerState> initializeCompiler(
@@ -251,19 +268,21 @@
 Future<List<int>> compileSummary(InitializedCompilerState compilerState,
     List<Uri> inputs, DiagnosticMessageHandler diagnosticMessageHandler,
     {bool includeOffsets: false}) async {
-  var result = await _compile(compilerState, inputs, diagnosticMessageHandler,
+  CompilerResult result = await _compile(
+      compilerState, inputs, diagnosticMessageHandler,
       summaryOnly: true, includeOffsets: includeOffsets);
   return result?.summary;
 }
 
 Future<Component> compileComponent(InitializedCompilerState compilerState,
     List<Uri> inputs, DiagnosticMessageHandler diagnosticMessageHandler) async {
-  var result = await _compile(compilerState, inputs, diagnosticMessageHandler,
+  CompilerResult result = await _compile(
+      compilerState, inputs, diagnosticMessageHandler,
       summaryOnly: false);
 
-  var component = result?.component;
+  Component component = result?.component;
   if (component != null) {
-    for (var lib in component.libraries) {
+    for (Library lib in component.libraries) {
       if (!inputs.contains(lib.importUri)) {
         // Excluding the library also means that their canonical names will not
         // be computed as part of serialization, so we need to do that
diff --git a/pkg/front_end/lib/src/api_unstable/compiler_state.dart b/pkg/front_end/lib/src/api_unstable/compiler_state.dart
index dc80525..57fdac4 100644
--- a/pkg/front_end/lib/src/api_unstable/compiler_state.dart
+++ b/pkg/front_end/lib/src/api_unstable/compiler_state.dart
@@ -16,9 +16,12 @@
   final ProcessedOptions processedOpts;
   final Map<Uri, WorkerInputComponent> workerInputCache;
   final IncrementalCompiler incrementalCompiler;
+  final Map<Uri, Uri> libraryToInputDill;
 
   InitializedCompilerState(this.options, this.processedOpts,
-      {this.workerInputCache, this.incrementalCompiler});
+      {this.workerInputCache,
+      this.incrementalCompiler,
+      this.libraryToInputDill});
 }
 
 /// A cached [Component] for a summary input file.
diff --git a/pkg/front_end/lib/src/api_unstable/dart2js.dart b/pkg/front_end/lib/src/api_unstable/dart2js.dart
index 947ca61..860f99f 100644
--- a/pkg/front_end/lib/src/api_unstable/dart2js.dart
+++ b/pkg/front_end/lib/src/api_unstable/dart2js.dart
@@ -4,7 +4,7 @@
 
 import 'dart:async' show Future;
 
-import 'package:kernel/kernel.dart' show Component;
+import 'package:kernel/kernel.dart' show Component, Statement;
 
 import 'package:kernel/ast.dart' as ir;
 
@@ -18,6 +18,8 @@
 
 import '../api_prototype/file_system.dart' show FileSystem;
 
+import '../api_prototype/kernel_generator.dart' show CompilerResult;
+
 import '../base/processed_options.dart' show ProcessedOptions;
 
 import '../base/libraries_specification.dart' show LibrariesSpecification;
@@ -159,9 +161,9 @@
   processedOpts.inputs.add(input);
   processedOpts.clearFileSystemCache();
 
-  var compilerResult = await CompilerContext.runWithOptions(processedOpts,
-      (CompilerContext context) async {
-    var compilerResult = await generateKernelInternal();
+  CompilerResult compilerResult = await CompilerContext.runWithOptions(
+      processedOpts, (CompilerContext context) async {
+    CompilerResult compilerResult = await generateKernelInternal();
     Component component = compilerResult?.component;
     if (component == null) return null;
     if (component.mainMethod == null) {
@@ -218,7 +220,7 @@
 // is implemented correctly for patch files (Issue #33495).
 bool isRedirectingFactory(ir.Procedure member) {
   if (member.kind == ir.ProcedureKind.Factory) {
-    var body = member.function.body;
+    Statement body = member.function.body;
     if (body is redirecting.RedirectingFactoryBody) return true;
     if (body is ir.ExpressionStatement) {
       ir.Expression expression = body.expression;
diff --git a/pkg/front_end/lib/src/api_unstable/ddc.dart b/pkg/front_end/lib/src/api_unstable/ddc.dart
index b53e029..547f79a 100644
--- a/pkg/front_end/lib/src/api_unstable/ddc.dart
+++ b/pkg/front_end/lib/src/api_unstable/ddc.dart
@@ -5,7 +5,8 @@
 import 'dart:async' show Future;
 
 import 'package:kernel/class_hierarchy.dart';
-import 'package:kernel/kernel.dart' show Component, CanonicalName;
+
+import 'package:kernel/kernel.dart' show Component, CanonicalName, Library;
 
 import 'package:kernel/target/targets.dart' show Target;
 
@@ -17,6 +18,8 @@
 
 import '../api_prototype/file_system.dart' show FileSystem;
 
+import '../api_prototype/kernel_generator.dart' show CompilerResult;
+
 import '../api_prototype/standard_file_system.dart' show StandardFileSystem;
 
 import '../base/processed_options.dart' show ProcessedOptions;
@@ -142,7 +145,8 @@
     Target target,
     {FileSystem fileSystem,
     Map<ExperimentalFlag, bool> experiments,
-    Map<String, String> environmentDefines}) async {
+    Map<String, String> environmentDefines,
+    bool trackNeededDillLibraries: false}) async {
   inputSummaries.sort((a, b) => a.toString().compareTo(b.toString()));
 
   IncrementalCompiler incrementalCompiler;
@@ -152,7 +156,7 @@
 
   Map<Uri, WorkerInputComponent> workerInputCache =
       oldState?.workerInputCache ?? new Map<Uri, WorkerInputComponent>();
-  var sdkDigest = workerInputDigests[sdkSummary];
+  final List<int> sdkDigest = workerInputDigests[sdkSummary];
   if (sdkDigest == null) {
     throw new StateError("Expected to get sdk digest at $sdkSummary");
   }
@@ -189,12 +193,13 @@
     workerInputCache[sdkSummary] = cachedSdkInput;
     incrementalCompiler = new IncrementalCompiler.fromComponent(
         new CompilerContext(processedOpts), cachedSdkInput.component);
+    incrementalCompiler.trackNeededDillLibraries = trackNeededDillLibraries;
   } else {
     options = oldState.options;
     options.inputSummaries = inputSummaries;
     processedOpts = oldState.processedOpts;
 
-    for (var lib in cachedSdkInput.component.libraries) {
+    for (Library lib in cachedSdkInput.component.libraries) {
       lib.isExternal = false;
     }
     cachedSdkInput.component.adoptChildren();
@@ -205,6 +210,7 @@
     // Reuse the incremental compiler, but reset as needed.
     incrementalCompiler = oldState.incrementalCompiler;
     incrementalCompiler.invalidateAllSources();
+    incrementalCompiler.trackNeededDillLibraries = trackNeededDillLibraries;
     options.packagesFileUri = packagesFile;
     options.fileSystem = fileSystem;
     processedOpts.clearFileSystemCache();
@@ -215,6 +221,10 @@
       incrementalCompiler: incrementalCompiler);
 
   CanonicalName nameRoot = cachedSdkInput.component.root;
+  Map<Uri, Uri> libraryToInputDill;
+  if (trackNeededDillLibraries) {
+    libraryToInputDill = new Map<Uri, Uri>();
+  }
   List<int> loadFromDillIndexes = new List<int>();
 
   // Notice that the ordering of the input summaries matter, so we need to
@@ -225,7 +235,7 @@
   for (int i = 0; i < inputSummaries.length; i++) {
     Uri inputSummary = inputSummaries[i];
     WorkerInputComponent cachedInput = workerInputCache[inputSummary];
-    var digest = workerInputDigests[inputSummary];
+    List<int> digest = workerInputDigests[inputSummary];
     if (digest == null) {
       throw new StateError("Expected to get digest for $inputSummary");
     }
@@ -235,9 +245,12 @@
       loadFromDillIndexes.add(i);
     } else {
       // Need to reset cached components so they are usable again.
-      var component = cachedInput.component;
-      for (var lib in component.libraries) {
+      Component component = cachedInput.component;
+      for (Library lib in component.libraries) {
         lib.isExternal = cachedInput.externalLibs.contains(lib.importUri);
+        if (trackNeededDillLibraries) {
+          libraryToInputDill[lib.importUri] = inputSummary;
+        }
       }
       component.computeCanonicalNames();
       doneInputSummaries[i] = component;
@@ -251,20 +264,26 @@
     if (digest == null) {
       throw new StateError("Expected to get digest for $summary");
     }
-    var bytes = await fileSystem.entityForUri(summary).readAsBytes();
+    List<int> bytes = await fileSystem.entityForUri(summary).readAsBytes();
     WorkerInputComponent cachedInput = WorkerInputComponent(
         digest,
         await compilerState.processedOpts
             .loadComponent(bytes, nameRoot, alwaysCreateNewNamedNodes: true));
     workerInputCache[summary] = cachedInput;
     doneInputSummaries[index] = cachedInput.component;
+    if (trackNeededDillLibraries) {
+      for (Library lib in cachedInput.component.libraries) {
+        libraryToInputDill[lib.importUri] = summary;
+      }
+    }
   }
 
   incrementalCompiler.setModulesToLoadOnNextComputeDelta(doneInputSummaries);
 
   return new InitializedCompilerState(options, processedOpts,
       workerInputCache: workerInputCache,
-      incrementalCompiler: incrementalCompiler);
+      incrementalCompiler: incrementalCompiler,
+      libraryToInputDill: libraryToInputDill);
 }
 
 Future<DdcResult> compile(InitializedCompilerState compilerState,
@@ -276,13 +295,13 @@
   processedOpts.inputs.clear();
   processedOpts.inputs.addAll(inputs);
 
-  var compilerResult =
+  CompilerResult compilerResult =
       await generateKernel(processedOpts, includeHierarchyAndCoreTypes: true);
 
-  var component = compilerResult?.component;
+  Component component = compilerResult?.component;
   if (component == null) return null;
 
   // This should be cached.
-  var summaries = await processedOpts.loadInputSummaries(null);
+  List<Component> summaries = await processedOpts.loadInputSummaries(null);
   return new DdcResult(component, summaries, compilerResult.classHierarchy);
 }
diff --git a/pkg/front_end/lib/src/base/libraries_specification.dart b/pkg/front_end/lib/src/base/libraries_specification.dart
index 09baff1..2907e69 100644
--- a/pkg/front_end/lib/src/base/libraries_specification.dart
+++ b/pkg/front_end/lib/src/base/libraries_specification.dart
@@ -106,7 +106,7 @@
   /// The library specification for a given [target], or throws if none is
   /// available.
   TargetLibrariesSpecification specificationFor(String target) {
-    var targetSpec = _targets[target];
+    TargetLibrariesSpecification targetSpec = _targets[target];
     if (targetSpec == null) {
       throw new LibrariesSpecificationException(
           'No library specification for target "$target"');
@@ -121,9 +121,9 @@
   /// invalid values.
   static LibrariesSpecification parse(Uri baseUri, String json) {
     if (json == null) return const LibrariesSpecification();
-    var jsonData;
+    Map<String, dynamic> jsonData;
     try {
-      var data = jsonDecode(json);
+      dynamic data = jsonDecode(json);
       if (data is! Map) {
         return _reportError('top-level specification is not a map');
       }
@@ -131,7 +131,8 @@
     } on FormatException catch (e) {
       throw new LibrariesSpecificationException(e);
     }
-    var targets = <String, TargetLibrariesSpecification>{};
+    Map<String, TargetLibrariesSpecification> targets =
+        <String, TargetLibrariesSpecification>{};
     jsonData.forEach((String targetName, targetData) {
       if (targetName.startsWith("comment:")) return null;
       Map<String, LibraryInfo> libraries = <String, LibraryInfo>{};
@@ -143,7 +144,7 @@
         return _reportError("target specification "
             "for '$targetName' doesn't have a libraries entry");
       }
-      var librariesData = targetData["libraries"];
+      dynamic librariesData = targetData["libraries"];
       if (librariesData is! Map) {
         return _reportError("libraries entry for '$targetName' is not a map");
       }
@@ -157,14 +158,14 @@
             return _reportError("uri value '$uriString' is not a string"
                 "(from library '$name' in target '$targetName')");
           }
-          var uri = Uri.parse(uriString);
+          Uri uri = Uri.parse(uriString);
           if (uri.scheme != '' && uri.scheme != 'file') {
             return _reportError("uri scheme in '$uriString' is not supported.");
           }
           return baseUri.resolveUri(uri);
         }
 
-        var uri = checkAndResolve(data['uri']);
+        Uri uri = checkAndResolve(data['uri']);
         List<Uri> patches;
         if (data['patches'] is List) {
           patches =
@@ -178,7 +179,7 @@
               "patches entry for '$name' is not a list or a string");
         }
 
-        var supported = data['supported'] ?? true;
+        dynamic supported = data['supported'] ?? true;
         if (supported is! bool) {
           return _reportError("\"supported\" entry: expected a 'bool' but "
               "got a '${supported.runtimeType}' ('$supported')");
@@ -201,11 +202,11 @@
   String toJsonString(Uri outputUri) => jsonEncode(toJsonMap(outputUri));
 
   Map toJsonMap(Uri outputUri) {
-    var result = {};
-    var dir = outputUri.resolve('.');
+    Map result = {};
+    Uri dir = outputUri.resolve('.');
     String pathFor(Uri uri) => relativizeUri(dir, uri, isWindows);
     _targets.forEach((targetName, target) {
-      var libraries = {};
+      Map libraries = {};
       target._libraries.forEach((name, lib) {
         libraries[name] = {
           'uri': pathFor(lib.uri),
diff --git a/pkg/front_end/lib/src/base/processed_options.dart b/pkg/front_end/lib/src/base/processed_options.dart
index ed907b5..b081701 100644
--- a/pkg/front_end/lib/src/base/processed_options.dart
+++ b/pkg/front_end/lib/src/base/processed_options.dart
@@ -142,7 +142,7 @@
   Future<List<int>> loadSdkSummaryBytes() async {
     if (_sdkSummaryBytes == null) {
       if (sdkSummary == null) return null;
-      var entry = fileSystem.entityForUri(sdkSummary);
+      FileSystemEntity entry = fileSystem.entityForUri(sdkSummary);
       _sdkSummaryBytes = await _readAsBytes(entry);
     }
     return _sdkSummaryBytes;
@@ -258,7 +258,7 @@
       return false;
     }
 
-    var summary = sdkSummary;
+    Uri summary = sdkSummary;
     if (summary != null && !await fileSystem.entityForUri(summary).exists()) {
       reportWithoutLocation(
           templateSdkSummaryNotFound.withArguments(summary), Severity.error);
@@ -326,7 +326,7 @@
   Future<Component> loadSdkSummary(CanonicalName nameRoot) async {
     if (_sdkSummaryComponent == null) {
       if (sdkSummary == null) return null;
-      var bytes = await loadSdkSummaryBytes();
+      List<int> bytes = await loadSdkSummaryBytes();
       if (bytes != null && bytes.isNotEmpty) {
         _sdkSummaryComponent = loadComponent(bytes, nameRoot);
       }
@@ -346,10 +346,10 @@
   // TODO(sigmund): move, this doesn't feel like an "option".
   Future<List<Component>> loadInputSummaries(CanonicalName nameRoot) async {
     if (_inputSummariesComponents == null) {
-      var uris = _raw.inputSummaries;
+      List<Uri> uris = _raw.inputSummaries;
       if (uris == null || uris.isEmpty) return const <Component>[];
       // TODO(sigmund): throttle # of concurrent operations.
-      var allBytes = await Future.wait(
+      List<List<int>> allBytes = await Future.wait(
           uris.map((uri) => _readAsBytes(fileSystem.entityForUri(uri))));
       _inputSummariesComponents =
           allBytes.map((bytes) => loadComponent(bytes, nameRoot)).toList();
@@ -368,10 +368,10 @@
   // TODO(sigmund): move, this doesn't feel like an "option".
   Future<List<Component>> loadLinkDependencies(CanonicalName nameRoot) async {
     if (_linkedDependencies == null) {
-      var uris = _raw.linkedDependencies;
+      List<Uri> uris = _raw.linkedDependencies;
       if (uris == null || uris.isEmpty) return const <Component>[];
       // TODO(sigmund): throttle # of concurrent operations.
-      var allBytes = await Future.wait(
+      List<List<int>> allBytes = await Future.wait(
           uris.map((uri) => _readAsBytes(fileSystem.entityForUri(uri))));
       _linkedDependencies =
           allBytes.map((bytes) => loadComponent(bytes, nameRoot)).toList();
@@ -405,7 +405,8 @@
     }
     if (_uriTranslator == null) {
       ticker.logMs("Started building UriTranslator");
-      var libraries = await _computeLibrarySpecification();
+      TargetLibrariesSpecification libraries =
+          await _computeLibrarySpecification();
       ticker.logMs("Read libraries file");
       Packages packages = await _getPackages();
       ticker.logMs("Read packages file");
@@ -415,7 +416,7 @@
   }
 
   Future<TargetLibrariesSpecification> _computeLibrarySpecification() async {
-    var name = target.name;
+    String name = target.name;
     // TODO(sigmund): Eek! We should get to the point where there is no
     // fasta-specific targets and the target names are meaningful.
     if (name.endsWith('_fasta')) name = name.substring(0, name.length - 6);
@@ -431,10 +432,10 @@
       return new TargetLibrariesSpecification(name);
     }
 
-    var json =
+    String json =
         await fileSystem.entityForUri(librariesSpecificationUri).readAsString();
     try {
-      var spec =
+      LibrariesSpecification spec =
           await LibrariesSpecification.parse(librariesSpecificationUri, json);
       return spec.specificationFor(name);
     } on LibrariesSpecificationException catch (e) {
@@ -464,7 +465,7 @@
       return _packages = Packages.noPackages;
     }
 
-    var input = inputs.first;
+    Uri input = inputs.first;
 
     // When compiling the SDK the input files are normally `dart:` URIs.
     if (input.scheme == 'dart') return _packages = Packages.noPackages;
@@ -530,7 +531,7 @@
   ///    * Unlike package:package_config, it does not look for a `packages/`
   ///    directory, as that won't be supported in Dart 2.
   Future<Packages> _findPackages(Uri scriptUri) async {
-    var dir = scriptUri.resolve('.');
+    Uri dir = scriptUri.resolve('.');
     if (!dir.isAbsolute) {
       reportWithoutLocation(
           templateInternalProblemUnsupported
@@ -546,11 +547,11 @@
     }
 
     // Check for $cwd/.packages
-    var candidate = await checkInDir(dir);
+    Uri candidate = await checkInDir(dir);
     if (candidate != null) return createPackagesFromFile(candidate);
 
     // Check for cwd(/..)+/.packages
-    var parentDir = dir.resolve('..');
+    Uri parentDir = dir.resolve('..');
     while (parentDir.path != dir.path) {
       candidate = await checkInDir(parentDir);
       if (candidate != null) break;
@@ -571,7 +572,7 @@
   void _ensureSdkDefaults() {
     if (_computedSdkDefaults) return;
     _computedSdkDefaults = true;
-    var root = _raw.sdkRoot;
+    Uri root = _raw.sdkRoot;
     if (root != null) {
       // Normalize to always end in '/'
       if (!root.path.endsWith('/')) {
@@ -606,7 +607,7 @@
   }
 
   String debugString() {
-    var sb = new StringBuffer();
+    StringBuffer sb = new StringBuffer();
     writeList(String name, List elements) {
       if (elements.isEmpty) {
         sb.writeln('$name: <empty>');
diff --git a/pkg/front_end/lib/src/fasta/builder/class_builder.dart b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
index b6bbd4a..6441675 100644
--- a/pkg/front_end/lib/src/fasta/builder/class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
@@ -63,9 +63,10 @@
         Scope,
         ScopeBuilder,
         TypeBuilder,
-        TypeDeclarationBuilder,
         TypeVariableBuilder;
 
+import 'declaration_builder.dart';
+
 import '../fasta_codes.dart'
     show
         LocatedMessage,
@@ -137,7 +138,7 @@
 
 import '../type_inference/type_schema.dart' show UnknownType;
 
-abstract class ClassBuilder extends TypeDeclarationBuilder {
+abstract class ClassBuilder extends DeclarationBuilder {
   /// The type variables declared on a class, extension or mixin declaration.
   List<TypeVariableBuilder> typeVariables;
 
@@ -153,12 +154,8 @@
   /// The types in the `on` clause of an extension or mixin declaration.
   List<TypeBuilder> onTypes;
 
-  final Scope scope;
-
   final Scope constructors;
 
-  final ScopeBuilder scopeBuilder;
-
   final ScopeBuilder constructorScopeBuilder;
 
   Map<String, ConstructorRedirection> redirectingConstructors;
@@ -173,13 +170,12 @@
       this.supertype,
       this.interfaces,
       this.onTypes,
-      this.scope,
+      Scope scope,
       this.constructors,
       LibraryBuilder parent,
       int charOffset)
-      : scopeBuilder = new ScopeBuilder(scope),
-        constructorScopeBuilder = new ScopeBuilder(constructors),
-        super(metadata, modifiers, name, parent, charOffset);
+      : constructorScopeBuilder = new ScopeBuilder(constructors),
+        super(metadata, modifiers, name, parent, charOffset, scope);
 
   String get debugName => "ClassBuilder";
 
@@ -198,11 +194,6 @@
 
   List<ConstructorReferenceBuilder> get constructorReferences => null;
 
-  LibraryBuilder get library {
-    LibraryBuilder library = parent;
-    return library.partOfLibrary ?? library;
-  }
-
   void buildOutlineExpressions(LibraryBuilder library) {
     void build(String ignore, Builder declaration) {
       MemberBuilder member = declaration;
@@ -324,6 +315,7 @@
   }
 
   /// Used to lookup a static member of this class.
+  @override
   Builder findStaticBuilder(
       String name, int charOffset, Uri fileUri, LibraryBuilder accessingLibrary,
       {bool isSetter: false}) {
@@ -358,33 +350,32 @@
     scope.forEach(f);
   }
 
-  /// Don't use for scope lookup. Only use when an element is known to exist
-  /// (and isn't a setter).
-  MemberBuilder getLocalMember(String name) {
-    return scope.local[name] ??
-        internalProblem(
-            templateInternalProblemNotFoundIn.withArguments(
-                name, fullNameForErrors),
-            -1,
-            null);
-  }
-
-  void addProblem(Message message, int charOffset, int length,
-      {bool wasHandled: false, List<LocatedMessage> context}) {
-    library.addProblem(message, charOffset, length, fileUri,
-        wasHandled: wasHandled, context: context);
+  @override
+  Builder lookupLocalMember(String name, {bool required: false}) {
+    Builder builder = scope.local[name];
+    if (builder == null && isPatch) {
+      builder = origin.scope.local[name];
+    }
+    if (required && builder == null) {
+      internalProblem(
+          templateInternalProblemNotFoundIn.withArguments(
+              name, fullNameForErrors),
+          -1,
+          null);
+    }
+    return builder;
   }
 
   /// Find the first member of this class with [name]. This method isn't
   /// suitable for scope lookups as it will throw an error if the name isn't
   /// declared. The [scope] should be used for that. This method is used to
-  /// find a member that is known to exist and it wil pick the first
+  /// find a member that is known to exist and it will pick the first
   /// declaration if the name is ambiguous.
   ///
   /// For example, this method is convenient for use when building synthetic
   /// members, such as those of an enum.
   MemberBuilder firstMemberNamed(String name) {
-    Builder declaration = getLocalMember(name);
+    Builder declaration = lookupLocalMember(name, required: true);
     while (declaration.next != null) {
       declaration = declaration.next;
     }
@@ -400,6 +391,9 @@
   @override
   ClassBuilder get origin => actualOrigin ?? this;
 
+  @override
+  InterfaceType get thisType => cls.thisType;
+
   /// [arguments] have already been built.
   InterfaceType buildTypesWithBuiltArguments(
       LibraryBuilder library, List<DartType> arguments) {
@@ -1230,8 +1224,10 @@
         i < declaredFunction.positionalParameters.length &&
             i < interfaceFunction.positionalParameters.length;
         i++) {
-      var declaredParameter = declaredFunction.positionalParameters[i];
-      var interfaceParameter = interfaceFunction.positionalParameters[i];
+      VariableDeclaration declaredParameter =
+          declaredFunction.positionalParameters[i];
+      VariableDeclaration interfaceParameter =
+          interfaceFunction.positionalParameters[i];
       _checkTypes(
           types,
           interfaceSubstitution,
@@ -1308,7 +1304,7 @@
           break outer;
         }
       }
-      var declaredParameter = declaredNamedParameters.current;
+      VariableDeclaration declaredParameter = declaredNamedParameters.current;
       _checkTypes(
           types,
           interfaceSubstitution,
@@ -1331,8 +1327,8 @@
         types, declaredMember, interfaceMember, null, null, isInterfaceCheck);
     Substitution declaredSubstitution =
         _computeDeclaredSubstitution(types, declaredMember);
-    var declaredType = declaredMember.getterType;
-    var interfaceType = interfaceMember.getterType;
+    DartType declaredType = declaredMember.getterType;
+    DartType interfaceType = interfaceMember.getterType;
     _checkTypes(
         types,
         interfaceSubstitution,
@@ -1354,9 +1350,9 @@
         types, declaredMember, interfaceMember, null, null, isInterfaceCheck);
     Substitution declaredSubstitution =
         _computeDeclaredSubstitution(types, declaredMember);
-    var declaredType = declaredMember.setterType;
-    var interfaceType = interfaceMember.setterType;
-    var declaredParameter =
+    DartType declaredType = declaredMember.setterType;
+    DartType interfaceType = interfaceMember.setterType;
+    VariableDeclaration declaredParameter =
         declaredMember.function?.positionalParameters?.elementAt(0);
     bool isCovariant = declaredParameter?.isCovariant ?? false;
     if (!isCovariant && declaredMember is Field) {
@@ -1568,7 +1564,8 @@
         DartType typeParameterBound =
             substitution.substituteType(typeParameter.bound);
         DartType typeArgument = typeArguments[i];
-        // Check whether the [typeArgument] respects the bounds of [typeParameter].
+        // Check whether the [typeArgument] respects the bounds of
+        // [typeParameter].
         if (!typeEnvironment.isSubtypeOf(typeArgument, typeParameterBound)) {
           addProblem(
               templateRedirectingFactoryIncompatibleTypeArgument.withArguments(
diff --git a/pkg/front_end/lib/src/fasta/builder/constructor_reference_builder.dart b/pkg/front_end/lib/src/fasta/builder/constructor_reference_builder.dart
index 6dac852..d73dd70 100644
--- a/pkg/front_end/lib/src/fasta/builder/constructor_reference_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/constructor_reference_builder.dart
@@ -41,7 +41,7 @@
   }
 
   void resolveIn(Scope scope, LibraryBuilder accessingLibrary) {
-    final name = this.name;
+    final Object name = this.name;
     Builder declaration;
     if (name is QualifiedName) {
       String prefix = name.qualifier;
diff --git a/pkg/front_end/lib/src/fasta/builder/declaration.dart b/pkg/front_end/lib/src/fasta/builder/declaration.dart
index 38db8e2..107d2a5 100644
--- a/pkg/front_end/lib/src/fasta/builder/declaration.dart
+++ b/pkg/front_end/lib/src/fasta/builder/declaration.dart
@@ -40,7 +40,141 @@
 
   bool get isGetter => false;
 
-  bool get isInstanceMember => false;
+  /// Returns `true` if this builder is an extension declaration.
+  ///
+  /// For instance `B` in:
+  ///
+  ///    class A {}
+  ///    extension B on A {}
+  ///
+  bool get isExtension => false;
+
+  /// Returns `true` if this builder is a member of a class, mixin, or extension
+  /// declaration.
+  ///
+  /// For instance `A.constructor`, `method1a`, `method1b`, `method2a`,
+  /// `method2b`, `method3a`, and `method3b` in:
+  ///
+  ///     class A {
+  ///       A.constructor();
+  ///       method1a() {}
+  ///       static method1b() {}
+  ///     }
+  ///     mixin B {
+  ///       method2a() {}
+  ///       static method2b() {}
+  ///     }
+  ///     extends C on A {
+  ///       method3a() {}
+  ///       static method3b() {}
+  ///     }
+  ///
+  bool get isDeclarationMember => false;
+
+  /// Returns `true` if this builder is a member of a class or mixin
+  /// declaration.
+  ///
+  /// For instance `A.constructor`, `method1a`, `method1b`, `method2a` and
+  /// `method2b` in:
+  ///
+  ///     class A {
+  ///       A.constructor();
+  ///       method1a() {}
+  ///       static method1b() {}
+  ///     }
+  ///     mixin B {
+  ///       method2a() {}
+  ///       static method2b() {}
+  ///     }
+  ///     extends C on A {
+  ///       method3a() {}        // Not a class member.
+  ///       static method3b() {} // Not a class member.
+  ///     }
+  ///
+  bool get isClassMember => false;
+
+  /// Returns `true` if this builder is a member of an extension declaration.
+  ///
+  /// For instance `method3a` and `method3b` in:
+  ///
+  ///     class A {
+  ///       A.constructor();     // Not an extension member.
+  ///       method1a() {}        // Not an extension member.
+  ///       static method1b() {} // Not an extension member.
+  ///     }
+  ///     mixin B {
+  ///       method2a() {}        // Not an extension member.
+  ///       static method2b() {} // Not an extension member.
+  ///     }
+  ///     extends C on A {
+  ///       method3a() {}
+  ///       static method3b() {}
+  ///     }
+  ///
+  bool get isExtensionMember => false;
+
+  /// Returns `true` if this builder is an instance member of a class, mixin, or
+  /// extension declaration.
+  ///
+  /// For instance `method1a`, `method2a`, and `method3a` in:
+  ///
+  ///     class A {
+  ///       A.constructor();     // Not a declaration instance member.
+  ///       method1a() {}
+  ///       static method1b() {} // Not a declaration instance member.
+  ///     }
+  ///     mixin B {
+  ///       method2a() {}
+  ///       static method2b() {} // Not a declaration instance member.
+  ///     }
+  ///     extends C on A {
+  ///       method3a() {}
+  ///       static method3b() {} // Not a declaration instance member.
+  ///     }
+  ///
+  bool get isDeclarationInstanceMember => false;
+
+  /// Returns `true` if this builder is an instance member of a class or mixin
+  /// extension declaration.
+  ///
+  /// For instance `method1a` and `method2a` in:
+  ///
+  ///     class A {
+  ///       A.constructor();     // Not a class instance member.
+  ///       method1a() {}
+  ///       static method1b() {} // Not a class instance member.
+  ///     }
+  ///     mixin B {
+  ///       method2a() {}
+  ///       static method2b() {} // Not a class instance member.
+  ///     }
+  ///     extends C on A {
+  ///       method3a() {}        // Not a class instance member.
+  ///       static method3b() {} // Not a class instance member.
+  ///     }
+  ///
+  bool get isClassInstanceMember => false;
+
+  /// Returns `true` if this builder is an instance member of an extension
+  /// declaration.
+  ///
+  /// For instance `method3a` in:
+  ///
+  ///     class A {
+  ///       A.constructor();     // Not an extension instance member.
+  ///       method1a() {}        // Not an extension instance member.
+  ///       static method1b() {} // Not an extension instance member.
+  ///     }
+  ///     mixin B {
+  ///       method2a() {}        // Not an extension instance member.
+  ///       static method2b() {} // Not an extension instance member.
+  ///     }
+  ///     extends C on A {
+  ///       method3a() {}
+  ///       static method3b() {} // Not an extension instance member.
+  ///     }
+  ///
+  bool get isExtensionInstanceMember => false;
 
   bool get isLocal => false;
 
diff --git a/pkg/front_end/lib/src/fasta/builder/declaration_builder.dart b/pkg/front_end/lib/src/fasta/builder/declaration_builder.dart
new file mode 100644
index 0000000..6704c07
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/builder/declaration_builder.dart
@@ -0,0 +1,54 @@
+// 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.
+
+import 'dart:core' hide MapEntry;
+
+import 'package:kernel/ast.dart';
+
+import '../messages.dart';
+import '../scope.dart';
+
+import 'builder.dart';
+import 'library_builder.dart';
+import 'metadata_builder.dart';
+import 'type_declaration_builder.dart';
+
+abstract class DeclarationBuilder extends TypeDeclarationBuilder {
+  final Scope scope;
+
+  final ScopeBuilder scopeBuilder;
+
+  DeclarationBuilder(List<MetadataBuilder> metadata, int modifiers, String name,
+      LibraryBuilder parent, int charOffset, this.scope)
+      : scopeBuilder = new ScopeBuilder(scope),
+        super(metadata, modifiers, name, parent, charOffset);
+
+  LibraryBuilder get library {
+    LibraryBuilder library = parent;
+    return library.partOfLibrary ?? library;
+  }
+
+  /// Lookup a member accessed statically through this declaration.
+  Builder findStaticBuilder(
+      String name, int charOffset, Uri fileUri, LibraryBuilder accessingLibrary,
+      {bool isSetter: false});
+
+  void addProblem(Message message, int charOffset, int length,
+      {bool wasHandled: false, List<LocatedMessage> context}) {
+    library.addProblem(message, charOffset, length, fileUri,
+        wasHandled: wasHandled, context: context);
+  }
+
+  /// Returns the type of `this` in an instance of this declaration.
+  ///
+  /// This is non-null for class and mixin declarations and `null` for
+  /// extension declarations.
+  InterfaceType get thisType;
+
+  /// Lookups the member [name] declared in this declaration.
+  ///
+  /// If [required] is `true` and no member is found an internal problem is
+  /// reported.
+  Builder lookupLocalMember(String name, {bool required: false});
+}
diff --git a/pkg/front_end/lib/src/fasta/builder/extension_builder.dart b/pkg/front_end/lib/src/fasta/builder/extension_builder.dart
new file mode 100644
index 0000000..d31fa16
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/builder/extension_builder.dart
@@ -0,0 +1,82 @@
+// 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.
+
+import 'dart:core' hide MapEntry;
+
+import 'package:kernel/ast.dart';
+
+import 'builder.dart';
+import 'declaration_builder.dart';
+import 'library_builder.dart';
+import 'metadata_builder.dart';
+import 'type_builder.dart';
+import 'type_variable_builder.dart';
+import '../fasta_codes.dart' show templateInternalProblemNotFoundIn;
+import '../scope.dart';
+import '../problems.dart';
+
+abstract class ExtensionBuilder extends DeclarationBuilder {
+  final List<TypeVariableBuilder> typeParameters;
+  final TypeBuilder onType;
+
+  ExtensionBuilder(
+      List<MetadataBuilder> metadata,
+      int modifiers,
+      String name,
+      LibraryBuilder parent,
+      int charOffset,
+      Scope scope,
+      this.typeParameters,
+      this.onType)
+      : super(metadata, modifiers, name, parent, charOffset, scope);
+
+  /// Lookup a static member of this declaration.
+  Builder findStaticBuilder(
+      String name, int charOffset, Uri fileUri, LibraryBuilder accessingLibrary,
+      {bool isSetter: false}) {
+    if (accessingLibrary.origin != library.origin && name.startsWith("_")) {
+      return null;
+    }
+    Builder declaration = isSetter
+        ? scope.lookupSetter(name, charOffset, fileUri, isInstanceScope: false)
+        : scope.lookup(name, charOffset, fileUri, isInstanceScope: false);
+    // TODO(johnniwinther): Handle patched extensions.
+    return declaration;
+  }
+
+  @override
+  DartType buildType(LibraryBuilder library, List<TypeBuilder> arguments) {
+    throw new UnsupportedError("ExtensionBuilder.buildType is not supported.");
+  }
+
+  @override
+  DartType buildTypesWithBuiltArguments(
+      LibraryBuilder library, List<DartType> arguments) {
+    throw new UnsupportedError("ExtensionBuilder.buildTypesWithBuiltArguments "
+        "is not supported.");
+  }
+
+  @override
+  bool get isExtension => true;
+
+  @override
+  InterfaceType get thisType => null;
+
+  @override
+  Builder lookupLocalMember(String name, {bool required: false}) {
+    // TODO(johnniwinther): Support patching on extensions.
+    Builder builder = scope.local[name];
+    if (required && builder == null) {
+      internalProblem(
+          templateInternalProblemNotFoundIn.withArguments(
+              name, fullNameForErrors),
+          -1,
+          null);
+    }
+    return builder;
+  }
+
+  @override
+  String get debugName => "ExtensionBuilder";
+}
diff --git a/pkg/front_end/lib/src/fasta/builder/field_builder.dart b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
index 364614d..91a427f 100644
--- a/pkg/front_end/lib/src/fasta/builder/field_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
@@ -46,6 +46,8 @@
 
 import '../type_inference/type_schema.dart' show UnknownType;
 
+import 'extension_builder.dart';
+
 class FieldBuilder extends MemberBuilder {
   final String name;
 
@@ -80,11 +82,33 @@
   bool get isEligibleForInference {
     return !library.legacyMode &&
         type == null &&
-        (hasInitializer || isInstanceMember);
+        (hasInitializer || isClassInstanceMember);
   }
 
   Field build(SourceLibraryBuilder library) {
-    field.name ??= new Name(name, library.target);
+    field
+      ..isCovariant = isCovariant
+      ..isFinal = isFinal
+      ..isConst = isConst
+      ..isLate = isLate;
+    if (isExtensionMember) {
+      ExtensionBuilder extension = parent;
+      field.name = new Name('${extension.name}|$name', library.target);
+      field
+        ..hasImplicitGetter = false
+        ..hasImplicitSetter = false
+        ..isStatic = true
+        ..isExtensionMember = true;
+    } else {
+      // TODO(johnniwinther): How can the name already have been computed.
+      field.name ??= new Name(name, library.target);
+      bool isInstanceMember = !isStatic && !isTopLevel;
+      field
+        ..hasImplicitGetter = isInstanceMember
+        ..hasImplicitSetter = isInstanceMember && !isConst && !isFinal
+        ..isStatic = !isInstanceMember
+        ..isExtensionMember = false;
+    }
     if (type != null) {
       field.type = type.build(library);
 
@@ -108,14 +132,6 @@
         }
       }
     }
-    bool isInstanceMember = !isStatic && !isTopLevel;
-    field
-      ..isCovariant = isCovariant
-      ..isFinal = isFinal
-      ..isConst = isConst
-      ..hasImplicitGetter = isInstanceMember
-      ..hasImplicitSetter = isInstanceMember && !isConst && !isFinal
-      ..isStatic = !isInstanceMember;
     return field;
   }
 
diff --git a/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart b/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
index 177280d..89fba82 100644
--- a/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
@@ -19,7 +19,7 @@
 
 import '../constant_context.dart' show ConstantContext;
 
-import '../modifier.dart' show finalMask, initializingFormalMask;
+import '../modifier.dart' show finalMask, initializingFormalMask, requiredMask;
 
 import '../scanner.dart' show Token;
 
@@ -74,8 +74,12 @@
 
   String get debugName => "FormalParameterBuilder";
 
+  // TODO(johnniwinther): Cleanup `isRequired` semantics in face of required
+  // named parameters.
   bool get isRequired => isMandatoryFormalParameterKind(kind);
 
+  bool get isNamedRequired => (modifiers & requiredMask) != 0;
+
   bool get isPositional {
     return isOptionalPositionalFormalParameterKind(kind) ||
         isMandatoryFormalParameterKind(kind);
@@ -100,7 +104,8 @@
           isFinal: isFinal,
           isConst: isConst,
           isFieldFormal: isInitializingFormal,
-          isCovariant: isCovariant)
+          isCovariant: isCovariant,
+          isRequired: isNamedRequired)
         ..fileOffset = charOffset;
     }
     return declaration;
@@ -149,7 +154,7 @@
     // needed to generated noSuchMethod forwarders.
     final bool isConstConstructorParameter =
         (parent is ConstructorBuilder && parent.target.isConst);
-    if ((isConstConstructorParameter || parent.isInstanceMember) &&
+    if ((isConstConstructorParameter || parent.isClassInstanceMember) &&
         initializerToken != null) {
       final ClassBuilder classBuilder = parent.parent;
       Scope scope = classBuilder.scope;
diff --git a/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart b/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart
index 34b14fd..16c1282 100644
--- a/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart
@@ -87,7 +87,8 @@
           if (formal.isRequired) requiredParameterCount++;
         } else if (formal.isNamed) {
           namedParameters ??= <NamedType>[];
-          namedParameters.add(new NamedType(formal.name, type));
+          namedParameters.add(new NamedType(formal.name, type,
+              isRequired: formal.isNamedRequired));
         }
       }
       if (namedParameters != null) {
diff --git a/pkg/front_end/lib/src/fasta/builder/library_builder.dart b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
index f74ee3d..d83d032 100644
--- a/pkg/front_end/lib/src/fasta/builder/library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
@@ -231,14 +231,20 @@
 
   void addSyntheticDeclarationOfDynamic();
 
-  /// Don't use for scope lookup. Only use when an element is known to exist
-  /// (and not a setter).
-  Builder getLocalMember(String name) {
-    return scope.local[name] ??
-        internalProblem(
-            templateInternalProblemNotFoundIn.withArguments(name, "$fileUri"),
-            -1,
-            fileUri);
+  /// Lookups the member [name] declared in this library.
+  ///
+  /// If [required] is `true` and no member is found an internal problem is
+  /// reported.
+  Builder lookupLocalMember(String name, {bool required: false}) {
+    Builder builder = scope.local[name];
+    if (required && builder == null) {
+      internalProblem(
+          templateInternalProblemNotFoundIn.withArguments(
+              name, fullNameForErrors),
+          -1,
+          null);
+    }
+    return builder;
   }
 
   Builder lookup(String name, int charOffset, Uri fileUri) {
diff --git a/pkg/front_end/lib/src/fasta/builder/member_builder.dart b/pkg/front_end/lib/src/fasta/builder/member_builder.dart
index dd40c72..cc6877d 100644
--- a/pkg/front_end/lib/src/fasta/builder/member_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/member_builder.dart
@@ -9,22 +9,42 @@
 import 'builder.dart'
     show ClassBuilder, Builder, LibraryBuilder, ModifierBuilder;
 
+import 'declaration_builder.dart';
+import 'extension_builder.dart';
+
 abstract class MemberBuilder extends ModifierBuilder {
   /// For top-level members, the parent is set correctly during
   /// construction. However, for class members, the parent is initially the
   /// library and updated later.
+  @override
   Builder parent;
 
+  @override
   String get name;
 
   MemberBuilder(this.parent, int charOffset) : super(parent, charOffset);
 
-  bool get isInstanceMember => isClassMember && !isStatic;
+  bool get isDeclarationInstanceMember => isDeclarationMember && !isStatic;
 
+  @override
+  bool get isClassInstanceMember => isClassMember && !isStatic;
+
+  @override
+  bool get isExtensionInstanceMember => isExtensionMember && !isStatic;
+
+  @override
+  bool get isDeclarationMember => parent is DeclarationBuilder;
+
+  @override
   bool get isClassMember => parent is ClassBuilder;
 
-  bool get isTopLevel => !isClassMember;
+  @override
+  bool get isExtensionMember => parent is ExtensionBuilder;
 
+  @override
+  bool get isTopLevel => !isDeclarationMember;
+
+  @override
   bool get isNative => false;
 
   bool get isRedirectingGenerativeConstructor => false;
diff --git a/pkg/front_end/lib/src/fasta/builder/modifier_builder.dart b/pkg/front_end/lib/src/fasta/builder/modifier_builder.dart
index 907ec5a..6357975 100644
--- a/pkg/front_end/lib/src/fasta/builder/modifier_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/modifier_builder.dart
@@ -9,12 +9,12 @@
         abstractMask,
         constMask,
         covariantMask,
-        extensionDeclarationMask,
         externalMask,
         finalMask,
         hasConstConstructorMask,
         hasInitializerMask,
         initializingFormalMask,
+        lateMask,
         mixinDeclarationMask,
         namedMixinApplicationMask,
         staticMask;
@@ -45,6 +45,13 @@
 
   bool get isStatic => (modifiers & staticMask) != 0;
 
+  bool get isLate => (modifiers & lateMask) != 0;
+
+  // TODO(johnniwinther): Add this when semantics for
+  // `FormalParameterBuilder.isRequired` has been updated to support required
+  // named parameters.
+  //bool get isRequired => (modifiers & requiredMask) != 0;
+
   bool get isNamedMixinApplication {
     return (modifiers & namedMixinApplicationMask) != 0;
   }
@@ -57,10 +64,6 @@
 
   bool get isMixin => (modifiers & mixinDeclarationMask) != 0;
 
-  bool get isExtension => (modifiers & extensionDeclarationMask) != 0;
-
-  bool get isClassMember => false;
-
   String get name;
 
   bool get isNative => false;
diff --git a/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart b/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
index d35ed97..b12233e 100644
--- a/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
@@ -72,7 +72,7 @@
   void resolveIn(
       Scope scope, int charOffset, Uri fileUri, LibraryBuilder library) {
     if (declaration != null) return;
-    final name = this.name;
+    final Object name = this.name;
     Builder member;
     if (name is QualifiedName) {
       Object qualifier = name.qualifier;
@@ -195,9 +195,10 @@
 
   Supertype handleInvalidSupertype(
       LibraryBuilder library, int charOffset, Uri fileUri) {
-    var template = declaration.isTypeVariable
-        ? templateSupertypeIsTypeVariable
-        : templateSupertypeIsIllegal;
+    Template<Message Function(String name)> template =
+        declaration.isTypeVariable
+            ? templateSupertypeIsTypeVariable
+            : templateSupertypeIsIllegal;
     library.addProblem(
         template.withArguments(flattenName(name, charOffset, fileUri)),
         charOffset,
diff --git a/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart b/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
index 0ce6588..6f97cf0 100644
--- a/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
@@ -24,6 +24,8 @@
         TypeBuilder,
         TypeVariableBuilder;
 
+import 'extension_builder.dart';
+
 import 'package:kernel/ast.dart'
     show
         Arguments,
@@ -47,6 +49,7 @@
         StaticInvocation,
         StringLiteral,
         SuperInitializer,
+        TreeNode,
         TypeParameter,
         TypeParameterType,
         VariableDeclaration,
@@ -113,10 +116,14 @@
 
   final List<FormalParameterBuilder> formals;
 
-  /// If this procedure is an instance member declared in an extension
-  /// declaration, [extensionThis] holds the synthetically added `this`
-  /// parameter.
-  VariableDeclaration extensionThis;
+  /// If this procedure is an extension instance member, [_extensionThis] holds
+  /// the synthetically added `this` parameter.
+  VariableDeclaration _extensionThis;
+
+  /// If this procedure is an extension instance member,
+  /// [_extensionTypeParameters] holds the type parameters copied from the
+  /// extension declaration.
+  List<TypeParameter> _extensionTypeParameters;
 
   FunctionBuilder(
       this.metadata,
@@ -237,7 +244,7 @@
       // but which needs to have a forwarding stub body in order to ensure that
       // covariance checks occur.  We don't want to replace the forwarding stub
       // body with null.
-      var parent = function.parent;
+      TreeNode parent = function.parent;
       if (!(newBody == null &&
           parent is Procedure &&
           parent.isForwardingSemiStub)) {
@@ -272,7 +279,8 @@
       if (enclosingClass.typeParameters.isNotEmpty) {
         needsCheckVisitor = new IncludesTypeParametersNonCovariantly(
             enclosingClass.typeParameters,
-            // We are checking the parameter types which are in a contravariant position.
+            // We are checking the parameter types which are in a
+            // contravariant position.
             initialVariance: Variance.contravariant);
       }
     }
@@ -307,7 +315,9 @@
         }
       }
     }
-    if (isSetter && (formals?.length != 1 || formals[0].isOptional)) {
+    if (!isExtensionInstanceMember &&
+        isSetter &&
+        (formals?.length != 1 || formals[0].isOptional)) {
       // Replace illegal parameters by single dummy parameter.
       // Do this after building the parameters, since the diet listener
       // assumes that parameters are built, even if illegal in number.
@@ -322,7 +332,9 @@
     if (returnType != null) {
       result.returnType = returnType.build(library);
     }
-    if (!isConstructor && !isInstanceMember && parent is ClassBuilder) {
+    if (!isConstructor &&
+        !isDeclarationInstanceMember &&
+        parent is ClassBuilder) {
       List<TypeParameter> typeParameters = parent.target.typeParameters;
       if (typeParameters.isNotEmpty) {
         Map<TypeParameter, DartType> substitution;
@@ -354,15 +366,38 @@
         }
       }
     }
-    if (parent is ClassBuilder) {
-      ClassBuilder cls = parent;
-      if (cls.isExtension && isInstanceMember) {
-        extensionThis = result.positionalParameters.first;
+    if (isExtensionInstanceMember) {
+      ExtensionBuilder extensionBuilder = parent;
+      _extensionThis = result.positionalParameters.first;
+      if (extensionBuilder.typeParameters != null) {
+        int count = extensionBuilder.typeParameters.length;
+        _extensionTypeParameters = new List<TypeParameter>(count);
+        for (int index = 0; index < count; index++) {
+          _extensionTypeParameters[index] = result.typeParameters[index];
+        }
       }
     }
     return function = result;
   }
 
+  /// Returns the parameter for 'this' synthetically added to extension
+  /// instance members.
+  VariableDeclaration get extensionThis {
+    assert(_extensionThis != null || !isExtensionInstanceMember,
+        "ProcedureBuilder.extensionThis has not been set.");
+    return _extensionThis;
+  }
+
+  /// Returns a list of synthetic type parameters added to extension instance
+  /// members.
+  List<TypeParameter> get extensionTypeParameters {
+    // Use [_extensionThis] as marker for whether extension type parameters have
+    // been computed.
+    assert(_extensionThis != null || !isExtensionInstanceMember,
+        "ProcedureBuilder.extensionTypeParameters has not been set.");
+    return _extensionTypeParameters;
+  }
+
   Member build(SourceLibraryBuilder library);
 
   @override
@@ -420,6 +455,7 @@
 class ProcedureBuilder extends FunctionBuilder {
   final Procedure procedure;
   final int charOpenParenOffset;
+  final ProcedureKind kind;
 
   AsyncMarker actualAsyncModifier = AsyncMarker.Sync;
 
@@ -435,7 +471,7 @@
       String name,
       List<TypeVariableBuilder> typeVariables,
       List<FormalParameterBuilder> formals,
-      ProcedureKind kind,
+      this.kind,
       SourceLibraryBuilder compilationUnit,
       int startCharOffset,
       int charOffset,
@@ -453,8 +489,6 @@
   @override
   ProcedureBuilder get origin => actualOrigin ?? this;
 
-  ProcedureKind get kind => procedure.kind;
-
   AsyncMarker get asyncModifier => actualAsyncModifier;
 
   Statement get body {
@@ -475,10 +509,10 @@
 
   bool get isEligibleForTopLevelInference {
     if (library.legacyMode) return false;
-    if (isInstanceMember) {
+    if (isDeclarationInstanceMember) {
       if (returnType == null) return true;
       if (formals != null) {
-        for (var formal in formals) {
+        for (FormalParameterBuilder formal in formals) {
           if (formal.type == null) return true;
         }
       }
@@ -488,11 +522,7 @@
 
   /// Returns `true` if this procedure is declared in an extension declaration.
   bool get isExtensionMethod {
-    if (parent is ClassBuilder) {
-      ClassBuilder cls = parent;
-      return cls.isExtension;
-    }
-    return false;
+    return parent is ExtensionBuilder;
   }
 
   Procedure build(SourceLibraryBuilder library) {
@@ -506,11 +536,32 @@
       procedure.isExternal = isExternal;
       procedure.isConst = isConst;
       if (isExtensionMethod) {
-        ClassBuilder extension = parent;
-        procedure.isStatic = false;
-        procedure.isExtensionMethod = true;
-        procedure.kind = ProcedureKind.Method;
-        procedure.name = new Name('${extension.name}|${name}', library.target);
+        ExtensionBuilder extension = parent;
+        procedure.isExtensionMember = true;
+        procedure.isStatic = true;
+        String kindInfix = '';
+        if (isExtensionInstanceMember) {
+          // Instance getter and setter are converted to methods so we use an
+          // infix to make their names unique.
+          switch (kind) {
+            case ProcedureKind.Getter:
+              kindInfix = 'get#';
+              break;
+            case ProcedureKind.Setter:
+              kindInfix = 'set#';
+              break;
+            case ProcedureKind.Method:
+            case ProcedureKind.Operator:
+              kindInfix = '';
+              break;
+            case ProcedureKind.Factory:
+              throw new UnsupportedError(
+                  'Unexpected extension method kind ${kind}');
+          }
+          procedure.kind = ProcedureKind.Method;
+        }
+        procedure.name =
+            new Name('${extension.name}|${kindInfix}${name}', library.target);
       } else {
         procedure.isStatic = isStatic;
         procedure.name = new Name(name, library.target);
@@ -599,7 +650,11 @@
   @override
   ConstructorBuilder get origin => actualOrigin ?? this;
 
-  bool get isInstanceMember => false;
+  @override
+  bool get isDeclarationInstanceMember => false;
+
+  @override
+  bool get isClassInstanceMember => false;
 
   bool get isConstructor => true;
 
@@ -614,7 +669,7 @@
   bool get isEligibleForTopLevelInference {
     if (library.legacyMode) return false;
     if (formals != null) {
-      for (var formal in formals) {
+      for (FormalParameterBuilder formal in formals) {
         if (formal.type == null && formal.isInitializingFormal) return true;
       }
     }
diff --git a/pkg/front_end/lib/src/fasta/builder/type_alias_builder.dart b/pkg/front_end/lib/src/fasta/builder/type_alias_builder.dart
index 430ef0a..3a151b4 100644
--- a/pkg/front_end/lib/src/fasta/builder/type_alias_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/type_alias_builder.dart
@@ -55,9 +55,8 @@
       [Typedef target])
       : target = target ??
             (new Typedef(name, null,
-                typeParameters:
-                    TypeVariableBuilder.kernelTypeParametersFromBuilders(
-                        typeVariables),
+                typeParameters: TypeVariableBuilder.typeParametersFromBuilders(
+                    typeVariables),
                 fileUri: parent.target.fileUri)
               ..fileOffset = charOffset),
         super(metadata, 0, name, parent, charOffset);
@@ -138,7 +137,7 @@
   /// [arguments] have already been built.
   DartType buildTypesWithBuiltArguments(
       LibraryBuilder library, List<DartType> arguments) {
-    var thisType = buildThisType(library);
+    DartType thisType = buildThisType(library);
     if (const DynamicType() == thisType) return thisType;
     FunctionType result = thisType;
     if (target.typeParameters.isEmpty && arguments == null) return result;
@@ -193,7 +192,7 @@
 
   @override
   DartType buildType(LibraryBuilder library, List<TypeBuilder> arguments) {
-    var thisType = buildThisType(library);
+    DartType thisType = buildThisType(library);
     if (thisType is InvalidType) return thisType;
     FunctionType result = thisType;
     if (target.typeParameters.isEmpty && arguments == null) return result;
diff --git a/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart b/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart
index 54a4f58..05f880f 100644
--- a/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart
@@ -125,7 +125,7 @@
   @override
   int get hashCode => target.hashCode;
 
-  static List<TypeParameter> kernelTypeParametersFromBuilders(
+  static List<TypeParameter> typeParametersFromBuilders(
       List<TypeVariableBuilder> builders) {
     if (builders == null) return null;
     List<TypeParameter> result =
diff --git a/pkg/front_end/lib/src/fasta/command_line_reporting.dart b/pkg/front_end/lib/src/fasta/command_line_reporting.dart
index 2f406fb..8aad521 100644
--- a/pkg/front_end/lib/src/fasta/command_line_reporting.dart
+++ b/pkg/front_end/lib/src/fasta/command_line_reporting.dart
@@ -50,24 +50,24 @@
       length = 1;
     }
     String prefix = severityPrefixes[severity];
-    String text =
+    String messageText =
         prefix == null ? message.message : "$prefix: ${message.message}";
     if (message.tip != null) {
-      text += "\n${message.tip}";
+      messageText += "\n${message.tip}";
     }
     if (CompilerContext.enableColors) {
       switch (severity) {
         case Severity.error:
         case Severity.internalProblem:
-          text = red(text);
+          messageText = red(messageText);
           break;
 
         case Severity.warning:
-          text = magenta(text);
+          messageText = magenta(messageText);
           break;
 
         case Severity.context:
-          text = green(text);
+          messageText = green(messageText);
           break;
 
         default:
@@ -84,42 +84,10 @@
         location = null;
       }
       String sourceLine = getSourceLine(location);
-      if (sourceLine == null) {
-        sourceLine = "";
-      } else if (sourceLine.isNotEmpty) {
-        // TODO(askesc): Much more could be done to indent properly in the
-        // presence of all sorts of unicode weirdness.
-        // This handling covers the common case of single-width characters
-        // indented with spaces and/or tabs, using no surrogates.
-        int indentLength = location.column - 1;
-        Uint8List indentation = new Uint8List(indentLength + length)
-          ..fillRange(0, indentLength, $SPACE)
-          ..fillRange(indentLength, indentLength + length, $CARET);
-        int lengthInSourceLine = min(indentation.length, sourceLine.length);
-        for (int i = 0; i < lengthInSourceLine; i++) {
-          if (sourceLine.codeUnitAt(i) == $TAB) {
-            indentation[i] = $TAB;
-          }
-        }
-        String pointer = new String.fromCharCodes(indentation);
-        if (pointer.length > sourceLine.length) {
-          // Truncate the carets to handle messages that span multiple lines.
-          int pointerLength = sourceLine.length;
-          // Add one to cover the case of a parser error pointing to EOF when
-          // the last line doesn't end with a newline. For messages spanning
-          // multiple lines, this also provides a minor visual clue that can be
-          // useful for debugging Fasta.
-          pointerLength += 1;
-          pointer = pointer.substring(0, pointerLength);
-          pointer += "...";
-        }
-        sourceLine = "\n$sourceLine\n$pointer";
-      }
-      String position =
-          location == null ? "" : ":${location.line}:${location.column}";
-      return "$path$position: $text$sourceLine";
+      return formatErrorMessage(
+          sourceLine, location, length, path, messageText);
     } else {
-      return text;
+      return messageText;
     }
   } catch (error, trace) {
     print("Crash when formatting: "
@@ -130,6 +98,44 @@
   }
 }
 
+String formatErrorMessage(String sourceLine, Location location,
+    int squigglyLength, String path, String messageText) {
+  if (sourceLine == null) {
+    sourceLine = "";
+  } else if (sourceLine.isNotEmpty) {
+    // TODO(askesc): Much more could be done to indent properly in the
+    // presence of all sorts of unicode weirdness.
+    // This handling covers the common case of single-width characters
+    // indented with spaces and/or tabs, using no surrogates.
+    int indentLength = location.column - 1;
+    Uint8List indentation = new Uint8List(indentLength + squigglyLength)
+      ..fillRange(0, indentLength, $SPACE)
+      ..fillRange(indentLength, indentLength + squigglyLength, $CARET);
+    int lengthInSourceLine = min(indentation.length, sourceLine.length);
+    for (int i = 0; i < lengthInSourceLine; i++) {
+      if (sourceLine.codeUnitAt(i) == $TAB) {
+        indentation[i] = $TAB;
+      }
+    }
+    String pointer = new String.fromCharCodes(indentation);
+    if (pointer.length > sourceLine.length) {
+      // Truncate the carets to handle messages that span multiple lines.
+      int pointerLength = sourceLine.length;
+      // Add one to cover the case of a parser error pointing to EOF when
+      // the last line doesn't end with a newline. For messages spanning
+      // multiple lines, this also provides a minor visual clue that can be
+      // useful for debugging Fasta.
+      pointerLength += 1;
+      pointer = pointer.substring(0, pointerLength);
+      pointer += "...";
+    }
+    sourceLine = "\n$sourceLine\n$pointer";
+  }
+  String position =
+      location == null ? "" : ":${location.line}:${location.column}";
+  return "$path$position: $messageText$sourceLine";
+}
+
 /// Are problems of [severity] suppressed?
 bool isHidden(Severity severity) {
   switch (severity) {
diff --git a/pkg/front_end/lib/src/fasta/compiler_context.dart b/pkg/front_end/lib/src/fasta/compiler_context.dart
index c861e50..4aabb61 100644
--- a/pkg/front_end/lib/src/fasta/compiler_context.dart
+++ b/pkg/front_end/lib/src/fasta/compiler_context.dart
@@ -106,8 +106,8 @@
     if (context == null) {
       // Note: we throw directly and don't use internalProblem, because
       // internalProblem depends on having a compiler context available.
-      var message = messageInternalProblemMissingContext.message;
-      var tip = messageInternalProblemMissingContext.tip;
+      String message = messageInternalProblemMissingContext.message;
+      String tip = messageInternalProblemMissingContext.tip;
       throw "Internal problem: $message\nTip: $tip";
     }
     return context;
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
index c058725..f95d327 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
@@ -16,7 +16,9 @@
         Library,
         ListLiteral,
         Member,
+        NamedNode,
         Procedure,
+        Reference,
         StaticGet,
         StringLiteral,
         Typedef;
@@ -159,7 +161,7 @@
     if (name == "_exports#") {
       Field field = member;
       StringLiteral string = field.initializer;
-      var json = jsonDecode(string.value);
+      Map<dynamic, dynamic> json = jsonDecode(string.value);
       unserializableExports =
           json != null ? new Map<String, String>.from(json) : null;
     } else {
@@ -253,8 +255,8 @@
       exportScopeBuilder.addMember(name, declaration);
     });
 
-    for (var reference in library.additionalExports) {
-      var node = reference.node;
+    for (Reference reference in library.additionalExports) {
+      NamedNode node = reference.node;
       Uri libraryUri;
       String name;
       bool isSetter = false;
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_loader.dart b/pkg/front_end/lib/src/fasta/dill/dill_loader.dart
index 46d79f1..1a6bbc2 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_loader.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_loader.dart
@@ -79,7 +79,7 @@
   ClassBuilder computeClassBuilderFromTargetClass(Class cls) {
     Library kernelLibrary = cls.enclosingLibrary;
     LibraryBuilder library = builders[kernelLibrary.importUri];
-    return library.getLocalMember(cls.name);
+    return library.lookupLocalMember(cls.name, required: true);
   }
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_member_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_member_builder.dart
index e733b84..1884cfc 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_member_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_member_builder.dart
@@ -14,7 +14,7 @@
         isRedirectingGenerativeConstructorImplementation;
 
 import '../modifier.dart'
-    show abstractMask, constMask, externalMask, finalMask, staticMask;
+    show abstractMask, constMask, externalMask, finalMask, lateMask, staticMask;
 
 import '../problems.dart' show unhandled;
 
@@ -37,7 +37,7 @@
   bool get isConstructor => member is Constructor;
 
   ProcedureKind get kind {
-    final member = this.member;
+    final Member member = this.member;
     return member is Procedure ? member.kind : null;
   }
 
@@ -70,6 +70,7 @@
   if (member is Field) {
     modifier |= member.isConst ? constMask : 0;
     modifier |= member.isFinal ? finalMask : 0;
+    modifier |= member.isLate ? lateMask : 0;
     modifier |= member.isStatic ? staticMask : 0;
   } else if (member is Procedure) {
     modifier |= member.isConst ? constMask : 0;
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_target.dart b/pkg/front_end/lib/src/fasta/dill/dill_target.dart
index 59386d9..e9453fe 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_target.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_target.dart
@@ -60,7 +60,9 @@
   @override
   DillLibraryBuilder createLibraryBuilder(Uri uri, Uri fileUri, origin) {
     assert(origin == null);
-    return libraryBuilders.remove(uri);
+    DillLibraryBuilder libraryBuilder = libraryBuilders.remove(uri);
+    assert(libraryBuilder != null, "No library found for $uri.");
+    return libraryBuilder;
   }
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
index 9c46c62..7db58b7 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -7,6 +7,8 @@
 // Instead modify 'pkg/front_end/messages.yaml' and run
 // 'pkg/front_end/tool/fasta generate-messages' to update.
 
+// ignore_for_file: lines_longer_than_80_chars
+
 part of fasta.codes;
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -3576,7 +3578,7 @@
     Read the SDK platform from <file>, which should be in Dill/Kernel IR format
     and contain the Dart SDK.
 
-  --target=dart2js|dart2js_server|dart_runner|flutter|flutter_runner|none|vm
+  --target=dart2js|dart2js_server|dart_runner|dartdevc|flutter|flutter_runner|none|vm
     Specify the target configuration.
 
   --enable-asserts
diff --git a/pkg/front_end/lib/src/fasta/flow_analysis/flow_analysis.dart b/pkg/front_end/lib/src/fasta/flow_analysis/flow_analysis.dart
index cafa01b..e17c773 100644
--- a/pkg/front_end/lib/src/fasta/flow_analysis/flow_analysis.dart
+++ b/pkg/front_end/lib/src/fasta/flow_analysis/flow_analysis.dart
@@ -138,48 +138,42 @@
     }
   }
 
-  void conditional_elseBegin(Expression conditionalExpression,
-      Expression thenExpression, bool isBool) {
+  void conditional_elseBegin(Expression thenExpression) {
     var afterThen = _current;
     var falseCondition = _stack.removeLast();
 
-    if (isBool) {
-      _conditionalEnd(thenExpression);
-      // Tail of the stack: falseThen, trueThen
-    }
+    _conditionalEnd(thenExpression);
+    // Tail of the stack: falseThen, trueThen
 
     _stack.add(afterThen);
     _current = falseCondition;
   }
 
-  void conditional_end(Expression conditionalExpression,
-      Expression elseExpression, bool isBool) {
+  void conditional_end(
+      Expression conditionalExpression, Expression elseExpression) {
     var afterThen = _stack.removeLast();
     var afterElse = _current;
 
-    if (isBool) {
-      _conditionalEnd(elseExpression);
-      // Tail of the stack: falseThen, trueThen, falseElse, trueElse
+    _conditionalEnd(elseExpression);
+    // Tail of the stack: falseThen, trueThen, falseElse, trueElse
 
-      var trueElse = _stack.removeLast();
-      var falseElse = _stack.removeLast();
+    var trueElse = _stack.removeLast();
+    var falseElse = _stack.removeLast();
 
-      var trueThen = _stack.removeLast();
-      var falseThen = _stack.removeLast();
+    var trueThen = _stack.removeLast();
+    var falseThen = _stack.removeLast();
 
-      var trueResult = _join(trueThen, trueElse);
-      var falseResult = _join(falseThen, falseElse);
+    var trueResult = _join(trueThen, trueElse);
+    var falseResult = _join(falseThen, falseElse);
 
-      _condition = conditionalExpression;
-      _conditionTrue = trueResult;
-      _conditionFalse = falseResult;
-    }
+    _condition = conditionalExpression;
+    _conditionTrue = trueResult;
+    _conditionFalse = falseResult;
 
     _current = _join(afterThen, afterElse);
   }
 
-  void conditional_thenBegin(
-      Expression conditionalExpression, Expression condition) {
+  void conditional_thenBegin(Expression condition) {
     _conditionalEnd(condition);
     // Tail of the stack: falseCondition, trueCondition
 
@@ -224,7 +218,7 @@
     _current = _join(_current, continueState);
   }
 
-  void doStatement_end(Statement doStatement, Expression condition) {
+  void doStatement_end(Expression condition) {
     _conditionalEnd(condition);
     // Tail of the stack:  break, falseCondition, trueCondition
 
@@ -399,33 +393,48 @@
     }
   }
 
-  void logicalAnd_end(Expression andExpression, Expression rightOperand) {
+  void logicalBinaryOp_end(Expression wholeExpression, Expression rightOperand,
+      {@required bool isAnd}) {
     _conditionalEnd(rightOperand);
     // Tail of the stack: falseLeft, trueLeft, falseRight, trueRight
 
     var trueRight = _stack.removeLast();
     var falseRight = _stack.removeLast();
 
-    _stack.removeLast(); // trueLeft is not used
+    var trueLeft = _stack.removeLast();
     var falseLeft = _stack.removeLast();
 
-    var trueResult = trueRight;
-    var falseResult = _join(falseLeft, falseRight);
+    FlowModel<Variable, Type> trueResult;
+    FlowModel<Variable, Type> falseResult;
+    if (isAnd) {
+      trueResult = trueRight;
+      falseResult = _join(falseLeft, falseRight);
+    } else {
+      trueResult = _join(trueLeft, trueRight);
+      falseResult = falseRight;
+    }
+
     var afterResult = _join(trueResult, falseResult);
 
-    _condition = andExpression;
+    _condition = wholeExpression;
     _conditionTrue = trueResult;
     _conditionFalse = falseResult;
 
     _current = afterResult;
   }
 
-  void logicalAnd_rightBegin(Expression andExpression, Expression leftOperand) {
+  void logicalBinaryOp_rightBegin(Expression leftOperand,
+      {@required bool isAnd}) {
     _conditionalEnd(leftOperand);
     // Tail of the stack: falseLeft, trueLeft
 
-    var trueLeft = _stack.last;
-    _current = trueLeft;
+    if (isAnd) {
+      var trueLeft = _stack.last;
+      _current = trueLeft;
+    } else {
+      var falseLeft = _stack[_stack.length - 2];
+      _current = falseLeft;
+    }
   }
 
   void logicalNot_end(Expression notExpression, Expression operand) {
@@ -438,35 +447,6 @@
     _conditionFalse = trueExpr;
   }
 
-  void logicalOr_end(Expression orExpression, Expression rightOperand) {
-    _conditionalEnd(rightOperand);
-    // Tail of the stack: falseLeft, trueLeft, falseRight, trueRight
-
-    var trueRight = _stack.removeLast();
-    var falseRight = _stack.removeLast();
-
-    var trueLeft = _stack.removeLast();
-    _stack.removeLast(); // falseLeft is not used
-
-    var trueResult = _join(trueLeft, trueRight);
-    var falseResult = falseRight;
-    var afterResult = _join(trueResult, falseResult);
-
-    _condition = orExpression;
-    _conditionTrue = trueResult;
-    _conditionFalse = falseResult;
-
-    _current = afterResult;
-  }
-
-  void logicalOr_rightBegin(Expression orExpression, Expression leftOperand) {
-    _conditionalEnd(leftOperand);
-    // Tail of the stack: falseLeft, trueLeft
-
-    var falseLeft = _stack[_stack.length - 2];
-    _current = falseLeft;
-  }
-
   /// Retrieves the type that the [variable] is promoted to, if the [variable]
   /// is currently promoted.  Otherwise returns `null`.
   Type promotedType(Variable variable) {
diff --git a/pkg/front_end/lib/src/fasta/get_dependencies.dart b/pkg/front_end/lib/src/fasta/get_dependencies.dart
index abd9879..22b621a 100644
--- a/pkg/front_end/lib/src/fasta/get_dependencies.dart
+++ b/pkg/front_end/lib/src/fasta/get_dependencies.dart
@@ -6,7 +6,7 @@
 
 import 'dart:async' show Future;
 
-import 'package:kernel/kernel.dart' show loadComponentFromBytes;
+import 'package:kernel/kernel.dart' show Component, loadComponentFromBytes;
 
 import 'package:kernel/target/targets.dart' show Target;
 
@@ -30,13 +30,14 @@
     Uri platform,
     bool verbose: false,
     Target target}) async {
-  var options = new CompilerOptions()
+  CompilerOptions options = new CompilerOptions()
     ..target = target
     ..verbose = verbose
     ..packagesFileUri = packages
     ..sdkSummary = platform
     ..sdkRoot = sdk;
-  var pOptions = new ProcessedOptions(options: options, inputs: <Uri>[script]);
+  ProcessedOptions pOptions =
+      new ProcessedOptions(options: options, inputs: <Uri>[script]);
   return await CompilerContext.runWithOptions(pOptions,
       (CompilerContext c) async {
     FileSystem fileSystem = c.options.fileSystem;
@@ -45,8 +46,8 @@
     DillTarget dillTarget =
         new DillTarget(c.options.ticker, uriTranslator, c.options.target);
     if (platform != null) {
-      var bytes = await fileSystem.entityForUri(platform).readAsBytes();
-      var platformComponent = loadComponentFromBytes(bytes);
+      List<int> bytes = await fileSystem.entityForUri(platform).readAsBytes();
+      Component platformComponent = loadComponentFromBytes(bytes);
       dillTarget.loader.appendLibraries(platformComponent);
     }
     KernelTarget kernelTarget =
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 a0ad9c1..c15646d 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -6,6 +6,8 @@
 
 import 'dart:core' hide MapEntry;
 
+import '../builder/declaration_builder.dart';
+
 import '../constant_context.dart' show ConstantContext;
 
 import '../dill/dill_library_builder.dart' show DillLibraryBuilder;
@@ -16,7 +18,8 @@
 
 import '../messages.dart' as messages show getLocationFromUri;
 
-import '../modifier.dart' show Modifier, constMask, covariantMask, finalMask;
+import '../modifier.dart'
+    show Modifier, constMask, covariantMask, finalMask, lateMask;
 
 import '../names.dart'
     show callName, emptyName, indexGetName, indexSetName, minusName, plusName;
@@ -81,36 +84,10 @@
 
 import 'constness.dart' show Constness;
 
-import 'expression_generator.dart'
-    show
-        DelayedAssignment,
-        DelayedPostfixIncrement,
-        Generator,
-        IncompleteErrorGenerator,
-        IncompletePropertyAccessGenerator,
-        IncompleteSendGenerator,
-        IndexedAccessGenerator,
-        LoadLibraryGenerator,
-        ParenthesizedExpressionGenerator,
-        ParserErrorGenerator,
-        PrefixUseGenerator,
-        PropertyAccessGenerator,
-        ReadOnlyAccessGenerator,
-        SendAccessGenerator,
-        StaticAccessGenerator,
-        SuperIndexedAccessGenerator,
-        ThisAccessGenerator,
-        ThisPropertyAccessGenerator,
-        TypeUseGenerator,
-        UnlinkedGenerator,
-        UnresolvedNameGenerator,
-        VariableUseGenerator,
-        buildIsNull;
+import 'expression_generator.dart';
 
 import 'expression_generator_helper.dart' show ExpressionGeneratorHelper;
 
-import 'fangorn.dart' show Fangorn;
-
 import 'forest.dart' show Forest;
 
 import 'implicit_type_argument.dart' show ImplicitTypeArgument;
@@ -151,6 +128,11 @@
 
   final ModifierBuilder member;
 
+  /// The class, mixin or extension declaration in which [member] is declared,
+  /// if any.
+  final DeclarationBuilder declarationBuilder;
+
+  /// The class or mixin declaration in which [member] is declared, if any.
   final ClassBuilder classBuilder;
 
   final ClassHierarchy hierarchy;
@@ -158,7 +140,7 @@
   @override
   final CoreTypes coreTypes;
 
-  final bool isInstanceMember;
+  final bool isDeclarationInstanceMember;
 
   final Scope enclosingScope;
 
@@ -280,79 +262,88 @@
   /// for `this`.
   final VariableDeclaration extensionThis;
 
+  final List<TypeParameter> extensionTypeParameters;
+
   BodyBuilder(
-      this.library,
+      {this.library,
       this.member,
       this.enclosingScope,
       this.formalParameterScope,
       this.hierarchy,
       this.coreTypes,
-      this.classBuilder,
-      this.isInstanceMember,
+      this.declarationBuilder,
+      this.isDeclarationInstanceMember,
       this.extensionThis,
+      this.extensionTypeParameters,
       this.uri,
-      this.typeInferrer)
-      : forest = const Fangorn(),
+      this.typeInferrer})
+      : forest = const Forest(),
+        classBuilder =
+            declarationBuilder is ClassBuilder ? declarationBuilder : null,
         enableNative =
             library.loader.target.backendTarget.enableNative(library.uri),
         stringExpectedAfterNative =
             library.loader.target.backendTarget.nativeExtensionExpectsString,
         ignoreMainInGetMainClosure = library.uri.scheme == 'dart' &&
             (library.uri.path == "_builtin" || library.uri.path == "ui"),
-        needsImplicitSuperInitializer =
-            coreTypes?.objectClass != classBuilder?.cls,
+        needsImplicitSuperInitializer = declarationBuilder is ClassBuilder &&
+            coreTypes?.objectClass != declarationBuilder.cls,
         typePromoter = typeInferrer?.typePromoter,
         legacyMode = library.legacyMode,
         super(enclosingScope);
 
   BodyBuilder.withParents(FieldBuilder field, SourceLibraryBuilder part,
-      ClassBuilder classBuilder, TypeInferrer typeInferrer)
+      DeclarationBuilder declarationBuilder, TypeInferrer typeInferrer)
       : this(
-            part,
-            field,
-            classBuilder?.scope ?? field.library.scope,
-            null,
-            part.loader.hierarchy,
-            part.loader.coreTypes,
-            classBuilder,
-            field.isInstanceMember,
-            null,
-            field.fileUri,
-            typeInferrer);
+            library: part,
+            member: field,
+            enclosingScope: declarationBuilder?.scope ?? field.library.scope,
+            formalParameterScope: null,
+            hierarchy: part.loader.hierarchy,
+            coreTypes: part.loader.coreTypes,
+            declarationBuilder: declarationBuilder,
+            isDeclarationInstanceMember: field.isDeclarationInstanceMember,
+            extensionThis: null,
+            uri: field.fileUri,
+            typeInferrer: typeInferrer);
 
   BodyBuilder.forField(FieldBuilder field, TypeInferrer typeInferrer)
       : this.withParents(
             field,
-            field.parent is ClassBuilder ? field.parent.parent : field.parent,
-            field.parent is ClassBuilder ? field.parent : null,
+            field.parent is DeclarationBuilder
+                ? field.parent.parent
+                : field.parent,
+            field.parent is DeclarationBuilder ? field.parent : null,
             typeInferrer);
 
   BodyBuilder.forOutlineExpression(
       SourceLibraryBuilder library,
-      ClassBuilder classBuilder,
+      DeclarationBuilder declarationBuilder,
       ModifierBuilder member,
       Scope scope,
       Uri fileUri)
       : this(
-            library,
-            member,
-            scope,
-            null,
-            library.loader.hierarchy,
-            library.loader.coreTypes,
-            classBuilder,
-            member?.isInstanceMember ?? false,
-            null,
-            fileUri,
-            library.loader.typeInferenceEngine?.createLocalTypeInferrer(
-                fileUri, classBuilder?.target?.thisType, library));
+            library: library,
+            member: member,
+            enclosingScope: scope,
+            formalParameterScope: null,
+            hierarchy: library.loader.hierarchy,
+            coreTypes: library.loader.coreTypes,
+            declarationBuilder: declarationBuilder,
+            isDeclarationInstanceMember:
+                member?.isDeclarationInstanceMember ?? false,
+            extensionThis: null,
+            uri: fileUri,
+            typeInferrer: library.loader.typeInferenceEngine
+                ?.createLocalTypeInferrer(
+                    fileUri, declarationBuilder?.thisType, library));
 
   bool get inConstructor {
     return functionNestingLevel == 0 && member is ConstructorBuilder;
   }
 
-  bool get isInstanceContext {
-    return isInstanceMember || member is ConstructorBuilder;
+  bool get isDeclarationInstanceContext {
+    return isDeclarationInstanceMember || member is ConstructorBuilder;
   }
 
   TypeEnvironment get typeEnvironment => typeInferrer?.typeSchemaEnvironment;
@@ -417,7 +408,7 @@
   }
 
   Statement popBlock(int count, Token openBrace, Token closeBrace) {
-    return forest.block(
+    return forest.createBlock(
         openBrace,
         const GrowableList<Statement>().pop(stack, count) ?? <Statement>[],
         closeBrace);
@@ -531,7 +522,7 @@
     pushQualifiedReference(beginToken.next, periodBeforeName);
     if (arguments != null) {
       push(arguments);
-      buildConstructorReferenceInvocation(
+      _buildConstructorReferenceInvocation(
           beginToken.next, beginToken.offset, Constness.explicitConst);
       push(popForValue());
     } else {
@@ -589,7 +580,6 @@
       Token beginToken,
       Token endToken) {
     debugEvent("TopLevelFields");
-    // TODO(danrubel): handle NNBD 'late' modifier
     if (!library.loader.target.enableNonNullable) {
       reportNonNullableModifierError(lateToken);
     }
@@ -600,7 +590,6 @@
   void endFields(Token staticToken, Token covariantToken, Token lateToken,
       Token varFinalOrConst, int count, Token beginToken, Token endToken) {
     debugEvent("Fields");
-    // TODO(danrubel): handle NNBD 'late' modifier
     if (!library.loader.target.enableNonNullable) {
       reportNonNullableModifierError(lateToken);
     }
@@ -617,10 +606,11 @@
       Identifier identifier = pop();
       String name = identifier.name;
       Builder declaration;
-      if (classBuilder != null) {
-        declaration = classBuilder.getLocalMember(name);
+      if (declarationBuilder != null) {
+        declaration =
+            declarationBuilder.lookupLocalMember(name, required: true);
       } else {
-        declaration = library.getLocalMember(name);
+        declaration = library.lookupLocalMember(name, required: true);
       }
       FieldBuilder field;
       if (declaration.isField && declaration.next == null) {
@@ -803,7 +793,7 @@
         if (parameter.isOptional || initializer != null) {
           VariableDeclaration realParameter = builder.formals[i].target;
           if (parameter.isOptional) {
-            initializer ??= forest.literalNull(
+            initializer ??= forest.createNullLiteral(
                 // TODO(ahe): Should store: realParameter.fileOffset
                 // https://github.com/dart-lang/sdk/issues/32289
                 null);
@@ -832,7 +822,7 @@
     // [legacyMode] is enabled.
     // 2) the member [typeEnvironment] might be null when [legacyMode] is
     // enabled.
-    // This particular behaviour can be observed when running the fasta perf
+    // This particular behavior can be observed when running the fasta perf
     // benchmarks.
     if (!legacyMode && builder.returnType != null) {
       DartType returnType = builder.function.returnType;
@@ -905,12 +895,13 @@
             statements.add(parameter.target);
           }
           statements.add(body);
-          body = forest.block(null, statements, null)..fileOffset = charOffset;
+          body = forest.createBlock(null, statements, null)
+            ..fileOffset = charOffset;
         }
-        body = forest.block(
+        body = forest.createBlock(
             null,
             <Statement>[
-              forest.expressionStatement(
+              forest.createExpressionStatement(
                   // This error is added after type inference is done, so we
                   // don't need to wrap errors in SyntheticExpressionJudgment.
                   desugarSyntheticExpression(buildProblem(
@@ -1009,7 +1000,9 @@
         }
       } else {
         TreeNode parent = invocation.parent;
-        while (parent is! Component && parent != null) parent = parent.parent;
+        while (parent is! Component && parent != null) {
+          parent = parent.parent;
+        }
         if (parent == null) continue;
       }
 
@@ -1032,7 +1025,7 @@
       } else if (resolvedTarget is Constructor &&
           resolvedTarget.enclosingClass.isAbstract) {
         replacementNode = evaluateArgumentsBefore(
-            forest.arguments(invocation.arguments.positional, null,
+            forest.createArguments(invocation.arguments.positional, null,
                 types: invocation.arguments.types,
                 named: invocation.arguments.named),
             buildAbstractClassInstantiationError(
@@ -1050,9 +1043,10 @@
           String errorName = redirectingFactoryBody.unresolvedName;
 
           replacementNode = throwNoSuchMethodError(
-              forest.literalNull(null)..fileOffset = invocation.fileOffset,
+              forest.createNullLiteral(null)
+                ..fileOffset = invocation.fileOffset,
               errorName,
-              forest.arguments(invocation.arguments.positional, null,
+              forest.createArguments(invocation.arguments.positional, null,
                   types: invocation.arguments.types,
                   named: invocation.arguments.named),
               initialTarget.fileOffset);
@@ -1070,7 +1064,7 @@
 
           replacementNode = buildStaticInvocation(
               resolvedTarget,
-              forest.arguments(invocation.arguments.positional, null,
+              forest.createArguments(invocation.arguments.positional, null,
                   types: invocation.arguments.types,
                   named: invocation.arguments.named),
               constness: invocation.isConst
@@ -1269,7 +1263,7 @@
       /// >unless the enclosing class is class Object.
       Constructor superTarget = lookupConstructor(emptyName, isSuper: true);
       Initializer initializer;
-      Arguments arguments = forest.argumentsEmpty(noLocation);
+      Arguments arguments = forest.createArgumentsEmpty(noLocation);
       if (superTarget == null ||
           checkArgumentsForFunction(superTarget.function, arguments,
                   builder.charOffset, const <TypeParameter>[]) !=
@@ -1307,7 +1301,7 @@
   @override
   void handleExpressionStatement(Token token) {
     debugEvent("ExpressionStatement");
-    push(forest.expressionStatement(popForEffect(), token));
+    push(forest.createExpressionStatement(popForEffect(), token));
   }
 
   @override
@@ -1343,18 +1337,20 @@
           arguments.getRange(0, firstNamedArgumentIndex));
       List<NamedExpression> named = new List<NamedExpression>.from(
           arguments.getRange(firstNamedArgumentIndex, arguments.length));
-      push(forest.arguments(positional, beginToken, named: named));
+      push(forest.createArguments(positional, beginToken, named: named));
     } else {
       // TODO(kmillikin): Find a way to avoid allocating a second list in the
       // case where there were no named arguments, which is a common one.
-      push(forest.arguments(new List<Expression>.from(arguments), beginToken));
+      push(forest.createArguments(
+          new List<Expression>.from(arguments), beginToken));
     }
   }
 
   @override
   void handleParenthesizedCondition(Token token) {
     debugEvent("ParenthesizedCondition");
-    push(forest.parenthesizedCondition(token, popForValue(), token.endGroup));
+    push(forest.createParenthesizedCondition(
+        token, popForValue(), token.endGroup));
   }
 
   @override
@@ -1405,8 +1401,7 @@
       if (arguments == null) {
         push(new IncompletePropertyAccessGenerator(this, beginToken, name));
       } else {
-        push(new SendAccessGenerator(
-            this, beginToken, name, forest.castArguments(arguments)));
+        push(new SendAccessGenerator(this, beginToken, name, arguments));
       }
     } else if (arguments == null) {
       push(receiver);
@@ -1495,7 +1490,7 @@
     if (receiver is ThisAccessGenerator && receiver.isSuper) {
       ThisAccessGenerator thisAccessorReceiver = receiver;
       isSuper = true;
-      receiver = forest.thisExpression(thisAccessorReceiver.token);
+      receiver = forest.createThisExpression(thisAccessorReceiver.token);
     }
     push(buildBinaryOperator(toValue(receiver), token, argument, isSuper));
   }
@@ -1520,12 +1515,12 @@
       }
     } else {
       Expression result = buildMethodInvocation(a, new Name(operator),
-          forest.arguments(<Expression>[b], noLocation), token.charOffset,
+          forest.createArguments(<Expression>[b], noLocation), token.charOffset,
           // This *could* be a constant expression, we can't know without
           // evaluating [a] and [b].
           isConstantExpression: !isSuper,
           isSuper: isSuper);
-      return negate ? forest.notExpression(result, null, true) : result;
+      return negate ? forest.createNot(result, null, true) : result;
     }
   }
 
@@ -1533,7 +1528,7 @@
     Expression argument = popForValue();
     Expression receiver = pop();
     Expression logicalExpression =
-        forest.logicalExpression(receiver, token, argument);
+        forest.createLogicalExpression(receiver, token, argument);
     typePromoter?.exitLogicalExpression(argument, logicalExpression);
     push(logicalExpression);
   }
@@ -1545,7 +1540,7 @@
     VariableDeclaration variable = new VariableDeclaration.forValue(a);
     push(new IfNullJudgment(
         variable,
-        forest.conditionalExpression(
+        forest.createConditionalExpression(
             buildIsNull(new VariableGet(variable), offsetForToken(token), this),
             token,
             b,
@@ -1634,10 +1629,10 @@
     if (legacyMode && constantContext == ConstantContext.none) {
       addProblem(message.messageObject, message.charOffset, message.length,
           wasHandled: true, context: context);
-      return forest.throwExpression(
+      return forest.createThrow(
           null,
           library.loader.instantiateNoSuchMethodError(
-              receiver, name, forest.castArguments(arguments), charOffset,
+              receiver, name, arguments, charOffset,
               isMethod: !isGetter && !isSetter,
               isGetter: isGetter,
               isSetter: isSetter,
@@ -1769,7 +1764,8 @@
 
   /// Helper method to create a [VariableGet] of the [variable] using
   /// [charOffset] as the file offset.
-  VariableGet _createVariableGet(VariableDeclaration variable, int charOffset) {
+  @override
+  VariableGet createVariableGet(VariableDeclaration variable, int charOffset) {
     Object fact =
         typePromoter?.getFactForAccess(variable, functionNestingLevel);
     Object scope = typePromoter?.currentScope;
@@ -1783,7 +1779,108 @@
   ReadOnlyAccessGenerator _createReadOnlyVariableAccess(
       VariableDeclaration variable, Token token, int charOffset, String name) {
     return new ReadOnlyAccessGenerator(
-        this, token, _createVariableGet(variable, charOffset), name);
+        this, token, createVariableGet(variable, charOffset), name);
+  }
+
+  @override
+  Expression createExtensionTearOff(
+      Procedure procedure,
+      VariableDeclaration extensionThis,
+      List<TypeParameter> extensionTypeParameters,
+      Token token) {
+    int charOffset = offsetForToken(token);
+
+    FunctionNode function = procedure.function;
+    List<TypeParameter> typeParameters = [];
+    List<DartType> typeArguments = [];
+    int extensionTypeParameterCount = extensionTypeParameters?.length ?? 0;
+    for (int index = 0; index < extensionTypeParameterCount; index++) {
+      typeArguments
+          .add(forest.createTypeParameterType(extensionTypeParameters[index]));
+    }
+    for (int index = extensionTypeParameterCount;
+        index < function.typeParameters.length;
+        index++) {
+      TypeParameter typeParameter = function.typeParameters[index];
+      TypeParameter newTypeParameter =
+          forest.createTypeParameter(typeParameter.name);
+      typeParameters.add(newTypeParameter);
+      typeArguments.add(forest.createTypeParameterType(newTypeParameter));
+    }
+    Substitution substitution =
+        Substitution.fromPairs(function.typeParameters, typeArguments);
+    for (int index = extensionTypeParameterCount;
+        index < function.typeParameters.length;
+        index++) {
+      TypeParameter oldTypeParameter = function.typeParameters[index];
+      TypeParameter newTypeParameter =
+          typeParameters[index - extensionTypeParameterCount];
+      newTypeParameter.bound =
+          substitution.substituteType(oldTypeParameter.bound);
+      newTypeParameter.defaultType = oldTypeParameter.defaultType;
+    }
+
+    DartType returnType = substitution.substituteType(function.returnType);
+
+    List<VariableDeclaration> positionalParameters = [];
+    List<Expression> positionalArguments = [];
+    functionNestingLevel++;
+
+    VariableDeclaration copyParameter(VariableDeclaration parameter,
+        {bool isOptional}) {
+      // TODO(johnniwinther): Handle default values.
+      return forest.createVariableDeclaration(
+          parameter.name, functionNestingLevel,
+          type: substitution.substituteType(parameter.type),
+          initializer: isOptional ? forest.createNullLiteral(token) : null);
+    }
+
+    for (int position = 0;
+        position < function.positionalParameters.length;
+        position++) {
+      VariableDeclaration parameter = function.positionalParameters[position];
+      if (position == 0) {
+        /// Pass `this` as a captured variable.
+        positionalArguments.add(createVariableGet(extensionThis, charOffset));
+      } else {
+        VariableDeclaration newParameter = copyParameter(parameter,
+            isOptional: position >= function.requiredParameterCount);
+        positionalParameters.add(newParameter);
+        positionalArguments.add(createVariableGet(newParameter, charOffset));
+      }
+    }
+    List<VariableDeclaration> namedParameters = [];
+    List<NamedExpression> namedArguments = [];
+    for (VariableDeclaration parameter in function.namedParameters) {
+      VariableDeclaration newParameter =
+          copyParameter(parameter, isOptional: true);
+      namedParameters.add(newParameter);
+      namedArguments.add(forest.createNamedExpression(
+          parameter.name, createVariableGet(newParameter, charOffset)));
+    }
+
+    Statement body = forest.createReturnStatement(
+        null,
+        buildStaticInvocation(
+            procedure,
+            forest.createArguments(positionalArguments, token,
+                types: typeArguments, named: namedArguments),
+            charOffset: charOffset),
+        charOffset);
+
+    FunctionExpression expression = forest.createFunctionExpression(
+        forest.createFunctionNode(body,
+            typeParameters: typeParameters,
+            positionalParameters: positionalParameters,
+            namedParameters: namedParameters,
+            requiredParameterCount:
+                procedure.function.requiredParameterCount - 1,
+            returnType: returnType,
+            asyncMarker: procedure.function.asyncMarker,
+            dartAsyncMarker: procedure.function.dartAsyncMarker),
+        charOffset);
+    functionNestingLevel--;
+    return expression;
   }
 
   /// Look up [name] in [scope] using [token] as location information (both to
@@ -1810,37 +1907,53 @@
           classBuilder.origin.findStaticBuilder(name, charOffset, uri, library);
     }
     if (declaration != null &&
-        declaration.isInstanceMember &&
+        declaration.isDeclarationInstanceMember &&
         inFieldInitializer &&
         !inInitializer) {
+      // We cannot access a class instance member in an initializer of a
+      // field.
+      //
+      // For instance
+      //
+      //     class M {
+      //       int foo = bar;
+      //       int bar;
+      //     }
+      //
       return new IncompleteErrorGenerator(this, token,
           fasta.templateThisAccessInFieldInitializer.withArguments(name));
     }
     if (declaration == null ||
-        (!isInstanceContext && declaration.isInstanceMember)) {
+        (!isDeclarationInstanceContext &&
+            declaration.isDeclarationInstanceMember)) {
+      // We either didn't find a declaration or found an instance member from
+      // a non-instance context.
       Name n = new Name(name, library.nameOrigin);
-      if (!isQualified && isInstanceContext) {
+      if (!isQualified && isDeclarationInstanceContext) {
         assert(declaration == null);
         if (constantContext != ConstantContext.none || member.isField) {
           return new UnresolvedNameGenerator(this, token, n);
         }
         if (extensionThis != null) {
+          // If we are in an extension instance member we interpret this as an
+          // implicit access on the 'this' parameter.
           return PropertyAccessGenerator.make(
               this,
               token,
-              _createVariableGet(extensionThis, charOffset),
+              createVariableGet(extensionThis, charOffset),
               n,
               null,
               null,
               false);
         } else {
+          // This is an implicit access on 'this'.
           return new ThisPropertyAccessGenerator(this, token, n,
               lookupInstanceMember(n), lookupInstanceMember(n, isSetter: true));
         }
       } else if (ignoreMainInGetMainClosure &&
           name == "main" &&
           member?.name == "_getMainClosure") {
-        return forest.literalNull(null)..fileOffset = charOffset;
+        return forest.createNullLiteral(null)..fileOffset = charOffset;
       } else {
         return new UnresolvedNameGenerator(this, token, n);
       }
@@ -1863,7 +1976,7 @@
       } else {
         return new VariableUseGenerator(this, token, declaration.target);
       }
-    } else if (declaration.isInstanceMember) {
+    } else if (declaration.isClassInstanceMember) {
       if (constantContext != ConstantContext.none &&
           !inInitializer &&
           // TODO(ahe): This is a hack because Fasta sets up the scope
@@ -1885,6 +1998,12 @@
         setter = lookupInstanceMember(n, isSetter: true);
       }
       return new ThisPropertyAccessGenerator(this, token, n, getter, setter);
+    } else if (declaration.isExtensionInstanceMember) {
+      Builder setter =
+          _getCorrespondingSetterBuilder(scope, declaration, name, charOffset);
+      // TODO(johnniwinther): Check for constantContext like below?
+      return new ExtensionInstanceAccessGenerator.fromBuilder(this,
+          extensionThis, extensionTypeParameters, declaration, token, setter);
     } else if (declaration.isRegularMethod) {
       assert(declaration.isStatic || declaration.isTopLevel);
       return new StaticAccessGenerator(this, token, declaration.target, null);
@@ -1893,21 +2012,11 @@
       return new PrefixUseGenerator(this, token, declaration);
     } else if (declaration is LoadLibraryBuilder) {
       return new LoadLibraryGenerator(this, token, declaration);
+    } else if (declaration.hasProblem && declaration is! AccessErrorBuilder) {
+      return declaration;
     } else {
-      if (declaration.hasProblem && declaration is! AccessErrorBuilder)
-        return declaration;
-      Builder setter;
-      if (declaration.isSetter) {
-        setter = declaration;
-      } else if (declaration.isGetter) {
-        setter = scope.lookupSetter(name, charOffset, uri);
-      } else if (declaration.isField) {
-        if (declaration.isFinal || declaration.isConst) {
-          setter = scope.lookupSetter(name, charOffset, uri);
-        } else {
-          setter = declaration;
-        }
-      }
+      Builder setter =
+          _getCorrespondingSetterBuilder(scope, declaration, name, charOffset);
       StaticAccessGenerator generator = new StaticAccessGenerator.fromBuilder(
           this, declaration, token, setter);
       if (constantContext != ConstantContext.none) {
@@ -1923,6 +2032,25 @@
     }
   }
 
+  /// Returns the setter builder corresponding to [declaration] using the
+  /// [name] and [charOffset] for the lookup into [scope] if necessary.
+  Builder _getCorrespondingSetterBuilder(
+      Scope scope, Builder declaration, String name, int charOffset) {
+    Builder setter;
+    if (declaration.isSetter) {
+      setter = declaration;
+    } else if (declaration.isGetter) {
+      setter = scope.lookupSetter(name, charOffset, uri);
+    } else if (declaration.isField) {
+      if (declaration.isFinal || declaration.isConst) {
+        setter = scope.lookupSetter(name, charOffset, uri);
+      } else {
+        setter = declaration;
+      }
+    }
+    return setter;
+  }
+
   @override
   void handleQualified(Token period) {
     debugEvent("Qualified");
@@ -1956,7 +2084,7 @@
     if (interpolationCount == 0) {
       Token token = pop();
       String value = unescapeString(token.lexeme, token, this);
-      push(forest.literalString(value, token));
+      push(forest.createStringLiteral(value, token));
     } else {
       int count = 1 + interpolationCount * 2;
       List<Object> parts = const FixedNullableList<Object>().pop(stack, count);
@@ -1973,7 +2101,7 @@
         String value =
             unescapeFirstStringPart(first.lexeme, quote, first, this);
         if (value.isNotEmpty) {
-          expressions.add(forest.literalString(value, first));
+          expressions.add(forest.createStringLiteral(value, first));
         }
       }
       for (int i = 1; i < parts.length - 1; i++) {
@@ -1981,7 +2109,7 @@
         if (part is Token) {
           if (part.lexeme.length != 0) {
             String value = unescape(part.lexeme, quote, part, this);
-            expressions.add(forest.literalString(value, part));
+            expressions.add(forest.createStringLiteral(value, part));
           }
         } else {
           expressions.add(toValue(part));
@@ -1992,10 +2120,10 @@
         String value = unescapeLastStringPart(
             last.lexeme, quote, last, last.isSynthetic, this);
         if (value.isNotEmpty) {
-          expressions.add(forest.literalString(value, last));
+          expressions.add(forest.createStringLiteral(value, last));
         }
       }
-      push(forest.stringConcatenationExpression(expressions, endToken));
+      push(forest.createStringConcatenation(expressions, endToken));
     }
   }
 
@@ -2033,7 +2161,7 @@
         }
       }
     }
-    push(forest.stringConcatenationExpression(expressions ?? parts, null));
+    push(forest.createStringConcatenation(expressions ?? parts, null));
   }
 
   @override
@@ -2045,16 +2173,16 @@
         push(unhandled(
             'large integer', 'handleLiteralInt', token.charOffset, uri));
       } else {
-        push(forest.literalInt(value, token));
+        push(forest.createIntLiteral(value, token));
       }
       return;
     }
     // Postpone parsing of literals resulting in a negative value
     // (hex literals >= 2^63). These are only allowed when not negated.
     if (value == null || value < 0) {
-      push(forest.literalLargeInt(token.lexeme, token));
+      push(forest.createIntLiteralLarge(token.lexeme, token));
     } else {
-      push(forest.literalInt(value, token));
+      push(forest.createIntLiteral(value, token));
     }
   }
 
@@ -2079,7 +2207,8 @@
       push(buildProblemStatement(
           fasta.messageConstructorWithReturnType, beginToken.charOffset));
     } else {
-      push(forest.returnStatement(beginToken, expression, endToken));
+      push(forest.createReturnStatement(
+          beginToken, expression, offsetForToken(beginToken)));
     }
   }
 
@@ -2103,7 +2232,8 @@
     Statement thenPart = popStatement();
     Expression condition = pop();
     typePromoter?.exitConditional();
-    push(forest.ifStatement(ifToken, condition, thenPart, elseToken, elsePart));
+    push(forest.createIfStatement(
+        ifToken, condition, thenPart, elseToken, elsePart));
   }
 
   @override
@@ -2150,6 +2280,7 @@
     assert(currentLocalVariableModifiers != -1);
     bool isConst = (currentLocalVariableModifiers & constMask) != 0;
     bool isFinal = (currentLocalVariableModifiers & finalMask) != 0;
+    bool isLate = (currentLocalVariableModifiers & lateMask) != 0;
     assert(isConst == (constantContext == ConstantContext.inferred));
     VariableDeclaration variable = new VariableDeclarationJudgment(
         identifier.name, functionNestingLevel,
@@ -2157,7 +2288,8 @@
         initializer: initializer,
         type: buildDartType(currentLocalVariableType),
         isFinal: isFinal,
-        isConst: isConst)
+        isConst: isConst,
+        isLate: isLate)
       ..fileOffset = identifier.charOffset
       ..fileEqualsOffset = offsetForToken(equalsToken);
     library.checkBoundsInVariableDeclaration(variable, typeEnvironment, uri);
@@ -2182,7 +2314,7 @@
     debugEvent("NoFieldInitializer");
     if (constantContext == ConstantContext.inferred) {
       // Creating a null value to prevent the Dart VM from crashing.
-      push(forest.literalNull(token));
+      push(forest.createNullLiteral(token));
     } else {
       push(NullValue.FieldInitializer);
     }
@@ -2207,12 +2339,12 @@
   void beginVariablesDeclaration(
       Token token, Token lateToken, Token varFinalOrConst) {
     debugEvent("beginVariablesDeclaration");
-    // TODO(danrubel): handle NNBD 'late' modifier
     if (!library.loader.target.enableNonNullable) {
       reportNonNullableModifierError(lateToken);
     }
     UnresolvedType type = pop();
-    int modifiers = Modifier.validateVarFinalOrConst(varFinalOrConst?.lexeme);
+    int modifiers = (lateToken != null ? lateMask : 0) |
+        Modifier.validateVarFinalOrConst(varFinalOrConst?.lexeme);
     super.push(currentLocalVariableModifiers);
     super.push(currentLocalVariableType ?? NullValue.Type);
     currentLocalVariableType = type;
@@ -2417,9 +2549,10 @@
       assert(forest.isEmptyStatement(conditionStatement));
     }
     if (entry is MapEntry) {
-      push(forest.forMapEntry(variables, condition, updates, entry, forToken));
+      push(forest.createForMapEntry(
+          variables, condition, updates, entry, forToken));
     } else {
-      push(forest.forElement(
+      push(forest.createForElement(
           variables, condition, updates, toValue(entry), forToken));
     }
   }
@@ -2443,7 +2576,7 @@
     JumpTarget continueTarget = exitContinueTarget();
     JumpTarget breakTarget = exitBreakTarget();
     if (continueTarget.hasUsers) {
-      body = forest.syntheticLabeledStatement(body);
+      body = forest.createLabeledStatement(body);
       continueTarget.resolveContinues(forest, body);
     }
     Expression condition;
@@ -2453,7 +2586,7 @@
     } else {
       assert(forest.isEmptyStatement(conditionStatement));
     }
-    Statement result = forest.forStatement(
+    Statement result = forest.createForStatement(
         forKeyword,
         leftParen,
         variables,
@@ -2464,7 +2597,7 @@
         leftParen.endGroup,
         body);
     if (breakTarget.hasUsers) {
-      result = forest.syntheticLabeledStatement(result);
+      result = forest.createLabeledStatement(result);
       breakTarget.resolveBreaks(forest, result);
     }
     if (variableOrExpression is ParserRecovery) {
@@ -2478,7 +2611,7 @@
   @override
   void endAwaitExpression(Token keyword, Token endToken) {
     debugEvent("AwaitExpression");
-    push(forest.awaitExpression(popForValue(), keyword));
+    push(forest.createAwaitExpression(popForValue(), keyword));
   }
 
   @override
@@ -2534,7 +2667,7 @@
       typeArgument = implicitTypeArgument;
     }
 
-    Expression node = forest.literalList(
+    Expression node = forest.createListLiteral(
         constKeyword,
         constKeyword != null || constantContext == ConstantContext.inferred,
         typeArgument,
@@ -2573,7 +2706,7 @@
       }
     }
 
-    Expression node = forest.literalSet(
+    Expression node = forest.createSetLiteral(
         constKeyword,
         constKeyword != null || constantContext == ConstantContext.inferred,
         typeArgument,
@@ -2654,19 +2787,19 @@
     debugEvent("LiteralBool");
     bool value = optional("true", token);
     assert(value || optional("false", token));
-    push(forest.literalBool(value, token));
+    push(forest.createBoolLiteral(value, token));
   }
 
   @override
   void handleLiteralDouble(Token token) {
     debugEvent("LiteralDouble");
-    push(forest.literalDouble(double.parse(token.lexeme), token));
+    push(forest.createDoubleLiteral(double.parse(token.lexeme), token));
   }
 
   @override
   void handleLiteralNull(Token token) {
     debugEvent("LiteralNull");
-    push(forest.literalNull(token));
+    push(forest.createNullLiteral(token));
   }
 
   void buildLiteralMap(List<UnresolvedType> typeArguments, Token constKeyword,
@@ -2691,7 +2824,7 @@
       valueType = implicitTypeArgument;
     }
 
-    Expression node = forest.literalMap(
+    Expression node = forest.createMapLiteral(
         constKeyword,
         constKeyword != null || constantContext == ConstantContext.inferred,
         keyType,
@@ -2709,7 +2842,7 @@
     debugEvent("LiteralMapEntry");
     Expression value = popForValue();
     Expression key = popForValue();
-    push(forest.mapEntry(key, colon, value));
+    push(forest.createMapEntry(key, colon, value));
   }
 
   String symbolPartToString(name) {
@@ -2731,8 +2864,7 @@
         push(new ParserErrorGenerator(
             this, hashToken, fasta.messageSyntheticToken));
       } else {
-        push(forest.literalSymbolSingular(
-            symbolPartToString(part), hashToken, part));
+        push(forest.createSymbolLiteral(symbolPartToString(part), hashToken));
       }
     } else {
       List<Identifier> parts =
@@ -2746,7 +2878,7 @@
       for (int i = 1; i < parts.length; i++) {
         value += ".${symbolPartToString(parts[i])}";
       }
-      push(forest.literalSymbolMultiple(value, hashToken, parts));
+      push(forest.createSymbolLiteral(value, hashToken));
     }
   }
 
@@ -2873,7 +3005,7 @@
           operator.charOffset,
           operator.length)));
     } else {
-      Expression node = forest.asExpression(expression, type, operator);
+      Expression node = forest.createAsExpression(expression, type, operator);
       push(node);
     }
   }
@@ -2885,7 +3017,7 @@
     Expression operand = popForValue();
     bool isInverted = not != null;
     Expression isExpression =
-        forest.isExpression(operand, isOperator, not, type);
+        forest.createIsExpression(operand, isOperator, not, type);
     library.checkBoundsInType(
         type, typeEnvironment, uri, isOperator.charOffset);
     if (operand is VariableGet) {
@@ -2926,7 +3058,7 @@
     Expression thenExpression = pop();
     Expression condition = pop();
     typePromoter?.exitConditional();
-    push(forest.conditionalExpression(
+    push(forest.createConditionalExpression(
         condition, question, thenExpression, colon, elseExpression));
   }
 
@@ -2940,7 +3072,7 @@
           throwToken.offset,
           throwToken.length));
     } else {
-      push(forest.throwExpression(throwToken, expression));
+      push(forest.createThrow(throwToken, expression));
     }
   }
 
@@ -3023,7 +3155,8 @@
         variable.initializer = initializer..parent = variable;
       }
     } else if (kind != FormalParameterKind.mandatory) {
-      variable.initializer ??= forest.literalNull(null)..parent = variable;
+      variable.initializer ??= forest.createNullLiteral(null)
+        ..parent = variable;
     }
     if (annotations != null) {
       if (functionNestingLevel == 0) {
@@ -3203,7 +3336,7 @@
         }
       }
     }
-    push(forest.catchClause(
+    push(forest.createCatch(
         onKeyword,
         exceptionType,
         catchKeyword,
@@ -3214,7 +3347,7 @@
     if (compileTimeErrors == null) {
       push(NullValue.Block);
     } else {
-      push(forest.block(null, compileTimeErrors, null));
+      push(forest.createBlock(null, compileTimeErrors, null));
     }
   }
 
@@ -3237,11 +3370,11 @@
       }
     }
     Statement tryBlock = popStatement();
-    Statement tryStatement = forest.tryStatement(
+    Statement tryStatement = forest.createTryStatement(
         tryKeyword, tryBlock, catchBlocks, finallyKeyword, finallyBlock);
     if (compileTimeErrors != null) {
       compileTimeErrors.add(tryStatement);
-      push(forest.block(null, compileTimeErrors, null));
+      push(forest.createBlock(null, compileTimeErrors, null));
     } else {
       push(tryStatement);
     }
@@ -3271,7 +3404,7 @@
     debugEvent("UnaryPrefixExpression");
     Object receiver = pop();
     if (optional("!", token)) {
-      push(forest.notExpression(toValue(receiver), token, false));
+      push(forest.createNot(toValue(receiver), token, false));
     } else {
       String operator = token.stringValue;
       Expression receiverValue;
@@ -3281,12 +3414,12 @@
       bool isSuper = false;
       if (receiver is ThisAccessGenerator && receiver.isSuper) {
         isSuper = true;
-        receiverValue = forest.thisExpression(receiver.token);
+        receiverValue = forest.createThisExpression(receiver.token);
       } else {
         receiverValue = toValue(receiver);
       }
       push(buildMethodInvocation(receiverValue, new Name(operator),
-          forest.argumentsEmpty(noLocation), token.charOffset,
+          forest.createArgumentsEmpty(noLocation), token.charOffset,
           // This *could* be a constant expression, we can't know without
           // evaluating [receiver].
           isConstantExpression: !isSuper,
@@ -3367,6 +3500,16 @@
   /// reference, or an expression in metadata), a list of type arguments, and a
   /// name.
   void pushQualifiedReference(Token start, Token periodBeforeName) {
+    assert(checkState(start, [
+      /*suffix*/ if (periodBeforeName != null) ValueKind.Identifier,
+      /*type arguments*/ ValueKind.TypeArgumentsOrNull,
+      /*type*/ unionOfKinds([
+        ValueKind.Generator,
+        ValueKind.QualifiedName,
+        ValueKind.ProblemBuilder,
+        ValueKind.ParserRecovery
+      ])
+    ]));
     Identifier suffix = popIfNotNull(periodBeforeName);
     Identifier identifier;
     List<UnresolvedType> typeArguments = pop();
@@ -3375,6 +3518,10 @@
       identifier = type;
       QualifiedName qualified = type;
       Object qualifier = qualified.qualifier;
+      assert(checkValue(
+          start,
+          unionOfKinds([ValueKind.Generator, ValueKind.ProblemBuilder]),
+          qualifier));
       if (qualifier is TypeUseGenerator) {
         type = qualifier;
         if (typeArguments != null) {
@@ -3385,6 +3532,8 @@
       } else if (qualifier is Generator) {
         type = qualifier.qualifiedLookup(deprecated_extractToken(identifier));
         identifier = null;
+      } else if (qualifier is ProblemBuilder) {
+        type = qualifier;
       } else {
         unhandled("${qualifier.runtimeType}", "pushQualifiedReference",
             start.charOffset, uri);
@@ -3404,6 +3553,17 @@
     push(typeArguments ?? NullValue.TypeArguments);
     push(name);
     push(suffix ?? identifier ?? NullValue.Identifier);
+
+    assert(checkState(start, [
+      /*constructor name identifier*/ ValueKind.IdentifierOrNull,
+      /*constructor name*/ ValueKind.Name,
+      /*type arguments*/ ValueKind.TypeArgumentsOrNull,
+      /*class*/ unionOfKinds([
+        ValueKind.Generator,
+        ValueKind.ProblemBuilder,
+        ValueKind.ParserRecovery
+      ]),
+    ]));
   }
 
   @override
@@ -3424,7 +3584,7 @@
       if (argMessage != null) {
         return wrapSyntheticExpression(
             throwNoSuchMethodError(
-                forest.literalNull(null)..fileOffset = charOffset,
+                forest.createNullLiteral(null)..fileOffset = charOffset,
                 target.name.name,
                 arguments,
                 charOffset,
@@ -3447,10 +3607,9 @@
             arguments,
             charOffset);
       }
-      ConstructorInvocation node = new ConstructorInvocation(
-          target, forest.castArguments(arguments),
-          isConst: isConst)
-        ..fileOffset = charOffset;
+      ConstructorInvocation node =
+          new ConstructorInvocation(target, arguments, isConst: isConst)
+            ..fileOffset = charOffset;
       library.checkBoundsInConstructorInvocation(node, typeEnvironment, uri);
       return node;
     } else {
@@ -3468,16 +3627,15 @@
               charOffset);
         }
         StaticInvocation node = FactoryConstructorInvocationJudgment(
-            target, forest.castArguments(arguments),
+            target, arguments,
             isConst: isConst)
           ..fileOffset = charOffset;
         library.checkBoundsInFactoryInvocation(node, typeEnvironment, uri);
         return node;
       } else {
-        StaticInvocation node = new StaticInvocation(
-            target, forest.castArguments(arguments),
-            isConst: isConst)
-          ..fileOffset = charOffset;
+        StaticInvocation node =
+            new StaticInvocation(target, arguments, isConst: isConst)
+              ..fileOffset = charOffset;
         library.checkBoundsInStaticInvocation(node, typeEnvironment, uri);
         return node;
       }
@@ -3622,12 +3780,23 @@
   @override
   void endNewExpression(Token token) {
     debugEvent("NewExpression");
-    buildConstructorReferenceInvocation(
+    _buildConstructorReferenceInvocation(
         token.next, token.offset, Constness.explicitNew);
   }
 
-  void buildConstructorReferenceInvocation(
+  void _buildConstructorReferenceInvocation(
       Token nameToken, int offset, Constness constness) {
+    assert(checkState(nameToken, [
+      /*arguments*/ ValueKind.Arguments,
+      /*constructor name identifier*/ ValueKind.IdentifierOrNull,
+      /*constructor name*/ ValueKind.Name,
+      /*type arguments*/ ValueKind.TypeArgumentsOrNull,
+      /*class*/ unionOfKinds([
+        ValueKind.Generator,
+        ValueKind.ProblemBuilder,
+        ValueKind.ParserRecovery
+      ]),
+    ]));
     Arguments arguments = pop();
     Identifier nameLastIdentifier = pop(NullValue.Identifier);
     Token nameLastToken =
@@ -3645,10 +3814,14 @@
       push(new ParserErrorGenerator(
           this, nameToken, fasta.messageSyntheticToken));
     } else {
+      String typeName;
+      if (type is ProblemBuilder) {
+        typeName = type.fullNameForErrors;
+      }
       push(wrapSyntheticExpression(
           throwNoSuchMethodError(
-              forest.literalNull(null)..fileOffset = offset,
-              debugName(getNodeName(type), name),
+              forest.createNullLiteral(null)..fileOffset = offset,
+              debugName(typeName, name),
               arguments,
               nameToken.charOffset),
           offset));
@@ -3659,7 +3832,7 @@
   @override
   void endImplicitCreationExpression(Token token) {
     debugEvent("ImplicitCreationExpression");
-    buildConstructorReferenceInvocation(
+    _buildConstructorReferenceInvocation(
         token, token.offset, Constness.implicit);
   }
 
@@ -3729,7 +3902,7 @@
           if (target.function.typeParameters != null &&
               target.function.typeParameters.length !=
                   forest.argumentsTypeArguments(arguments).length) {
-            arguments = forest.arguments(
+            arguments = forest.createArguments(
                 forest.argumentsPositional(arguments), null,
                 named: forest.argumentsNamed(arguments),
                 types: new List<DartType>.filled(
@@ -3737,7 +3910,7 @@
                     growable: true));
           }
           invocation = new FactoryConstructorInvocationJudgment(
-              target, forest.castArguments(arguments),
+              target, arguments,
               isConst: constness == Constness.explicitConst)
             ..fileOffset = nameToken.charOffset;
         } else {
@@ -3769,7 +3942,7 @@
 
     return wrapUnresolvedTargetInvocation(
         throwNoSuchMethodError(
-            forest.literalNull(null)..fileOffset = charOffset,
+            forest.createNullLiteral(null)..fileOffset = charOffset,
             errorName,
             arguments,
             nameLastToken.charOffset,
@@ -3781,7 +3954,7 @@
   @override
   void endConstExpression(Token token) {
     debugEvent("endConstExpression");
-    buildConstructorReferenceInvocation(
+    _buildConstructorReferenceInvocation(
         token.next, token.offset, Constness.explicitConst);
   }
 
@@ -3837,9 +4010,10 @@
 
     transformCollections = true;
     if (entry is MapEntry) {
-      push(forest.ifMapEntry(toValue(condition), entry, null, ifToken));
+      push(forest.createIfMapEntry(toValue(condition), entry, null, ifToken));
     } else {
-      push(forest.ifElement(toValue(condition), toValue(entry), null, ifToken));
+      push(forest.createIfElement(
+          toValue(condition), toValue(entry), null, ifToken));
     }
   }
 
@@ -3876,10 +4050,10 @@
     transformCollections = true;
     if (thenEntry is MapEntry) {
       if (elseEntry is MapEntry) {
-        push(forest.ifMapEntry(
+        push(forest.createIfMapEntry(
             toValue(condition), thenEntry, elseEntry, ifToken));
       } else if (elseEntry is SpreadElement) {
-        push(forest.ifMapEntry(
+        push(forest.createIfMapEntry(
             toValue(condition),
             thenEntry,
             new SpreadMapEntry(elseEntry.expression, elseEntry.isNullAware),
@@ -3898,7 +4072,7 @@
       }
     } else if (elseEntry is MapEntry) {
       if (thenEntry is SpreadElement) {
-        push(forest.ifMapEntry(
+        push(forest.createIfMapEntry(
             toValue(condition),
             new SpreadMapEntry(thenEntry.expression, thenEntry.isNullAware),
             elseEntry,
@@ -3916,7 +4090,7 @@
           ..fileOffset = offsetForToken(ifToken));
       }
     } else {
-      push(forest.ifElement(
+      push(forest.createIfElement(
           toValue(condition), toValue(thenEntry), toValue(elseEntry), ifToken));
     }
   }
@@ -3946,7 +4120,7 @@
     }
 
     transformCollections = true;
-    push(forest.spreadElement(toValue(expression), spreadToken));
+    push(forest.createSpreadElement(toValue(expression), spreadToken));
   }
 
   @override
@@ -3965,7 +4139,7 @@
   @override
   void handleThisExpression(Token token, IdentifierContext context) {
     debugEvent("ThisExpression");
-    if (context.isScopeReference && isInstanceContext) {
+    if (context.isScopeReference && isDeclarationInstanceContext) {
       if (extensionThis != null) {
         push(_createReadOnlyVariableAccess(
             extensionThis, token, offsetForToken(token), 'this'));
@@ -3983,7 +4157,7 @@
   void handleSuperExpression(Token token, IdentifierContext context) {
     debugEvent("SuperExpression");
     if (context.isScopeReference &&
-        isInstanceContext &&
+        isDeclarationInstanceContext &&
         extensionThis == null) {
       Member member = this.member.target;
       member.transformerFlags |= TransformerFlag.superCalls;
@@ -4128,10 +4302,10 @@
           // This must have been a compile-time error.
           assert(isErroneousNode(variable.initializer));
 
-          push(forest.block(
+          push(forest.createBlock(
               null,
               <Statement>[
-                forest.expressionStatement(variable.initializer, token),
+                forest.createExpressionStatement(variable.initializer, token),
                 declaration
               ],
               null)
@@ -4208,13 +4382,13 @@
     JumpTarget continueTarget = exitContinueTarget();
     JumpTarget breakTarget = exitBreakTarget();
     if (continueTarget.hasUsers) {
-      body = forest.syntheticLabeledStatement(body);
+      body = forest.createLabeledStatement(body);
       continueTarget.resolveContinues(forest, body);
     }
-    Statement result =
-        forest.doStatement(doKeyword, body, whileKeyword, condition, endToken);
+    Statement result = forest.createDoStatement(
+        doKeyword, body, whileKeyword, condition, endToken);
     if (breakTarget.hasUsers) {
-      result = forest.syntheticLabeledStatement(result);
+      result = forest.createLabeledStatement(result);
       breakTarget.resolveBreaks(forest, result);
     }
     exitLoopOrSwitch(result);
@@ -4278,11 +4452,11 @@
     Expression problem = checkForInVariable(lvalue, variable, forToken);
     Statement prologue = buildForInBody(lvalue, variable, forToken, inToken);
     if (entry is MapEntry) {
-      push(forest.forInMapEntry(
+      push(forest.createForInMapEntry(
           variable, iterable, prologue, entry, problem, forToken,
           isAsync: awaitToken != null));
     } else {
-      push(forest.forInElement(
+      push(forest.createForInElement(
           variable, iterable, prologue, toValue(entry), problem, forToken,
           isAsync: awaitToken != null));
     }
@@ -4337,7 +4511,7 @@
             desugarSyntheticExpression(syntheticAssignment),
             offsetForToken(lvalue.token));
       }
-      return forest.expressionStatement(syntheticAssignment, null);
+      return forest.createExpressionStatement(syntheticAssignment, null);
     }
     Message message = forest.isVariablesDeclaration(lvalue)
         ? fasta.messageForInLoopExactlyOneVariable
@@ -4345,17 +4519,17 @@
     Token token = forToken.next.next;
     Statement body;
     if (forest.isVariablesDeclaration(lvalue)) {
-      body = forest.block(
+      body = forest.createBlock(
           null,
           // New list because the declarations are not a growable list.
           new List<Statement>.from(
               forest.variablesDeclarationExtractDeclarations(lvalue)),
           null);
     } else {
-      body = forest.expressionStatement(lvalue, null);
+      body = forest.createExpressionStatement(lvalue, null);
     }
     return combineStatements(
-        forest.expressionStatement(
+        forest.createExpressionStatement(
             buildProblem(message, offsetForToken(token), lengthForToken(token)),
             null),
         body);
@@ -4376,7 +4550,7 @@
     JumpTarget continueTarget = exitContinueTarget();
     JumpTarget breakTarget = exitBreakTarget();
     if (continueTarget.hasUsers) {
-      body = forest.syntheticLabeledStatement(body);
+      body = forest.createLabeledStatement(body);
       continueTarget.resolveContinues(forest, body);
     }
     VariableDeclaration variable = buildForInVariable(lvalue);
@@ -4401,12 +4575,12 @@
       ..fileOffset = awaitToken?.charOffset ?? forToken.charOffset
       ..bodyOffset = body.fileOffset; // TODO(ahe): Isn't this redundant?
     if (breakTarget.hasUsers) {
-      result = forest.syntheticLabeledStatement(result);
+      result = forest.createLabeledStatement(result);
       breakTarget.resolveBreaks(forest, result);
     }
     if (problem != null) {
-      result =
-          combineStatements(forest.expressionStatement(problem, null), result);
+      result = combineStatements(
+          forest.createExpressionStatement(problem, null), result);
     }
     exitLoopOrSwitch(result);
   }
@@ -4448,7 +4622,7 @@
             uri);
       }
       if (statement is! LabeledStatement) {
-        statement = forest.syntheticLabeledStatement(statement);
+        statement = forest.createLabeledStatement(statement);
       }
       target.breakTarget.resolveBreaks(forest, statement);
       target.continueTarget.resolveContinues(forest, statement);
@@ -4460,7 +4634,7 @@
   void endRethrowStatement(Token rethrowToken, Token endToken) {
     debugEvent("RethrowStatement");
     if (inCatchBlock) {
-      push(forest.rethrowStatement(rethrowToken, endToken));
+      push(forest.createRethrowStatement(rethrowToken, endToken));
     } else {
       push(new ExpressionStatementJudgment(buildProblem(
           fasta.messageRethrowNotCatch,
@@ -4484,12 +4658,13 @@
     JumpTarget continueTarget = exitContinueTarget();
     JumpTarget breakTarget = exitBreakTarget();
     if (continueTarget.hasUsers) {
-      body = forest.syntheticLabeledStatement(body);
+      body = forest.createLabeledStatement(body);
       continueTarget.resolveContinues(forest, body);
     }
-    Statement result = forest.whileStatement(whileKeyword, condition, body);
+    Statement result =
+        forest.createWhileStatement(whileKeyword, condition, body);
     if (breakTarget.hasUsers) {
-      result = forest.syntheticLabeledStatement(result);
+      result = forest.createLabeledStatement(result);
       breakTarget.resolveBreaks(forest, result);
     }
     exitLoopOrSwitch(result);
@@ -4498,7 +4673,7 @@
   @override
   void handleEmptyStatement(Token token) {
     debugEvent("EmptyStatement");
-    push(forest.emptyStatement(token));
+    push(forest.createEmptyStatement(token));
   }
 
   @override
@@ -4519,8 +4694,8 @@
 
     switch (kind) {
       case Assert.Statement:
-        push(forest.assertStatement(assertKeyword, leftParenthesis, condition,
-            commaToken, message, semicolonToken));
+        push(forest.createAssertStatement(assertKeyword, leftParenthesis,
+            condition, commaToken, message, semicolonToken));
         break;
 
       case Assert.Expression:
@@ -4531,7 +4706,7 @@
         break;
 
       case Assert.Initializer:
-        push(forest.assertInitializer(
+        push(forest.createAssertInitializer(
             assertKeyword, leftParenthesis, condition, commaToken, message));
         break;
     }
@@ -4540,7 +4715,8 @@
   @override
   void endYieldStatement(Token yieldToken, Token starToken, Token endToken) {
     debugEvent("YieldStatement");
-    push(forest.yieldStatement(yieldToken, starToken, popForValue(), endToken));
+    push(forest.createYieldStatement(
+        yieldToken, starToken, popForValue(), endToken));
   }
 
   @override
@@ -4634,7 +4810,7 @@
     Statement result = new SwitchStatementJudgment(expression, cases)
       ..fileOffset = switchKeyword.charOffset;
     if (target.hasUsers) {
-      result = forest.syntheticLabeledStatement(result);
+      result = forest.createLabeledStatement(result);
       target.resolveBreaks(forest, result);
     }
     exitLoopOrSwitch(result);
@@ -4719,7 +4895,7 @@
       push(buildProblemTargetOutsideLocalFunction(name, breakKeyword));
     } else {
       Statement statement =
-          forest.breakStatement(breakKeyword, identifier, endToken);
+          forest.createBreakStatement(breakKeyword, identifier, endToken);
       target.addBreak(statement);
       push(statement);
     }
@@ -4798,7 +4974,7 @@
       push(buildProblemTargetOutsideLocalFunction(name, continueKeyword));
     } else {
       Statement statement =
-          forest.continueStatement(continueKeyword, identifier, endToken);
+          forest.createContinueStatement(continueKeyword, identifier, endToken);
       target.addContinue(statement);
       push(statement);
     }
@@ -4957,14 +5133,14 @@
     // TODO(ahe): Compute a LocatedMessage above instead?
     Location location = messages.getLocationFromUri(uri, charOffset);
 
-    return forest.throwExpression(
+    return forest.createThrow(
         null,
         buildStaticInvocation(
             library.loader.coreTypes.fallThroughErrorUrlAndLineConstructor,
-            forest.arguments(<Expression>[
-              forest.literalString("${location?.file ?? uri}", null)
+            forest.createArguments(<Expression>[
+              forest.createStringLiteral("${location?.file ?? uri}", null)
                 ..fileOffset = charOffset,
-              forest.literalInt(location?.line ?? 0, null)
+              forest.createIntLiteral(location?.line ?? 0, null)
                 ..fileOffset = charOffset,
             ], noLocation),
             charOffset: charOffset))
@@ -4979,15 +5155,15 @@
     Builder constructor = library.loader.getAbstractClassInstantiationError();
     Expression invocation = buildStaticInvocation(
         constructor.target,
-        forest.arguments(<Expression>[
-          forest.literalString(className, null)..fileOffset = charOffset
+        forest.createArguments(<Expression>[
+          forest.createStringLiteral(className, null)..fileOffset = charOffset
         ], noLocation)
           ..fileOffset = charOffset,
         charOffset: charOffset);
     if (invocation is shadow.SyntheticExpressionJudgment) {
       invocation = desugarSyntheticExpression(invocation);
     }
-    return forest.throwExpression(null, invocation)..fileOffset = charOffset;
+    return forest.createThrow(null, invocation)..fileOffset = charOffset;
   }
 
   Statement buildProblemStatement(Message message, int charOffset,
@@ -5049,8 +5225,7 @@
   Initializer buildFieldInitializer(bool isSynthetic, String name,
       int fieldNameOffset, int assignmentOffset, Expression expression,
       {DartType formalType}) {
-    Builder builder =
-        classBuilder.scope.local[name] ?? classBuilder.origin.scope.local[name];
+    Builder builder = declarationBuilder.lookupLocalMember(name);
     if (builder?.next != null) {
       // Duplicated name, already reported.
       return new LocalInitializer(
@@ -5062,7 +5237,7 @@
                 ..fileOffset = fieldNameOffset)
             ..fileOffset = fieldNameOffset)
         ..fileOffset = fieldNameOffset;
-    } else if (builder is FieldBuilder && builder.isInstanceMember) {
+    } else if (builder is FieldBuilder && builder.isDeclarationInstanceMember) {
       initializedFields ??= <String, int>{};
       if (initializedFields.containsKey(name)) {
         return buildDuplicatedInitializer(builder.field, expression, name,
@@ -5084,8 +5259,9 @@
             library.loader.getDuplicatedFieldInitializerError();
         Expression invocation = buildStaticInvocation(
             constructor.target,
-            forest.arguments(<Expression>[
-              forest.literalString(name, null)..fileOffset = assignmentOffset
+            forest.createArguments(<Expression>[
+              forest.createStringLiteral(name, null)
+                ..fileOffset = assignmentOffset
             ], noLocation)
               ..fileOffset = assignmentOffset,
             charOffset: assignmentOffset);
@@ -5096,7 +5272,7 @@
             builder.field,
             expression,
             new VariableDeclaration.forValue(
-                forest.throwExpression(null, invocation)
+                forest.createThrow(null, invocation)
                   ..fileOffset = assignmentOffset))
           ..fileOffset = assignmentOffset;
       } else {
@@ -5135,7 +5311,7 @@
     if (member.isConst && !constructor.isConst) {
       return buildInvalidSuperInitializer(
           constructor,
-          forest.castArguments(arguments),
+          arguments,
           desugarSyntheticExpression(buildProblem(
               fasta.messageConstConstructorWithNonConstSuper,
               charOffset,
@@ -5143,8 +5319,7 @@
           charOffset);
     }
     needsImplicitSuperInitializer = false;
-    return new SuperInitializerJudgment(
-        constructor, forest.castArguments(arguments))
+    return new SuperInitializerJudgment(constructor, arguments)
       ..fileOffset = charOffset
       ..isSynthetic = isSynthetic;
   }
@@ -5161,8 +5336,7 @@
       // TODO(askesc): Produce invalid initializer.
     }
     needsImplicitSuperInitializer = false;
-    return new RedirectingInitializerJudgment(
-        constructor, forest.castArguments(arguments))
+    return new RedirectingInitializerJudgment(constructor, arguments)
       ..fileOffset = charOffset;
   }
 
@@ -5183,7 +5357,7 @@
     if (member.isNative) {
       push(NullValue.FunctionBody);
     } else {
-      push(forest.block(
+      push(forest.createBlock(
           token,
           <Statement>[
             buildProblemStatement(
@@ -5202,7 +5376,7 @@
     if (builder is NamedTypeBuilder && builder.declaration.isTypeVariable) {
       TypeParameter typeParameter = builder.declaration.target;
       LocatedMessage message;
-      if (!isInstanceContext && typeParameter.parent is Class) {
+      if (!isDeclarationInstanceContext && typeParameter.parent is Class) {
         message = fasta.messageTypeVariableInStaticContext.withLocation(
             unresolved.fileUri,
             unresolved.charOffset,
@@ -5277,8 +5451,7 @@
               offset,
               name.name.length);
         }
-        return new SuperMethodInvocationJudgment(
-            name, forest.castArguments(arguments),
+        return new SuperMethodInvocationJudgment(name, arguments,
             interfaceTarget: target)
           ..fileOffset = offset;
       }
@@ -5286,7 +5459,7 @@
       receiver = new SuperPropertyGetJudgment(name, interfaceTarget: target)
         ..fileOffset = offset;
       MethodInvocation node = new MethodInvocationJudgment(
-          receiver, callName, forest.castArguments(arguments),
+          receiver, callName, arguments,
           isImplicitCall: true)
         ..fileOffset = forest.readOffset(arguments);
       return node;
@@ -5296,19 +5469,19 @@
       VariableDeclaration variable = new VariableDeclaration.forValue(receiver);
       return new NullAwareMethodInvocationJudgment(
           variable,
-          forest.conditionalExpression(
+          forest.createConditionalExpression(
               buildIsNull(new VariableGet(variable), offset, this),
               null,
-              forest.literalNull(null)..fileOffset = offset,
+              forest.createNullLiteral(null)..fileOffset = offset,
               null,
-              new MethodInvocation(new VariableGet(variable), name,
-                  forest.castArguments(arguments), interfaceTarget)
+              new MethodInvocation(
+                  new VariableGet(variable), name, arguments, interfaceTarget)
                 ..fileOffset = offset)
             ..fileOffset = offset)
         ..fileOffset = offset;
     } else {
       MethodInvocation node = new MethodInvocationJudgment(
-          receiver, name, forest.castArguments(arguments),
+          receiver, name, arguments,
           isImplicitCall: isImplicitCall, interfaceTarget: interfaceTarget)
         ..fileOffset = offset;
       return node;
diff --git a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
index 80dbfc9..99197b8 100644
--- a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
@@ -254,8 +254,9 @@
     Builder supertypeDeclaration = supertypeNode.cls;
     if (depth < supertypes.length) {
       TypeBuilder asSupertypeOf = supertypes[depth];
-      if (asSupertypeOf.declaration == supertypeDeclaration)
+      if (asSupertypeOf.declaration == supertypeDeclaration) {
         return asSupertypeOf;
+      }
     }
     supertypes = clsNode.interfaces;
     for (int i = 0; i < supertypes.length; i++) {
@@ -421,8 +422,8 @@
       case MergeKind.superclassSetters:
         // [a] is a method declared in [cls]. This means it defines the
         // interface of this class regardless if its abstract.
-        debug?.log(
-            "superclass: checkValidOverride(${cls.fullNameForErrors}, ${fullName(a)}, ${fullName(b)})");
+        debug?.log("superclass: checkValidOverride(${cls.fullNameForErrors}, "
+            "${fullName(a)}, ${fullName(b)})");
         checkValidOverride(
             a, AbstractMemberOverridingImplementation.selectAbstract(b));
 
@@ -502,8 +503,8 @@
 
         // If [a] is declared in this class, it defines the interface.
         if (a.parent == cls) {
-          debug?.log(
-              "supertypes: checkValidOverride(${cls.fullNameForErrors}, ${fullName(a)}, ${fullName(b)})");
+          debug?.log("supertypes: checkValidOverride(${cls.fullNameForErrors}, "
+              "${fullName(a)}, ${fullName(b)})");
           checkValidOverride(a, b);
           if (a is DelayedMember && !a.isInheritableConflict) {
             if (b is DelayedMember) {
@@ -588,8 +589,8 @@
       assert(substitutions.containsKey(aCls.target),
           "${cls.fullNameForErrors} ${aCls.fullNameForErrors}");
       aSubstitution = substitutions[aCls.target];
-      debug?.log(
-          "${cls.fullNameForErrors} -> ${aCls.fullNameForErrors} $aSubstitution");
+      debug?.log("${cls.fullNameForErrors} -> ${aCls.fullNameForErrors} "
+          "$aSubstitution");
     }
     ClassBuilder bCls = b.parent;
     Substitution bSubstitution;
@@ -597,8 +598,8 @@
       assert(substitutions.containsKey(bCls.target),
           "${cls.fullNameForErrors} ${bCls.fullNameForErrors}");
       bSubstitution = substitutions[bCls.target];
-      debug?.log(
-          "${cls.fullNameForErrors} -> ${bCls.fullNameForErrors} $bSubstitution");
+      debug?.log("${cls.fullNameForErrors} -> ${bCls.fullNameForErrors} "
+          "$bSubstitution");
     }
     Procedure aProcedure = a.target;
     if (b.target is! Procedure) {
@@ -860,8 +861,8 @@
   }
 
   bool inferFieldTypes(MemberBuilder a, Builder b) {
-    debug?.log(
-        "Trying to infer field types for ${fullName(a)} based on ${fullName(b)}");
+    debug?.log("Trying to infer field types for ${fullName(a)} "
+        "based on ${fullName(b)}");
     if (b is DelayedMember) {
       bool hasSameSignature = true;
       List<Builder> declarations = b.declarations;
@@ -902,8 +903,8 @@
       assert(substitutions.containsKey(aCls.target),
           "${cls.fullNameForErrors} ${aCls.fullNameForErrors}");
       aSubstitution = substitutions[aCls.target];
-      debug?.log(
-          "${cls.fullNameForErrors} -> ${aCls.fullNameForErrors} $aSubstitution");
+      debug?.log("${cls.fullNameForErrors} -> ${aCls.fullNameForErrors} "
+          "$aSubstitution");
     }
     ClassBuilder bCls = b.parent;
     Substitution bSubstitution;
@@ -911,8 +912,8 @@
       assert(substitutions.containsKey(bCls.target),
           "${cls.fullNameForErrors} ${bCls.fullNameForErrors}");
       bSubstitution = substitutions[bCls.target];
-      debug?.log(
-          "${cls.fullNameForErrors} -> ${bCls.fullNameForErrors} $bSubstitution");
+      debug?.log("${cls.fullNameForErrors} -> ${bCls.fullNameForErrors} "
+          "$bSubstitution");
     }
     if (bSubstitution != null && inheritedType is! ImplicitFieldType) {
       inheritedType = bSubstitution.substituteType(inheritedType);
@@ -1072,7 +1073,8 @@
     }
     // TODO(ahe): Enable this optimization:
     // if (cls is DillClassBuilder) return;
-    // assert(mergeKind == MergeKind.interfaces || member is! InterfaceConflict);
+    // assert(mergeKind == MergeKind.interfaces ||
+    //    member is! InterfaceConflict);
     if ((mergeKind == MergeKind.superclassMembers ||
             mergeKind == MergeKind.superclassSetters) &&
         isAbstract(member)) {
@@ -1174,9 +1176,9 @@
     /// setters of [cls], but not its superclasses.
     List<Builder> classSetters;
 
-    /// Members (excluding setters) inherited from interfaces. This contains no static
-    /// members. Is null if no interfaces are implemented by this class or its
-    /// superclasses.
+    /// Members (excluding setters) inherited from interfaces. This contains no
+    /// static members. Is null if no interfaces are implemented by this class
+    /// or its superclasses.
     List<Builder> interfaceMembers;
 
     /// Setters inherited from interfaces. This contains no static setters. Is
@@ -1318,8 +1320,8 @@
 
   TypeBuilder recordSupertype(TypeBuilder supertype) {
     if (supertype is NamedTypeBuilder) {
-      debug?.log(
-          "In ${this.cls.fullNameForErrors} recordSupertype(${supertype.fullNameForErrors})");
+      debug?.log("In ${this.cls.fullNameForErrors} "
+          "recordSupertype(${supertype.fullNameForErrors})");
       Builder declaration = supertype.declaration;
       if (declaration is! ClassBuilder) return supertype;
       ClassBuilder cls = declaration;
@@ -1421,8 +1423,8 @@
 
   MergeResult mergeInterfaces(
       ClassHierarchyNode supernode, List<TypeBuilder> interfaces) {
-    debug?.log(
-        "mergeInterfaces($cls (${this.cls}) ${supernode.interfaces} ${interfaces}");
+    debug?.log("mergeInterfaces($cls (${this.cls}) "
+        "${supernode.interfaces} ${interfaces}");
     List<List<Builder>> memberLists =
         new List<List<Builder>>(interfaces.length + 1);
     List<List<Builder>> setterLists =
@@ -1918,6 +1920,9 @@
   Class get functionClass => hierarchy.functionKernelClass;
 
   @override
+  Class get futureClass => hierarchy.futureKernelClass;
+
+  @override
   Class get futureOrClass => hierarchy.futureOrKernelClass;
 
   @override
@@ -1985,8 +1990,8 @@
     }
 
     Builder a = this.a;
-    debug?.log(
-        "Delayed override check of ${fullName(a)} ${fullName(b)} wrt. ${cls.fullNameForErrors}");
+    debug?.log("Delayed override check of ${fullName(a)} "
+        "${fullName(b)} wrt. ${cls.fullNameForErrors}");
     if (cls == a.parent) {
       if (a is ProcedureBuilder) {
         if (a.isGetter && !hasExplicitReturnType(a)) {
@@ -2249,13 +2254,13 @@
         bestTypeSoFar = candidateType;
       } else {
         if (isMoreSpecific(hierarchy, candidateType, bestTypeSoFar)) {
-          debug?.log(
-              "Combined Member Signature: ${fullName(candidate)} ${candidateType} <: ${fullName(bestSoFar)} ${bestTypeSoFar}");
+          debug?.log("Combined Member Signature: ${fullName(candidate)} "
+              "${candidateType} <: ${fullName(bestSoFar)} ${bestTypeSoFar}");
           bestSoFar = candidate;
           bestTypeSoFar = candidateType;
         } else {
-          debug?.log(
-              "Combined Member Signature: ${fullName(candidate)} !<: ${fullName(bestSoFar)}");
+          debug?.log("Combined Member Signature: "
+              "${fullName(candidate)} !<: ${fullName(bestSoFar)}");
         }
       }
     }
@@ -2266,8 +2271,8 @@
         Member target = candidate.target;
         DartType candidateType = computeMemberType(hierarchy, thisType, target);
         if (!isMoreSpecific(hierarchy, bestTypeSoFar, candidateType)) {
-          debug?.log(
-              "Combined Member Signature: ${fullName(bestSoFar)} !<: ${fullName(candidate)}");
+          debug?.log("Combined Member Signature: "
+              "${fullName(bestSoFar)} !<: ${fullName(candidate)}");
 
           String uri = '${parent.library.uri}';
           if (uri == 'dart:js' &&
@@ -2300,8 +2305,8 @@
           context: context);
       return null;
     }
-    debug?.log(
-        "Combined Member Signature of ${fullNameForErrors}: ${fullName(bestSoFar)}");
+    debug?.log("Combined Member Signature of ${fullNameForErrors}: "
+        "${fullName(bestSoFar)}");
 
     ProcedureKind kind = ProcedureKind.Method;
     if (bestSoFar.isField || bestSoFar.isSetter || bestSoFar.isGetter) {
@@ -2312,8 +2317,8 @@
     }
 
     if (modifyKernel) {
-      debug?.log(
-          "Combined Member Signature of ${fullNameForErrors}: new ForwardingNode($parent, $bestSoFar, $declarations, $kind)");
+      debug?.log("Combined Member Signature of ${fullNameForErrors}: "
+          "new ForwardingNode($parent, $bestSoFar, $declarations, $kind)");
       Member stub =
           new ForwardingNode(hierarchy, parent, bestSoFar, declarations, kind)
               .finalize();
@@ -2323,8 +2328,8 @@
         if (bestSoFar.target is Procedure) {
           library.forwardersOrigins..add(stub)..add(bestSoFar.target);
         }
-        debug?.log(
-            "Combined Member Signature of ${fullNameForErrors}: added stub $stub");
+        debug?.log("Combined Member Signature of ${fullNameForErrors}: "
+            "added stub $stub");
         if (parent.isMixinApplication) {
           return combinedMemberSignatureResult = bestSoFar.target;
         } else {
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
index c672dd8..326f81e 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -77,7 +77,8 @@
   coreTypes ??= new CoreTypes(component);
   hierarchy ??= new ClassHierarchy(component);
 
-  final typeEnvironment = new TypeEnvironment(coreTypes, hierarchy);
+  final TypeEnvironment typeEnvironment =
+      new TypeEnvironment(coreTypes, hierarchy);
 
   transformLibraries(component.libraries, backend, environmentDefines,
       typeEnvironment, errorReporter,
@@ -265,7 +266,7 @@
   // Handle definition of constants:
 
   visitFunctionNode(FunctionNode node) {
-    final positionalParameterCount = node.positionalParameters.length;
+    final int positionalParameterCount = node.positionalParameters.length;
     for (int i = 0; i < positionalParameterCount; ++i) {
       final VariableDeclaration variable = node.positionalParameters[i];
       transformAnnotations(variable.annotations, variable);
@@ -569,9 +570,10 @@
     } on _AbortDueToError catch (e) {
       final Uri uri = getFileUri(e.node);
       final int fileOffset = getFileOffset(uri, e.node);
-      final locatedMessage = e.message.withLocation(uri, fileOffset, noLength);
+      final LocatedMessage locatedMessage =
+          e.message.withLocation(uri, fileOffset, noLength);
 
-      final contextMessages = <LocatedMessage>[];
+      final List<LocatedMessage> contextMessages = <LocatedMessage>[];
       if (e.context != null) contextMessages.addAll(e.context);
       for (final TreeNode node in contextChain) {
         final Uri uri = getFileUri(node);
@@ -872,8 +874,9 @@
           node, 'Constructor "$node" belongs to abstract class "${klass}".');
     }
 
-    final positionals = evaluatePositionalArguments(node.arguments);
-    final named = evaluateNamedArguments(node.arguments);
+    final List<Constant> positionals =
+        evaluatePositionalArguments(node.arguments);
+    final Map<String, Constant> named = evaluateNamedArguments(node.arguments);
 
     if (isSymbol && shouldBeUnevaluated) {
       return unevaluated(
@@ -895,7 +898,8 @@
           templateConstEvalInvalidSymbolName.withArguments(nameValue));
     }
 
-    final typeArguments = evaluateTypeArguments(node, node.arguments);
+    final List<DartType> typeArguments =
+        evaluateTypeArguments(node, node.arguments);
 
     // Fill in any missing type arguments with "dynamic".
     for (int i = typeArguments.length; i < klass.typeParameters.length; i++) {
@@ -949,8 +953,8 @@
   bool isValidSymbolName(String name) {
     // See https://api.dartlang.org/stable/2.0.0/dart-core/Symbol/Symbol.html:
     //
-    //  A qualified name is a valid name preceded by a public identifier name and
-    //  a '.', e.g., foo.bar.baz= is a qualified version of baz=.
+    //  A qualified name is a valid name preceded by a public identifier name
+    //  and a '.', e.g., foo.bar.baz= is a qualified version of baz=.
     //
     //  That means that the content of the name String must be either
     //     - a valid public Dart identifier (that is, an identifier not
@@ -962,7 +966,7 @@
     //     - or the empty string (the default name of a library with no library
     //       name declaration).
 
-    const operatorNames = const <String>[
+    const List<String> operatorNames = const <String>[
       '+',
       '-',
       '*',
@@ -988,7 +992,7 @@
     if (name == null) return false;
     if (name == '') return true;
 
-    final parts = name.split('.');
+    final List<String> parts = name.split('.');
 
     // Each qualifier must be a public identifier.
     for (int i = 0; i < parts.length - 1; ++i) {
@@ -1082,7 +1086,8 @@
 
         // We simulate now the constructor invocation.
 
-        // Step 1) Map type arguments and normal arguments from caller to callee.
+        // Step 1) Map type arguments and normal arguments from caller to
+        //         callee.
         for (int i = 0; i < klass.typeParameters.length; i++) {
           env.addTypeParameterValue(klass.typeParameters[i], typeArguments[i]);
         }
@@ -1100,7 +1105,8 @@
           env.addVariableValue(parameter, value);
         }
 
-        // Step 2) Run all initializers (including super calls) with environment setup.
+        // Step 2) Run all initializers (including super calls) with environment
+        //         setup.
         for (final Field field in klass.fields) {
           if (!field.isStatic) {
             instanceBuilder.setFieldValue(
@@ -1213,10 +1219,12 @@
               unevaluatedArguments(arguments, {}, node.arguments.types)));
     }
 
+    final String op = node.name.name;
+
     // Handle == and != first (it's common between all types). Since `a != b` is
     // parsed as `!(a == b)` it is handled implicitly through ==.
-    if (arguments.length == 1 && node.name.name == '==') {
-      final right = arguments[0];
+    if (arguments.length == 1 && op == '==') {
+      final Constant right = arguments[0];
 
       // [DoubleConstant] uses [identical] to determine equality, so we need two
       // special cases:
@@ -1248,7 +1256,7 @@
     // This is a white-listed set of methods we need to support on constants.
     if (receiver is StringConstant) {
       if (arguments.length == 1) {
-        switch (node.name.name) {
+        switch (op) {
           case '+':
             final Constant other = arguments[0];
             if (other is StringConstant) {
@@ -1266,7 +1274,7 @@
       }
     } else if (receiver is IntConstant || receiver is JavaScriptIntConstant) {
       if (arguments.length == 0) {
-        switch (node.name.name) {
+        switch (op) {
           case 'unary-':
             if (targetingJavaScript) {
               BigInt value = (receiver as JavaScriptIntConstant).bigIntValue;
@@ -1288,10 +1296,9 @@
         }
       } else if (arguments.length == 1) {
         final Constant other = arguments[0];
-        final op = node.name.name;
         if (other is IntConstant || other is JavaScriptIntConstant) {
           if ((op == '<<' || op == '>>' || op == '>>>')) {
-            var receiverValue = receiver is IntConstant
+            Object receiverValue = receiver is IntConstant
                 ? receiver.value
                 : (receiver as JavaScriptIntConstant).bigIntValue;
             int otherValue = other is IntConstant
@@ -1300,14 +1307,15 @@
             if (otherValue < 0) {
               return report(
                   node.arguments.positional.first,
-                  // TODO(askesc): Change argument types in template to constants.
+                  // TODO(askesc): Change argument types in template to
+                  // constants.
                   templateConstEvalNegativeShift.withArguments(
                       op, '${receiverValue}', '${otherValue}'));
             }
           }
 
           if ((op == '%' || op == '~/')) {
-            var receiverValue = receiver is IntConstant
+            Object receiverValue = receiver is IntConstant
                 ? receiver.value
                 : (receiver as JavaScriptIntConstant).bigIntValue;
             int otherValue = other is IntConstant
@@ -1339,7 +1347,7 @@
                       .toUnsigned(32)
                       .toInt();
               return evaluateBinaryBitOperation(
-                  node.name.name, receiverValue, otherValue, node);
+                  op, receiverValue, otherValue, node);
             case '<<':
             case '>>':
             case '>>>':
@@ -1358,7 +1366,7 @@
                   : (other as JavaScriptIntConstant).bigIntValue.toInt();
 
               return evaluateBinaryShiftOperation(
-                  node.name.name, receiverValue, otherValue, node,
+                  op, receiverValue, otherValue, node,
                   negativeReceiver: negative);
             default:
               num receiverValue = receiver is IntConstant
@@ -1368,26 +1376,46 @@
                   ? other.value
                   : (other as DoubleConstant).value;
               return evaluateBinaryNumericOperation(
-                  node.name.name, receiverValue, otherValue, node);
+                  op, receiverValue, otherValue, node);
           }
         } else if (other is DoubleConstant) {
+          if ((op == '|' || op == '&' || op == '^') ||
+              (op == '<<' || op == '>>' || op == '>>>')) {
+            return report(
+                node,
+                templateConstEvalInvalidBinaryOperandType.withArguments(
+                    op,
+                    other,
+                    typeEnvironment.intType,
+                    other.getType(typeEnvironment)));
+          }
           num receiverValue = receiver is IntConstant
               ? receiver.value
               : (receiver as DoubleConstant).value;
           return evaluateBinaryNumericOperation(
-              node.name.name, receiverValue, other.value, node);
+              op, receiverValue, other.value, node);
         }
         return report(
             node,
             templateConstEvalInvalidBinaryOperandType.withArguments(
-                node.name.name,
+                op,
                 receiver,
                 typeEnvironment.numType,
                 other.getType(typeEnvironment)));
       }
     } else if (receiver is DoubleConstant) {
+      if ((op == '|' || op == '&' || op == '^') ||
+          (op == '<<' || op == '>>' || op == '>>>')) {
+        return report(
+            node,
+            templateConstEvalInvalidBinaryOperandType.withArguments(
+                op,
+                receiver,
+                typeEnvironment.intType,
+                receiver.getType(typeEnvironment)));
+      }
       if (arguments.length == 0) {
-        switch (node.name.name) {
+        switch (op) {
           case 'unary-':
             return canonicalize(makeDoubleConstant(-receiver.value));
         }
@@ -1399,12 +1427,12 @@
               ? other.value
               : (other as DoubleConstant).value;
           return evaluateBinaryNumericOperation(
-              node.name.name, receiver.value, value, node);
+              op, receiver.value, value, node);
         }
         return report(
             node,
             templateConstEvalInvalidBinaryOperandType.withArguments(
-                node.name.name,
+                op,
                 receiver,
                 typeEnvironment.numType,
                 other.getType(typeEnvironment)));
@@ -1413,7 +1441,7 @@
       if (arguments.length == 1) {
         final Constant other = arguments[0];
         if (other is BoolConstant) {
-          switch (node.name.name) {
+          switch (op) {
             case '|':
               return canonicalize(
                   new BoolConstant(receiver.value || other.value));
@@ -1430,10 +1458,8 @@
       return report(node, messageConstEvalNullValue);
     }
 
-    return report(
-        node,
-        templateConstEvalInvalidMethodInvocation.withArguments(
-            node.name.name, receiver));
+    return report(node,
+        templateConstEvalInvalidMethodInvocation.withArguments(op, receiver));
   }
 
   visitLogicalExpression(LogicalExpression node) {
@@ -1637,7 +1663,8 @@
       }
     }
     if (concatenated.length > 1) {
-      final expressions = new List<Expression>(concatenated.length);
+      final List<Expression> expressions =
+          new List<Expression>(concatenated.length);
       for (int i = 0; i < concatenated.length; i++) {
         Object value = concatenated[i];
         if (value is StringBuffer) {
@@ -1657,8 +1684,8 @@
   visitStaticInvocation(StaticInvocation node) {
     final Procedure target = node.target;
     final Arguments arguments = node.arguments;
-    final positionals = evaluatePositionalArguments(arguments);
-    final named = evaluateNamedArguments(arguments);
+    final List<Constant> positionals = evaluatePositionalArguments(arguments);
+    final Map<String, Constant> named = evaluateNamedArguments(arguments);
     if (shouldBeUnevaluated) {
       return unevaluated(
           node,
@@ -1721,7 +1748,7 @@
       }
     } else if (target.name.name == 'identical') {
       // Ensure the "identical()" function comes from dart:core.
-      final parent = target.parent;
+      final TreeNode parent = target.parent;
       if (parent is Library && parent == coreTypes.coreLibrary) {
         final Constant left = positionals[0];
         final Constant right = positionals[1];
@@ -1801,7 +1828,7 @@
   }
 
   visitSymbolLiteral(SymbolLiteral node) {
-    final libraryReference =
+    final Reference libraryReference =
         node.value.startsWith('_') ? libraryOf(node).reference : null;
     return canonicalize(new SymbolConstant(node.value, libraryReference));
   }
@@ -1817,7 +1844,8 @@
     if (constant is TearOffConstant) {
       if (node.typeArguments.length ==
           constant.procedure.function.typeParameters.length) {
-        final typeArguments = evaluateDartTypes(node, node.typeArguments);
+        final List<DartType> typeArguments =
+            evaluateDartTypes(node, node.typeArguments);
         return canonicalize(
             new PartialInstantiationConstant(constant, typeArguments));
       }
@@ -1878,7 +1906,7 @@
       // Convert to an integer when possible (matching the runtime behavior
       // of `is int`).
       if (value.isFinite && !identical(value, -0.0)) {
-        var i = value.toInt();
+        int i = value.toInt();
         if (value == i.toDouble()) return new JavaScriptIntConstant(i);
       }
     }
@@ -1931,7 +1959,7 @@
   }
 
   DartType evaluateDartType(TreeNode node, DartType type) {
-    final result = env.substituteType(type);
+    final DartType result = env.substituteType(type);
 
     if (!isInstantiated(result)) {
       return report(
@@ -1959,8 +1987,10 @@
 
   Arguments unevaluatedArguments(List<Constant> positionalArgs,
       Map<String, Constant> namedArgs, List<DartType> types) {
-    final positional = new List<Expression>(positionalArgs.length);
-    final named = new List<NamedExpression>(namedArgs.length);
+    final List<Expression> positional =
+        new List<Expression>(positionalArgs.length);
+    final List<NamedExpression> named =
+        new List<NamedExpression>(namedArgs.length);
     for (int i = 0; i < positionalArgs.length; ++i) {
       positional[i] = extract(positionalArgs[i]);
     }
@@ -2025,7 +2055,7 @@
       case '>>':
         if (targetingJavaScript) {
           if (negativeReceiver) {
-            const signBit = 0x80000000;
+            const int signBit = 0x80000000;
             a -= (a & signBit) << 1;
           }
           result = a >> b;
@@ -2286,7 +2316,7 @@
   }
 
   bool visitFunctionType(FunctionType node) {
-    final parameters = node.typeParameters;
+    final List<TypeParameter> parameters = node.typeParameters;
     _availableVariables.addAll(parameters);
     final bool result = node.returnType.accept(this) &&
         node.positionalParameters.every((p) => p.accept(this)) &&
@@ -2301,7 +2331,7 @@
 }
 
 bool _isFormalParameter(VariableDeclaration variable) {
-  final parent = variable.parent;
+  final TreeNode parent = variable.parent;
   if (parent is FunctionNode) {
     return parent.positionalParameters.contains(variable) ||
         parent.namedParameters.contains(variable);
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 419b85a..a025fd0 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -5,6 +5,8 @@
 /// A library to help generate expression.
 library fasta.expression_generator;
 
+import 'dart:core' hide MapEntry;
+
 import 'package:kernel/ast.dart'
     show
         Constructor,
@@ -26,6 +28,9 @@
 
 import '../constant_context.dart' show ConstantContext;
 
+import '../builder/builder.dart' show PrefixBuilder, TypeDeclarationBuilder;
+import '../builder/declaration_builder.dart';
+
 import '../fasta_codes.dart'
     show
         LocatedMessage,
@@ -86,13 +91,7 @@
 
 import 'expression_generator_helper.dart' show ExpressionGeneratorHelper;
 
-import 'forest.dart'
-    show
-        Forest,
-        LoadLibraryBuilder,
-        PrefixBuilder,
-        TypeDeclarationBuilder,
-        UnlinkedDeclaration;
+import 'forest.dart';
 
 import 'kernel_api.dart' show NameSystem, printNodeOn, printQualifiedNameOn;
 
@@ -112,10 +111,11 @@
     show
         AccessErrorBuilder,
         Builder,
-        ClassBuilder,
         InvalidTypeBuilder,
+        LoadLibraryBuilder,
         NamedTypeBuilder,
         TypeBuilder,
+        UnlinkedDeclaration,
         UnresolvedType;
 
 import 'kernel_shadow_ast.dart'
@@ -217,18 +217,18 @@
       {bool voidContext: false}) {
     var complexAssignment = startComplexAssignment(value);
     if (voidContext) {
-      var nullAwareCombiner = _forest.conditionalExpression(
+      var nullAwareCombiner = _forest.createConditionalExpression(
           buildIsNull(_makeRead(complexAssignment), offset, _helper),
           null,
           _makeWrite(value, false, complexAssignment),
           null,
-          _forest.literalNull(null)..fileOffset = offset)
+          _forest.createNullLiteral(null)..fileOffset = offset)
         ..fileOffset = offset;
       complexAssignment?.nullAwareCombiner = nullAwareCombiner;
       return _finish(nullAwareCombiner, complexAssignment);
     }
     var tmp = new VariableDeclaration.forValue(_makeRead(complexAssignment));
-    var nullAwareCombiner = _forest.conditionalExpression(
+    var nullAwareCombiner = _forest.createConditionalExpression(
         buildIsNull(new VariableGet(tmp), offset, _helper),
         null,
         _makeWrite(value, false, complexAssignment),
@@ -265,7 +265,7 @@
       bool voidContext: false,
       Procedure interfaceTarget}) {
     return buildCompoundAssignment(
-        binaryOperator, _forest.literalInt(1, null)..fileOffset = offset,
+        binaryOperator, _forest.createIntLiteral(1, null)..fileOffset = offset,
         offset: offset,
         voidContext: voidContext,
         interfaceTarget: interfaceTarget,
@@ -279,14 +279,14 @@
       bool voidContext: false,
       Procedure interfaceTarget}) {
     if (voidContext) {
-      return buildCompoundAssignment(
-          binaryOperator, _forest.literalInt(1, null)..fileOffset = offset,
+      return buildCompoundAssignment(binaryOperator,
+          _forest.createIntLiteral(1, null)..fileOffset = offset,
           offset: offset,
           voidContext: voidContext,
           interfaceTarget: interfaceTarget,
           isPostIncDec: true);
     }
-    var rhs = _forest.literalInt(1, null)..fileOffset = offset;
+    var rhs = _forest.createIntLiteral(1, null)..fileOffset = offset;
     var complexAssignment = startComplexAssignment(rhs);
     var value = new VariableDeclaration.forValue(_makeRead(complexAssignment));
     valueAccess() => new VariableGet(value);
@@ -308,9 +308,9 @@
   Expression _makeInvalidRead() {
     return _helper.wrapSyntheticExpression(
         _helper.throwNoSuchMethodError(
-            _forest.literalNull(token),
+            _forest.createNullLiteral(token),
             _plainNameForRead,
-            _forest.argumentsEmpty(noLocation),
+            _forest.createArgumentsEmpty(noLocation),
             offsetForToken(token),
             isGetter: true),
         offsetForToken(token));
@@ -323,9 +323,9 @@
   Expression _makeInvalidWrite(Expression value) {
     return _helper.wrapSyntheticExpression(
         _helper.throwNoSuchMethodError(
-            _forest.literalNull(token),
+            _forest.createNullLiteral(token),
             _plainNameForRead,
-            _forest.arguments(<Expression>[value], noLocation),
+            _forest.createArguments(<Expression>[value], noLocation),
             offsetForToken(token),
             isSetter: true),
         offsetForToken(token));
@@ -420,6 +420,8 @@
   /// * If this is an [IncompleteErrorGenerator], this will return the error
   ///   generator itself.
   ///
+  /// If the invocation has explicit type arguments
+  /// [buildTypeWithResolvedArguments] called instead.
   /* Expression | Generator | Initializer */ doInvocation(
       int offset, Arguments arguments);
 
@@ -473,7 +475,7 @@
     }
     return _helper.wrapInvalidConstructorInvocation(
         _helper.throwNoSuchMethodError(
-            _forest.literalNull(token),
+            _forest.createNullLiteral(token),
             _helper.constructorNameForDiagnostics(name,
                 className: _plainNameForRead),
             arguments,
@@ -778,8 +780,9 @@
     if (getter == null) {
       _helper.warnUnresolvedGet(name, offsetForToken(token));
     }
-    var read = new PropertyGet(_forest.thisExpression(token), name, getter)
-      ..fileOffset = offsetForToken(token);
+    var read =
+        new PropertyGet(_forest.createThisExpression(token), name, getter)
+          ..fileOffset = offsetForToken(token);
     complexAssignment?.read = read;
     return read;
   }
@@ -790,9 +793,9 @@
     if (setter == null) {
       _helper.warnUnresolvedSet(name, offsetForToken(token));
     }
-    var write =
-        new PropertySet(_forest.thisExpression(token), name, value, setter)
-          ..fileOffset = offsetForToken(token);
+    var write = new PropertySet(
+        _forest.createThisExpression(token), name, value, setter)
+      ..fileOffset = offsetForToken(token);
     complexAssignment?.write = write;
     return write;
   }
@@ -809,7 +812,7 @@
       interfaceTarget = null;
     }
     return _helper.buildMethodInvocation(
-        _forest.thisExpression(null), name, arguments, offset,
+        _forest.createThisExpression(null), name, arguments, offset,
         interfaceTarget: interfaceTarget);
   }
 
@@ -882,10 +885,10 @@
   Expression _finish(
       Expression body, ComplexAssignmentJudgment complexAssignment) {
     var offset = offsetForToken(token);
-    var nullAwareGuard = _forest.conditionalExpression(
+    var nullAwareGuard = _forest.createConditionalExpression(
         buildIsNull(receiverAccess(), offset, _helper),
         null,
-        _forest.literalNull(null)..fileOffset = offset,
+        _forest.createNullLiteral(null)..fileOffset = offset,
         null,
         body)
       ..fileOffset = offset;
@@ -1046,7 +1049,7 @@
   @override
   Expression _makeSimpleRead() {
     var read = new MethodInvocationJudgment(receiver, indexGetName,
-        _forest.castArguments(_forest.arguments(<Expression>[index], token)),
+        _forest.createArguments(<Expression>[index], token),
         interfaceTarget: getter)
       ..fileOffset = offsetForToken(token);
     return read;
@@ -1056,11 +1059,8 @@
   Expression _makeSimpleWrite(Expression value, bool voidContext,
       ComplexAssignmentJudgment complexAssignment) {
     if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
-    var write = new MethodInvocationJudgment(
-        receiver,
-        indexSetName,
-        _forest.castArguments(
-            _forest.arguments(<Expression>[index, value], token)),
+    var write = new MethodInvocationJudgment(receiver, indexSetName,
+        _forest.createArguments(<Expression>[index, value], token),
         interfaceTarget: setter)
       ..fileOffset = offsetForToken(token);
     complexAssignment?.write = write;
@@ -1069,11 +1069,8 @@
 
   @override
   Expression _makeRead(ComplexAssignmentJudgment complexAssignment) {
-    var read = new MethodInvocationJudgment(
-        receiverAccess(),
-        indexGetName,
-        _forest.castArguments(
-            _forest.arguments(<Expression>[indexAccess()], token)),
+    var read = new MethodInvocationJudgment(receiverAccess(), indexGetName,
+        _forest.createArguments(<Expression>[indexAccess()], token),
         interfaceTarget: getter)
       ..fileOffset = offsetForToken(token);
     complexAssignment?.read = read;
@@ -1084,11 +1081,8 @@
   Expression _makeWrite(Expression value, bool voidContext,
       ComplexAssignmentJudgment complexAssignment) {
     if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
-    var write = new MethodInvocationJudgment(
-        receiverAccess(),
-        indexSetName,
-        _forest.castArguments(
-            _forest.arguments(<Expression>[indexAccess(), value], token)),
+    var write = new MethodInvocationJudgment(receiverAccess(), indexSetName,
+        _forest.createArguments(<Expression>[indexAccess(), value], token),
         interfaceTarget: setter)
       ..fileOffset = offsetForToken(token);
     complexAssignment?.write = write;
@@ -1105,9 +1099,8 @@
     var write = new MethodInvocationJudgment(
         receiverAccess(),
         indexSetName,
-        _forest.castArguments(_forest.arguments(
-            <Expression>[indexAccess(), new VariableGet(valueVariable)],
-            token)),
+        _forest.createArguments(
+            <Expression>[indexAccess(), new VariableGet(valueVariable)], token),
         interfaceTarget: setter)
       ..fileOffset = offsetForToken(token);
     complexAssignment?.write = write;
@@ -1203,11 +1196,10 @@
       Expression value, ComplexAssignmentJudgment complexAssignment) {
     var valueVariable = new VariableDeclaration.forValue(value);
     var write = new MethodInvocationJudgment(
-        _forest.thisExpression(token),
+        _forest.createThisExpression(token),
         indexSetName,
-        _forest.castArguments(_forest.arguments(
-            <Expression>[indexAccess(), new VariableGet(valueVariable)],
-            token)),
+        _forest.createArguments(
+            <Expression>[indexAccess(), new VariableGet(valueVariable)], token),
         interfaceTarget: setter)
       ..fileOffset = offsetForToken(token);
     complexAssignment?.write = write;
@@ -1218,10 +1210,8 @@
 
   @override
   Expression _makeSimpleRead() {
-    return new MethodInvocationJudgment(
-        _forest.thisExpression(token),
-        indexGetName,
-        _forest.castArguments(_forest.arguments(<Expression>[index], token)),
+    return new MethodInvocationJudgment(_forest.createThisExpression(token),
+        indexGetName, _forest.createArguments(<Expression>[index], token),
         interfaceTarget: getter)
       ..fileOffset = offsetForToken(token);
   }
@@ -1231,10 +1221,9 @@
       ComplexAssignmentJudgment complexAssignment) {
     if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
     var write = new MethodInvocationJudgment(
-        _forest.thisExpression(token),
+        _forest.createThisExpression(token),
         indexSetName,
-        _forest.castArguments(
-            _forest.arguments(<Expression>[index, value], token)),
+        _forest.createArguments(<Expression>[index, value], token),
         interfaceTarget: setter)
       ..fileOffset = offsetForToken(token);
     complexAssignment?.write = write;
@@ -1244,10 +1233,9 @@
   @override
   Expression _makeRead(ComplexAssignmentJudgment complexAssignment) {
     var read = new MethodInvocationJudgment(
-        _forest.thisExpression(token),
+        _forest.createThisExpression(token),
         indexGetName,
-        _forest.castArguments(
-            _forest.arguments(<Expression>[indexAccess()], token)),
+        _forest.createArguments(<Expression>[indexAccess()], token),
         interfaceTarget: getter)
       ..fileOffset = offsetForToken(token);
     complexAssignment?.read = read;
@@ -1259,10 +1247,9 @@
       ComplexAssignmentJudgment complexAssignment) {
     if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
     var write = new MethodInvocationJudgment(
-        _forest.thisExpression(token),
+        _forest.createThisExpression(token),
         indexSetName,
-        _forest.castArguments(
-            _forest.arguments(<Expression>[indexAccess(), value], token)),
+        _forest.createArguments(<Expression>[indexAccess(), value], token),
         interfaceTarget: setter)
       ..fileOffset = offsetForToken(token);
     complexAssignment?.write = write;
@@ -1331,9 +1318,8 @@
     }
     var write = new SuperMethodInvocation(
         indexSetName,
-        _forest.castArguments(_forest.arguments(
-            <Expression>[indexAccess(), new VariableGet(valueVariable)],
-            token)),
+        _forest.createArguments(
+            <Expression>[indexAccess(), new VariableGet(valueVariable)], token),
         setter)
       ..fileOffset = offsetForToken(token);
     complexAssignment?.write = write;
@@ -1349,8 +1335,8 @@
           isSuper: true);
     }
     // TODO(ahe): Use [DirectMethodInvocation] when possible.
-    return new SuperMethodInvocationJudgment(indexGetName,
-        _forest.castArguments(_forest.arguments(<Expression>[index], token)),
+    return new SuperMethodInvocationJudgment(
+        indexGetName, _forest.createArguments(<Expression>[index], token),
         interfaceTarget: getter)
       ..fileOffset = offsetForToken(token);
   }
@@ -1363,11 +1349,8 @@
       _helper.warnUnresolvedMethod(indexSetName, offsetForToken(token),
           isSuper: true);
     }
-    var write = new SuperMethodInvocation(
-        indexSetName,
-        _forest.castArguments(
-            _forest.arguments(<Expression>[index, value], token)),
-        setter)
+    var write = new SuperMethodInvocation(indexSetName,
+        _forest.createArguments(<Expression>[index, value], token), setter)
       ..fileOffset = offsetForToken(token);
     complexAssignment?.write = write;
     return write;
@@ -1379,11 +1362,8 @@
       _helper.warnUnresolvedMethod(indexGetName, offsetForToken(token),
           isSuper: true);
     }
-    var read = new SuperMethodInvocation(
-        indexGetName,
-        _forest.castArguments(
-            _forest.arguments(<Expression>[indexAccess()], token)),
-        getter)
+    var read = new SuperMethodInvocation(indexGetName,
+        _forest.createArguments(<Expression>[indexAccess()], token), getter)
       ..fileOffset = offsetForToken(token);
     complexAssignment?.read = read;
     return read;
@@ -1399,8 +1379,7 @@
     }
     var write = new SuperMethodInvocation(
         indexSetName,
-        _forest.castArguments(
-            _forest.arguments(<Expression>[indexAccess(), value], token)),
+        _forest.createArguments(<Expression>[indexAccess(), value], token),
         setter)
       ..fileOffset = offsetForToken(token);
     complexAssignment?.write = write;
@@ -1440,9 +1419,52 @@
   }
 }
 
+/// A [StaticAccessGenerator] represents a subexpression whose prefix is
+/// a static or top-level member, including static extension members.
+///
+/// For instance
+///
+///   get property => 0;
+///   set property(_) {}
+///   var field;
+///   method() {}
+///
+///   main() {
+///     property;     // a StaticAccessGenerator is created for `property`.
+///     property = 0; // a StaticAccessGenerator is created for `property`.
+///     field = 0;    // a StaticAccessGenerator is created for `field`.
+///     method;       // a StaticAccessGenerator is created for `method`.
+///     method();     // a StaticAccessGenerator is created for `method`.
+///   }
+///
+///   class A {}
+///   extension B on A {
+///     static get property => 0;
+///     static set property(_) {}
+///     static var field;
+///     static method() {
+///       property;     // this StaticAccessGenerator is created for `property`.
+///       property = 0; // this StaticAccessGenerator is created for `property`.
+///       field = 0;    // this StaticAccessGenerator is created for `field`.
+///       method;       // this StaticAccessGenerator is created for `method`.
+///       method();     // this StaticAccessGenerator is created for `method`.
+///     }
+///   }
+///
 class StaticAccessGenerator extends Generator {
+  /// The static [Member] used for performing a read or invocation on this
+  /// subexpression.
+  ///
+  /// This can be `null` if the subexpression doesn't have a readable target.
+  /// For instance if the subexpression is a setter without a corresponding
+  /// getter.
   final Member readTarget;
 
+  /// The static [Member] used for performing a write on this subexpression.
+  ///
+  /// This can be `null` if the subexpression doesn't have a writable target.
+  /// For instance if the subexpression is a final field, a method, or a getter
+  /// without a corresponding setter.
   final Member writeTarget;
 
   StaticAccessGenerator(ExpressionGeneratorHelper helper, Token token,
@@ -1549,6 +1571,222 @@
   }
 }
 
+/// An [ExtensionInstanceAccessGenerator] represents a subexpression whose
+/// prefix is an extension instance member.
+///
+/// For instance
+///
+///   class A {}
+///   extension B on A {
+///     get property => 0;
+///     set property(_) {}
+///     var field;
+///     method() {
+///       property;     // this generator is created for `property`.
+///       property = 0; // this generator is created for `property`.
+///       field = 0;    // this generator is created for `field`.
+///       method;       // this generator is created for `method`.
+///       method();     // this generator is created for `method`.
+///     }
+///   }
+///
+class ExtensionInstanceAccessGenerator extends Generator {
+  /// The static [Member] generated for an instance extension member which is
+  /// used for performing a read or invocation on this subexpression.
+  ///
+  /// This can be `null` if the subexpression doesn't have a readable target.
+  /// For instance if the subexpression is a setter without a corresponding
+  /// getter.
+  final Procedure readTarget;
+
+  /// `true` if the [readTarget] is declared as a regular method in the
+  /// extension.
+  ///
+  /// All extension instance members are converted into to top level methods so
+  /// this field is needed to know whether a read should be a tear off, which
+  /// is the case for regular methods, or an invocation should be a read follow
+  /// by a call, which is the case for getters.
+  final bool readTargetIsRegularMethod;
+
+  /// The static [Member] generated for an instance extension member which is
+  /// used for performing a write on this subexpression.
+  ///
+  /// This can be `null` if the subexpression doesn't have a writable target.
+  /// For instance if the subexpression is a final field, a method, or a getter
+  /// without a corresponding setter.
+  final Procedure writeTarget;
+
+  /// The parameter holding the value for `this` within the current extension
+  /// instance method.
+  // TODO(johnniwinther): Handle static access to extension instance members,
+  // in which case the access is erroneous and [extensionThis] is `null`.
+  final VariableDeclaration extensionThis;
+
+  /// The type parameters synthetically added to  the current extension
+  /// instance method.
+  final List<TypeParameter> extensionTypeParameters;
+
+  ExtensionInstanceAccessGenerator(
+      ExpressionGeneratorHelper helper,
+      Token token,
+      this.readTarget,
+      this.readTargetIsRegularMethod,
+      this.writeTarget,
+      this.extensionThis,
+      this.extensionTypeParameters)
+      : assert(readTarget != null || writeTarget != null),
+        assert(extensionThis != null),
+        super(helper, token);
+
+  factory ExtensionInstanceAccessGenerator.fromBuilder(
+      ExpressionGeneratorHelper helper,
+      VariableDeclaration extensionThis,
+      List<TypeParameter> extensionTypeParameters,
+      Builder declaration,
+      Token token,
+      Builder builderSetter) {
+    if (declaration is AccessErrorBuilder) {
+      AccessErrorBuilder error = declaration;
+      declaration = error.builder;
+      // We should only see an access error here if we've looked up a setter
+      // when not explicitly looking for a setter.
+      assert(declaration.isSetter);
+    } else if (declaration.target == null) {
+      return unhandled(
+          "${declaration.runtimeType}",
+          "InstanceExtensionAccessGenerator.fromBuilder",
+          offsetForToken(token),
+          helper.uri);
+    }
+    bool readTargetIsRegularMethod = declaration.isRegularMethod;
+    Procedure getter;
+    if (declaration.isGetter || declaration.isRegularMethod) {
+      getter = declaration.target;
+    }
+    Procedure setter;
+    if (builderSetter != null && builderSetter.isSetter) {
+      setter = builderSetter.target;
+    }
+    return new ExtensionInstanceAccessGenerator(
+        helper,
+        token,
+        getter,
+        readTargetIsRegularMethod,
+        setter,
+        extensionThis,
+        extensionTypeParameters);
+  }
+
+  @override
+  String get _debugName => "InstanceExtensionAccessGenerator";
+
+  @override
+  String get _plainNameForRead => (readTarget ?? writeTarget).name.name;
+
+  @override
+  Expression _makeRead(ComplexAssignmentJudgment complexAssignment) {
+    Expression read;
+    if (readTarget == null) {
+      read = _makeInvalidRead();
+      if (complexAssignment != null) {
+        read = _helper.desugarSyntheticExpression(read);
+      }
+    } else if (readTargetIsRegularMethod) {
+      read = _helper.createExtensionTearOff(
+          readTarget, extensionThis, extensionTypeParameters, token);
+    } else {
+      List<DartType> typeArguments;
+      if (extensionTypeParameters != null) {
+        typeArguments = [];
+        for (TypeParameter typeParameter in extensionTypeParameters) {
+          typeArguments.add(_forest.createTypeParameterType(typeParameter));
+        }
+      }
+      read = _helper.buildStaticInvocation(
+          readTarget,
+          _helper.forest.createArguments([
+            _helper.createVariableGet(extensionThis, offsetForToken(token))
+          ], token, types: typeArguments),
+          charOffset: token.charOffset);
+    }
+    complexAssignment?.read = read;
+    return read;
+  }
+
+  @override
+  Expression _makeWrite(Expression value, bool voidContext,
+      ComplexAssignmentJudgment complexAssignment) {
+    Expression write;
+    if (writeTarget == null) {
+      write = _makeInvalidWrite(value);
+      if (complexAssignment != null) {
+        write = _helper.desugarSyntheticExpression(write);
+      }
+    } else {
+      List<DartType> typeArguments;
+      if (extensionTypeParameters != null) {
+        typeArguments = [];
+        for (TypeParameter typeParameter in extensionTypeParameters) {
+          typeArguments.add(_forest.createTypeParameterType(typeParameter));
+        }
+      }
+      write = _helper.buildStaticInvocation(
+          writeTarget,
+          _helper.forest.createArguments([
+            _helper.createVariableGet(extensionThis, offsetForToken(token)),
+            value
+          ], token, types: typeArguments),
+          charOffset: token.charOffset);
+    }
+    complexAssignment?.write = write;
+    write.fileOffset = offsetForToken(token);
+    return write;
+  }
+
+  @override
+  Expression doInvocation(int offset, Arguments arguments) {
+    if (readTargetIsRegularMethod) {
+      List<Expression> positionalArguments = [
+        _helper.createVariableGet(extensionThis, offset)
+      ]..addAll(arguments.positional);
+      List<DartType> typeArguments;
+      if (extensionTypeParameters != null) {
+        typeArguments = [];
+        for (TypeParameter typeParameter in extensionTypeParameters) {
+          typeArguments.add(_forest.createTypeParameterType(typeParameter));
+        }
+        if (arguments.types.isNotEmpty) {
+          typeArguments.addAll(arguments.types);
+        }
+      } else if (arguments.types.isNotEmpty) {
+        typeArguments = arguments.types;
+      }
+      return _helper.buildStaticInvocation(
+          readTarget,
+          _forest.createArguments(positionalArguments, token,
+              named: arguments.named, types: typeArguments),
+          charOffset: offset);
+    } else {
+      return _helper.buildMethodInvocation(buildSimpleRead(), callName,
+          arguments, adjustForImplicitCall(_plainNameForRead, offset),
+          isImplicitCall: true);
+    }
+  }
+
+  @override
+  ComplexAssignmentJudgment startComplexAssignment(Expression rhs) =>
+      SyntheticWrapper.wrapStaticAssignment(rhs);
+
+  @override
+  void printOn(StringSink sink) {
+    NameSystem syntheticNames = new NameSystem();
+    sink.write(", readTarget: ");
+    printQualifiedNameOn(readTarget, sink, syntheticNames: syntheticNames);
+    sink.write(", writeTarget: ");
+    printQualifiedNameOn(writeTarget, sink, syntheticNames: syntheticNames);
+  }
+}
+
 class LoadLibraryGenerator extends Generator {
   final LoadLibraryBuilder builder;
 
@@ -1810,12 +2048,12 @@
         _helper.addProblemErrorIfConst(
             declaration.message.messageObject, offset, token.length);
         super.expression = _helper.wrapSyntheticExpression(
-            _forest.throwExpression(
-                null, _forest.literalString(declaration.message.message, token))
+            _forest.createThrow(null,
+                _forest.createStringLiteral(declaration.message.message, token))
               ..fileOffset = offset,
             offset);
       } else {
-        super.expression = _forest.literalType(
+        super.expression = _forest.createTypeLiteral(
             _helper.buildDartType(
                 new UnresolvedType(
                     buildTypeWithResolvedArguments(null), offset, _uri),
@@ -1830,9 +2068,9 @@
   Expression _makeInvalidWrite(Expression value) {
     return _helper.wrapSyntheticExpression(
         _helper.throwNoSuchMethodError(
-            _forest.literalNull(token),
+            _forest.createNullLiteral(token),
             _plainNameForRead,
-            _forest.arguments(<Expression>[value], null)
+            _forest.createArguments(<Expression>[value], null)
               ..fileOffset = value.fileOffset,
             offsetForToken(token),
             isSetter: true),
@@ -1849,8 +2087,8 @@
     Name name = send.name;
     Arguments arguments = send.arguments;
 
-    if (declaration is ClassBuilder) {
-      ClassBuilder declaration = this.declaration;
+    if (declaration is DeclarationBuilder) {
+      DeclarationBuilder declaration = this.declaration;
       Builder member = declaration.findStaticBuilder(
           name.name, offsetForToken(send.token), _uri, _helper.library);
 
@@ -2004,7 +2242,7 @@
   @override
   Initializer buildFieldInitializer(Map<String, int> initializedFields) {
     return _helper.buildInvalidInitializer(_helper.desugarSyntheticExpression(
-        buildError(_forest.argumentsEmpty(token), isSetter: true)));
+        buildError(_forest.createArgumentsEmpty(token), isSetter: true)));
   }
 
   @override
@@ -2021,7 +2259,7 @@
 
   @override
   Expression buildAssignment(Expression value, {bool voidContext: false}) {
-    return buildError(_forest.arguments(<Expression>[value], token),
+    return buildError(_forest.createArguments(<Expression>[value], token),
         isSetter: true);
   }
 
@@ -2032,7 +2270,7 @@
       Procedure interfaceTarget,
       bool isPreIncDec: false,
       bool isPostIncDec: false}) {
-    return buildError(_forest.arguments(<Expression>[value], token),
+    return buildError(_forest.createArguments(<Expression>[value], token),
         isGetter: true);
   }
 
@@ -2040,9 +2278,9 @@
   Expression buildPrefixIncrement(Name binaryOperator,
       {int offset: -1, bool voidContext: false, Procedure interfaceTarget}) {
     return buildError(
-        _forest.arguments(
-            <Expression>[_forest.literalInt(1, null)..fileOffset = offset],
-            token),
+        _forest.createArguments(<Expression>[
+          _forest.createIntLiteral(1, null)..fileOffset = offset
+        ], token),
         isGetter: true)
       ..fileOffset = offset;
   }
@@ -2051,9 +2289,9 @@
   Expression buildPostfixIncrement(Name binaryOperator,
       {int offset: -1, bool voidContext: false, Procedure interfaceTarget}) {
     return buildError(
-        _forest.arguments(
-            <Expression>[_forest.literalInt(1, null)..fileOffset = offset],
-            token),
+        _forest.createArguments(<Expression>[
+          _forest.createIntLiteral(1, null)..fileOffset = offset
+        ], token),
         isGetter: true)
       ..fileOffset = offset;
   }
@@ -2062,23 +2300,23 @@
   Expression buildNullAwareAssignment(
       Expression value, DartType type, int offset,
       {bool voidContext: false}) {
-    return buildError(_forest.arguments(<Expression>[value], token),
+    return buildError(_forest.createArguments(<Expression>[value], token),
         isSetter: true);
   }
 
   @override
   Expression buildSimpleRead() {
-    return buildError(_forest.argumentsEmpty(token), isGetter: true);
+    return buildError(_forest.createArgumentsEmpty(token), isGetter: true);
   }
 
   @override
   Expression _makeInvalidRead() {
-    return buildError(_forest.argumentsEmpty(token), isGetter: true);
+    return buildError(_forest.createArgumentsEmpty(token), isGetter: true);
   }
 
   @override
   Expression _makeInvalidWrite(Expression value) {
-    return buildError(_forest.arguments(<Expression>[value], token),
+    return buildError(_forest.createArguments(<Expression>[value], token),
         isSetter: true);
   }
 
@@ -2137,7 +2375,7 @@
     offset ??= offsetForToken(this.token);
     return _helper.wrapSyntheticExpression(
         _helper.throwNoSuchMethodError(
-            _forest.literalNull(null)..fileOffset = offset,
+            _forest.createNullLiteral(null)..fileOffset = offset,
             _plainNameForRead,
             arguments,
             offset,
@@ -2168,7 +2406,7 @@
 
   @override
   Expression buildSimpleRead() {
-    return buildError(_forest.argumentsEmpty(token), isGetter: true)
+    return buildError(_forest.createArgumentsEmpty(token), isGetter: true)
       ..fileOffset = token.charOffset;
   }
 
@@ -2182,7 +2420,7 @@
       bool isCompound, Expression value) {
     return _helper.wrapUnresolvedVariableAssignment(
         _helper.desugarSyntheticExpression(buildError(
-            _forest.arguments(<Expression>[value], token),
+            _forest.createArguments(<Expression>[value], token),
             isSetter: true)),
         isCompound,
         value,
@@ -2468,7 +2706,8 @@
   /* Expression | Generator | Initializer */ doInvocation(
       int offset, Arguments arguments) {
     return _helper.wrapInLocatedProblem(
-        _helper.evaluateArgumentsBefore(arguments, _forest.literalNull(token)),
+        _helper.evaluateArgumentsBefore(
+            arguments, _forest.createNullLiteral(token)),
         messageCantUsePrefixAsExpression.withLocation(
             _helper.uri, offsetForToken(token), lengthForToken(token)));
   }
@@ -2481,10 +2720,8 @@
           "'${send.name.name}' != ${send.token.lexeme}");
       Object result = qualifiedLookup(send.token);
       if (send is SendAccessGenerator) {
-        result = _helper.finishSend(
-            result,
-            send.arguments as dynamic /* TODO(ahe): Remove this cast. */,
-            offsetForToken(token));
+        result =
+            _helper.finishSend(result, send.arguments, offsetForToken(token));
       }
       if (isNullAware) {
         result = _helper.wrapInLocatedProblem(
@@ -2540,7 +2777,7 @@
   Expression doInvocation(int offset, Arguments arguments) {
     return _helper.wrapSyntheticExpression(
         _helper.throwNoSuchMethodError(
-            _forest.literalNull(null)..fileOffset = offset,
+            _forest.createNullLiteral(null)..fileOffset = offset,
             _plainNameForRead,
             arguments,
             offsetForToken(token)),
@@ -2733,7 +2970,7 @@
       if (inFieldInitializer) {
         return buildFieldInitializerError(null);
       } else {
-        return _forest.thisExpression(token);
+        return _forest.createThisExpression(token);
       }
     } else {
       return _helper.buildProblem(messageSuperAsExpression,
@@ -2779,8 +3016,8 @@
         _helper.warnUnresolvedMethod(name, offsetForToken(send.token),
             isSuper: isSuper);
       }
-      return _helper.buildMethodInvocation(_forest.thisExpression(null), name,
-          send.arguments, offsetForToken(send.token),
+      return _helper.buildMethodInvocation(_forest.createThisExpression(null),
+          name, send.arguments, offsetForToken(send.token),
           isSuper: isSuper, interfaceTarget: getter);
     } else {
       Member setter =
@@ -2812,7 +3049,7 @@
       return _helper.buildProblem(messageSuperAsExpression, offset, noLength);
     } else {
       return _helper.buildMethodInvocation(
-          _forest.thisExpression(null), callName, arguments, offset,
+          _forest.createThisExpression(null), callName, arguments, offset,
           isImplicitCall: true);
     }
   }
@@ -2836,7 +3073,7 @@
     if (message != null) {
       return _helper.buildInvalidInitializer(_helper.wrapSyntheticExpression(
           _helper.throwNoSuchMethodError(
-              _forest.literalNull(null)..fileOffset = offset,
+              _forest.createNullLiteral(null)..fileOffset = offset,
               _helper.constructorNameForDiagnostics(name.name,
                   isSuper: isSuper),
               arguments,
@@ -2942,7 +3179,7 @@
 
   @override
   Expression buildSimpleRead() {
-    return buildError(_forest.argumentsEmpty(token), isGetter: true)
+    return buildError(_forest.createArgumentsEmpty(token), isGetter: true)
       ..fileOffset = offsetForToken(token);
   }
 
@@ -3144,9 +3381,8 @@
   return new MethodInvocationJudgment(
       left,
       operator,
-      helper.forest
-          .castArguments(helper.forest.arguments(<Expression>[right], null))
-            ..fileOffset = offset,
+      helper.forest.createArguments(<Expression>[right], null)
+        ..fileOffset = offset,
       interfaceTarget: interfaceTarget)
     ..fileOffset = offset;
 }
@@ -3154,7 +3390,7 @@
 Expression buildIsNull(
     Expression value, int offset, ExpressionGeneratorHelper helper) {
   return makeBinary(value, equalsName, null,
-      helper.forest.literalNull(null)..fileOffset = offset, helper,
+      helper.forest.createNullLiteral(null)..fileOffset = offset, helper,
       offset: offset);
 }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
index 128a924..3beeb4f 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
@@ -36,7 +36,8 @@
         Name,
         Procedure,
         StaticGet,
-        TypeParameter;
+        TypeParameter,
+        VariableDeclaration;
 
 import 'kernel_builder.dart'
     show PrefixBuilder, LibraryBuilder, TypeDeclarationBuilder;
@@ -159,4 +160,41 @@
 
   Expression wrapUnresolvedVariableAssignment(
       Expression desugared, bool isCompound, Expression rhs, int charOffset);
+
+  /// Creates a [VariableGet] of the [variable] using [charOffset] as the file
+  /// offset of the created node.
+  Expression createVariableGet(VariableDeclaration variable, int charOffset);
+
+  /// Creates a tear off of the extension instance method [procedure].
+  ///
+  /// The tear off is created as a function expression that captures the
+  /// current `this` value from [extensionThis] and [extensionTypeParameters]
+  /// synthetically copied to the extension instance method.
+  ///
+  /// For instance the declaration of `B.m`:
+  ///
+  ///     class A<X, Y> {}
+  ///     class B<S, T> on A<S, T> {
+  ///       void m<U>(U u) {}
+  ///     }
+  ///
+  /// is converted into this top level method:
+  ///
+  ///     void B<S,T>|m<U>(A<S, T> #this, U u) {}
+  ///
+  /// and a tear off
+  ///
+  ///     A<X, Y> a = ...;
+  ///     var f = a.m;
+  ///
+  /// is converted into:
+  ///
+  ///     A<int, String> a = ...;
+  ///     var f = <#U>(#U u) => B<S,T>|m<int,String,#U>(a, u);
+  ///
+  Expression createExtensionTearOff(
+      Procedure procedure,
+      VariableDeclaration extensionThis,
+      List<TypeParameter> extensionTypeParameters,
+      Token token);
 }
diff --git a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
deleted file mode 100644
index ecbb93e..0000000
--- a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
+++ /dev/null
@@ -1,651 +0,0 @@
-// 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.
-
-library fasta.fangorn;
-
-import 'dart:core' hide MapEntry;
-
-import 'package:kernel/ast.dart'
-    show
-        Arguments,
-        AsExpression,
-        AssertInitializer,
-        AwaitExpression,
-        Block,
-        BoolLiteral,
-        BreakStatement,
-        Catch,
-        CheckLibraryIsLoaded,
-        ConditionalExpression,
-        DartType,
-        EmptyStatement,
-        Expression,
-        ExpressionStatement,
-        InvalidExpression,
-        IsExpression,
-        LabeledStatement,
-        Let,
-        LibraryDependency,
-        LogicalExpression,
-        MapEntry,
-        NamedExpression,
-        Not,
-        NullLiteral,
-        Rethrow,
-        Statement,
-        StringConcatenation,
-        StringLiteral,
-        ThisExpression,
-        Throw,
-        TreeNode,
-        VariableDeclaration,
-        setParents;
-
-import '../parser.dart' show offsetForToken, optional;
-
-import '../problems.dart' show unsupported;
-
-import '../scanner.dart' show Token;
-
-import 'body_builder.dart' show LabelTarget;
-
-import 'collections.dart'
-    show
-        ForElement,
-        ForInElement,
-        ForInMapEntry,
-        ForMapEntry,
-        IfElement,
-        IfMapEntry,
-        SpreadElement;
-
-import 'kernel_shadow_ast.dart'
-    show
-        ArgumentsJudgment,
-        AssertInitializerJudgment,
-        AssertStatementJudgment,
-        BlockJudgment,
-        CatchJudgment,
-        DoJudgment,
-        DoubleJudgment,
-        EmptyStatementJudgment,
-        ExpressionStatementJudgment,
-        ForJudgment,
-        IfJudgment,
-        IntJudgment,
-        ListLiteralJudgment,
-        LoadLibraryJudgment,
-        MapLiteralJudgment,
-        ReturnJudgment,
-        SetLiteralJudgment,
-        ShadowLargeIntLiteral,
-        SymbolLiteralJudgment,
-        SyntheticExpressionJudgment,
-        TryCatchJudgment,
-        TryFinallyJudgment,
-        TypeLiteralJudgment,
-        WhileJudgment,
-        YieldJudgment;
-
-import 'forest.dart' show Forest;
-
-/// A shadow tree factory.
-class Fangorn extends Forest {
-  const Fangorn();
-
-  @override
-  ArgumentsJudgment arguments(List<Expression> positional, Token token,
-      {List<DartType> types, List<NamedExpression> named}) {
-    return new ArgumentsJudgment(positional, types: types, named: named)
-      ..fileOffset = offsetForToken(token);
-  }
-
-  @override
-  ArgumentsJudgment argumentsEmpty(Token token) {
-    return arguments(<Expression>[], token);
-  }
-
-  @override
-  List<NamedExpression> argumentsNamed(Arguments arguments) {
-    return arguments.named;
-  }
-
-  @override
-  List<Expression> argumentsPositional(Arguments arguments) {
-    return arguments.positional;
-  }
-
-  @override
-  List<DartType> argumentsTypeArguments(Arguments arguments) {
-    return arguments.types;
-  }
-
-  @override
-  void argumentsSetTypeArguments(Arguments arguments, List<DartType> types) {
-    ArgumentsJudgment.setNonInferrableArgumentTypes(arguments, types);
-  }
-
-  @override
-  StringLiteral asLiteralString(Expression value) => value;
-
-  @override
-  BoolLiteral literalBool(bool value, Token token) {
-    return new BoolLiteral(value)..fileOffset = offsetForToken(token);
-  }
-
-  @override
-  DoubleJudgment literalDouble(double value, Token token) {
-    return new DoubleJudgment(value)..fileOffset = offsetForToken(token);
-  }
-
-  @override
-  IntJudgment literalInt(int value, Token token) {
-    return new IntJudgment(value, token?.lexeme)
-      ..fileOffset = offsetForToken(token);
-  }
-
-  @override
-  ShadowLargeIntLiteral literalLargeInt(String literal, Token token) {
-    return new ShadowLargeIntLiteral(literal, offsetForToken(token));
-  }
-
-  @override
-  ListLiteralJudgment literalList(
-      Token constKeyword,
-      bool isConst,
-      Object typeArgument,
-      Object typeArguments,
-      Token leftBracket,
-      List<Expression> expressions,
-      Token rightBracket) {
-    // TODO(brianwilkerson): The file offset computed below will not be correct
-    // if there are type arguments but no `const` keyword.
-    return new ListLiteralJudgment(expressions,
-        typeArgument: typeArgument, isConst: isConst)
-      ..fileOffset = offsetForToken(constKeyword ?? leftBracket);
-  }
-
-  @override
-  SetLiteralJudgment literalSet(
-      Token constKeyword,
-      bool isConst,
-      Object typeArgument,
-      Object typeArguments,
-      Token leftBrace,
-      List<Expression> expressions,
-      Token rightBrace) {
-    // TODO(brianwilkerson): The file offset computed below will not be correct
-    // if there are type arguments but no `const` keyword.
-    return new SetLiteralJudgment(expressions,
-        typeArgument: typeArgument, isConst: isConst)
-      ..fileOffset = offsetForToken(constKeyword ?? leftBrace);
-  }
-
-  @override
-  MapLiteralJudgment literalMap(
-      Token constKeyword,
-      bool isConst,
-      DartType keyType,
-      DartType valueType,
-      Object typeArguments,
-      Token leftBrace,
-      List<MapEntry> entries,
-      Token rightBrace) {
-    // TODO(brianwilkerson): The file offset computed below will not be correct
-    // if there are type arguments but no `const` keyword.
-    return new MapLiteralJudgment(entries,
-        keyType: keyType, valueType: valueType, isConst: isConst)
-      ..fileOffset = offsetForToken(constKeyword ?? leftBrace);
-  }
-
-  @override
-  NullLiteral literalNull(Token token) {
-    return new NullLiteral()..fileOffset = offsetForToken(token);
-  }
-
-  @override
-  StringLiteral literalString(String value, Token token) {
-    return new StringLiteral(value)..fileOffset = offsetForToken(token);
-  }
-
-  @override
-  SymbolLiteralJudgment literalSymbolMultiple(String value, Token hash, _) {
-    return new SymbolLiteralJudgment(value)..fileOffset = offsetForToken(hash);
-  }
-
-  @override
-  SymbolLiteralJudgment literalSymbolSingular(String value, Token hash, _) {
-    return new SymbolLiteralJudgment(value)..fileOffset = offsetForToken(hash);
-  }
-
-  @override
-  TypeLiteralJudgment literalType(DartType type, Token token) {
-    return new TypeLiteralJudgment(type)..fileOffset = offsetForToken(token);
-  }
-
-  @override
-  MapEntry mapEntry(Expression key, Token colon, Expression value) {
-    return new MapEntry(key, value)..fileOffset = offsetForToken(colon);
-  }
-
-  @override
-  int readOffset(TreeNode node) => node.fileOffset;
-
-  @override
-  Expression loadLibrary(LibraryDependency dependency, Arguments arguments) {
-    return new LoadLibraryJudgment(dependency, arguments);
-  }
-
-  @override
-  Expression checkLibraryIsLoaded(LibraryDependency dependency) {
-    return new CheckLibraryIsLoaded(dependency);
-  }
-
-  @override
-  Expression asExpression(Expression expression, DartType type, Token token) {
-    return new AsExpression(expression, type)
-      ..fileOffset = offsetForToken(token);
-  }
-
-  @override
-  Expression spreadElement(Expression expression, Token token) {
-    return new SpreadElement(expression, token.lexeme == '...?')
-      ..fileOffset = offsetForToken(token);
-  }
-
-  @override
-  Expression ifElement(Expression condition, Expression then,
-      Expression otherwise, Token token) {
-    return new IfElement(condition, then, otherwise)
-      ..fileOffset = offsetForToken(token);
-  }
-
-  @override
-  MapEntry ifMapEntry(
-      Expression condition, MapEntry then, MapEntry otherwise, Token token) {
-    return new IfMapEntry(condition, then, otherwise)
-      ..fileOffset = offsetForToken(token);
-  }
-
-  @override
-  Expression forElement(
-      List<VariableDeclaration> variables,
-      Expression condition,
-      List<Expression> updates,
-      Expression body,
-      Token token) {
-    return new ForElement(variables, condition, updates, body)
-      ..fileOffset = offsetForToken(token);
-  }
-
-  @override
-  MapEntry forMapEntry(
-      List<VariableDeclaration> variables,
-      Expression condition,
-      List<Expression> updates,
-      MapEntry body,
-      Token token) {
-    return new ForMapEntry(variables, condition, updates, body)
-      ..fileOffset = offsetForToken(token);
-  }
-
-  @override
-  Expression forInElement(VariableDeclaration variable, Expression iterable,
-      Statement prologue, Expression body, Expression problem, Token token,
-      {bool isAsync: false}) {
-    return new ForInElement(variable, iterable, prologue, body, problem,
-        isAsync: isAsync)
-      ..fileOffset = offsetForToken(token);
-  }
-
-  @override
-  MapEntry forInMapEntry(VariableDeclaration variable, Expression iterable,
-      Statement prologue, MapEntry body, Expression problem, Token token,
-      {bool isAsync: false}) {
-    return new ForInMapEntry(variable, iterable, prologue, body, problem,
-        isAsync: isAsync)
-      ..fileOffset = offsetForToken(token);
-  }
-
-  @override
-  AssertInitializer assertInitializer(
-      Token assertKeyword,
-      Token leftParenthesis,
-      Expression condition,
-      Token comma,
-      Expression message) {
-    return new AssertInitializerJudgment(assertStatement(
-        assertKeyword, leftParenthesis, condition, comma, message, null));
-  }
-
-  @override
-  Statement assertStatement(Token assertKeyword, Token leftParenthesis,
-      Expression condition, Token comma, Expression message, Token semicolon) {
-    // Compute start and end offsets for the condition expression.
-    // This code is a temporary workaround because expressions don't carry
-    // their start and end offsets currently.
-    //
-    // The token that follows leftParenthesis is considered to be the
-    // first token of the condition.
-    // TODO(ahe): this really should be condition.fileOffset.
-    int startOffset = leftParenthesis.next.offset;
-    int endOffset;
-    {
-      // Search forward from leftParenthesis to find the last token of
-      // the condition - which is a token immediately followed by a commaToken,
-      // right parenthesis or a trailing comma.
-      Token conditionBoundary = comma ?? leftParenthesis.endGroup;
-      Token conditionLastToken = leftParenthesis;
-      while (!conditionLastToken.isEof) {
-        Token nextToken = conditionLastToken.next;
-        if (nextToken == conditionBoundary) {
-          break;
-        } else if (optional(',', nextToken) &&
-            nextToken.next == conditionBoundary) {
-          // The next token is trailing comma, which means current token is
-          // the last token of the condition.
-          break;
-        }
-        conditionLastToken = nextToken;
-      }
-      if (conditionLastToken.isEof) {
-        endOffset = startOffset = -1;
-      } else {
-        endOffset = conditionLastToken.offset + conditionLastToken.length;
-      }
-    }
-    return new AssertStatementJudgment(condition,
-        conditionStartOffset: startOffset,
-        conditionEndOffset: endOffset,
-        message: message);
-  }
-
-  @override
-  Expression awaitExpression(Expression operand, Token token) {
-    return new AwaitExpression(operand)..fileOffset = offsetForToken(token);
-  }
-
-  @override
-  Statement block(
-      Token openBrace, List<Statement> statements, Token closeBrace) {
-    List<Statement> copy;
-    for (int i = 0; i < statements.length; i++) {
-      Statement statement = statements[i];
-      if (statement is _VariablesDeclaration) {
-        copy ??= new List<Statement>.from(statements.getRange(0, i));
-        copy.addAll(statement.declarations);
-      } else if (copy != null) {
-        copy.add(statement);
-      }
-    }
-    return new BlockJudgment(copy ?? statements)
-      ..fileOffset = offsetForToken(openBrace);
-  }
-
-  @override
-  Statement breakStatement(Token breakKeyword, Object label, Token semicolon) {
-    return new BreakStatement(null)..fileOffset = breakKeyword.charOffset;
-  }
-
-  @override
-  Catch catchClause(
-      Token onKeyword,
-      DartType exceptionType,
-      Token catchKeyword,
-      VariableDeclaration exceptionParameter,
-      VariableDeclaration stackTraceParameter,
-      DartType stackTraceType,
-      Statement body) {
-    return new CatchJudgment(exceptionParameter, body,
-        guard: exceptionType, stackTrace: stackTraceParameter)
-      ..fileOffset = offsetForToken(onKeyword ?? catchKeyword);
-  }
-
-  @override
-  Expression conditionalExpression(Expression condition, Token question,
-      Expression thenExpression, Token colon, Expression elseExpression) {
-    return new ConditionalExpression(
-        condition, thenExpression, elseExpression, null)
-      ..fileOffset = offsetForToken(question);
-  }
-
-  @override
-  Statement continueStatement(
-      Token continueKeyword, Object label, Token semicolon) {
-    return new BreakStatement(null)..fileOffset = continueKeyword.charOffset;
-  }
-
-  @override
-  Statement doStatement(Token doKeyword, Statement body, Token whileKeyword,
-      Expression condition, Token semicolon) {
-    return new DoJudgment(body, condition)..fileOffset = doKeyword.charOffset;
-  }
-
-  Statement expressionStatement(Expression expression, Token semicolon) {
-    return new ExpressionStatementJudgment(expression);
-  }
-
-  @override
-  Statement emptyStatement(Token semicolon) {
-    return new EmptyStatementJudgment();
-  }
-
-  @override
-  Statement forStatement(
-      Token forKeyword,
-      Token leftParenthesis,
-      List<VariableDeclaration> variables,
-      Token leftSeparator,
-      Expression condition,
-      Statement conditionStatement,
-      List<Expression> updaters,
-      Token rightParenthesis,
-      Statement body) {
-    return new ForJudgment(variables, condition, updaters, body)
-      ..fileOffset = forKeyword.charOffset;
-  }
-
-  @override
-  Statement ifStatement(Token ifKeyword, Expression condition,
-      Statement thenStatement, Token elseKeyword, Statement elseStatement) {
-    return new IfJudgment(condition, thenStatement, elseStatement)
-      ..fileOffset = ifKeyword.charOffset;
-  }
-
-  @override
-  Expression isExpression(
-      Expression operand, Token isOperator, Token notOperator, DartType type) {
-    Expression result = new IsExpression(operand, type)
-      ..fileOffset = offsetForToken(isOperator);
-    if (notOperator != null) {
-      result = notExpression(result, notOperator, false);
-    }
-    return result;
-  }
-
-  @override
-  Statement labeledStatement(LabelTarget target, Statement statement) =>
-      statement;
-
-  @override
-  Expression logicalExpression(
-      Expression leftOperand, Token operator, Expression rightOperand) {
-    return new LogicalExpression(
-        leftOperand, operator.stringValue, rightOperand)
-      ..fileOffset = offsetForToken(operator);
-  }
-
-  @override
-  Expression notExpression(Expression operand, Token token, bool isSynthetic) {
-    return new Not(operand)..fileOffset = offsetForToken(token);
-  }
-
-  @override
-  Expression parenthesizedCondition(
-      Token leftParenthesis, Expression expression, Token rightParenthesis) {
-    return expression;
-  }
-
-  @override
-  Statement rethrowStatement(Token rethrowKeyword, Token semicolon) {
-    return new ExpressionStatementJudgment(
-        new Rethrow()..fileOffset = offsetForToken(rethrowKeyword));
-  }
-
-  @override
-  Statement returnStatement(
-      Token returnKeyword, Expression expression, Token semicolon) {
-    return new ReturnJudgment(returnKeyword?.lexeme, expression)
-      ..fileOffset = returnKeyword.charOffset;
-  }
-
-  @override
-  Expression stringConcatenationExpression(
-      List<Expression> expressions, Token token) {
-    return new StringConcatenation(expressions)
-      ..fileOffset = offsetForToken(token);
-  }
-
-  @override
-  Statement syntheticLabeledStatement(Statement statement) {
-    return new LabeledStatement(statement);
-  }
-
-  @override
-  Expression thisExpression(Token token) {
-    return new ThisExpression()..fileOffset = offsetForToken(token);
-  }
-
-  @override
-  Expression throwExpression(Token throwKeyword, Expression expression) {
-    return new Throw(expression)..fileOffset = offsetForToken(throwKeyword);
-  }
-
-  @override
-  bool isThrow(Object o) => o is Throw;
-
-  @override
-  Statement tryStatement(Token tryKeyword, Statement body,
-      List<Catch> catchClauses, Token finallyKeyword, Statement finallyBlock) {
-    Statement result = body;
-    if (catchClauses != null) {
-      result = new TryCatchJudgment(result, catchClauses);
-    }
-    if (finallyBlock != null) {
-      result = new TryFinallyJudgment(result, finallyBlock);
-    }
-    return result;
-  }
-
-  @override
-  _VariablesDeclaration variablesDeclaration(
-      List<VariableDeclaration> declarations, Uri uri) {
-    return new _VariablesDeclaration(declarations, uri);
-  }
-
-  @override
-  List<VariableDeclaration> variablesDeclarationExtractDeclarations(
-      _VariablesDeclaration variablesDeclaration) {
-    return variablesDeclaration.declarations;
-  }
-
-  @override
-  Statement wrapVariables(Statement statement) {
-    if (statement is _VariablesDeclaration) {
-      return new BlockJudgment(
-          new List<Statement>.from(statement.declarations, growable: true))
-        ..fileOffset = statement.fileOffset;
-    } else if (statement is VariableDeclaration) {
-      return new BlockJudgment(<Statement>[statement])
-        ..fileOffset = statement.fileOffset;
-    } else {
-      return statement;
-    }
-  }
-
-  @override
-  Statement whileStatement(
-      Token whileKeyword, Expression condition, Statement body) {
-    return new WhileJudgment(condition, body)
-      ..fileOffset = whileKeyword.charOffset;
-  }
-
-  @override
-  Statement yieldStatement(
-      Token yieldKeyword, Token star, Expression expression, Token semicolon) {
-    return new YieldJudgment(star != null, expression)
-      ..fileOffset = yieldKeyword.charOffset;
-  }
-
-  @override
-  Expression getExpressionFromExpressionStatement(Statement statement) {
-    return (statement as ExpressionStatement).expression;
-  }
-
-  @override
-  bool isBlock(Object node) => node is Block;
-
-  @override
-  bool isEmptyStatement(Statement statement) => statement is EmptyStatement;
-
-  @override
-  bool isErroneousNode(Object node) {
-    if (node is ExpressionStatement) {
-      ExpressionStatement statement = node;
-      node = statement.expression;
-    }
-    if (node is VariableDeclaration) {
-      VariableDeclaration variable = node;
-      node = variable.initializer;
-    }
-    if (node is SyntheticExpressionJudgment) {
-      SyntheticExpressionJudgment synth = node;
-      node = synth.desugared;
-    }
-    if (node is Let) {
-      Let let = node;
-      node = let.variable.initializer;
-    }
-    return node is InvalidExpression;
-  }
-
-  @override
-  bool isExpressionStatement(Statement statement) =>
-      statement is ExpressionStatement;
-
-  @override
-  bool isThisExpression(Object node) => node is ThisExpression;
-
-  @override
-  bool isVariablesDeclaration(Object node) => node is _VariablesDeclaration;
-}
-
-class _VariablesDeclaration extends Statement {
-  final List<VariableDeclaration> declarations;
-  final Uri uri;
-
-  _VariablesDeclaration(this.declarations, this.uri) {
-    setParents(declarations, this);
-  }
-
-  @override
-  accept(v) {
-    unsupported("accept", fileOffset, uri);
-  }
-
-  @override
-  accept1(v, arg) {
-    unsupported("accept1", fileOffset, uri);
-  }
-
-  @override
-  visitChildren(v) {
-    unsupported("visitChildren", fileOffset, uri);
-  }
-
-  @override
-  transformChildren(v) {
-    unsupported("transformChildren", fileOffset, uri);
-  }
-}
diff --git a/pkg/front_end/lib/src/fasta/kernel/forest.dart b/pkg/front_end/lib/src/fasta/kernel/forest.dart
index 8a0136c..34cbd35 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forest.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forest.dart
@@ -2,79 +2,112 @@
 // 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.
 
-library fasta.forest;
+library fasta.fangorn;
 
 import 'dart:core' hide MapEntry;
 
-import 'package:kernel/ast.dart'
-    show
-        Arguments,
-        Catch,
-        DartType,
-        Expression,
-        LibraryDependency,
-        MapEntry,
-        NamedExpression,
-        Statement,
-        TreeNode,
-        VariableDeclaration;
+import 'package:kernel/ast.dart';
 
-import 'body_builder.dart' show LabelTarget;
+import '../parser.dart' show offsetForToken, optional;
 
-import 'kernel_builder.dart' show Identifier;
+import '../problems.dart' show unsupported;
 
 import '../scanner.dart' show Token;
 
-export '../fasta_codes.dart' show Message;
-
-export 'body_builder.dart' show Operator;
-
-export 'constness.dart' show Constness;
-
-export 'expression_generator.dart' show Generator, PrefixUseGenerator;
-
-export 'expression_generator_helper.dart' show ExpressionGeneratorHelper;
-
-export 'kernel_builder.dart'
+import 'collections.dart'
     show
-        Identifier,
-        LoadLibraryBuilder,
-        PrefixBuilder,
-        TypeDeclarationBuilder,
-        UnlinkedDeclaration;
+        ForElement,
+        ForInElement,
+        ForInMapEntry,
+        ForMapEntry,
+        IfElement,
+        IfMapEntry,
+        SpreadElement;
 
-/// A tree factory.
-abstract class Forest {
+import 'kernel_shadow_ast.dart'
+    show
+        ArgumentsJudgment,
+        AssertInitializerJudgment,
+        AssertStatementJudgment,
+        BlockJudgment,
+        CatchJudgment,
+        DoJudgment,
+        DoubleJudgment,
+        EmptyStatementJudgment,
+        ExpressionStatementJudgment,
+        ForJudgment,
+        FunctionNodeJudgment,
+        IfJudgment,
+        IntJudgment,
+        ListLiteralJudgment,
+        LoadLibraryJudgment,
+        MapLiteralJudgment,
+        ReturnJudgment,
+        SetLiteralJudgment,
+        ShadowLargeIntLiteral,
+        SymbolLiteralJudgment,
+        SyntheticExpressionJudgment,
+        TryCatchJudgment,
+        TryFinallyJudgment,
+        TypeLiteralJudgment,
+        VariableDeclarationJudgment,
+        WhileJudgment,
+        YieldJudgment;
+
+/// A shadow tree factory.
+class Forest {
   const Forest();
 
-  Arguments arguments(List<Expression> positional, Token location,
-      {List<DartType> types, List<NamedExpression> named});
+  Arguments createArguments(List<Expression> positional, Token token,
+      {List<DartType> types, List<NamedExpression> named}) {
+    return new ArgumentsJudgment(positional, types: types, named: named)
+      ..fileOffset = offsetForToken(token);
+  }
 
-  Arguments argumentsEmpty(Token location);
+  Arguments createArgumentsEmpty(Token token) {
+    return createArguments(<Expression>[], token);
+  }
 
-  List<Object> argumentsNamed(Arguments arguments);
+  List<NamedExpression> argumentsNamed(Arguments arguments) {
+    return arguments.named;
+  }
 
-  List<Expression> argumentsPositional(Arguments arguments);
+  List<Expression> argumentsPositional(Arguments arguments) {
+    return arguments.positional;
+  }
 
-  List<DartType> argumentsTypeArguments(Arguments arguments);
+  List<DartType> argumentsTypeArguments(Arguments arguments) {
+    return arguments.types;
+  }
 
-  void argumentsSetTypeArguments(Arguments arguments, List<DartType> types);
+  void argumentsSetTypeArguments(Arguments arguments, List<DartType> types) {
+    ArgumentsJudgment.setNonInferrableArgumentTypes(arguments, types);
+  }
 
-  Expression asLiteralString(Expression value);
+  StringLiteral asLiteralString(Expression value) => value;
 
   /// Return a representation of a boolean literal at the given [location]. The
   /// literal has the given [value].
-  Expression literalBool(bool value, Token location);
+  BoolLiteral createBoolLiteral(bool value, Token token) {
+    return new BoolLiteral(value)..fileOffset = offsetForToken(token);
+  }
 
   /// Return a representation of a double literal at the given [location]. The
   /// literal has the given [value].
-  Expression literalDouble(double value, Token location);
+  DoubleLiteral createDoubleLiteral(double value, Token token) {
+    return new DoubleJudgment(value)..fileOffset = offsetForToken(token);
+  }
 
   /// Return a representation of an integer literal at the given [location]. The
   /// literal has the given [value].
-  Expression literalInt(int value, Token location);
+  IntLiteral createIntLiteral(int value, Token token) {
+    return new IntJudgment(value, token?.lexeme)
+      ..fileOffset = offsetForToken(token);
+  }
 
-  Expression literalLargeInt(String literal, Token location);
+  IntLiteral createIntLiteralLarge(String literal, Token token) {
+    return new ShadowLargeIntLiteral(literal, offsetForToken(token));
+  }
 
   /// Return a representation of a list literal. The [constKeyword] is the
   /// location of the `const` keyword, or `null` if there is no keyword. The
@@ -87,14 +120,20 @@
   /// type arguments. The [leftBracket] is the location of the `[`. The list of
   /// [expressions] is a list of the representations of the list elements. The
   /// [rightBracket] is the location of the `]`.
-  Expression literalList(
+  ListLiteral createListLiteral(
       Token constKeyword,
       bool isConst,
       Object typeArgument,
       Object typeArguments,
       Token leftBracket,
       List<Expression> expressions,
-      Token rightBracket);
+      Token rightBracket) {
+    // TODO(brianwilkerson): The file offset computed below will not be correct
+    // if there are type arguments but no `const` keyword.
+    return new ListLiteralJudgment(expressions,
+        typeArgument: typeArgument, isConst: isConst)
+      ..fileOffset = offsetForToken(constKeyword ?? leftBracket);
+  }
 
   /// Return a representation of a set literal. The [constKeyword] is the
   /// location of the `const` keyword, or `null` if there is no keyword. The
@@ -107,14 +146,20 @@
   /// type arguments. The [leftBrace] is the location of the `{`. The list of
   /// [expressions] is a list of the representations of the set elements. The
   /// [rightBrace] is the location of the `}`.
-  Expression literalSet(
+  SetLiteral createSetLiteral(
       Token constKeyword,
       bool isConst,
       Object typeArgument,
       Object typeArguments,
       Token leftBrace,
       List<Expression> expressions,
-      Token rightBrace);
+      Token rightBrace) {
+    // TODO(brianwilkerson): The file offset computed below will not be correct
+    // if there are type arguments but no `const` keyword.
+    return new SetLiteralJudgment(expressions,
+        typeArgument: typeArgument, isConst: isConst)
+      ..fileOffset = offsetForToken(constKeyword ?? leftBrace);
+  }
 
   /// Return a representation of a map literal. The [constKeyword] is the
   /// location of the `const` keyword, or `null` if there is no keyword. The
@@ -129,7 +174,7 @@
   /// `null` if there are no type arguments. The [leftBrace] is the location
   /// of the `{`. The list of [entries] is a list of the representations of the
   /// map entries. The [rightBrace] is the location of the `}`.
-  Expression literalMap(
+  MapLiteral createMapLiteral(
       Token constKeyword,
       bool isConst,
       DartType keyType,
@@ -137,128 +182,257 @@
       Object typeArguments,
       Token leftBrace,
       List<MapEntry> entries,
-      Token rightBrace);
+      Token rightBrace) {
+    // TODO(brianwilkerson): The file offset computed below will not be correct
+    // if there are type arguments but no `const` keyword.
+    return new MapLiteralJudgment(entries,
+        keyType: keyType, valueType: valueType, isConst: isConst)
+      ..fileOffset = offsetForToken(constKeyword ?? leftBrace);
+  }
 
   /// Return a representation of a null literal at the given [location].
-  Expression literalNull(Token location);
+  NullLiteral createNullLiteral(Token token) {
+    return new NullLiteral()..fileOffset = offsetForToken(token);
+  }
 
   /// Return a representation of a simple string literal at the given
   /// [location]. The literal has the given [value]. This does not include
   /// either adjacent strings or interpolated strings.
-  Expression literalString(String value, Token location);
+  StringLiteral createStringLiteral(String value, Token token) {
+    return new StringLiteral(value)..fileOffset = offsetForToken(token);
+  }
 
-  /// Return a representation of a symbol literal defined by the [hash] and the
-  /// list of [components]. The [value] is the string value of the symbol.
-  Expression literalSymbolMultiple(
-      String value, Token hash, List<Identifier> components);
+  /// Return a representation of a symbol literal defined by [value].
+  SymbolLiteral createSymbolLiteral(String value, Token token) {
+    return new SymbolLiteralJudgment(value)..fileOffset = offsetForToken(token);
+  }
 
-  /// Return a representation of a symbol literal defined by the [hash] and the
-  /// single [component]. The component can be either an [Identifier] or an
-  /// [Operator]. The [value] is the string value of the symbol.
-  Expression literalSymbolSingular(String value, Token hash, Object component);
-
-  Expression literalType(DartType type, Token location);
+  TypeLiteral createTypeLiteral(DartType type, Token token) {
+    return new TypeLiteralJudgment(type)..fileOffset = offsetForToken(token);
+  }
 
   /// Return a representation of a key/value pair in a literal map. The [key] is
   /// the representation of the expression used to compute the key. The [colon]
   /// is the location of the colon separating the key and the value. The [value]
   /// is the representation of the expression used to compute the value.
-  Object mapEntry(Expression key, Token colon, Expression value);
+  MapEntry createMapEntry(Expression key, Token colon, Expression value) {
+    return new MapEntry(key, value)..fileOffset = offsetForToken(colon);
+  }
 
-  int readOffset(TreeNode node);
+  int readOffset(TreeNode node) => node.fileOffset;
 
-  Expression loadLibrary(LibraryDependency dependency, Arguments arguments);
+  Expression createLoadLibrary(
+      LibraryDependency dependency, Arguments arguments) {
+    return new LoadLibraryJudgment(dependency, arguments);
+  }
 
-  Expression checkLibraryIsLoaded(LibraryDependency dependency);
+  Expression checkLibraryIsLoaded(LibraryDependency dependency) {
+    return new CheckLibraryIsLoaded(dependency);
+  }
 
-  Expression asExpression(Expression expression, DartType type, Token location);
+  Expression createAsExpression(
+      Expression expression, DartType type, Token token) {
+    return new AsExpression(expression, type)
+      ..fileOffset = offsetForToken(token);
+  }
 
-  Expression spreadElement(Expression expression, Token token);
+  Expression createSpreadElement(Expression expression, Token token) {
+    return new SpreadElement(expression, token.lexeme == '...?')
+      ..fileOffset = offsetForToken(token);
+  }
 
-  Expression ifElement(
-      Expression condition, Expression then, Expression otherwise, Token token);
+  Expression createIfElement(Expression condition, Expression then,
+      Expression otherwise, Token token) {
+    return new IfElement(condition, then, otherwise)
+      ..fileOffset = offsetForToken(token);
+  }
 
-  MapEntry ifMapEntry(
-      Expression condition, MapEntry then, MapEntry otherwise, Token token);
+  MapEntry createIfMapEntry(
+      Expression condition, MapEntry then, MapEntry otherwise, Token token) {
+    return new IfMapEntry(condition, then, otherwise)
+      ..fileOffset = offsetForToken(token);
+  }
 
-  Expression forElement(
+  Expression createForElement(
       List<VariableDeclaration> variables,
       Expression condition,
       List<Expression> updates,
       Expression body,
-      Token token);
+      Token token) {
+    return new ForElement(variables, condition, updates, body)
+      ..fileOffset = offsetForToken(token);
+  }
 
-  MapEntry forMapEntry(
+  MapEntry createForMapEntry(
       List<VariableDeclaration> variables,
       Expression condition,
       List<Expression> updates,
       MapEntry body,
-      Token token);
+      Token token) {
+    return new ForMapEntry(variables, condition, updates, body)
+      ..fileOffset = offsetForToken(token);
+  }
 
-  Expression forInElement(VariableDeclaration variable, Expression iterable,
-      Statement prologue, Expression body, Expression problem, Token token,
-      {bool isAsync: false});
+  Expression createForInElement(
+      VariableDeclaration variable,
+      Expression iterable,
+      Statement prologue,
+      Expression body,
+      Expression problem,
+      Token token,
+      {bool isAsync: false}) {
+    return new ForInElement(variable, iterable, prologue, body, problem,
+        isAsync: isAsync)
+      ..fileOffset = offsetForToken(token);
+  }
 
-  MapEntry forInMapEntry(VariableDeclaration variable, Expression iterable,
-      Statement prologue, MapEntry body, Expression problem, Token token,
-      {bool isAsync: false});
+  MapEntry createForInMapEntry(
+      VariableDeclaration variable,
+      Expression iterable,
+      Statement prologue,
+      MapEntry body,
+      Expression problem,
+      Token token,
+      {bool isAsync: false}) {
+    return new ForInMapEntry(variable, iterable, prologue, body, problem,
+        isAsync: isAsync)
+      ..fileOffset = offsetForToken(token);
+  }
 
   /// Return a representation of an assert that appears in a constructor's
   /// initializer list.
-  Object assertInitializer(Token assertKeyword, Token leftParenthesis,
-      Expression condition, Token comma, Expression message);
+  AssertInitializer createAssertInitializer(
+      Token assertKeyword,
+      Token leftParenthesis,
+      Expression condition,
+      Token comma,
+      Expression message) {
+    return new AssertInitializerJudgment(createAssertStatement(
+        assertKeyword, leftParenthesis, condition, comma, message, null));
+  }
 
   /// Return a representation of an assert that appears as a statement.
-  Statement assertStatement(Token assertKeyword, Token leftParenthesis,
-      Expression condition, Token comma, Expression message, Token semicolon);
+  Statement createAssertStatement(Token assertKeyword, Token leftParenthesis,
+      Expression condition, Token comma, Expression message, Token semicolon) {
+    // Compute start and end offsets for the condition expression.
+    // This code is a temporary workaround because expressions don't carry
+    // their start and end offsets currently.
+    //
+    // The token that follows leftParenthesis is considered to be the
+    // first token of the condition.
+    // TODO(ahe): this really should be condition.fileOffset.
+    int startOffset = leftParenthesis.next.offset;
+    int endOffset;
+    {
+      // Search forward from leftParenthesis to find the last token of
+      // the condition - which is a token immediately followed by a commaToken,
+      // right parenthesis or a trailing comma.
+      Token conditionBoundary = comma ?? leftParenthesis.endGroup;
+      Token conditionLastToken = leftParenthesis;
+      while (!conditionLastToken.isEof) {
+        Token nextToken = conditionLastToken.next;
+        if (nextToken == conditionBoundary) {
+          break;
+        } else if (optional(',', nextToken) &&
+            nextToken.next == conditionBoundary) {
+          // The next token is trailing comma, which means current token is
+          // the last token of the condition.
+          break;
+        }
+        conditionLastToken = nextToken;
+      }
+      if (conditionLastToken.isEof) {
+        endOffset = startOffset = -1;
+      } else {
+        endOffset = conditionLastToken.offset + conditionLastToken.length;
+      }
+    }
+    return new AssertStatementJudgment(condition,
+        conditionStartOffset: startOffset,
+        conditionEndOffset: endOffset,
+        message: message);
+  }
 
-  Expression awaitExpression(Expression operand, Token location);
+  Expression createAwaitExpression(Expression operand, Token token) {
+    return new AwaitExpression(operand)..fileOffset = offsetForToken(token);
+  }
 
   /// Return a representation of a block of [statements] enclosed between the
   /// [openBracket] and [closeBracket].
-  Statement block(
-      Token openBrace, List<Statement> statements, Token closeBrace);
+  Statement createBlock(
+      Token openBrace, List<Statement> statements, Token closeBrace) {
+    List<Statement> copy;
+    for (int i = 0; i < statements.length; i++) {
+      Statement statement = statements[i];
+      if (statement is _VariablesDeclaration) {
+        copy ??= new List<Statement>.from(statements.getRange(0, i));
+        copy.addAll(statement.declarations);
+      } else if (copy != null) {
+        copy.add(statement);
+      }
+    }
+    return new BlockJudgment(copy ?? statements)
+      ..fileOffset = offsetForToken(openBrace);
+  }
 
   /// Return a representation of a break statement.
-  Statement breakStatement(
-      Token breakKeyword, Identifier label, Token semicolon);
+  Statement createBreakStatement(
+      Token breakKeyword, Object label, Token semicolon) {
+    return new BreakStatement(null)..fileOffset = breakKeyword.charOffset;
+  }
 
   /// Return a representation of a catch clause.
-  Object catchClause(
+  Catch createCatch(
       Token onKeyword,
       DartType exceptionType,
       Token catchKeyword,
       VariableDeclaration exceptionParameter,
       VariableDeclaration stackTraceParameter,
       DartType stackTraceType,
-      Statement body);
+      Statement body) {
+    return new CatchJudgment(exceptionParameter, body,
+        guard: exceptionType, stackTrace: stackTraceParameter)
+      ..fileOffset = offsetForToken(onKeyword ?? catchKeyword);
+  }
 
   /// Return a representation of a conditional expression. The [condition] is
   /// the expression preceding the question mark. The [question] is the `?`. The
   /// [thenExpression] is the expression following the question mark. The
   /// [colon] is the `:`. The [elseExpression] is the expression following the
   /// colon.
-  Expression conditionalExpression(Expression condition, Token question,
-      Expression thenExpression, Token colon, Expression elseExpression);
+  Expression createConditionalExpression(Expression condition, Token question,
+      Expression thenExpression, Token colon, Expression elseExpression) {
+    return new ConditionalExpression(
+        condition, thenExpression, elseExpression, null)
+      ..fileOffset = offsetForToken(question);
+  }
 
   /// Return a representation of a continue statement.
-  Statement continueStatement(
-      Token continueKeyword, Identifier label, Token semicolon);
+  Statement createContinueStatement(
+      Token continueKeyword, Object label, Token semicolon) {
+    return new BreakStatement(null)..fileOffset = continueKeyword.charOffset;
+  }
 
   /// Return a representation of a do statement.
-  Statement doStatement(Token doKeyword, Statement body, Token whileKeyword,
-      Expression condition, Token semicolon);
+  Statement createDoStatement(Token doKeyword, Statement body,
+      Token whileKeyword, Expression condition, Token semicolon) {
+    return new DoJudgment(body, condition)..fileOffset = doKeyword.charOffset;
+  }
 
   /// Return a representation of an expression statement composed from the
   /// [expression] and [semicolon].
-  Statement expressionStatement(Expression expression, Token semicolon);
+  Statement createExpressionStatement(Expression expression, Token semicolon) {
+    return new ExpressionStatementJudgment(expression);
+  }
 
   /// Return a representation of an empty statement consisting of the given
   /// [semicolon].
-  Statement emptyStatement(Token semicolon);
+  Statement createEmptyStatement(Token semicolon) {
+    return new EmptyStatementJudgment();
+  }
 
   /// Return a representation of a for statement.
-  Statement forStatement(
+  Statement createForStatement(
       Token forKeyword,
       Token leftParenthesis,
       List<VariableDeclaration> variables,
@@ -267,59 +441,90 @@
       Statement conditionStatement,
       List<Expression> updaters,
       Token rightParenthesis,
-      Statement body);
+      Statement body) {
+    return new ForJudgment(variables, condition, updaters, body)
+      ..fileOffset = forKeyword.charOffset;
+  }
 
   /// Return a representation of an `if` statement.
-  Statement ifStatement(Token ifKeyword, Expression condition,
-      Statement thenStatement, Token elseKeyword, Statement elseStatement);
+  Statement createIfStatement(Token ifKeyword, Expression condition,
+      Statement thenStatement, Token elseKeyword, Statement elseStatement) {
+    return new IfJudgment(condition, thenStatement, elseStatement)
+      ..fileOffset = ifKeyword.charOffset;
+  }
 
   /// Return a representation of an `is` expression. The [operand] is the
   /// representation of the left operand. The [isOperator] is the `is` operator.
   /// The [notOperator] is either the `!` or `null` if the test is not negated.
   /// The [type] is a representation of the type that is the right operand.
-  Expression isExpression(
-      Expression operand, Token isOperator, Token notOperator, DartType type);
-
-  /// Return a representation of a [statement] that has one or more labels (from
-  /// the [target]) associated with it.
-  Statement labeledStatement(LabelTarget target, Statement statement);
+  Expression createIsExpression(
+      Expression operand, Token isOperator, Token notOperator, DartType type) {
+    Expression result = new IsExpression(operand, type)
+      ..fileOffset = offsetForToken(isOperator);
+    if (notOperator != null) {
+      result = createNot(result, notOperator, false);
+    }
+    return result;
+  }
 
   /// Return a representation of a logical expression having the [leftOperand],
   /// [rightOperand] and the [operator] (either `&&` or `||`).
-  Expression logicalExpression(
-      Expression leftOperand, Token operator, Expression rightOperand);
+  Expression createLogicalExpression(
+      Expression leftOperand, Token operator, Expression rightOperand) {
+    return new LogicalExpression(
+        leftOperand, operator.stringValue, rightOperand)
+      ..fileOffset = offsetForToken(operator);
+  }
 
-  Expression notExpression(
-      Expression operand, Token location, bool isSynthetic);
+  Expression createNot(Expression operand, Token token, bool isSynthetic) {
+    return new Not(operand)..fileOffset = offsetForToken(token);
+  }
 
   /// Return a representation of a parenthesized condition consisting of the
   /// given [expression] between the [leftParenthesis] and [rightParenthesis].
-  Object parenthesizedCondition(
-      Token leftParenthesis, Expression expression, Token rightParenthesis);
+  Expression createParenthesizedCondition(
+      Token leftParenthesis, Expression expression, Token rightParenthesis) {
+    return expression;
+  }
 
   /// Return a representation of a rethrow statement consisting of the
   /// [rethrowKeyword] followed by the [semicolon].
-  Statement rethrowStatement(Token rethrowKeyword, Token semicolon);
+  Statement createRethrowStatement(Token rethrowKeyword, Token semicolon) {
+    return new ExpressionStatementJudgment(
+        new Rethrow()..fileOffset = offsetForToken(rethrowKeyword));
+  }
 
   /// Return a representation of a return statement.
-  Statement returnStatement(
-      Token returnKeyword, Expression expression, Token semicolon);
+  Statement createReturnStatement(
+      Token returnKeyword, Expression expression, int charOffset) {
+    return new ReturnJudgment(returnKeyword?.lexeme, expression)
+      ..fileOffset = charOffset;
+  }
 
-  Expression stringConcatenationExpression(
-      List<Expression> expressions, Token location);
+  Expression createStringConcatenation(
+      List<Expression> expressions, Token token) {
+    return new StringConcatenation(expressions)
+      ..fileOffset = offsetForToken(token);
+  }
 
   /// The given [statement] is being used as the target of either a break or
   /// continue statement. Return the statement that should be used as the actual
   /// target.
-  Statement syntheticLabeledStatement(Statement statement);
+  Statement createLabeledStatement(Statement statement) {
+    return new LabeledStatement(statement);
+  }
 
-  Expression thisExpression(Token location);
+  Expression createThisExpression(Token token) {
+    return new ThisExpression()..fileOffset = offsetForToken(token);
+  }
 
   /// Return a representation of a throw expression consisting of the
   /// [throwKeyword].
-  Expression throwExpression(Token throwKeyword, Expression expression);
+  Expression createThrow(Token throwKeyword, Expression expression) {
+    return new Throw(expression)..fileOffset = offsetForToken(throwKeyword);
+  }
 
-  bool isThrow(Object o);
+  bool isThrow(Object o) => o is Throw;
 
   /// Return a representation of a try statement. The statement is introduced by
   /// the [tryKeyword] and the given [body]. If catch clauses were included,
@@ -329,49 +534,176 @@
   /// was an error in some part of the try statement, then an [errorReplacement]
   /// might be provided, in which case it could be returned instead of the
   /// representation of the try statement.
-  Statement tryStatement(Token tryKeyword, Statement body,
-      List<Catch> catchClauses, Token finallyKeyword, Statement finallyBlock);
+  Statement createTryStatement(Token tryKeyword, Statement body,
+      List<Catch> catchClauses, Token finallyKeyword, Statement finallyBlock) {
+    Statement result = body;
+    if (catchClauses != null) {
+      result = new TryCatchJudgment(result, catchClauses);
+    }
+    if (finallyBlock != null) {
+      result = new TryFinallyJudgment(result, finallyBlock);
+    }
+    return result;
+  }
 
-  Statement variablesDeclaration(
-      List<VariableDeclaration> declarations, Uri uri);
+  _VariablesDeclaration variablesDeclaration(
+      List<VariableDeclaration> declarations, Uri uri) {
+    return new _VariablesDeclaration(declarations, uri);
+  }
 
   List<VariableDeclaration> variablesDeclarationExtractDeclarations(
-      covariant Statement variablesDeclaration);
+      _VariablesDeclaration variablesDeclaration) {
+    return variablesDeclaration.declarations;
+  }
 
-  Statement wrapVariables(Statement statement);
+  Statement wrapVariables(Statement statement) {
+    if (statement is _VariablesDeclaration) {
+      return new BlockJudgment(
+          new List<Statement>.from(statement.declarations, growable: true))
+        ..fileOffset = statement.fileOffset;
+    } else if (statement is VariableDeclaration) {
+      return new BlockJudgment(<Statement>[statement])
+        ..fileOffset = statement.fileOffset;
+    } else {
+      return statement;
+    }
+  }
 
   /// Return a representation of a while statement introduced by the
   /// [whileKeyword] and consisting of the given [condition] and [body].
-  Statement whileStatement(
-      Token whileKeyword, Expression condition, Statement body);
+  Statement createWhileStatement(
+      Token whileKeyword, Expression condition, Statement body) {
+    return new WhileJudgment(condition, body)
+      ..fileOffset = whileKeyword.charOffset;
+  }
 
   /// Return a representation of a yield statement consisting of the
   /// [yieldKeyword], [star], [expression], and [semicolon]. The [star] is null
   /// when no star was included in the source code.
-  Statement yieldStatement(
-      Token yieldKeyword, Token star, Expression expression, Token semicolon);
+  Statement createYieldStatement(
+      Token yieldKeyword, Token star, Expression expression, Token semicolon) {
+    return new YieldJudgment(star != null, expression)
+      ..fileOffset = yieldKeyword.charOffset;
+  }
 
   /// Return the expression from the given expression [statement].
-  Expression getExpressionFromExpressionStatement(Statement statement);
+  Expression getExpressionFromExpressionStatement(Statement statement) {
+    return (statement as ExpressionStatement).expression;
+  }
 
-  bool isBlock(Object node);
+  bool isBlock(Object node) => node is Block;
 
   /// Return `true` if the given [statement] is the representation of an empty
   /// statement.
-  bool isEmptyStatement(Statement statement);
+  bool isEmptyStatement(Statement statement) => statement is EmptyStatement;
 
-  bool isErroneousNode(Object node);
+  bool isErroneousNode(Object node) {
+    if (node is ExpressionStatement) {
+      ExpressionStatement statement = node;
+      node = statement.expression;
+    }
+    if (node is VariableDeclaration) {
+      VariableDeclaration variable = node;
+      node = variable.initializer;
+    }
+    if (node is SyntheticExpressionJudgment) {
+      SyntheticExpressionJudgment synth = node;
+      node = synth.desugared;
+    }
+    if (node is Let) {
+      Let let = node;
+      node = let.variable.initializer;
+    }
+    return node is InvalidExpression;
+  }
 
   /// Return `true` if the given [statement] is the representation of an
   /// expression statement.
-  bool isExpressionStatement(Statement statement);
+  bool isExpressionStatement(Statement statement) =>
+      statement is ExpressionStatement;
 
-  bool isThisExpression(Object node);
+  bool isThisExpression(Object node) => node is ThisExpression;
 
-  bool isVariablesDeclaration(Object node);
+  bool isVariablesDeclaration(Object node) => node is _VariablesDeclaration;
 
-  // TODO(ahe): Remove this method when all users are moved here.
-  Arguments castArguments(Arguments arguments) {
-    return arguments;
+  /// Creates [VariableDeclaration] for a variable named [name] at the given
+  /// [functionNestingLevel].
+  VariableDeclaration createVariableDeclaration(
+      String name, int functionNestingLevel,
+      {Expression initializer,
+      DartType type,
+      bool isFinal: false,
+      bool isConst: false,
+      bool isFieldFormal: false,
+      bool isCovariant: false,
+      bool isLocalFunction: false}) {
+    return VariableDeclarationJudgment(name, functionNestingLevel,
+        type: type,
+        initializer: initializer,
+        isFinal: isFinal,
+        isConst: isConst,
+        isFieldFormal: isFieldFormal,
+        isCovariant: isCovariant,
+        isLocalFunction: isLocalFunction);
+  }
+
+  FunctionNode createFunctionNode(Statement body,
+      {List<TypeParameter> typeParameters,
+      List<VariableDeclaration> positionalParameters,
+      List<VariableDeclaration> namedParameters,
+      int requiredParameterCount,
+      DartType returnType: const DynamicType(),
+      AsyncMarker asyncMarker: AsyncMarker.Sync,
+      AsyncMarker dartAsyncMarker}) {
+    return new FunctionNodeJudgment(body,
+        typeParameters: typeParameters,
+        positionalParameters: positionalParameters,
+        namedParameters: namedParameters,
+        requiredParameterCount: requiredParameterCount,
+        returnType: returnType,
+        asyncMarker: asyncMarker,
+        dartAsyncMarker: dartAsyncMarker);
+  }
+
+  TypeParameter createTypeParameter(String name) {
+    return new TypeParameter(name);
+  }
+
+  TypeParameterType createTypeParameterType(TypeParameter typeParameter) {
+    return new TypeParameterType(typeParameter);
+  }
+
+  FunctionExpression createFunctionExpression(
+      FunctionNode function, int fileOffset) {
+    return new FunctionExpression(function)..fileOffset = fileOffset;
+  }
+
+  NamedExpression createNamedExpression(String name, Expression expression) {
+    return new NamedExpression(name, expression);
+  }
+}
+
+class _VariablesDeclaration extends Statement {
+  final List<VariableDeclaration> declarations;
+  final Uri uri;
+
+  _VariablesDeclaration(this.declarations, this.uri) {
+    setParents(declarations, this);
+  }
+
+  accept(v) {
+    unsupported("accept", fileOffset, uri);
+  }
+
+  accept1(v, arg) {
+    unsupported("accept1", fileOffset, uri);
+  }
+
+  visitChildren(v) {
+    unsupported("visitChildren", fileOffset, uri);
+  }
+
+  transformChildren(v) {
+    unsupported("transformChildren", fileOffset, uri);
   }
 }
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 1c9ab5d..2c7a1d3 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -1880,7 +1880,8 @@
         DartType caseExpressionType =
             inferrer.inferExpression(caseExpression, expressionType, true);
 
-        // Check whether the expression type is assignable to the case expression type.
+        // Check whether the expression type is assignable to the case
+        // expression type.
         if (!inferrer.isAssignable(expressionType, caseExpressionType)) {
           inferrer.helper.addProblem(
               templateSwitchExpressionNotAssignable.withArguments(
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
index cdb96b5..db9a1c5 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
@@ -764,8 +764,8 @@
 /// Common base class for shadow objects representing initializers in kernel
 /// form.
 abstract class InitializerJudgment implements Initializer {
-  /// Performs type inference for whatever concrete type of [InitializerJudgment]
-  /// this is.
+  /// Performs type inference for whatever concrete type of
+  /// [InitializerJudgment] this is.
   void acceptInference(InferenceVisitor visitor);
 }
 
@@ -1568,7 +1568,9 @@
       bool isConst: false,
       bool isFieldFormal: false,
       bool isCovariant: false,
-      bool isLocalFunction: false})
+      bool isLocalFunction: false,
+      bool isLate: false,
+      bool isRequired: false})
       : _implicitlyTyped = type == null,
         _isLocalFunction = isLocalFunction,
         super(name,
@@ -1577,7 +1579,9 @@
             isFinal: isFinal,
             isConst: isConst,
             isFieldFormal: isFieldFormal,
-            isCovariant: isCovariant);
+            isCovariant: isCovariant,
+            isLate: isLate,
+            isRequired: isRequired);
 
   VariableDeclarationJudgment.forEffect(
       Expression initializer, this._functionNestingLevel)
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 9a38348..ab78a04 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -204,7 +204,7 @@
   LibraryBuilder createLibraryBuilder(
       Uri uri, Uri fileUri, SourceLibraryBuilder origin) {
     if (dillTarget.isLoaded) {
-      var builder = dillTarget.loader.builders[uri];
+      LibraryBuilder builder = dillTarget.loader.builders[uri];
       if (builder != null) {
         return builder;
       }
@@ -247,11 +247,14 @@
       loader.createTypeInferenceEngine();
       await loader.buildOutlines();
       loader.coreLibrary.becomeCoreLibrary();
-      dynamicType.bind(loader.coreLibrary.getLocalMember("dynamic"));
+      dynamicType.bind(
+          loader.coreLibrary.lookupLocalMember("dynamic", required: true));
       loader.resolveParts();
       loader.computeLibraryScopes();
-      objectType.bind(loader.coreLibrary.getLocalMember("Object"));
-      bottomType.bind(loader.coreLibrary.getLocalMember("Null"));
+      objectType
+          .bind(loader.coreLibrary.lookupLocalMember("Object", required: true));
+      bottomType
+          .bind(loader.coreLibrary.lookupLocalMember("Null", required: true));
       loader.resolveTypes();
       loader.computeDefaultTypes(dynamicType, bottomType, objectClassBuilder);
       List<SourceClassBuilder> myClasses =
@@ -483,7 +486,7 @@
       Constructor constructor, Map<TypeParameter, DartType> substitutionMap) {
     VariableDeclaration copyFormal(VariableDeclaration formal) {
       // TODO(ahe): Handle initializers.
-      var copy = new VariableDeclaration(formal.name,
+      VariableDeclaration copy = new VariableDeclaration(formal.name,
           isFinal: formal.isFinal, isConst: formal.isConst);
       if (formal.type != null) {
         copy.type = substitute(formal.type, substitutionMap);
diff --git a/pkg/front_end/lib/src/fasta/kernel/load_library_builder.dart b/pkg/front_end/lib/src/fasta/kernel/load_library_builder.dart
index 7748bdb..c4e8e9998 100644
--- a/pkg/front_end/lib/src/fasta/kernel/load_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/load_library_builder.dart
@@ -42,7 +42,7 @@
 
   LoadLibrary createLoadLibrary(
       int charOffset, Forest forest, Arguments arguments) {
-    return forest.loadLibrary(importDependency, arguments)
+    return forest.createLoadLibrary(importDependency, arguments)
       ..fileOffset = charOffset;
   }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/redirecting_factory_body.dart b/pkg/front_end/lib/src/fasta/kernel/redirecting_factory_body.dart
index ea9f61d..4af23ec 100644
--- a/pkg/front_end/lib/src/fasta/kernel/redirecting_factory_body.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/redirecting_factory_body.dart
@@ -40,12 +40,12 @@
       : this.internal(new StringLiteral(name));
 
   Member get target {
-    var value = getValue(expression);
+    dynamic value = getValue(expression);
     return value is StaticGet ? value.target : null;
   }
 
   String get unresolvedName {
-    var value = getValue(expression);
+    dynamic value = getValue(expression);
     return value is StringLiteral ? value.value : null;
   }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart b/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
index 6861ad1..58bd5a7 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
@@ -339,7 +339,7 @@
   TypeVariableBuilder variable,
   TypeBuilder type,
 ) {
-  var uses = <NamedTypeBuilder>[];
+  List<NamedTypeBuilder> uses = <NamedTypeBuilder>[];
   if (type is NamedTypeBuilder) {
     if (type.declaration == variable) {
       uses.add(type);
@@ -380,9 +380,9 @@
 /// bound.  The second element in the pair is the list of found references
 /// represented as type builders.
 List<Object> findInboundReferences(List<TypeVariableBuilder> variables) {
-  var variablesAndDependencies = <Object>[];
+  List<Object> variablesAndDependencies = <Object>[];
   for (TypeVariableBuilder dependent in variables) {
-    var dependencies = <NamedTypeBuilder>[];
+    List<NamedTypeBuilder> dependencies = <NamedTypeBuilder>[];
     for (TypeVariableBuilder dependence in variables) {
       List<NamedTypeBuilder> uses =
           findVariableUsesInType(dependence, dependent.bound);
@@ -405,7 +405,7 @@
 /// variables of that type with inbound references in the format specified in
 /// [findInboundReferences].
 List<Object> findRawTypesWithInboundReferences(TypeBuilder type) {
-  var typesAndDependencies = <Object>[];
+  List<Object> typesAndDependencies = <Object>[];
   if (type is NamedTypeBuilder) {
     if (type.arguments == null) {
       TypeDeclarationBuilder declaration = type.declaration;
@@ -502,7 +502,7 @@
 /// generic types with inbound references in its bound.  The second element of
 /// the triplet is the error message.  The third element is the context.
 List<Object> getInboundReferenceIssues(List<TypeVariableBuilder> variables) {
-  var issues = <Object>[];
+  List<Object> issues = <Object>[];
   for (TypeVariableBuilder variable in variables) {
     if (variable.bound != null) {
       List<Object> rawTypesAndMutualDependencies =
@@ -554,7 +554,7 @@
     TypeBuilder start, TypeDeclarationBuilder end,
     [Set<TypeDeclarationBuilder> visited]) {
   visited ??= new Set<TypeDeclarationBuilder>.identity();
-  var paths = <List<Object>>[];
+  List<List<Object>> paths = <List<Object>>[];
   if (start is NamedTypeBuilder) {
     TypeDeclarationBuilder declaration = start.declaration;
     if (start.arguments == null) {
@@ -639,7 +639,7 @@
 /// The reason for putting the type variables into the cycles is better error
 /// reporting.
 List<List<Object>> findRawTypeCycles(TypeDeclarationBuilder declaration) {
-  var cycles = <List<Object>>[];
+  List<List<Object>> cycles = <List<Object>>[];
   if (declaration is ClassBuilder && declaration.typeVariables != null) {
     for (TypeVariableBuilder variable in declaration.typeVariables) {
       if (variable.bound != null) {
@@ -699,7 +699,7 @@
           .withArguments(type.declaration.name));
       issues.add(null); // Context.
     } else {
-      var context = <LocatedMessage>[];
+      List<LocatedMessage> context = <LocatedMessage>[];
       for (int i = 0; i < cycle.length; i += 2) {
         TypeVariableBuilder variable = cycle[i];
         NamedTypeBuilder type = cycle[i + 1];
@@ -747,7 +747,7 @@
 List<Object> getNonSimplicityIssuesForDeclaration(
     TypeDeclarationBuilder declaration,
     {bool performErrorRecovery: true}) {
-  var issues = <Object>[];
+  List<Object> issues = <Object>[];
   if (declaration is ClassBuilder && declaration.typeVariables != null) {
     issues.addAll(getInboundReferenceIssues(declaration.typeVariables));
   } else if (declaration is TypeAliasBuilder &&
diff --git a/pkg/front_end/lib/src/fasta/kernel/utils.dart b/pkg/front_end/lib/src/fasta/kernel/utils.dart
index c7556d8..41f5eb7 100644
--- a/pkg/front_end/lib/src/fasta/kernel/utils.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/utils.dart
@@ -89,7 +89,7 @@
         <TypeParameter, TypeParameter>{};
     Map<TypeParameter, DartType> typeSubstitution = <TypeParameter, DartType>{};
     for (TypeParameter typeParam in realClass.typeParameters) {
-      var newNode = new TypeParameter(typeParam.name);
+      TypeParameter newNode = new TypeParameter(typeParam.name);
       typeParams[typeParam] = newNode;
       typeSubstitution[typeParam] = new TypeParameterType(newNode);
     }
diff --git a/pkg/front_end/lib/src/fasta/kernel/verifier.dart b/pkg/front_end/lib/src/fasta/kernel/verifier.dart
index 091020b..f24a1ce 100644
--- a/pkg/front_end/lib/src/fasta/kernel/verifier.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/verifier.dart
@@ -83,7 +83,7 @@
   }
 
   void checkSuperInvocation(TreeNode node) {
-    var containingMember = getContainingMember(node);
+    Member containingMember = getContainingMember(node);
     if (containingMember == null) {
       problem(node, 'Super call outside of any member');
     } else {
diff --git a/pkg/front_end/lib/src/fasta/loader.dart b/pkg/front_end/lib/src/fasta/loader.dart
index 33b2bfc..1fcfc87 100644
--- a/pkg/front_end/lib/src/fasta/loader.dart
+++ b/pkg/front_end/lib/src/fasta/loader.dart
@@ -8,7 +8,7 @@
 
 import 'dart:collection' show Queue;
 
-import 'package:kernel/ast.dart' show Library;
+import 'package:kernel/ast.dart' show Class, DartType, Library;
 
 import 'builder/builder.dart'
     show ClassBuilder, Builder, LibraryBuilder, TypeBuilder;
@@ -126,9 +126,19 @@
       int packageSpecifiedLanguageVersionMinor;
       if (packageFragment != null) {
         List<String> properties = packageFragment.split("&");
+        int foundEntries = 0;
         for (int i = 0; i < properties.length; ++i) {
           String property = properties[i];
           if (property.startsWith("dart=")) {
+            if (++foundEntries > 1) {
+              // Force error to be issued if more than one "dart=" entry.
+              // (The error will be issued in library.setLanguageVersion below
+              // when giving it `null` version numbers.)
+              packageSpecifiedLanguageVersionMajor = null;
+              packageSpecifiedLanguageVersionMinor = null;
+              break;
+            }
+
             hasPackageSpecifiedLanguageVersion = true;
             String langaugeVersionString = property.substring(5);
 
@@ -140,7 +150,6 @@
               packageSpecifiedLanguageVersionMinor =
                   int.tryParse(dotSeparatedParts[1]);
             }
-            break;
           }
         }
       }
@@ -335,7 +344,7 @@
 
   Builder getNativeAnnotation() => target.getNativeAnnotation(this);
 
-  ClassBuilder computeClassBuilderFromTargetClass(covariant Object cls);
+  ClassBuilder computeClassBuilderFromTargetClass(Class cls);
 
-  TypeBuilder computeTypeBuilder(covariant Object type);
+  TypeBuilder computeTypeBuilder(DartType type);
 }
diff --git a/pkg/front_end/lib/src/fasta/modifier.dart b/pkg/front_end/lib/src/fasta/modifier.dart
index 44d7b1d..b8796c0 100644
--- a/pkg/front_end/lib/src/fasta/modifier.dart
+++ b/pkg/front_end/lib/src/fasta/modifier.dart
@@ -30,17 +30,18 @@
 
 const int staticMask = finalMask << 1;
 
-const int namedMixinApplicationMask = staticMask << 1;
+const int lateMask = staticMask << 1;
+
+const int requiredMask = lateMask << 1;
+
+const int namedMixinApplicationMask = requiredMask << 1;
 
 /// Not a modifier, used for mixins declared explicitly by using the `mixin`
 /// keyword.
 const int mixinDeclarationMask = namedMixinApplicationMask << 1;
 
-/// Not a modifier, used for extension declarations.
-const int extensionDeclarationMask = mixinDeclarationMask << 1;
-
 /// Not a modifier, used by fields to track if they have an initializer.
-const int hasInitializerMask = extensionDeclarationMask << 1;
+const int hasInitializerMask = mixinDeclarationMask << 1;
 
 /// Not a modifier, used by formal parameters to track if they are initializing.
 const int initializingFormalMask = hasInitializerMask << 1;
diff --git a/pkg/front_end/lib/src/fasta/parser/formal_parameter_kind.dart b/pkg/front_end/lib/src/fasta/parser/formal_parameter_kind.dart
index 2093e83..11b1041 100644
--- a/pkg/front_end/lib/src/fasta/parser/formal_parameter_kind.dart
+++ b/pkg/front_end/lib/src/fasta/parser/formal_parameter_kind.dart
@@ -4,6 +4,7 @@
 
 library fasta.parser.formal_parameter_kind;
 
+// TODO(johnniwinther): Update this to support required named arguments.
 enum FormalParameterKind {
   mandatory,
   optionalNamed,
diff --git a/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart b/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
index 4c42056..9a462ff 100644
--- a/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
+++ b/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
@@ -87,7 +87,14 @@
   Token ensureIdentifier(Token token, Parser parser) {
     Token identifier = token.next;
     assert(identifier.kind != IDENTIFIER_TOKEN);
-    const followingValues = const [';', ',', 'if', 'as', 'show', 'hide'];
+    const List<String> followingValues = const [
+      ';',
+      ',',
+      'if',
+      'as',
+      'show',
+      'hide'
+    ];
 
     if (identifier.isIdentifier) {
       if (!looksLikeStartOfNextTopLevelDeclaration(identifier) ||
@@ -163,7 +170,7 @@
   Token ensureIdentifier(Token token, Parser parser) {
     Token identifier = token.next;
     assert(identifier.kind != IDENTIFIER_TOKEN);
-    const followingValues = const ['.', '==', ')'];
+    const List<String> followingValues = const ['.', '==', ')'];
 
     if (identifier.isIdentifier) {
       // DottedNameIdentifierContext are only used in conditional import
@@ -291,14 +298,19 @@
     // Recovery
     parser.reportRecoverableErrorWithToken(
         identifier, fasta.templateExpectedIdentifier);
-    if (!looksLikeStatementStart(identifier)) {
+    if (optional(r'$', token) &&
+        identifier.isKeyword &&
+        identifier.next.kind == STRING_TOKEN) {
+      // Keyword used as identifier in string interpolation
+      return identifier;
+    } else if (!looksLikeStatementStart(identifier)) {
       if (identifier.isKeywordOrIdentifier) {
         if (isContinuation || !isOneOfOrEof(identifier, const ['as', 'is'])) {
           return identifier;
         }
       } else if (!identifier.isOperator &&
           !isOneOfOrEof(identifier,
-              const ['.', ',', '(', ')', '[', ']', '}', '?', ':', ';'])) {
+              const ['.', ',', '(', ')', '[', ']', '{', '}', '?', ':', ';'])) {
         // When in doubt, consume the token to ensure we make progress
         token = identifier;
         identifier = token.next;
@@ -377,7 +389,17 @@
     }
 
     // Recovery
-    const followingValues = const [':', '=', ',', '(', ')', '[', ']', '{', '}'];
+    const List<String> followingValues = const [
+      ':',
+      '=',
+      ',',
+      '(',
+      ')',
+      '[',
+      ']',
+      '{',
+      '}'
+    ];
     if (looksLikeStartOfNextClassMember(identifier) ||
         looksLikeStatementStart(identifier) ||
         isOneOfOrEof(identifier, followingValues)) {
@@ -411,7 +433,14 @@
     }
 
     // Recovery
-    const followingValues = const [';', 'if', 'show', 'hide', 'deferred', 'as'];
+    const List<String> followingValues = const [
+      ';',
+      'if',
+      'show',
+      'hide',
+      'deferred',
+      'as'
+    ];
     if (identifier.type.isBuiltIn &&
         isOneOfOrEof(identifier.next, followingValues)) {
       parser.reportRecoverableErrorWithToken(
@@ -577,7 +606,7 @@
   Token ensureIdentifier(Token token, Parser parser) {
     Token identifier = token.next;
     assert(identifier.kind != IDENTIFIER_TOKEN);
-    const followingValues = const ['.', ';'];
+    const List<String> followingValues = const ['.', ';'];
 
     if (identifier.isIdentifier) {
       Token next = identifier.next;
@@ -822,7 +851,7 @@
     }
 
     // Recovery
-    const followingValues = const ['(', '<', '=', ';'];
+    const List<String> followingValues = const ['(', '<', '=', ';'];
     if (identifier.type.isBuiltIn &&
         isOneOfOrEof(identifier.next, followingValues)) {
       parser.reportRecoverableErrorWithToken(
@@ -911,7 +940,14 @@
     }
 
     // Recovery
-    const followingValues = const ['<', '>', ';', '}', 'extends', 'super'];
+    const List<String> followingValues = const [
+      '<',
+      '>',
+      ';',
+      '}',
+      'extends',
+      'super'
+    ];
     if (looksLikeStartOfNextTopLevelDeclaration(identifier) ||
         looksLikeStartOfNextClassMember(identifier) ||
         looksLikeStatementStart(identifier) ||
diff --git a/pkg/front_end/lib/src/fasta/parser/literal_entry_info_impl.dart b/pkg/front_end/lib/src/fasta/parser/literal_entry_info_impl.dart
index f5e4b8b..313d580 100644
--- a/pkg/front_end/lib/src/fasta/parser/literal_entry_info_impl.dart
+++ b/pkg/front_end/lib/src/fasta/parser/literal_entry_info_impl.dart
@@ -29,7 +29,7 @@
       awaitToken = token = next;
       next = token.next;
     }
-    final forToken = next;
+    final Token forToken = next;
     assert(optional('for', forToken));
     parser.listener.beginForControlFlow(awaitToken, forToken);
 
@@ -141,7 +141,7 @@
 
   @override
   Token parse(Token token, Parser parser) {
-    final ifToken = token.next;
+    final Token ifToken = token.next;
     assert(optional('if', ifToken));
     parser.listener.beginIfControlFlow(ifToken);
     Token result = parser.ensureParenthesizedCondition(ifToken);
@@ -261,7 +261,7 @@
 
   @override
   Token parse(Token token, Parser parser) {
-    final operator = token.next;
+    final Token operator = token.next;
     assert(optional('...', operator) || optional('...?', operator));
     token = parser.parseExpression(operator);
     parser.listener.handleSpreadExpression(operator);
diff --git a/pkg/front_end/lib/src/fasta/parser/modifier_context.dart b/pkg/front_end/lib/src/fasta/parser/modifier_context.dart
index 93e717d..5807629 100644
--- a/pkg/front_end/lib/src/fasta/parser/modifier_context.dart
+++ b/pkg/front_end/lib/src/fasta/parser/modifier_context.dart
@@ -182,7 +182,7 @@
     // Process invalid and out-of-order modifiers
     Token next = token.next;
     while (true) {
-      final value = next.stringValue;
+      final String value = next.stringValue;
       if (isModifier(next)) {
         if (identical('abstract', value)) {
           token = parseAbstract(token);
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index 6d47cea..7b7f7a7 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -1482,7 +1482,10 @@
       token = periodAfterThis;
     }
     next = token.next;
-    if (inFunctionType && !isNamedParameter && !next.isKeywordOrIdentifier) {
+    if (inFunctionType &&
+        !isNamedParameter &&
+        !next.isKeywordOrIdentifier &&
+        beforeInlineFunctionType == null) {
       nameToken = token.next;
       listener.handleNoName(nameToken);
     } else {
@@ -2545,9 +2548,6 @@
       ++count;
       next = token.next;
       if (!optional(',', next)) {
-        if (!next.isKeywordOrIdentifier) {
-          break;
-        }
         // Recovery: Found an identifier which could be
         // 1) missing preceding `,` thus it's another initializer, or
         // 2) missing preceding `;` thus it's a class member, or
@@ -2558,6 +2558,9 @@
             break;
           }
           // Looks like assert expression ... fall through to insert comma
+        } else if (!next.isIdentifier && !optional('this', next)) {
+          // An identifier that wasn't an initializer. Break.
+          break;
         } else {
           if (optional('this', next)) {
             next = next.next;
@@ -2565,7 +2568,7 @@
               break;
             }
             next = next.next;
-            if (!next.isKeywordOrIdentifier) {
+            if (!next.isIdentifier && !optional('assert', next)) {
               break;
             }
           }
@@ -4740,7 +4743,8 @@
   /// ;
   ///
   /// mapLiteral:
-  ///   'const'? typeArguments? '{' (mapLiteralEntry (',' mapLiteralEntry)* ','?)? '}'
+  ///   'const'? typeArguments?
+  ///     '{' (mapLiteralEntry (',' mapLiteralEntry)* ','?)? '}'
   /// ;
   ///
   /// mapLiteralEntry:
diff --git a/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart b/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
index b6d698e..63a28eb 100644
--- a/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
+++ b/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
@@ -459,7 +459,7 @@
           token, IdentifierContext.prefixedTypeReference);
     }
 
-    final typeVariableEndGroups = <Token>[];
+    final List<Token> typeVariableEndGroups = <Token>[];
     for (Link<Token> t = typeVariableStarters; t.isNotEmpty; t = t.tail) {
       typeVariableEndGroups.add(
           computeTypeParamOrArg(t.head, true).parseVariables(t.head, parser));
@@ -1092,7 +1092,7 @@
 
         // Parse the type so that the token stream is properly modified,
         // but ensure that parser events are ignored by replacing the listener.
-        final originalListener = parser.listener;
+        final Listener originalListener = parser.listener;
         parser.listener = new ForwardingListener();
         token = invalidType.parseType(token, parser);
         next = token.next;
@@ -1115,7 +1115,7 @@
 
       // Parse the type so that the token stream is properly modified,
       // but ensure that parser events are ignored by replacing the listener.
-      final originalListener = parser.listener;
+      final Listener originalListener = parser.listener;
       parser.listener = new ForwardingListener();
       token = isArguments
           ? invalidTypeVar.parseArguments(token, parser)
@@ -1166,7 +1166,7 @@
 
 /// Return `true` if [token] is one of `>`, `>>`, `>>>`, `>=`, `>>=`, or `>>>=`.
 bool isCloser(Token token) {
-  final value = token.stringValue;
+  final String value = token.stringValue;
   return identical(value, '>') ||
       identical(value, '>>') ||
       identical(value, '>=') ||
diff --git a/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart b/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart
index 072da5e..143a72e 100644
--- a/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart
+++ b/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart
@@ -511,8 +511,9 @@
     // This recovers nicely from from situations like "{[}".
     while (!identical(originalStack, groupingStack)) {
       // Don't report unmatched errors for <; it is also the less-than operator.
-      if (!identical(groupingStack.head.kind, LT_TOKEN))
+      if (!identical(groupingStack.head.kind, LT_TOKEN)) {
         unmatchedBeginGroup(originalStack.head);
+      }
       originalStack = originalStack.tail;
     }
     return true;
@@ -1298,7 +1299,8 @@
       return tokenizeSingleLineCommentRest(next, start, false);
     }
 
-    var languageVersion = createLanguageVersionToken(start, major, minor);
+    LanguageVersionToken languageVersion =
+        createLanguageVersionToken(start, major, minor);
     if (languageVersionChanged != null) {
       // TODO(danrubel): make this required and remove the languageVersion field
       languageVersionChanged(this, languageVersion);
@@ -1742,7 +1744,8 @@
   }
 
   int unexpected(int character) {
-    var errorToken = buildUnexpectedCharacterToken(character, tokenStart);
+    ErrorToken errorToken =
+        buildUnexpectedCharacterToken(character, tokenStart);
     if (errorToken is NonAsciiIdentifierToken) {
       int charOffset;
       List<int> codeUnits = <int>[];
@@ -1864,7 +1867,7 @@
     if (newLength < newLengthMinimum) newLength = newLengthMinimum;
 
     if (array is Uint16List) {
-      final newArray = new Uint16List(newLength);
+      final Uint16List newArray = new Uint16List(newLength);
       newArray.setRange(0, arrayLength, array);
       array = newArray;
     } else {
@@ -1873,7 +1876,7 @@
   }
 
   void switchToUint32(int newLength) {
-    final newArray = new Uint32List(newLength);
+    final Uint32List newArray = new Uint32List(newLength);
     newArray.setRange(0, arrayLength, array);
     array = newArray;
   }
diff --git a/pkg/front_end/lib/src/fasta/scanner/error_token.dart b/pkg/front_end/lib/src/fasta/scanner/error_token.dart
index f8f5f19..7c4ba8a 100644
--- a/pkg/front_end/lib/src/fasta/scanner/error_token.dart
+++ b/pkg/front_end/lib/src/fasta/scanner/error_token.dart
@@ -73,14 +73,14 @@
   int get length => 1;
 
   String get lexeme {
-    var errorMsg = assertionMessage.message;
+    String errorMsg = assertionMessage.message;
 
     // Attempt to include the location which is calling the parser
     // in an effort to debug https://github.com/dart-lang/sdk/issues/37528
-    var pattern = RegExp('^#[0-9]* *Parser');
-    var traceLines = StackTrace.current.toString().split('\n');
+    RegExp pattern = RegExp('^#[0-9]* *Parser');
+    List<String> traceLines = StackTrace.current.toString().split('\n');
     for (int index = traceLines.length - 2; index >= 0; --index) {
-      var line = traceLines[index];
+      String line = traceLines[index];
       if (line.startsWith(pattern)) {
         errorMsg = '$errorMsg - ${traceLines[index + 1]}';
         break;
diff --git a/pkg/front_end/lib/src/fasta/scanner/recover.dart b/pkg/front_end/lib/src/fasta/scanner/recover.dart
index 6bc6e87..6f72ed4 100644
--- a/pkg/front_end/lib/src/fasta/scanner/recover.dart
+++ b/pkg/front_end/lib/src/fasta/scanner/recover.dart
@@ -22,7 +22,7 @@
   // TODO(danrubel): Remove this in a while after the dust has settled.
 
   // Skip over prepended error tokens
-  var token = tokens;
+  Token token = tokens;
   while (token is ErrorToken) {
     token = token.next;
   }
@@ -31,11 +31,11 @@
   while (!token.isEof) {
     if (token is ErrorToken) {
       for (int count = 0; count < 3; ++count) {
-        var previous = token.previous;
+        Token previous = token.previous;
         if (previous.isEof) break;
         token = previous;
       }
-      var msg = new StringBuffer(
+      StringBuffer msg = new StringBuffer(
           "Internal error: All error tokens should have been prepended:");
       for (int count = 0; count < 7; ++count) {
         if (token.isEof) break;
diff --git a/pkg/front_end/lib/src/fasta/scanner/scanner_main.dart b/pkg/front_end/lib/src/fasta/scanner/scanner_main.dart
index fd3c030..dfe85de 100644
--- a/pkg/front_end/lib/src/fasta/scanner/scanner_main.dart
+++ b/pkg/front_end/lib/src/fasta/scanner/scanner_main.dart
@@ -12,7 +12,7 @@
   Stopwatch sw = new Stopwatch()..start();
   int byteCount = 0;
   files.forEach((Uri uri, List<int> bytes) {
-    var token = scan(bytes).tokens;
+    Token token = scan(bytes).tokens;
     if (verbose) printTokens(token);
     if (verify) verifyErrorTokens(token, uri);
     byteCount += bytes.length - 1;
diff --git a/pkg/front_end/lib/src/fasta/scanner/string_canonicalizer.dart b/pkg/front_end/lib/src/fasta/scanner/string_canonicalizer.dart
index 323082f..7f1996b 100644
--- a/pkg/front_end/lib/src/fasta/scanner/string_canonicalizer.dart
+++ b/pkg/front_end/lib/src/fasta/scanner/string_canonicalizer.dart
@@ -37,7 +37,7 @@
   List<Node> _nodes = new List<Node>(INITIAL_SIZE);
 
   static String decode(List<int> data, int start, int end, bool asciiOnly) {
-    var s;
+    String s;
     if (asciiOnly) {
       s = new String.fromCharCodes(data, start, end);
     } else {
@@ -63,8 +63,8 @@
   }
 
   rehash() {
-    var newSize = _size * 2;
-    var newNodes = new List<Node>(newSize);
+    int newSize = _size * 2;
+    List<Node> newNodes = new List<Node>(newSize);
     for (int i = 0; i < _size; i++) {
       Node t = _nodes[i];
       while (t != null) {
@@ -105,10 +105,11 @@
       t = t.next;
     }
     String payload;
-    if (data is String)
+    if (data is String) {
       payload = data.substring(start, end);
-    else
+    } else {
       payload = decode(data, start, end, asciiOnly);
+    }
     _nodes[index] = new Node(data, start, end, payload, s);
     _count++;
     return payload;
diff --git a/pkg/front_end/lib/src/fasta/scanner/token.dart b/pkg/front_end/lib/src/fasta/scanner/token.dart
index fb1f65f..916dc60 100644
--- a/pkg/front_end/lib/src/fasta/scanner/token.dart
+++ b/pkg/front_end/lib/src/fasta/scanner/token.dart
@@ -83,7 +83,7 @@
       return valueOrLazySubstring;
     } else {
       assert(valueOrLazySubstring is _LazySubstring);
-      var data = valueOrLazySubstring.data;
+      dynamic data = valueOrLazySubstring.data;
       int start = valueOrLazySubstring.start;
       int end = start + valueOrLazySubstring.length;
       if (data is String) {
diff --git a/pkg/front_end/lib/src/fasta/scanner/utf8_bytes_scanner.dart b/pkg/front_end/lib/src/fasta/scanner/utf8_bytes_scanner.dart
index ae2610d..528e5b7 100644
--- a/pkg/front_end/lib/src/fasta/scanner/utf8_bytes_scanner.dart
+++ b/pkg/front_end/lib/src/fasta/scanner/utf8_bytes_scanner.dart
@@ -95,7 +95,7 @@
   }
 
   bool containsBomAt(int offset) {
-    const BOM_UTF8 = const [0xEF, 0xBB, 0xBF];
+    const List<int> BOM_UTF8 = const [0xEF, 0xBB, 0xBF];
 
     return offset + 3 < bytes.length &&
         bytes[offset] == BOM_UTF8[0] &&
@@ -157,9 +157,9 @@
       stringOffsetSlackOffset = byteOffset;
       // In case of a surrogate pair, return a single code point.
       // Gracefully degrade given invalid UTF-8.
-      var runes = codePoint.runes.iterator;
+      RuneIterator runes = codePoint.runes.iterator;
       if (!runes.moveNext()) return unicodeReplacementCharacter;
-      var codeUnit = runes.current;
+      int codeUnit = runes.current;
       return !runes.moveNext() ? codeUnit : unicodeReplacementCharacter;
     } else {
       return unicodeReplacementCharacter;
diff --git a/pkg/front_end/lib/src/fasta/scope.dart b/pkg/front_end/lib/src/fasta/scope.dart
index f3349aa..40ca796 100644
--- a/pkg/front_end/lib/src/fasta/scope.dart
+++ b/pkg/front_end/lib/src/fasta/scope.dart
@@ -138,7 +138,7 @@
     if (builder.next != null) {
       return new AmbiguousBuilder(name.isEmpty ? classNameOrDebugName : name,
           builder, charOffset, fileUri);
-    } else if (!isInstanceScope && builder.isInstanceMember) {
+    } else if (!isInstanceScope && builder.isDeclarationInstanceMember) {
       return null;
     } else {
       return builder;
@@ -357,28 +357,46 @@
   AccessErrorBuilder(String name, Builder builder, int charOffset, Uri fileUri)
       : super(name, builder, charOffset, fileUri);
 
+  @override
   Builder get parent => builder;
 
+  @override
   bool get isFinal => builder.isFinal;
 
+  @override
   bool get isField => builder.isField;
 
+  @override
   bool get isRegularMethod => builder.isRegularMethod;
 
+  @override
   bool get isGetter => !builder.isGetter;
 
+  @override
   bool get isSetter => !builder.isSetter;
 
-  bool get isInstanceMember => builder.isInstanceMember;
+  @override
+  bool get isDeclarationInstanceMember => builder.isDeclarationInstanceMember;
 
+  @override
+  bool get isClassInstanceMember => builder.isClassInstanceMember;
+
+  @override
+  bool get isExtensionInstanceMember => builder.isExtensionInstanceMember;
+
+  @override
   bool get isStatic => builder.isStatic;
 
+  @override
   bool get isTopLevel => builder.isTopLevel;
 
+  @override
   bool get isTypeDeclaration => builder.isTypeDeclaration;
 
+  @override
   bool get isLocal => builder.isLocal;
 
+  @override
   Message get message => templateAccessError.withArguments(name);
 }
 
@@ -386,8 +404,10 @@
   AmbiguousBuilder(String name, Builder builder, int charOffset, Uri fileUri)
       : super(name, builder, charOffset, fileUri);
 
+  @override
   Builder get parent => null;
 
+  @override
   Message get message => templateDuplicatedDeclarationUse.withArguments(name);
 
   // TODO(ahe): Also provide context.
@@ -404,12 +424,15 @@
 class ScopeLocalDeclarationIterator implements Iterator<Builder> {
   Iterator<Builder> local;
   final Iterator<Builder> setters;
+
+  @override
   Builder current;
 
   ScopeLocalDeclarationIterator(Scope scope)
       : local = scope.local.values.iterator,
         setters = scope.setters.values.iterator;
 
+  @override
   bool moveNext() {
     Builder next = current?.next;
     if (next != null) {
@@ -438,6 +461,7 @@
   Iterator<String> localNames;
   final Iterator<String> setterNames;
 
+  @override
   String name;
 
   ScopeLocalDeclarationNameIterator(Scope scope)
@@ -445,6 +469,7 @@
         setterNames = scope.setters.keys.iterator,
         super(scope);
 
+  @override
   bool moveNext() {
     Builder next = current?.next;
     if (next != null) {
diff --git a/pkg/front_end/lib/src/fasta/source/diet_listener.dart b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
index 04476fb..69f967d 100644
--- a/pkg/front_end/lib/src/fasta/source/diet_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
@@ -13,6 +13,7 @@
         LibraryDependency,
         LibraryPart,
         TreeNode,
+        TypeParameter,
         VariableDeclaration;
 
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
@@ -23,6 +24,8 @@
 
 import '../builder/builder.dart';
 
+import '../builder/declaration_builder.dart';
+
 import '../constant_context.dart' show ConstantContext;
 
 import '../crash.dart' show Crash;
@@ -49,6 +52,8 @@
 
 import '../type_inference/type_inference_engine.dart' show TypeInferenceEngine;
 
+import '../type_inference/type_inferrer.dart' show TypeInferrer;
+
 import 'source_library_builder.dart' show SourceLibraryBuilder;
 
 import 'stack_listener.dart'
@@ -74,7 +79,8 @@
   int importExportDirectiveIndex = 0;
   int partDirectiveIndex = 0;
 
-  ClassBuilder currentClass;
+  DeclarationBuilder _currentDeclaration;
+  ClassBuilder _currentClass;
 
   bool currentClassIsParserRecovery = false;
 
@@ -82,7 +88,7 @@
   int unnamedExtensionCounter = 0;
 
   /// For top-level declarations, this is the library scope. For class members,
-  /// this is the instance scope of [currentClass].
+  /// this is the instance scope of [currentDeclaration].
   Scope memberScope;
 
   @override
@@ -98,6 +104,19 @@
         stringExpectedAfterNative =
             library.loader.target.backendTarget.nativeExtensionExpectsString;
 
+  DeclarationBuilder get currentDeclaration => _currentDeclaration;
+
+  void set currentDeclaration(DeclarationBuilder builder) {
+    if (builder == null) {
+      _currentClass = _currentDeclaration = null;
+    } else {
+      _currentDeclaration = builder;
+      _currentClass = builder is ClassBuilder ? builder : null;
+    }
+  }
+
+  ClassBuilder get currentClass => _currentClass;
+
   @override
   void endMetadataStar(int count) {
     assert(checkState(null, repeatedKinds(ValueKind.Token, count)));
@@ -349,6 +368,15 @@
 
   @override
   void handleQualified(Token period) {
+    assert(checkState(period, [
+      /*suffix*/ ValueKind.NameOrParserRecovery,
+      /*prefix*/ unionOfKinds([
+        ValueKind.Name,
+        ValueKind.Generator,
+        ValueKind.ParserRecovery,
+        ValueKind.QualifiedName,
+      ]),
+    ]));
     debugEvent("handleQualified");
     Object suffix = pop();
     Object prefix = pop();
@@ -590,7 +618,7 @@
     if (name is ParserRecovery || currentClassIsParserRecovery) return;
     FunctionBuilder builder;
     if (name is QualifiedName ||
-        (getOrSet == null && name == currentClass.name)) {
+        (getOrSet == null && name == currentClass?.name)) {
       builder = lookupConstructor(beginToken, name);
     } else {
       builder = lookupBuilder(beginToken, getOrSet, name);
@@ -604,32 +632,35 @@
             : MemberKind.NonStaticMethod);
   }
 
-  StackListener createListener(
-      ModifierBuilder builder, Scope memberScope, bool isInstanceMember,
-      {VariableDeclaration extensionThis, Scope formalParameterScope}) {
+  StackListener createListener(ModifierBuilder builder, Scope memberScope,
+      {bool isDeclarationInstanceMember,
+      VariableDeclaration extensionThis,
+      List<TypeParameter> extensionTypeParameters,
+      Scope formalParameterScope}) {
     // Note: we set thisType regardless of whether we are building a static
     // member, since that provides better error recovery.
     // TODO(johnniwinther): Provide a dummy this on static extension methods
     // for better error recovery?
     InterfaceType thisType =
-        extensionThis == null ? currentClass?.target?.thisType : null;
-    var typeInferrer =
+        extensionThis == null ? currentDeclaration?.thisType : null;
+    TypeInferrer typeInferrer =
         typeInferenceEngine?.createLocalTypeInferrer(uri, thisType, library);
     ConstantContext constantContext = builder.isConstructor && builder.isConst
         ? ConstantContext.inferred
         : ConstantContext.none;
     return new BodyBuilder(
-        library,
-        builder,
-        memberScope,
-        formalParameterScope,
-        hierarchy,
-        coreTypes,
-        currentClass,
-        isInstanceMember,
-        extensionThis,
-        uri,
-        typeInferrer)
+        library: library,
+        member: builder,
+        enclosingScope: memberScope,
+        formalParameterScope: formalParameterScope,
+        hierarchy: hierarchy,
+        coreTypes: coreTypes,
+        declarationBuilder: currentDeclaration,
+        isDeclarationInstanceMember: isDeclarationInstanceMember,
+        extensionThis: extensionThis,
+        extensionTypeParameters: extensionTypeParameters,
+        uri: uri,
+        typeInferrer: typeInferrer)
       ..constantContext = constantContext;
   }
 
@@ -640,8 +671,10 @@
         builder.computeFormalParameterScope(typeParameterScope);
     assert(typeParameterScope != null);
     assert(formalParameterScope != null);
-    return createListener(builder, typeParameterScope, builder.isInstanceMember,
+    return createListener(builder, typeParameterScope,
+        isDeclarationInstanceMember: builder.isDeclarationInstanceMember,
         extensionThis: builder.extensionThis,
+        extensionTypeParameters: builder.extensionTypeParameters,
         formalParameterScope: formalParameterScope);
   }
 
@@ -676,7 +709,9 @@
     // TODO(paulberry): don't re-parse the field if we've already parsed it
     // for type inference.
     parseFields(
-        createListener(declaration, memberScope, declaration.isInstanceMember),
+        createListener(declaration, memberScope,
+            isDeclarationInstanceMember:
+                declaration.isDeclarationInstanceMember),
         token,
         metadata,
         isTopLevel);
@@ -713,21 +748,21 @@
     Token beginToken = pop();
     Object name = pop();
     pop(); // Annotation begin token.
-    assert(currentClass == null);
+    assert(currentDeclaration == null);
     assert(memberScope == library.scope);
     if (name is ParserRecovery) {
       currentClassIsParserRecovery = true;
       return;
     }
-    currentClass = lookupBuilder(beginToken, null, name);
-    memberScope = currentClass.scope;
+    currentDeclaration = lookupBuilder(beginToken, null, name);
+    memberScope = currentDeclaration.scope;
   }
 
   @override
   void endClassOrMixinBody(
       ClassKind kind, int memberCount, Token beginToken, Token endToken) {
     debugEvent("ClassOrMixinBody");
-    currentClass = null;
+    currentDeclaration = null;
     currentClassIsParserRecovery = false;
     memberScope = library.scope;
   }
@@ -828,7 +863,7 @@
       }
       token = parser.parseFormalParametersOpt(
           parser.syntheticPreviousToken(token), kind);
-      var formals = listener.pop();
+      Object formals = listener.pop();
       listener.checkEmpty(token.next.charOffset);
       token = parser.parseInitializersOpt(token);
       token = parser.parseAsyncModifierOpt(token);
@@ -836,7 +871,7 @@
       bool isExpression = false;
       bool allowAbstract = asyncModifier == AsyncMarker.Sync;
       parser.parseFunctionBody(token, isExpression, allowAbstract);
-      var body = listener.pop();
+      Object body = listener.pop();
       listener.checkEmpty(token.charOffset);
       listenerFinishFunction(
           listener, startToken, kind, formals, asyncModifier, body);
@@ -863,16 +898,16 @@
   Builder lookupBuilder(Token token, Token getOrSet, String name) {
     // TODO(ahe): Can I move this to Scope or ScopeBuilder?
     Builder declaration;
-    if (currentClass != null) {
-      if (uri != currentClass.fileUri) {
-        unexpected("$uri", "${currentClass.fileUri}", currentClass.charOffset,
-            currentClass.fileUri);
+    if (currentDeclaration != null) {
+      if (uri != currentDeclaration.fileUri) {
+        unexpected("$uri", "${currentDeclaration.fileUri}",
+            currentDeclaration.charOffset, currentDeclaration.fileUri);
       }
 
       if (getOrSet != null && optional("set", getOrSet)) {
-        declaration = currentClass.scope.setters[name];
+        declaration = currentDeclaration.scope.setters[name];
       } else {
-        declaration = currentClass.scope.local[name];
+        declaration = currentDeclaration.scope.local[name];
       }
     } else if (getOrSet != null && optional("set", getOrSet)) {
       declaration = library.scope.setters[name];
@@ -956,8 +991,9 @@
   List<Expression> parseMetadata(
       ModifierBuilder builder, Token metadata, TreeNode parent) {
     if (metadata != null) {
-      var listener = createListener(builder, memberScope, false);
-      var parser = new Parser(listener);
+      StackListener listener = createListener(builder, memberScope,
+          isDeclarationInstanceMember: false);
+      Parser parser = new Parser(listener);
       parser.parseMetadataStar(parser.syntheticPreviousToken(metadata));
       return listener.finishMetadata(parent);
     }
diff --git a/pkg/front_end/lib/src/fasta/source/outline_builder.dart b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
index 830352f..65d70e6 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -27,6 +27,7 @@
         messageOperatorWithOptionalFormals,
         messageStaticConstructor,
         messageTypedefNotFunction,
+        Template,
         templateCycleInTypeVariables,
         templateDirectCycleInTypeVariables,
         templateDuplicatedParameterName,
@@ -58,10 +59,11 @@
         abstractMask,
         constMask,
         covariantMask,
-        extensionDeclarationMask,
         externalMask,
         finalMask,
+        lateMask,
         mixinDeclarationMask,
+        requiredMask,
         staticMask;
 
 import '../operator.dart'
@@ -413,6 +415,13 @@
 
   @override
   void handleQualified(Token period) {
+    assert(checkState(period, [
+      /*suffix offset*/ ValueKind.Integer,
+      /*suffix*/ ValueKind.NameOrParserRecovery,
+      /*prefix offset*/ ValueKind.Integer,
+      /*prefix*/ unionOfKinds(
+          [ValueKind.Name, ValueKind.ParserRecovery, ValueKind.QualifiedName]),
+    ]));
     debugEvent("handleQualified");
     int suffixOffset = pop();
     Object suffix = pop();
@@ -666,7 +675,8 @@
     library.addExtensionDeclaration(
         documentationComment,
         metadata,
-        extensionDeclarationMask,
+        // TODO(johnniwinther): Support modifiers on extensions?
+        0,
         name,
         typeVariables,
         supertype,
@@ -868,7 +878,7 @@
       kind = ProcedureKind.Operator;
       int requiredArgumentCount = operatorRequiredArgumentCount(nameOrOperator);
       if ((formals?.length ?? 0) != requiredArgumentCount) {
-        var template;
+        Template<Message Function(String name)> template;
         switch (requiredArgumentCount) {
           case 0:
             template = templateOperatorParameterMismatch0;
@@ -954,6 +964,8 @@
         // TODO(johnniwinther): Handle shadowing of extension type variables.
         List<TypeVariableBuilder> synthesizedTypeVariables = library
             .copyTypeVariables(extension.typeVariables, declarationBuilder,
+                // TODO(johnniwinther): The synthesized names show up in
+                // messages. Move synthesizing of names later to avoid this.
                 synthesizeTypeParameterNames: true);
         substitution = {};
         for (int i = 0; i < synthesizedTypeVariables.length; i++) {
@@ -1154,6 +1166,7 @@
       reportNonNullableModifierError(requiredToken);
     }
     push((covariantToken != null ? covariantMask : 0) |
+        (requiredToken != null ? requiredMask : 0) |
         Modifier.validateVarFinalOrConst(varFinalOrConst?.lexeme));
   }
 
@@ -1410,7 +1423,7 @@
       functionType =
           library.addFunctionType(returnType, null, formals, charOffset);
     } else {
-      var type = pop();
+      Object type = pop();
       typeVariables = pop();
       charOffset = pop();
       name = pop();
@@ -1448,7 +1461,6 @@
       Token beginToken,
       Token endToken) {
     debugEvent("endTopLevelFields");
-    // TODO(danrubel): handle NNBD 'late' modifier
     if (!library.loader.target.enableNonNullable) {
       reportNonNullableModifierError(lateToken);
     }
@@ -1456,6 +1468,7 @@
     TypeBuilder type = nullIfParserRecovery(pop());
     int modifiers = (staticToken != null ? staticMask : 0) |
         (covariantToken != null ? covariantMask : 0) |
+        (lateToken != null ? lateMask : 0) |
         Modifier.validateVarFinalOrConst(varFinalOrConst?.lexeme);
     List<MetadataBuilder> metadata = pop();
     checkEmpty(beginToken.charOffset);
@@ -1469,7 +1482,6 @@
   void endFields(Token staticToken, Token covariantToken, Token lateToken,
       Token varFinalOrConst, int count, Token beginToken, Token endToken) {
     debugEvent("Fields");
-    // TODO(danrubel): handle NNBD 'late' modifier
     if (!library.loader.target.enableNonNullable) {
       reportNonNullableModifierError(lateToken);
     }
@@ -1477,6 +1489,7 @@
     TypeBuilder type = pop();
     int modifiers = (staticToken != null ? staticMask : 0) |
         (covariantToken != null ? covariantMask : 0) |
+        (lateToken != null ? lateMask : 0) |
         Modifier.validateVarFinalOrConst(varFinalOrConst?.lexeme);
     if (staticToken == null && modifiers & constMask != 0) {
       // It is a compile-time error if an instance variable is declared to be
@@ -1567,12 +1580,12 @@
           // Find cycle: If there's no cycle we can at most step through all
           // `typeParameters` (at which point the last builders bound will be
           // null).
-          // If there is a cycle with `builder` 'inside' the steps to get back to
-          // it will also be bound by `typeParameters.length`.
-          // If there is a cycle without `builder` 'inside' we will just ignore it
-          // for now. It will be reported when processing one of the `builder`s
-          // that is in fact `inside` the cycle. This matches the cyclic class
-          // hierarchy error.
+          // If there is a cycle with `builder` 'inside' the steps to get back
+          // to it will also be bound by `typeParameters.length`.
+          // If there is a cycle without `builder` 'inside' we will just ignore
+          // it for now. It will be reported when processing one of the
+          // `builder`s that is in fact `inside` the cycle. This matches the
+          // cyclic class hierarchy error.
           TypeVariableBuilder bound = builder;
           for (int steps = 0;
               bound.bound != null && steps < typeParameters.length;
@@ -1811,7 +1824,7 @@
     Token docToken = token.precedingComments;
     if (docToken == null) return null;
     bool inSlash = false;
-    var buffer = new StringBuffer();
+    StringBuffer buffer = new StringBuffer();
     while (docToken != null) {
       String lexeme = docToken.lexeme;
       if (lexeme.startsWith('/**')) {
diff --git a/pkg/front_end/lib/src/fasta/source/scope_listener.dart b/pkg/front_end/lib/src/fasta/source/scope_listener.dart
index 8c6a4c1..4fdb854 100644
--- a/pkg/front_end/lib/src/fasta/source/scope_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/scope_listener.dart
@@ -133,7 +133,7 @@
   @override
   void endDoWhileStatementBody(Token token) {
     debugEvent("endDoWhileStatementBody");
-    var body = pop();
+    Object body = pop();
     exitLocalScope();
     push(body);
   }
@@ -147,7 +147,7 @@
   @override
   void endWhileStatementBody(Token token) {
     debugEvent("endWhileStatementBody");
-    var body = pop();
+    Object body = pop();
     exitLocalScope();
     push(body);
   }
@@ -161,7 +161,7 @@
   @override
   void endForStatementBody(Token token) {
     debugEvent("endForStatementBody");
-    var body = pop();
+    Object body = pop();
     exitLocalScope();
     push(body);
   }
@@ -175,7 +175,7 @@
   @override
   void endForInBody(Token token) {
     debugEvent("endForInBody");
-    var body = pop();
+    Object body = pop();
     exitLocalScope();
     push(body);
   }
@@ -189,7 +189,7 @@
   @override
   void endThenStatement(Token token) {
     debugEvent("endThenStatement");
-    var body = pop();
+    Object body = pop();
     exitLocalScope();
     push(body);
   }
@@ -203,7 +203,7 @@
   @override
   void endElseStatement(Token token) {
     debugEvent("endElseStatement");
-    var body = pop();
+    Object body = pop();
     exitLocalScope();
     push(body);
   }
diff --git a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
index 66cef5e..7edee90 100644
--- a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
@@ -55,7 +55,7 @@
   cls ??= new Class(
       name: name,
       typeParameters:
-          TypeVariableBuilder.kernelTypeParametersFromBuilders(typeVariables));
+          TypeVariableBuilder.typeParametersFromBuilders(typeVariables));
   cls.fileUri ??= parent.fileUri;
   if (cls.startFileOffset == TreeNode.noOffset) {
     cls.startFileOffset = startCharOffset;
@@ -94,15 +94,15 @@
       LibraryBuilder parent,
       this.constructorReferences,
       int startCharOffset,
-      int charOffset,
+      int nameOffset,
       int charEndOffset,
       {Class cls,
       this.mixedInType,
       this.isMixinDeclaration = false})
       : actualCls = initializeClass(cls, typeVariables, name, parent,
-            startCharOffset, charOffset, charEndOffset),
+            startCharOffset, nameOffset, charEndOffset),
         super(metadata, modifiers, name, typeVariables, supertype, interfaces,
-            onTypes, scope, constructors, parent, charOffset);
+            onTypes, scope, constructors, parent, nameOffset);
 
   @override
   Class get cls => origin.actualCls;
@@ -130,13 +130,9 @@
           }
         } else if (declaration is FunctionBuilder) {
           Member function = declaration.build(library);
-          if (isExtension) {
-            library.target.addMember(function);
-          } else {
-            function.parent = cls;
-            if (!declaration.isPatch && declaration.next == null) {
-              cls.addMember(function);
-            }
+          function.parent = cls;
+          if (!declaration.isPatch && declaration.next == null) {
+            cls.addMember(function);
           }
         } else {
           unhandled("${declaration.runtimeType}", "buildBuilders",
@@ -219,7 +215,8 @@
               member.isRegularMethod && member.isStatic && setter.isStatic)) {
         return;
       }
-      if (member.isInstanceMember == setter.isInstanceMember) {
+      if (member.isDeclarationInstanceMember ==
+          setter.isDeclarationInstanceMember) {
         addProblem(templateConflictsWithMember.withArguments(name),
             setter.charOffset, noLength);
         // TODO(ahe): Context argument to previous message?
diff --git a/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart b/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
new file mode 100644
index 0000000..fd87fa7
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
@@ -0,0 +1,115 @@
+// 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.
+
+import 'dart:core' hide MapEntry;
+import 'package:kernel/ast.dart';
+import '../builder/declaration.dart';
+import '../builder/extension_builder.dart';
+import '../builder/library_builder.dart';
+import '../builder/metadata_builder.dart';
+import '../builder/procedure_builder.dart';
+import '../builder/type_builder.dart';
+import '../builder/type_variable_builder.dart';
+import '../scope.dart';
+import 'source_library_builder.dart';
+import '../kernel/kernel_builder.dart';
+
+import '../problems.dart' show unexpected, unhandled;
+
+import '../fasta_codes.dart'
+    show
+        noLength,
+        templateConflictsWithMember,
+        templateConflictsWithMemberWarning,
+        templateConflictsWithSetter,
+        templateConflictsWithSetterWarning;
+
+class SourceExtensionBuilder extends ExtensionBuilder {
+  final Extension _extension;
+
+  SourceExtensionBuilder(
+      List<MetadataBuilder> metadata,
+      int modifiers,
+      String name,
+      List<TypeVariableBuilder> typeParameters,
+      TypeBuilder onType,
+      Scope scope,
+      LibraryBuilder parent,
+      int startOffset,
+      int nameOffset,
+      int endOffset)
+      : _extension = new Extension(
+            name: name,
+            fileUri: parent.fileUri,
+            typeParameters:
+                TypeVariableBuilder.typeParametersFromBuilders(typeParameters))
+          ..fileOffset = nameOffset,
+        super(metadata, modifiers, name, parent, nameOffset, scope,
+            typeParameters, onType);
+
+  Extension build(SourceLibraryBuilder library, LibraryBuilder coreLibrary) {
+    void buildBuilders(String name, Builder declaration) {
+      do {
+        if (declaration.parent != this) {
+          if (fileUri != declaration.parent.fileUri) {
+            unexpected("$fileUri", "${declaration.parent.fileUri}", charOffset,
+                fileUri);
+          } else {
+            unexpected(fullNameForErrors, declaration.parent?.fullNameForErrors,
+                charOffset, fileUri);
+          }
+        } else if (declaration is FieldBuilder) {
+          Field field = declaration.build(library);
+          library.target.addMember(field);
+          _extension.members.add(new ExtensionMemberDescriptor(
+              name: new Name(declaration.name, library.target),
+              member: field.reference,
+              isStatic: declaration.isStatic));
+        } else if (declaration is FunctionBuilder) {
+          Member function = declaration.build(library);
+          library.target.addMember(function);
+          _extension.members.add(new ExtensionMemberDescriptor(
+              name: new Name(declaration.name, library.target),
+              member: function.reference,
+              isStatic: declaration.isStatic,
+              isExternal: declaration.isExternal,
+              kind: declaration.kind));
+        } else {
+          unhandled("${declaration.runtimeType}", "buildBuilders",
+              declaration.charOffset, declaration.fileUri);
+        }
+        declaration = declaration.next;
+      } while (declaration != null);
+    }
+
+    scope.forEach(buildBuilders);
+
+    scope.setters.forEach((String name, Builder setter) {
+      Builder member = scopeBuilder[name];
+      if (member == null ||
+          !(member.isField && !member.isFinal && !member.isConst ||
+              member.isRegularMethod && member.isStatic && setter.isStatic)) {
+        return;
+      }
+      if (member.isDeclarationInstanceMember ==
+          setter.isDeclarationInstanceMember) {
+        addProblem(templateConflictsWithMember.withArguments(name),
+            setter.charOffset, noLength);
+        // TODO(ahe): Context argument to previous message?
+        addProblem(templateConflictsWithSetter.withArguments(name),
+            member.charOffset, noLength);
+      } else {
+        addProblem(templateConflictsWithMemberWarning.withArguments(name),
+            setter.charOffset, noLength);
+        // TODO(ahe): Context argument to previous message?
+        addProblem(templateConflictsWithSetterWarning.withArguments(name),
+            member.charOffset, noLength);
+      }
+    });
+
+    _extension.onType = onType?.build(library);
+
+    return _extension;
+  }
+}
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index 210f149..5747b08 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -15,6 +15,7 @@
         DartType,
         DynamicType,
         Expression,
+        Extension,
         Field,
         FunctionNode,
         FunctionType,
@@ -79,6 +80,8 @@
         UnresolvedType,
         flattenName;
 
+import '../builder/extension_builder.dart';
+
 import '../combinator.dart' show Combinator;
 
 import '../configuration.dart' show Configuration;
@@ -109,6 +112,7 @@
         messageTypeVariableDuplicatedName,
         messageTypeVariableSameNameAsEnclosing,
         noLength,
+        Template,
         templateConflictsWithMember,
         templateConflictsWithSetter,
         templateConflictsWithTypeVariable,
@@ -218,6 +222,8 @@
 
 import 'source_class_builder.dart' show SourceClassBuilder;
 
+import 'source_extension_builder.dart' show SourceExtensionBuilder;
+
 import 'source_loader.dart' show SourceLoader;
 
 class SourceLibraryBuilder extends LibraryBuilder {
@@ -503,7 +509,7 @@
       }
     }
 
-    var exportedLibrary = loader
+    LibraryBuilder exportedLibrary = loader
         .read(resolve(this.uri, uri, uriOffset), charOffset, accessor: this);
     exportedLibrary.addExporter(this, combinators, charOffset);
     exports.add(new Export(this, exportedLibrary, combinators, charOffset));
@@ -1040,7 +1046,9 @@
               // additionalExports either. Add the last one only (the one that
               // will eventually be added to the library).
               Builder memberLast = member;
-              while (memberLast.next != null) memberLast = memberLast.next;
+              while (memberLast.next != null) {
+                memberLast = memberLast.next;
+              }
               library.additionalExports.add(memberLast.target.reference);
             }
         }
@@ -1402,43 +1410,26 @@
         scope.withTypeVariables(typeVariables), "extension $extensionName",
         isModifiable: false);
 
-    // When looking up a constructor, we don't consider type variables or the
-    // library scope.
-    Scope constructorScope =
-        new Scope(constructors, null, null, extensionName, isModifiable: false);
-    bool isMixinDeclaration = false;
-    if (modifiers & mixinDeclarationMask != 0) {
-      isMixinDeclaration = true;
-      modifiers = (modifiers & ~mixinDeclarationMask) | abstractMask;
-    }
-    if (declaration.hasConstConstructor) {
-      modifiers |= hasConstConstructorMask;
-    }
-    ClassBuilder cls = new SourceClassBuilder(
+    ExtensionBuilder extension = new SourceExtensionBuilder(
         metadata,
         modifiers,
         extensionName,
         typeVariables,
-        null, // No explicit supertype.
-        null, // No implemented interfaces.
-        [type],
+        type,
         classScope,
-        constructorScope,
         this,
-        new List<ConstructorReferenceBuilder>.from(constructorReferences),
         startOffset,
         nameOffset,
-        endOffset,
-        isMixinDeclaration: isMixinDeclaration);
+        endOffset);
     loader.target.metadataCollector
-        ?.setDocumentationComment(cls.target, documentationComment);
+        ?.setDocumentationComment(extension.target, documentationComment);
 
     constructorReferences.clear();
     Map<String, TypeVariableBuilder> typeVariablesByName =
-        checkTypeVariables(typeVariables, cls);
+        checkTypeVariables(typeVariables, extension);
     void setParent(String name, MemberBuilder member) {
       while (member != null) {
-        member.parent = cls;
+        member.parent = extension;
         member = member.next;
       }
     }
@@ -1447,8 +1438,10 @@
       if (typeVariablesByName != null) {
         TypeVariableBuilder tv = typeVariablesByName[name];
         if (tv != null) {
-          cls.addProblem(templateConflictsWithTypeVariable.withArguments(name),
-              member.charOffset, name.length,
+          extension.addProblem(
+              templateConflictsWithTypeVariable.withArguments(name),
+              member.charOffset,
+              name.length,
               context: [
                 messageConflictsWithTypeVariableCause.withLocation(
                     tv.fileUri, tv.charOffset, name.length)
@@ -1461,7 +1454,7 @@
     members.forEach(setParentAndCheckConflicts);
     constructors.forEach(setParentAndCheckConflicts);
     setters.forEach(setParentAndCheckConflicts);
-    addBuilder(extensionName, cls, nameOffset);
+    addBuilder(extensionName, extension, nameOffset);
   }
 
   TypeBuilder applyMixins(TypeBuilder type, int startCharOffset, int charOffset,
@@ -1898,7 +1891,7 @@
           nativeMethodName);
     }
 
-    var metadataCollector = loader.target.metadataCollector;
+    MetadataCollector metadataCollector = loader.target.metadataCollector;
     metadataCollector?.setDocumentationComment(
         procedure.target, documentationComment);
     metadataCollector?.setConstructorNameOffset(procedure.target, name);
@@ -1958,7 +1951,8 @@
       List<TypeVariableBuilder> typeVariables,
       List<FormalParameterBuilder> formals,
       int charOffset) {
-    var builder = new FunctionTypeBuilder(returnType, typeVariables, formals);
+    FunctionTypeBuilder builder =
+        new FunctionTypeBuilder(returnType, typeVariables, formals);
     checkTypeVariables(typeVariables, null);
     // Nested declaration began in `OutlineBuilder.beginFunctionType` or
     // `OutlineBuilder.beginFunctionTypedFormalParameter`.
@@ -1989,7 +1983,8 @@
 
   TypeVariableBuilder addTypeVariable(
       String name, TypeBuilder bound, int charOffset) {
-    var builder = new TypeVariableBuilder(name, this, charOffset, bound: bound);
+    TypeVariableBuilder builder =
+        new TypeVariableBuilder(name, this, charOffset, bound: bound);
     boundlessTypeVariables.add(builder);
     return builder;
   }
@@ -2001,10 +1996,13 @@
 
   void buildBuilder(Builder declaration, LibraryBuilder coreLibrary) {
     Class cls;
+    Extension extension;
     Member member;
     Typedef typedef;
     if (declaration is SourceClassBuilder) {
       cls = declaration.build(this, coreLibrary);
+    } else if (declaration is SourceExtensionBuilder) {
+      extension = declaration.build(this, coreLibrary);
     } else if (declaration is FieldBuilder) {
       member = declaration.build(this)..isStatic = true;
     } else if (declaration is ProcedureBuilder) {
@@ -2043,6 +2041,10 @@
         cls.name += "#$count";
       }
       library.addClass(cls);
+    } else if (extension != null) {
+      if (declaration.next == null) {
+        library.addExtension(extension);
+      }
     } else if (member != null) {
       if (declaration.next == null) {
         library.addMember(member);
@@ -2166,7 +2168,7 @@
     }
     if (preferred != null) {
       if (isLocal) {
-        var template = isExport
+        Template<Message Function(String name, Uri uri)> template = isExport
             ? templateLocalDefinitionHidesExport
             : templateLocalDefinitionHidesImport;
         addProblem(template.withArguments(name, hiddenUri), charOffset,
@@ -2175,7 +2177,7 @@
         addProblem(templateLoadLibraryHidesMember.withArguments(preferredUri),
             charOffset, noLength, fileUri);
       } else {
-        var template =
+        Template<Message Function(String name, Uri uri, Uri uri2)> template =
             isExport ? templateExportHidesExport : templateImportHidesImport;
         addProblem(template.withArguments(name, preferredUri, hiddenUri),
             charOffset, noLength, fileUri);
@@ -2195,13 +2197,14 @@
           });
       }
     }
-    var template =
+    Template<Message Function(String name, Uri uri, Uri uri2)> template =
         isExport ? templateDuplicatedExport : templateDuplicatedImport;
     Message message = template.withArguments(name, uri, otherUri);
     addProblem(message, charOffset, noLength, fileUri);
-    var builderTemplate = isExport
-        ? templateDuplicatedExportInType
-        : templateDuplicatedImportInType;
+    Template<Message Function(String name, Uri uri, Uri uri2)> builderTemplate =
+        isExport
+            ? templateDuplicatedExportInType
+            : templateDuplicatedImportInType;
     message = builderTemplate.withArguments(
         name,
         // TODO(ahe): We should probably use a context object here
@@ -2218,7 +2221,7 @@
 
   int finishDeferredLoadTearoffs() {
     int total = 0;
-    for (var import in imports) {
+    for (Import import in imports) {
       if (import.deferred) {
         Procedure tearoff = import.prefixBuilder.loadLibraryBuilder.tearoff;
         if (tearoff != null) library.addMember(tearoff);
@@ -2303,7 +2306,7 @@
     List<TypeBuilder> newTypes = <TypeBuilder>[];
     List<TypeVariableBuilder> copy = <TypeVariableBuilder>[];
     for (TypeVariableBuilder variable in original) {
-      var newVariable = new TypeVariableBuilder(
+      TypeVariableBuilder newVariable = new TypeVariableBuilder(
           variable.name, this, variable.charOffset,
           bound: variable.bound?.clone(newTypes),
           synthesizeTypeParameterName: synthesizeTypeParameterNames);
@@ -2379,7 +2382,7 @@
     }
 
     bool legacyMode = loader.target.legacyMode;
-    for (var declaration in libraryDeclaration.members.values) {
+    for (Builder declaration in libraryDeclaration.members.values) {
       if (declaration is ClassBuilder) {
         {
           List<Object> issues = legacyMode
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 599dc2f..c954495 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -83,7 +83,8 @@
         LibraryBuilder,
         MemberBuilder,
         NamedTypeBuilder,
-        TypeBuilder;
+        TypeBuilder,
+        TypeDeclarationBuilder;
 
 import '../kernel/kernel_target.dart' show KernelTarget;
 
@@ -308,10 +309,11 @@
     }
   }
 
+  // TODO(johnniwinther,jensj): Handle expression in extensions?
   Future<Expression> buildExpression(
       SourceLibraryBuilder library,
       String enclosingClass,
-      bool isInstanceMember,
+      bool isClassInstanceMember,
       FunctionNode parameters) async {
     Token token = await tokenize(library, suppressLexicalErrors: false);
     if (token == null) return null;
@@ -323,7 +325,7 @@
       if (cls is ClassBuilder) {
         parent = cls;
         dietListener
-          ..currentClass = cls
+          ..currentDeclaration = cls
           ..memberScope = cls.scope.copyWithParent(
               dietListener.memberScope.withTypeVariables(cls.typeVariables),
               "debugExpression in $enclosingClass");
@@ -333,7 +335,8 @@
         null, null, ProcedureKind.Method, library, 0, 0, -1, -1)
       ..parent = parent;
     BodyBuilder listener = dietListener.createListener(
-        builder, dietListener.memberScope, isInstanceMember);
+        builder, dietListener.memberScope,
+        isDeclarationInstanceMember: isClassInstanceMember);
 
     return listener.parseSingleExpression(
         new Parser(listener), token, parameters);
@@ -597,8 +600,8 @@
 
     Set<ClassBuilder> blackListedClasses = new Set<ClassBuilder>();
     for (int i = 0; i < blacklistedCoreClasses.length; i++) {
-      blackListedClasses
-          .add(coreLibrary.getLocalMember(blacklistedCoreClasses[i]));
+      blackListedClasses.add(coreLibrary
+          .lookupLocalMember(blacklistedCoreClasses[i], required: true));
     }
 
     // Sort the classes topologically.
@@ -679,7 +682,7 @@
     if (mixedInType != null) {
       bool isClassBuilder = false;
       if (mixedInType is NamedTypeBuilder) {
-        var builder = mixedInType.declaration;
+        TypeDeclarationBuilder builder = mixedInType.declaration;
         if (builder is ClassBuilder) {
           isClassBuilder = true;
           for (Builder constructor in builder.constructors.local.values) {
@@ -1111,7 +1114,7 @@
     if (library == null) {
       return target.dillTarget.loader.computeClassBuilderFromTargetClass(cls);
     }
-    return library.getLocalMember(cls.name);
+    return library.lookupLocalMember(cls.name, required: true);
   }
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/source/stack_listener.dart b/pkg/front_end/lib/src/fasta/source/stack_listener.dart
index db32120..457f5d5 100644
--- a/pkg/front_end/lib/src/fasta/source/stack_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/stack_listener.dart
@@ -79,25 +79,47 @@
 abstract class StackListener extends Listener {
   final Stack stack = new Stack();
 
+  /// Checks that [value] matches the expected [kind].
+  ///
+  /// Use this in assert statements like
+  ///
+  ///     assert(checkValue(token, ValueKind.Token, value));
+  ///
+  /// to document and validate the expected value kind.
+  bool checkValue(Token token, ValueKind kind, Object value) {
+    if (!kind.check(value)) {
+      String message = 'Unexpected value `${value}` (${value.runtimeType}). '
+          'Expected ${kind}.';
+      if (token != null) {
+        // If offset is available report and internal problem to show the
+        // parsed code in the output.
+        throw internalProblem(
+            new Message(null, message: message), token.charOffset, uri);
+      } else {
+        throw message;
+      }
+    }
+    return true;
+  }
+
   /// Checks the top of the current stack against [kinds]. If a mismatch is
   /// found, a top of the current stack is print along with the expected [kinds]
   /// marking the frames that don't match, and throws an exception.
   ///
-  /// Use this in assert statements like `assert(checkState([ValueKind.Token]))`
+  /// Use this in assert statements like
+  ///
+  ///     assert(checkState(token, [ValueKind.Integer, ValueKind.StringOrNull]))
+  ///
   /// to document the expected stack and get earlier errors on unexpected stack
   /// content.
   bool checkState(Token token, List<ValueKind> kinds) {
-    bool checkValue(ValueKind kind, Object value) {
-      return kind.check(value);
-    }
-
     bool success = true;
     for (int kindIndex = 0; kindIndex < kinds.length; kindIndex++) {
       int stackIndex = stack.arrayLength - kindIndex - 1;
       ValueKind kind = kinds[kindIndex];
       if (stackIndex >= 0) {
         Object value = stack.array[stackIndex];
-        if (!checkValue(kind, value)) {
+        if (!kind.check(value)) {
           success = false;
         }
       } else {
@@ -151,7 +173,7 @@
         }
         if (stackIndex >= 0) {
           Object value = stack.array[stackIndex];
-          if (kind == null || checkValue(kind, value)) {
+          if (kind == null || kind.check(value)) {
             sb.write(' ');
           } else {
             sb.write('*');
@@ -503,7 +525,7 @@
   int get length => arrayLength;
 
   Object get last {
-    final value = array[arrayLength - 1];
+    final Object value = array[arrayLength - 1];
     return value is NullValue ? null : value;
   }
 
diff --git a/pkg/front_end/lib/src/fasta/source/value_kinds.dart b/pkg/front_end/lib/src/fasta/source/value_kinds.dart
index c9c5f57..9186a6d 100644
--- a/pkg/front_end/lib/src/fasta/source/value_kinds.dart
+++ b/pkg/front_end/lib/src/fasta/source/value_kinds.dart
@@ -33,46 +33,55 @@
   /// Checks the [value] an returns `true` if the value is of the expected kind.
   bool check(Object value);
 
+  static const ValueKind Arguments = _SingleValueKind<type.Arguments>();
   static const ValueKind ArgumentsOrNull =
       _SingleValueKind<type.Arguments>(NullValue.Arguments);
-  static const ValueKind Expression = _SingleValueKind<type.Expression>();
-  static const ValueKind Identifier = _SingleValueKind<type.Identifier>();
-  static const ValueKind Integer = _SingleValueKind<int>();
+  static const ValueKind Expression = const _SingleValueKind<type.Expression>();
+  static const ValueKind Identifier = const _SingleValueKind<type.Identifier>();
+  static const ValueKind IdentifierOrNull =
+      const _SingleValueKind<type.Identifier>(NullValue.Identifier);
+  static const ValueKind Integer = const _SingleValueKind<int>();
   static const ValueKind Formals =
-      _SingleValueKind<List<type.FormalParameterBuilder>>();
+      const _SingleValueKind<List<type.FormalParameterBuilder>>();
   static const ValueKind FormalsOrNull =
-      _SingleValueKind<List<type.FormalParameterBuilder>>(
+      const _SingleValueKind<List<type.FormalParameterBuilder>>(
           NullValue.FormalParameters);
-  static const ValueKind Generator = _SingleValueKind<type.Generator>();
-  static const ValueKind MethodBody = _SingleValueKind<type.MethodBody>();
-  static const ValueKind Modifiers = _SingleValueKind<List<type.Modifier>>();
+  static const ValueKind Generator = const _SingleValueKind<type.Generator>();
+  static const ValueKind MethodBody = const _SingleValueKind<type.MethodBody>();
+  static const ValueKind Modifiers =
+      const _SingleValueKind<List<type.Modifier>>();
   static const ValueKind ModifiersOrNull =
-      _SingleValueKind<List<type.Modifier>>(NullValue.Modifiers);
-  static const ValueKind Name = _SingleValueKind<String>();
-  static const ValueKind NameOrNull = _SingleValueKind<String>(NullValue.Name);
+      const _SingleValueKind<List<type.Modifier>>(NullValue.Modifiers);
+  static const ValueKind Name = const _SingleValueKind<String>();
+  static const ValueKind NameOrNull =
+      const _SingleValueKind<String>(NullValue.Name);
   static const ValueKind NameOrOperator = _UnionValueKind([Name, Operator]);
   static const ValueKind NameOrQualifiedNameOrOperator =
-      _UnionValueKind([Name, QualifiedName, Operator]);
+      const _UnionValueKind([Name, QualifiedName, Operator]);
   static const ValueKind NameOrParserRecovery =
-      _UnionValueKind([Name, ParserRecovery]);
+      const _UnionValueKind([Name, ParserRecovery]);
   static const ValueKind MetadataListOrNull =
-      _SingleValueKind<List<type.MetadataBuilder>>(NullValue.Metadata);
-  static const ValueKind Operator = _SingleValueKind<type.Operator>();
+      const _SingleValueKind<List<type.MetadataBuilder>>(NullValue.Metadata);
+  static const ValueKind Operator = const _SingleValueKind<type.Operator>();
   static const ValueKind ParserRecovery =
       _SingleValueKind<type.ParserRecovery>();
   static const ValueKind ProblemBuilder =
       _SingleValueKind<type.ProblemBuilder>();
-  static const ValueKind QualifiedName = _SingleValueKind<type.QualifiedName>();
-  static const ValueKind Token = _SingleValueKind<type.Token>();
+  static const ValueKind QualifiedName =
+      const _SingleValueKind<type.QualifiedName>();
+  static const ValueKind Token = const _SingleValueKind<type.Token>();
   static const ValueKind TokenOrNull =
-      _SingleValueKind<type.Token>(NullValue.Token);
+      const _SingleValueKind<type.Token>(NullValue.Token);
   static const ValueKind TypeArgumentsOrNull =
-      _SingleValueKind<List<type.UnresolvedType>>(NullValue.TypeArguments);
-  static const ValueKind TypeBuilder = _SingleValueKind<type.TypeBuilder>();
+      const _SingleValueKind<List<type.UnresolvedType>>(
+          NullValue.TypeArguments);
+  static const ValueKind TypeBuilder =
+      const _SingleValueKind<type.TypeBuilder>();
   static const ValueKind TypeBuilderOrNull =
-      _SingleValueKind<type.TypeBuilder>(NullValue.Type);
+      const _SingleValueKind<type.TypeBuilder>(NullValue.Type);
   static const ValueKind TypeVariableListOrNull =
-      _SingleValueKind<List<type.TypeVariableBuilder>>(NullValue.TypeVariables);
+      const _SingleValueKind<List<type.TypeVariableBuilder>>(
+          NullValue.TypeVariables);
 }
 
 /// A [ValueKind] for a particular type [T], optionally with a recognized
diff --git a/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart b/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart
index 8a1b4e5..62bc602 100644
--- a/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart
+++ b/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart
@@ -188,8 +188,8 @@
 
   Future<Result<Component>> run(
       Component component, ChainContext context) async {
-    var errorFormatter = new ErrorFormatter();
-    var checker =
+    ErrorFormatter errorFormatter = new ErrorFormatter();
+    NaiveTypeChecker checker =
         new NaiveTypeChecker(errorFormatter, component, ignoreSdk: true);
     checker.checkComponent(component);
     if (errorFormatter.numberOfFailures == 0) {
diff --git a/pkg/front_end/lib/src/fasta/testing/validating_instrumentation.dart b/pkg/front_end/lib/src/fasta/testing/validating_instrumentation.dart
index 5547c5f..c6a2461 100644
--- a/pkg/front_end/lib/src/fasta/testing/validating_instrumentation.dart
+++ b/pkg/front_end/lib/src/fasta/testing/validating_instrumentation.dart
@@ -80,7 +80,7 @@
   void finish() {
     _unsatisfiedExpectations.forEach((uri, expectationsForUri) {
       expectationsForUri.forEach((offset, expectationsAtOffset) {
-        for (var expectation in expectationsAtOffset) {
+        for (_Expectation expectation in expectationsAtOffset) {
           _problem(
               uri,
               offset,
@@ -97,10 +97,10 @@
   /// pairs that were observed.
   Future<Null> fixSource(Uri uri, bool offsetsCountCharacters) async {
     uri = Uri.base.resolveUri(uri);
-    var fixes = _fixes[uri];
+    List<_Fix> fixes = _fixes[uri];
     if (fixes == null) return;
     File file = new File.fromUri(uri);
-    var bytes = (await file.readAsBytes()).toList();
+    List<int> bytes = (await file.readAsBytes()).toList();
     int convertOffset(int offset) {
       if (offsetsCountCharacters) {
         return utf8.encode(utf8.decode(bytes).substring(0, offset)).length;
@@ -112,7 +112,7 @@
     // Apply the fixes in reverse order so that offsets don't need to be
     // adjusted after each fix.
     fixes.sort((a, b) => a.offset.compareTo(b.offset));
-    for (var fix in fixes.reversed) {
+    for (_Fix fix in fixes.reversed) {
       bytes.replaceRange(convertOffset(fix.offset),
           convertOffset(fix.offset + fix.length), utf8.encode(fix.replacement));
     }
@@ -124,10 +124,12 @@
   /// Should be called before [finish].
   Future<Null> loadExpectations(Uri uri) async {
     uri = Uri.base.resolveUri(uri);
-    var bytes = await readBytesFromFile(uri);
-    var expectations = _unsatisfiedExpectations.putIfAbsent(uri, () => {});
-    var testedFeaturesState = _testedFeaturesState.putIfAbsent(uri, () => {});
-    var tokenOffsets = _tokenOffsets.putIfAbsent(uri, () => []);
+    List<int> bytes = await readBytesFromFile(uri);
+    Map<int, List<_Expectation>> expectations =
+        _unsatisfiedExpectations.putIfAbsent(uri, () => {});
+    Map<int, Set<String>> testedFeaturesState =
+        _testedFeaturesState.putIfAbsent(uri, () => {});
+    List<int> tokenOffsets = _tokenOffsets.putIfAbsent(uri, () => []);
     ScannerResult result = scan(bytes, includeComments: true);
     for (Token token = result.tokens; !token.isEof; token = token.next) {
       tokenOffsets.add(token.offset);
@@ -136,8 +138,8 @@
           commentToken = commentToken.next) {
         String lexeme = commentToken.lexeme;
         if (lexeme.startsWith('/*@') && lexeme.endsWith('*/')) {
-          var expectation = lexeme.substring(3, lexeme.length - 2);
-          var equals = expectation.indexOf('=');
+          String expectation = lexeme.substring(3, lexeme.length - 2);
+          int equals = expectation.indexOf('=');
           String property;
           String value;
           if (equals == -1) {
@@ -161,8 +163,8 @@
             }
             testedFeaturesState[commentToken.offset] = state;
           } else {
-            var offset = token.charOffset;
-            var expectationsAtOffset =
+            int offset = token.charOffset;
+            List<_Expectation> expectationsAtOffset =
                 expectations.putIfAbsent(offset, () => []);
             expectationsAtOffset.add(new _Expectation(
                 property, value, commentToken.offset, commentToken.length));
@@ -179,13 +181,14 @@
     if (offset == -1) {
       throw _formatProblem(uri, 0, 'No offset for $property=$value', null);
     }
-    var expectationsForUri = _unsatisfiedExpectations[uri];
+    Map<int, List<_Expectation>> expectationsForUri =
+        _unsatisfiedExpectations[uri];
     if (expectationsForUri == null) return;
     offset = _normalizeOffset(offset, _tokenOffsets[uri]);
-    var expectationsAtOffset = expectationsForUri[offset];
+    List<_Expectation> expectationsAtOffset = expectationsForUri[offset];
     if (expectationsAtOffset != null) {
       for (int i = 0; i < expectationsAtOffset.length; i++) {
-        var expectation = expectationsAtOffset[i];
+        _Expectation expectation = expectationsAtOffset[i];
         if (expectation.property == property) {
           if (!value.matches(expectation.value)) {
             _problemWithStack(
@@ -273,12 +276,12 @@
   }
 
   bool _shouldCheck(String property, Uri uri, int offset) {
-    var state = false;
-    var testedFeaturesStateForUri = _testedFeaturesState[uri];
+    bool state = false;
+    Map<int, Set<String>> testedFeaturesStateForUri = _testedFeaturesState[uri];
     if (testedFeaturesStateForUri == null) return false;
     for (int i in testedFeaturesStateForUri.keys) {
       if (i > offset) break;
-      var testedFeaturesStateAtOffset = testedFeaturesStateForUri[i];
+      Set<String> testedFeaturesStateAtOffset = testedFeaturesStateForUri[i];
       state = testedFeaturesStateAtOffset.contains(property);
     }
     return state;
diff --git a/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart b/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart
index b77b943..982987c 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart
@@ -23,6 +23,8 @@
 
 abstract class StandardBounds {
   Class get functionClass;
+  Class get futureClass;
+  Class get futureOrClass;
   InterfaceType get nullType;
   InterfaceType get objectType;
   InterfaceType get rawFunctionType;
@@ -99,6 +101,43 @@
       return type2;
     }
 
+    // See https://github.com/dart-lang/sdk/issues/37439#issuecomment-519654959.
+    if (type1 is InterfaceType && type1.classNode == futureOrClass) {
+      if (type2 is InterfaceType) {
+        if (type2.classNode == futureOrClass) {
+          // GLB(FutureOr<A>, FutureOr<B>) == FutureOr<GLB(A, B)>
+          return new InterfaceType(futureOrClass, <DartType>[
+            getStandardLowerBound(
+                type1.typeArguments[0], type2.typeArguments[0])
+          ]);
+        }
+        if (type2.classNode == futureClass) {
+          // GLB(FutureOr<A>, Future<B>) == Future<GLB(A, B)>
+          return new InterfaceType(futureClass, <DartType>[
+            getStandardLowerBound(
+                type1.typeArguments[0], type2.typeArguments[0])
+          ]);
+        }
+      }
+      // GLB(FutureOr<A>, B) == GLB(A, B)
+      return getStandardLowerBound(type1.typeArguments[0], type2);
+    }
+    // The if-statement below handles the following rule:
+    //     GLB(A, FutureOr<B>) ==  GLB(FutureOr<B>, A)
+    // It's broken down into sub-cases instead of making a recursive call to
+    // avoid making the checks that were already made above.  Note that at this
+    // point it's not possible for type1 to be a FutureOr.
+    if (type2 is InterfaceType && type2.classNode == futureOrClass) {
+      if (type1 is InterfaceType && type1.classNode == futureClass) {
+        // GLB(Future<A>, FutureOr<B>) == Future<GLB(B, A)>
+        return new InterfaceType(futureClass, <DartType>[
+          getStandardLowerBound(type2.typeArguments[0], type1.typeArguments[0])
+        ]);
+      }
+      // GLB(A, FutureOr<B>) == GLB(B, A)
+      return getStandardLowerBound(type2.typeArguments[0], type1);
+    }
+
     // No subtype relation, so the lower bound is bottom.
     return const BottomType();
   }
@@ -211,12 +250,12 @@
     // Calculate the SUB of each corresponding pair of parameters.
     int totalPositional =
         math.max(f.positionalParameters.length, g.positionalParameters.length);
-    var positionalParameters = new List<DartType>(totalPositional);
+    List<DartType> positionalParameters = new List<DartType>(totalPositional);
     for (int i = 0; i < totalPositional; i++) {
       if (i < f.positionalParameters.length) {
-        var fType = f.positionalParameters[i];
+        DartType fType = f.positionalParameters[i];
         if (i < g.positionalParameters.length) {
-          var gType = g.positionalParameters[i];
+          DartType gType = g.positionalParameters[i];
           positionalParameters[i] = getStandardUpperBound(fType, gType);
         } else {
           positionalParameters[i] = fType;
@@ -241,8 +280,8 @@
       while (true) {
         if (i < f.namedParameters.length) {
           if (j < g.namedParameters.length) {
-            var fName = f.namedParameters[i].name;
-            var gName = g.namedParameters[j].name;
+            String fName = f.namedParameters[i].name;
+            String gName = g.namedParameters[j].name;
             int order = fName.compareTo(gName);
             if (order < 0) {
               namedParameters.add(f.namedParameters[i++]);
@@ -307,7 +346,7 @@
     // other.
     int totalPositional =
         math.min(f.positionalParameters.length, g.positionalParameters.length);
-    var positionalParameters = new List<DartType>(totalPositional);
+    List<DartType> positionalParameters = new List<DartType>(totalPositional);
     for (int i = 0; i < totalPositional; i++) {
       positionalParameters[i] = getStandardLowerBound(
           f.positionalParameters[i], g.positionalParameters[i]);
@@ -321,8 +360,8 @@
       while (true) {
         if (i < f.namedParameters.length) {
           if (j < g.namedParameters.length) {
-            var fName = f.namedParameters[i].name;
-            var gName = g.namedParameters[j].name;
+            String fName = f.namedParameters[i].name;
+            String gName = g.namedParameters[j].name;
             int order = fName.compareTo(gName);
             if (order < 0) {
               i++;
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
index e23a716..aca7253 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
@@ -12,6 +12,7 @@
         FunctionType,
         InterfaceType,
         Member,
+        NamedType,
         TypeParameter,
         TypeParameterType,
         TypedefType,
@@ -68,14 +69,14 @@
     if (node.returnType.accept(this)) return true;
     Variance oldVariance = _variance;
     _variance = Variance.invariant;
-    for (var parameter in node.typeParameters) {
+    for (TypeParameter parameter in node.typeParameters) {
       if (parameter.bound.accept(this)) return true;
     }
     _variance = invertVariance(oldVariance);
-    for (var parameter in node.positionalParameters) {
+    for (DartType parameter in node.positionalParameters) {
       if (parameter.accept(this)) return true;
     }
-    for (var parameter in node.namedParameters) {
+    for (NamedType parameter in node.namedParameters) {
       if (parameter.type.accept(this)) return true;
     }
     _variance = oldVariance;
@@ -84,7 +85,7 @@
 
   @override
   bool visitInterfaceType(InterfaceType node) {
-    for (var argument in node.typeArguments) {
+    for (DartType argument in node.typeArguments) {
       if (argument.accept(this)) return true;
     }
     return false;
@@ -156,10 +157,12 @@
     // Field types have all been inferred so there cannot be a cyclic
     // dependency.
     for (Constructor constructor in toBeInferred.keys) {
-      for (var declaration in constructor.function.positionalParameters) {
+      for (VariableDeclaration declaration
+          in constructor.function.positionalParameters) {
         inferInitializingFormal(declaration, constructor);
       }
-      for (var declaration in constructor.function.namedParameters) {
+      for (VariableDeclaration declaration
+          in constructor.function.namedParameters) {
         inferInitializingFormal(declaration, constructor);
       }
     }
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart b/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart
index a47eda7..e5ba185 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart
@@ -9,6 +9,7 @@
         DartTypeVisitor1,
         FunctionType,
         InterfaceType,
+        NamedType,
         TypedefType,
         Visitor;
 
@@ -105,10 +106,10 @@
   @override
   bool visitFunctionType(FunctionType node) {
     if (!node.returnType.accept(this)) return false;
-    for (var parameterType in node.positionalParameters) {
+    for (DartType parameterType in node.positionalParameters) {
       if (!parameterType.accept(this)) return false;
     }
-    for (var namedParameterType in node.namedParameters) {
+    for (NamedType namedParameterType in node.namedParameters) {
       if (!namedParameterType.type.accept(this)) return false;
     }
     return true;
@@ -116,7 +117,7 @@
 
   @override
   bool visitInterfaceType(InterfaceType node) {
-    for (var typeArgument in node.typeArguments) {
+    for (DartType typeArgument in node.typeArguments) {
       if (!typeArgument.accept(this)) return false;
     }
     return true;
@@ -124,7 +125,7 @@
 
   @override
   bool visitTypedefType(TypedefType node) {
-    for (var typeArgument in node.typeArguments) {
+    for (DartType typeArgument in node.typeArguments) {
       if (!typeArgument.accept(this)) return false;
     }
     return true;
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 cf4c6bf..5c0233d 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
@@ -72,8 +72,9 @@
       DartType substitution = node.namedParameters[i].type.accept(this);
       if (substitution != null) {
         newNamedParameters ??= node.namedParameters.toList(growable: false);
-        newNamedParameters[i] =
-            new NamedType(node.namedParameters[i].name, substitution);
+        newNamedParameters[i] = new NamedType(
+            node.namedParameters[i].name, substitution,
+            isRequired: node.namedParameters[i].isRequired);
       }
     }
     isLeastClosure = !isLeastClosure;
@@ -122,8 +123,9 @@
   /// schema object is returned to avoid unnecessary allocation.
   static DartType run(
       CoreTypes coreTypes, bool isLeastClosure, DartType schema) {
-    var visitor = new _TypeSchemaEliminationVisitor(coreTypes, isLeastClosure);
-    var result = schema.accept(visitor);
+    _TypeSchemaEliminationVisitor visitor =
+        new _TypeSchemaEliminationVisitor(coreTypes, isLeastClosure);
+    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 46d023e..cf1097f 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
@@ -35,13 +35,14 @@
     FunctionType type,
     Map<TypeParameter, DartType> substitutionMap,
     List<TypeParameter> newTypeParameters) {
-  var substitution = Substitution.fromMap(substitutionMap);
+  Substitution substitution = Substitution.fromMap(substitutionMap);
   return new FunctionType(
       type.positionalParameters.map(substitution.substituteType).toList(),
       substitution.substituteType(type.returnType),
       namedParameters: type.namedParameters
           .map((named) => new NamedType(
-              named.name, substitution.substituteType(named.type)))
+              named.name, substitution.substituteType(named.type),
+              isRequired: named.isRequired))
           .toList(),
       typeParameters: newTypeParameters,
       requiredParameterCount: type.requiredParameterCount,
@@ -95,6 +96,10 @@
 
   Class get functionClass => coreTypes.functionClass;
 
+  Class get futureClass => coreTypes.futureClass;
+
+  Class get futureOrClass => coreTypes.futureOrClass;
+
   InterfaceType getLegacyLeastUpperBound(
       InterfaceType type1, InterfaceType type2) {
     return hierarchy.getLegacyLeastUpperBound(type1, type2);
@@ -161,7 +166,8 @@
     // to be inferred. It will optimistically assume these type parameters can
     // be subtypes (or supertypes) as necessary, and track the constraints that
     // are implied by this.
-    var gatherer = new TypeConstraintGatherer(this, typeParametersToInfer);
+    TypeConstraintGatherer gatherer =
+        new TypeConstraintGatherer(this, typeParametersToInfer);
 
     if (!isEmptyContext(returnContextType)) {
       if (isConst) {
@@ -223,7 +229,7 @@
     for (int i = 0; i < typeParametersToInfer.length; i++) {
       TypeParameter typeParam = typeParametersToInfer[i];
 
-      var typeParamBound = typeParam.bound;
+      DartType typeParamBound = typeParam.bound;
       DartType extendsConstraint;
       if (!hasOmittedBound(typeParam)) {
         extendsConstraint =
@@ -231,7 +237,7 @@
                 .substituteType(typeParamBound);
       }
 
-      var constraint = constraints[typeParam];
+      TypeConstraint constraint = constraints[typeParam];
       if (downwardsInferPhase) {
         inferredTypes[i] =
             _inferTypeParameterFromContext(constraint, extendsConstraint);
@@ -248,19 +254,19 @@
     }
 
     // Check the inferred types against all of the constraints.
-    var knownTypes = <TypeParameter, DartType>{};
+    Map<TypeParameter, DartType> knownTypes = <TypeParameter, DartType>{};
     for (int i = 0; i < typeParametersToInfer.length; i++) {
       TypeParameter typeParam = typeParametersToInfer[i];
-      var constraint = constraints[typeParam];
-      var typeParamBound =
+      TypeConstraint constraint = constraints[typeParam];
+      DartType typeParamBound =
           Substitution.fromPairs(typeParametersToInfer, inferredTypes)
               .substituteType(typeParam.bound);
 
-      var inferred = inferredTypes[i];
+      DartType inferred = inferredTypes[i];
       bool success = typeSatisfiesConstraint(inferred, constraint);
       if (success && !hasOmittedBound(typeParam)) {
         // If everything else succeeded, check the `extends` constraint.
-        var extendsConstraint = typeParamBound;
+        DartType extendsConstraint = typeParamBound;
         success = isSubtypeOf(inferred, extendsConstraint);
       }
 
diff --git a/pkg/front_end/lib/src/kernel_generator_impl.dart b/pkg/front_end/lib/src/kernel_generator_impl.dart
index cfdf775..8240c92 100644
--- a/pkg/front_end/lib/src/kernel_generator_impl.dart
+++ b/pkg/front_end/lib/src/kernel_generator_impl.dart
@@ -18,6 +18,8 @@
 
 import 'fasta/dill/dill_target.dart' show DillTarget;
 
+import 'fasta/fasta_codes.dart' show LocatedMessage;
+
 import 'fasta/kernel/kernel_target.dart' show KernelTarget;
 
 import 'fasta/kernel/utils.dart' show printComponentText, serializeComponent;
@@ -32,6 +34,8 @@
 
 import 'api_prototype/front_end.dart' show CompilerResult;
 
+import 'api_prototype/file_system.dart' show FileSystem;
+
 /// Implementation for the
 /// `package:front_end/src/api_prototype/kernel_generator.dart` and
 /// `package:front_end/src/api_prototype/summary_generator.dart` APIs.
@@ -58,14 +62,14 @@
     bool includeOffsets: true,
     bool retainDataForTesting: false,
     bool includeHierarchyAndCoreTypes: false}) async {
-  var options = CompilerContext.current.options;
-  var fs = options.fileSystem;
+  ProcessedOptions options = CompilerContext.current.options;
+  FileSystem fs = options.fileSystem;
 
   Loader sourceLoader;
   return withCrashReporting<CompilerResult>(() async {
     UriTranslator uriTranslator = await options.getUriTranslator();
 
-    var dillTarget =
+    DillTarget dillTarget =
         new DillTarget(options.ticker, uriTranslator, options.target);
 
     Set<Uri> externalLibs(Component component) {
@@ -75,12 +79,12 @@
           .toSet();
     }
 
-    var sdkSummary = await options.loadSdkSummary(null);
+    Component sdkSummary = await options.loadSdkSummary(null);
     // By using the nameRoot of the the summary, we enable sharing the
     // sdkSummary between multiple invocations.
     CanonicalName nameRoot = sdkSummary?.root ?? new CanonicalName.root();
     if (sdkSummary != null) {
-      var excluded = externalLibs(sdkSummary);
+      Set<Uri> excluded = externalLibs(sdkSummary);
       dillTarget.loader.appendLibraries(sdkSummary,
           filter: (uri) => !excluded.contains(uri));
     }
@@ -88,8 +92,8 @@
     // TODO(sigmund): provide better error reporting if input summaries or
     // linked dependencies were listed out of order (or provide mechanism to
     // sort them).
-    for (var inputSummary in await options.loadInputSummaries(nameRoot)) {
-      var excluded = externalLibs(inputSummary);
+    for (Component inputSummary in await options.loadInputSummaries(nameRoot)) {
+      Set<Uri> excluded = externalLibs(inputSummary);
       dillTarget.loader.appendLibraries(inputSummary,
           filter: (uri) => !excluded.contains(uri));
     }
@@ -102,15 +106,16 @@
 
     // Linked dependencies are meant to be part of the component so they are not
     // marked external.
-    for (var dependency in await options.loadLinkDependencies(nameRoot)) {
-      var excluded = externalLibs(dependency);
+    for (Component dependency in await options.loadLinkDependencies(nameRoot)) {
+      Set<Uri> excluded = externalLibs(dependency);
       dillTarget.loader.appendLibraries(dependency,
           filter: (uri) => !excluded.contains(uri));
     }
 
     await dillTarget.buildOutlines();
 
-    var kernelTarget = new KernelTarget(fs, false, dillTarget, uriTranslator);
+    KernelTarget kernelTarget =
+        new KernelTarget(fs, false, dillTarget, uriTranslator);
     sourceLoader = kernelTarget.loader;
     kernelTarget.setEntryPoints(options.inputs);
     Component summaryComponent =
@@ -118,7 +123,7 @@
     List<int> summary = null;
     if (buildSummary) {
       if (options.verify) {
-        for (var error in verifyComponent(summaryComponent)) {
+        for (LocatedMessage error in verifyComponent(summaryComponent)) {
           options.report(error, Severity.error);
         }
       }
@@ -132,7 +137,7 @@
       // Note: we don't pass the library argument to the constructor to
       // preserve the the libraries parent pointer (it should continue to point
       // to the component within KernelTarget).
-      var trimmedSummaryComponent =
+      Component trimmedSummaryComponent =
           new Component(nameRoot: summaryComponent.root)
             ..libraries.addAll(truncateSummary
                 ? kernelTarget.loader.libraries
diff --git a/pkg/front_end/lib/src/scanner/errors.dart b/pkg/front_end/lib/src/scanner/errors.dart
index ffd2d7f..2836434 100644
--- a/pkg/front_end/lib/src/scanner/errors.dart
+++ b/pkg/front_end/lib/src/scanner/errors.dart
@@ -113,7 +113,7 @@
     reportError(errorCode, charOffset, arguments);
   }
 
-  var errorCode = token.errorCode;
+  Code<dynamic> errorCode = token.errorCode;
   switch (errorCode.analyzerCodes?.first) {
     case "UNTERMINATED_STRING_LITERAL":
       // TODO(paulberry,ahe): Fasta reports the error location as the entire
diff --git a/pkg/front_end/lib/src/testing/compiler_common.dart b/pkg/front_end/lib/src/testing/compiler_common.dart
index a328e0e..58de336 100644
--- a/pkg/front_end/lib/src/testing/compiler_common.dart
+++ b/pkg/front_end/lib/src/testing/compiler_common.dart
@@ -92,9 +92,9 @@
 Future<Null> setup(CompilerOptions options, Map<String, dynamic> sources,
     {List<String> inputSummaries: const [],
     List<String> linkedDependencies: const []}) async {
-  var fs = new MemoryFileSystem(_defaultDir);
+  MemoryFileSystem fs = new MemoryFileSystem(_defaultDir);
   sources.forEach((name, data) {
-    var entity = fs.entityForUri(toTestUri(name));
+    MemoryFileSystemEntity entity = fs.entityForUri(toTestUri(name));
     if (data is String) {
       entity.writeAsStringSync(data);
     } else {
diff --git a/pkg/front_end/lib/src/testing/features.dart b/pkg/front_end/lib/src/testing/features.dart
index 7c6e5b8..4fd6391 100644
--- a/pkg/front_end/lib/src/testing/features.dart
+++ b/pkg/front_end/lib/src/testing/features.dart
@@ -256,8 +256,8 @@
                 "expected '$expectedValue', found '${actualValue}'");
           }
         } else if (expectedValue != actualValue) {
-          errorsFound.add(
-              "Mismatch for $key: expected '$expectedValue', found '${actualValue}'");
+          errorsFound.add("Mismatch for $key: expected '$expectedValue', "
+              "found '${actualValue}'");
         }
       });
       actualFeatures.forEach((String key, Object value) {
diff --git a/pkg/front_end/lib/src/testing/id_extractor.dart b/pkg/front_end/lib/src/testing/id_extractor.dart
index 9ea0e06..0afbb82 100644
--- a/pkg/front_end/lib/src/testing/id_extractor.dart
+++ b/pkg/front_end/lib/src/testing/id_extractor.dart
@@ -44,6 +44,11 @@
   /// If `null` is returned, [cls] has no associated data.
   T computeClassValue(Id id, Class cls) => null;
 
+  /// Implement this to compute the data corresponding to [extension].
+  ///
+  /// If `null` is returned, [extension] has no associated data.
+  T computeExtensionValue(Id id, Extension extension) => null;
+
   /// Implement this to compute the data corresponding to [member].
   ///
   /// If `null` is returned, [member] has no associated data.
@@ -71,6 +76,14 @@
         id, value, cls);
   }
 
+  void computeForExtension(Extension extension) {
+    ClassId id = new ClassId(extension.name);
+    T value = computeExtensionValue(id, extension);
+    TreeNode nodeWithOffset = computeTreeNodeWithOffset(extension);
+    registerValue(nodeWithOffset?.location?.file, nodeWithOffset?.fileOffset,
+        id, value, extension);
+  }
+
   void computeForMember(Member member) {
     MemberId id = computeMemberId(member);
     if (id == null) return;
@@ -154,8 +167,24 @@
   }
 
   @override
-  defaultMember(Member node) {
-    super.defaultMember(node);
+  visitProcedure(Procedure node) {
+    // Avoid visiting annotations.
+    node.function.accept(this);
+    computeForMember(node);
+  }
+
+  @override
+  visitConstructor(Constructor node) {
+    // Avoid visiting annotations.
+    visitList(node.initializers, this);
+    node.function.accept(this);
+    computeForMember(node);
+  }
+
+  @override
+  visitField(Field node) {
+    // Avoid visiting annotations.
+    node.initializer?.accept(this);
     computeForMember(node);
   }
 
@@ -200,7 +229,8 @@
       // Skip synthetic variables and function declaration variables.
       computeForNode(node, computeDefaultNodeId(node));
     }
-    super.visitVariableDeclaration(node);
+    // Avoid visiting annotations.
+    node.initializer?.accept(this);
   }
 
   @override
diff --git a/pkg/front_end/lib/src/testing/id_testing.dart b/pkg/front_end/lib/src/testing/id_testing.dart
index d8a777e..6aba9fb 100644
--- a/pkg/front_end/lib/src/testing/id_testing.dart
+++ b/pkg/front_end/lib/src/testing/id_testing.dart
@@ -189,17 +189,21 @@
 ///
 /// If [testLibDirectory] is not `null`, files in [testLibDirectory] with the
 /// [testFile] name as a prefix are included.
-TestData computeTestData(FileSystemEntity testFile, Directory testLibDirectory,
+TestData computeTestData(FileSystemEntity testFile,
     {Iterable<String> supportedMarkers,
-    Uri createUriForFileName(String fileName, {bool isLib}),
+    Uri createUriForFileName(String fileName),
     void onFailure(String message)}) {
-  Uri entryPoint = createUriForFileName('main.dart', isLib: false);
+  Uri entryPoint = createUriForFileName('main.dart');
 
+  String testName;
   File mainTestFile;
+  Uri testFileUri = testFile.uri;
   Map<String, File> additionalFiles;
   if (testFile is File) {
+    testName = testFileUri.pathSegments.last;
     mainTestFile = testFile;
   } else if (testFile is Directory) {
+    testName = testFileUri.pathSegments[testFileUri.pathSegments.length - 2];
     additionalFiles = new Map<String, File>();
     for (FileSystemEntity entry in testFile.listSync(recursive: true)) {
       if (entry is! File) continue;
@@ -228,55 +232,37 @@
     entryPoint.path: code[entryPoint].sourceCode
   };
 
-  List<String> libFileNames;
-
-  addSupportingFile(String libFileName, File libEntity, bool isLib) {
-    libFileNames ??= [];
-    libFileNames.add(libFileName);
-    Uri libFileUri = createUriForFileName(libFileName, isLib: isLib);
-    String libCode = libEntity.readAsStringSync();
-    AnnotatedCode annotatedLibCode =
-        new AnnotatedCode.fromText(libCode, commentStart, commentEnd);
-    memorySourceFiles[libFileUri.path] = annotatedLibCode.sourceCode;
-    code[libFileUri] = annotatedLibCode;
-    computeExpectedMap(libFileUri, libFileName, annotatedLibCode, expectedMaps,
-        onFailure: onFailure);
-  }
-
-  if (testLibDirectory != null) {
-    String name = testFile.uri.pathSegments.last;
-    String filePrefix = name.substring(0, name.lastIndexOf('.'));
-    for (FileSystemEntity libEntity in testLibDirectory.listSync()) {
-      String libFileName = libEntity.uri.pathSegments.last;
-      if (libFileName.startsWith(filePrefix)) {
-        addSupportingFile(libFileName, libEntity, true);
-      }
-    }
-  }
   if (additionalFiles != null) {
     for (MapEntry<String, File> additionalFileData in additionalFiles.entries) {
-      addSupportingFile(
-          additionalFileData.key, additionalFileData.value, false);
+      String libFileName = additionalFileData.key;
+      File libEntity = additionalFileData.value;
+      Uri libFileUri = createUriForFileName(libFileName);
+      String libCode = libEntity.readAsStringSync();
+      AnnotatedCode annotatedLibCode =
+          new AnnotatedCode.fromText(libCode, commentStart, commentEnd);
+      memorySourceFiles[libFileUri.path] = annotatedLibCode.sourceCode;
+      code[libFileUri] = annotatedLibCode;
+      computeExpectedMap(
+          libFileUri, libFileName, annotatedLibCode, expectedMaps,
+          onFailure: onFailure);
     }
   }
 
-  return new TestData(testFile.uri, entryPoint, memorySourceFiles, code,
-      expectedMaps, libFileNames);
+  return new TestData(
+      testName, testFileUri, entryPoint, memorySourceFiles, code, expectedMaps);
 }
 
 /// Data for an annotated test.
 class TestData {
+  final String name;
   final Uri testFileUri;
   final Uri entryPoint;
   final Map<String, String> memorySourceFiles;
   final Map<Uri, AnnotatedCode> code;
   final Map<String, MemberAnnotations<IdValue>> expectedMaps;
-  final List<String> libFileNames;
 
-  TestData(this.testFileUri, this.entryPoint, this.memorySourceFiles, this.code,
-      this.expectedMaps, this.libFileNames);
-
-  String get name => testFileUri.pathSegments.last;
+  TestData(this.name, this.testFileUri, this.entryPoint, this.memorySourceFiles,
+      this.code, this.expectedMaps);
 }
 
 /// The actual result computed for an annotated test.
@@ -594,24 +580,14 @@
 typedef Future<bool> RunTestFunction(TestData testData,
     {bool testAfterFailures, bool verbose, bool succinct, bool printCode});
 
-/// Check code for all test files int [data] using [computeFromAst] and
-/// [computeFromKernel] from the respective front ends. If [skipForKernel]
-/// contains the name of the test file it isn't tested for kernel.
-///
-/// [libDirectory] contains the directory for any supporting libraries that need
-/// to be loaded. We expect supporting libraries to have the same prefix as the
-/// original test in [dataDir]. So, for example, if testing `foo.dart` in
-/// [dataDir], then this function will consider any files named `foo.*\.dart`,
-/// such as `foo2.dart`, `foo_2.dart`, and `foo_blah_blah_blah.dart` in
-/// [libDirectory] to be supporting library files for `foo.dart`.
+/// Check code for all tests in [dataDir] using [runTest].
 Future runTests(Directory dataDir,
     {List<String> args: const <String>[],
-    Directory libDirectory: null,
     int shards: 1,
     int shardIndex: 0,
     void onTest(Uri uri),
     Iterable<String> supportedMarkers,
-    Uri createUriForFileName(String fileName, {bool isLib}),
+    Uri createUriForFileName(String fileName),
     void onFailure(String message),
     RunTestFunction runTest}) async {
   // TODO(johnniwinther): Support --show to show actual data for an input.
@@ -624,7 +600,7 @@
   bool continued = false;
   bool hasFailures = false;
 
-  var relativeDir = dataDir.uri.path.replaceAll(Uri.base.path, '');
+  String relativeDir = dataDir.uri.path.replaceAll(Uri.base.path, '');
   print('Data dir: ${relativeDir}');
   List<FileSystemEntity> entities = dataDir.listSync();
   if (shards > 1) {
@@ -635,6 +611,9 @@
   int testCount = 0;
   for (FileSystemEntity entity in entities) {
     String name = entity.uri.pathSegments.last;
+    if (entity is Directory) {
+      name = entity.uri.pathSegments[entity.uri.pathSegments.length - 2];
+    }
     if (args.isNotEmpty && !args.contains(name) && !continued) continue;
     if (shouldContinue) continued = true;
     testCount++;
@@ -644,18 +623,11 @@
     }
     print('----------------------------------------------------------------');
 
-    TestData testData = computeTestData(
-        entity, entity is File ? libDirectory : null,
+    TestData testData = computeTestData(entity,
         supportedMarkers: supportedMarkers,
         createUriForFileName: createUriForFileName,
         onFailure: onFailure);
-    print('Test file: ${testData.testFileUri}');
-    if (!succinct && testData.libFileNames != null) {
-      print('Supporting libraries:');
-      for (String libFileName in testData.libFileNames) {
-        print('    - libs/$libFileName');
-      }
-    }
+    print('Test: ${testData.testFileUri}');
 
     if (await runTest(testData,
         testAfterFailures: testAfterFailures,
diff --git a/pkg/front_end/lib/src/testing/id_testing_helper.dart b/pkg/front_end/lib/src/testing/id_testing_helper.dart
index de701d1..c6f7538 100644
--- a/pkg/front_end/lib/src/testing/id_testing_helper.dart
+++ b/pkg/front_end/lib/src/testing/id_testing_helper.dart
@@ -72,6 +72,13 @@
       Map<Id, ActualData<T>> actualMap,
       {bool verbose}) {}
 
+  /// Function that computes a data mapping for [extension].
+  ///
+  /// Fills [actualMap] with the data.
+  void computeExtensionData(InternalCompilerResult compilerResult,
+      Extension extension, Map<Id, ActualData<T>> actualMap,
+      {bool verbose}) {}
+
   /// Function that computes a data mapping for [library].
   ///
   /// Fills [actualMap] with the data.
@@ -130,6 +137,11 @@
       return offset;
     } else if (id is ClassId) {
       Library library = lookupLibrary(compilerResult.component, uri);
+      Extension extension =
+          lookupExtension(library, id.className, required: false);
+      if (extension != null) {
+        return extension.fileOffset;
+      }
       Class cls = lookupClass(library, id.className);
       return cls.fileOffset;
     }
@@ -164,7 +176,7 @@
 }
 
 /// Create the testing URI used for [fileName] in annotated tests.
-Uri createUriForFileName(String fileName, {bool isLib}) => toTestUri(fileName);
+Uri createUriForFileName(String fileName) => toTestUri(fileName);
 
 void onFailure(String message) => throw new StateError(message);
 
@@ -299,6 +311,11 @@
         verbose: verbose);
   }
 
+  void processExtension(Extension extension, Map<Id, ActualData<T>> actualMap) {
+    dataComputer.computeExtensionData(compilerResult, extension, actualMap,
+        verbose: verbose);
+  }
+
   bool excludeLibrary(Library library) {
     return forUserLibrariesOnly &&
         (library.importUri.scheme == 'dart' ||
@@ -321,6 +338,9 @@
     for (Member member in library.members) {
       processMember(member, actualMapFor(member));
     }
+    for (Extension extension in library.extensions) {
+      processExtension(extension, actualMapFor(extension));
+    }
   }
 
   List<Uri> globalLibraries = <Uri>[
diff --git a/pkg/front_end/lib/src/testing/id_testing_utils.dart b/pkg/front_end/lib/src/testing/id_testing_utils.dart
index 37fb3ac..83179c8 100644
--- a/pkg/front_end/lib/src/testing/id_testing_utils.dart
+++ b/pkg/front_end/lib/src/testing/id_testing_utils.dart
@@ -4,6 +4,7 @@
 
 import 'package:kernel/ast.dart';
 import '../fasta/builder/builder.dart';
+import '../fasta/builder/extension_builder.dart';
 import '../fasta/kernel/kernel_builder.dart';
 import '../fasta/messages.dart';
 import '../fasta/source/source_library_builder.dart';
@@ -39,7 +40,7 @@
   });
 }
 
-/// Finds the first [Class] in [component] with the given [className].
+/// Finds the first [Class] in [library] with the given [className].
 ///
 /// If [required] is `true` an error is thrown if no class was found.
 Class lookupClass(Library library, String className, {bool required: true}) {
@@ -52,6 +53,21 @@
   });
 }
 
+/// Finds the first [Extension] in [library] with the given [className].
+///
+/// If [required] is `true` an error is thrown if no class was found.
+Extension lookupExtension(Library library, String extensionName,
+    {bool required: true}) {
+  return library.extensions.firstWhere(
+      (Extension extension) => extension.name == extensionName, orElse: () {
+    if (required) {
+      throw new ArgumentError(
+          "Extension '$extensionName' not found in '$library'.");
+    }
+    return null;
+  });
+}
+
 /// Finds the first [Member] in [library] with the given canonical simple
 /// [memberName] as computed by [getMemberName].
 ///
@@ -105,6 +121,19 @@
   return clsBuilder;
 }
 
+ExtensionBuilder lookupExtensionBuilder(
+    InternalCompilerResult compilerResult, Extension extension,
+    {bool required: true}) {
+  TypeParameterScopeBuilder libraryBuilder = lookupLibraryDeclarationBuilder(
+      compilerResult, extension.enclosingLibrary,
+      required: required);
+  ExtensionBuilder extensionBuilder = libraryBuilder.members[extension.name];
+  if (extensionBuilder == null && required) {
+    throw new ArgumentError("ExtensionBuilder for $extension not found.");
+  }
+  return extensionBuilder;
+}
+
 /// Look up the [MemberBuilder] for [member] through the [ClassBuilder] for
 /// [cls] using [memberName] as its name.
 MemberBuilder lookupClassMemberBuilder(InternalCompilerResult compilerResult,
@@ -132,7 +161,23 @@
     InternalCompilerResult compilerResult, Member member,
     {bool required: true}) {
   MemberBuilder memberBuilder;
-  if (member.enclosingClass != null) {
+  if (member.isExtensionMember) {
+    String memberName = member.name.name;
+    String extensionName = memberName.substring(0, memberName.indexOf('|'));
+    memberName = memberName.substring(extensionName.length + 1);
+    bool isSetter = member is Procedure && member.isSetter;
+    if (memberName.startsWith('set#')) {
+      memberName = memberName.substring(4);
+      isSetter = true;
+    } else if (memberName.startsWith('get#')) {
+      memberName = memberName.substring(4);
+    }
+    Extension extension =
+        lookupExtension(member.enclosingLibrary, extensionName);
+    memberBuilder = lookupExtensionMemberBuilder(
+        compilerResult, extension, member, memberName,
+        isSetter: isSetter, required: required);
+  } else if (member.enclosingClass != null) {
     memberBuilder = lookupClassMemberBuilder(
         compilerResult, member.enclosingClass, member, member.name.name,
         required: required);
@@ -151,6 +196,31 @@
   return memberBuilder;
 }
 
+/// Look up the [MemberBuilder] for [member] through the [ClassBuilder] for
+/// [cls] using [memberName] as its name.
+MemberBuilder lookupExtensionMemberBuilder(
+    InternalCompilerResult compilerResult,
+    Extension extension,
+    Member member,
+    String memberName,
+    {bool isSetter: false,
+    bool required: true}) {
+  ExtensionBuilder extensionBuilder =
+      lookupExtensionBuilder(compilerResult, extension, required: required);
+  MemberBuilder memberBuilder;
+  if (extensionBuilder != null) {
+    if (isSetter) {
+      memberBuilder = extensionBuilder.scope.setters[memberName];
+    } else {
+      memberBuilder = extensionBuilder.scope.local[memberName];
+    }
+  }
+  if (memberBuilder == null && required) {
+    throw new ArgumentError("MemberBuilder for $member not found.");
+  }
+  return memberBuilder;
+}
+
 /// Returns a textual representation of the constant [node] to be used in
 /// testing.
 String constantToText(Constant node) {
@@ -445,3 +515,44 @@
 String errorsToText(List<FormattedMessage> errors) {
   return errors.map((m) => m.message).join(',');
 }
+
+/// Returns a textual representation of [descriptor] to be used in testing.
+String extensionMethodDescriptorToText(ExtensionMemberDescriptor descriptor) {
+  StringBuffer sb = new StringBuffer();
+  if (descriptor.isExternal) {
+    sb.write('external ');
+  }
+  if (descriptor.isStatic) {
+    sb.write('static ');
+  }
+  if (descriptor.kind == null) {
+    sb.write('field ');
+  } else {
+    switch (descriptor.kind) {
+      case ProcedureKind.Method:
+        break;
+      case ProcedureKind.Getter:
+        sb.write('getter ');
+        break;
+      case ProcedureKind.Setter:
+        sb.write('setter ');
+        break;
+      case ProcedureKind.Operator:
+        sb.write('operator ');
+        break;
+      case ProcedureKind.Factory:
+        throw new UnsupportedError(
+            "Unexpected procedure kind ${descriptor.kind}.");
+    }
+  }
+  sb.write(descriptor.name.name);
+  sb.write('=');
+  Member member = descriptor.member.asMember;
+  String name = member.name.name;
+  if (member is Procedure && member.isSetter) {
+    sb.write('$name=');
+  } else {
+    sb.write(name);
+  }
+  return sb.toString();
+}
diff --git a/pkg/front_end/lib/src/testing/package_root.dart b/pkg/front_end/lib/src/testing/package_root.dart
index 8905d4b..b586376 100644
--- a/pkg/front_end/lib/src/testing/package_root.dart
+++ b/pkg/front_end/lib/src/testing/package_root.dart
@@ -11,9 +11,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');
+  String pkgRootVar = const String.fromEnvironment('pkgRoot');
   if (pkgRootVar != null) {
-    var path = pathos.join(Directory.current.path, pkgRootVar);
+    String path = pathos.join(Directory.current.path, pkgRootVar);
     if (!path.endsWith(pathos.separator)) path += pathos.separator;
     return path;
   }
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index b4db9e7..4b3a96a 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -12,7 +12,7 @@
 # 3. Examples that produce the message (one of expression, statement,
 #    declaration, member, script, bytes or external). Note that 'external'
 #    should be the path to an external test. The external test will not be run,
-#    but the existance of the file will be verified.
+#    but the existence of the file will be verified.
 #
 # A message shouldn't indicate which kind of diagnostic it is, for example,
 # warning or error. Tools are expected to prepend "Warning: ", or "Error: ",
@@ -41,7 +41,7 @@
 # which will be used when generating code in Analyzer for translating
 # fasta error codes to Analyzer error codes.
 #
-# In some cases a mesage is internal to the frontend, and no meaningful
+# In some cases a message is internal to the frontend, and no meaningful
 # analyzer code can be provided. In such cases set `frontendInternal: true`.
 #
 # ## Parameter Substitution in Template and Tip
@@ -1522,7 +1522,7 @@
         Read the SDK platform from <file>, which should be in Dill/Kernel IR format
         and contain the Dart SDK.
 
-      --target=dart2js|dart2js_server|dart_runner|flutter|flutter_runner|none|vm
+      --target=dart2js|dart2js_server|dart_runner|dartdevc|flutter|flutter_runner|none|vm
         Specify the target configuration.
 
       --enable-asserts
diff --git a/pkg/front_end/pubspec.yaml b/pkg/front_end/pubspec.yaml
index 85f5f11..731b221 100644
--- a/pkg/front_end/pubspec.yaml
+++ b/pkg/front_end/pubspec.yaml
@@ -1,19 +1,19 @@
 name: front_end
 # Currently, front_end API is not stable and users should not
 # depend on semver semantics when depending on this package.
-version: 0.1.20
+version: 0.1.22
 author: Dart Team <misc@dartlang.org>
 description: Front end for compilation of Dart code.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/front_end
 environment:
   sdk: '>=2.2.2 <3.0.0'
 dependencies:
-  kernel: 0.3.20
+  kernel: 0.3.22
   package_config: '^1.0.1'
   path: '^1.3.9'
   yaml: '^2.1.12'
 dev_dependencies:
-  analyzer: 0.37.0
+  analyzer: 0.38.0
   args: '>=0.13.0 <2.0.0'
   build_integration:
     path: ../build_integration
diff --git a/pkg/front_end/test/extensions/data/explicit_this.dart b/pkg/front_end/test/extensions/data/explicit_this.dart
index 8540598..b684007 100644
--- a/pkg/front_end/test/extensions/data/explicit_this.dart
+++ b/pkg/front_end/test/extensions/data/explicit_this.dart
@@ -9,10 +9,13 @@
 
 /*class: A2:
  builder-name=A2,
- builder-onTypes=[A1],
- builder-supertype=Object,
- cls-name=A2,
- cls-supertype=Object
+ builder-onType=A1,
+ extension-members=[
+  method2=A2|method2,
+  method3=A2|method3,
+  method4=A2|method4],
+ extension-name=A2,
+ extension-onType=A1
 */
 extension A2 on A1 {
   /*member: A2|method2:
diff --git a/pkg/front_end/test/extensions/data/extension_on_type_variable.dart b/pkg/front_end/test/extensions/data/extension_on_type_variable.dart
index 17202c4..44f9af1 100644
--- a/pkg/front_end/test/extensions/data/extension_on_type_variable.dart
+++ b/pkg/front_end/test/extensions/data/extension_on_type_variable.dart
@@ -4,12 +4,12 @@
 
 /*class: GeneralGeneric:
  builder-name=GeneralGeneric,
- builder-onTypes=[T],
- builder-supertype=Object,
+ builder-onType=T,
  builder-type-params=[T],
- cls-name=GeneralGeneric,
- cls-supertype=Object,
- cls-type-params=[T]
+ extension-members=[method=GeneralGeneric|method],
+ extension-name=GeneralGeneric,
+ extension-onType=T,
+ extension-type-params=[T]
 */
 extension GeneralGeneric<T> on T {
   /*member: GeneralGeneric|method:
diff --git a/pkg/front_end/test/extensions/data/implicit_this.dart b/pkg/front_end/test/extensions/data/implicit_this.dart
index 5024529..9a9e7de 100644
--- a/pkg/front_end/test/extensions/data/implicit_this.dart
+++ b/pkg/front_end/test/extensions/data/implicit_this.dart
@@ -9,10 +9,13 @@
 
 /*class: A2:
  builder-name=A2,
- builder-onTypes=[A1],
- builder-supertype=Object,
- cls-name=A2,
- cls-supertype=Object
+ builder-onType=A1,
+ extension-members=[
+  method2=A2|method2,
+  method3=A2|method3,
+  method4=A2|method4],
+ extension-name=A2,
+ extension-onType=A1
 */
 extension A2 on A1 {
   /*member: A2|method2:
diff --git a/pkg/front_end/test/extensions/data/instance_members.dart b/pkg/front_end/test/extensions/data/instance_members.dart
index 258b2fe..35463d5 100644
--- a/pkg/front_end/test/extensions/data/instance_members.dart
+++ b/pkg/front_end/test/extensions/data/instance_members.dart
@@ -6,10 +6,14 @@
 
 /*class: A2:
  builder-name=A2,
- builder-onTypes=[A1],
- builder-supertype=Object,
- cls-name=A2,
- cls-supertype=Object
+ builder-onType=A1,
+ extension-members=[
+  method1=A2|method1,
+  method2=A2|method2,
+  method3=A2|method3,
+  method4=A2|method4],
+ extension-name=A2,
+ extension-onType=A1
 */
 extension A2 on A1 {
   /*member: A2|method1:
@@ -70,12 +74,14 @@
 
 /*class: B2:
  builder-name=B2,
- builder-onTypes=[B1<T>],
- builder-supertype=Object,
+ builder-onType=B1<T>,
  builder-type-params=[T],
- cls-name=B2,
- cls-supertype=Object,
- cls-type-params=[T]
+ extension-members=[
+  method1=B2|method1,
+  method2=B2|method2],
+ extension-name=B2,
+ extension-onType=B1<T>,
+ extension-type-params=[T]
 */
 extension B2<T> on B1<T> {
   /*member: B2|method1:
diff --git a/pkg/front_end/test/extensions/data/named_declarations.dart b/pkg/front_end/test/extensions/data/named_declarations.dart
index 5123f5d..c9e7c08 100644
--- a/pkg/front_end/test/extensions/data/named_declarations.dart
+++ b/pkg/front_end/test/extensions/data/named_declarations.dart
@@ -6,10 +6,9 @@
 
 /*class: A2:
  builder-name=A2,
- builder-onTypes=[A1],
- builder-supertype=Object,
- cls-name=A2,
- cls-supertype=Object
+ builder-onType=A1,
+ extension-name=A2,
+ extension-onType=A1
 */
 extension A2 on A1 {}
 
@@ -17,34 +16,28 @@
 
 /*class: B2:
  builder-name=B2,
- builder-onTypes=[B1<T>],
- builder-supertype=Object,
+ builder-onType=B1<T>,
  builder-type-params=[T],
- cls-name=B2,
- cls-supertype=Object,
- cls-type-params=[T]
+ extension-name=B2,
+ extension-onType=B1<T>,
+ extension-type-params=[T]
 */
 extension B2<T> on B1<T> {}
 
-// TODO(johnniwinther): Remove class type parameters.
 /*class: B3:
  builder-name=B3,
- builder-onTypes=[B1<A1>],
- builder-supertype=Object,
- cls-name=B3,
- cls-supertype=Object
+ builder-onType=B1<A1>,
+ extension-name=B3,
+ extension-onType=B1<A1>
 */
 extension B3 on B1<A1> {}
 
-// TODO(johnniwinther): Remove class type parameters.
 /*class: B4:
  builder-name=B4,
- builder-onTypes=[B1<T>],
- builder-supertype=Object,
+ builder-onType=B1<T>,
  builder-type-params=[T extends A1],
- cls-name=B4,
- cls-supertype=Object,
- cls-type-params=[T extends A1]
+ extension-name=B4,extension-onType=B1<T>,
+ extension-type-params=[T extends A1]
 */
 extension B4<T extends A1> on B1<T> {}
 
diff --git a/pkg/front_end/test/extensions/data/other_kinds.dart b/pkg/front_end/test/extensions/data/other_kinds.dart
new file mode 100644
index 0000000..72f4547
--- /dev/null
+++ b/pkg/front_end/test/extensions/data/other_kinds.dart
@@ -0,0 +1,85 @@
+// 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.
+
+class A1 {
+  int _instanceField;
+  int getInstanceField() => _instanceField;
+  void setInstanceField(int value) {
+    _instanceField = value;
+  }
+  static int _staticField = 0;
+  static int getStaticField() => _staticField;
+  static void setStaticField(int value) {
+    _staticField = value;
+  }
+}
+
+/*class: A2:
+ builder-name=A2,
+ builder-onType=A1,
+ extension-members=[
+  operator +=A2|+,
+  getter instanceProperty=A2|get#instanceProperty,
+  setter instanceProperty=A2|set#instanceProperty,
+  static field staticField=A2|staticField,
+  static getter staticProperty=A2|staticProperty,
+  static setter staticProperty=A2|staticProperty=],
+ extension-name=A2,
+ extension-onType=A1
+*/
+extension A2 on A1 {
+  /*member: A2|get#instanceProperty:
+   builder-name=instanceProperty,
+   builder-params=[#this],
+   member-name=A2|get#instanceProperty,
+   member-params=[#this]
+  */
+  int get instanceProperty => getInstanceField();
+
+  /*member: A2|set#instanceProperty:
+   builder-name=instanceProperty,
+   builder-params=[#this,value],
+   member-name=A2|set#instanceProperty,
+   member-params=[#this,value]
+  */
+  void set instanceProperty(int value) {
+    setInstanceField(value);
+  }
+
+  // TODO(johnniwinther): Test operator -() and operator -(val).
+
+  /*member: A2|+:
+   builder-name=+,
+   builder-params=[#this,value],
+   member-name=A2|+,
+   member-params=[#this,value]
+  */
+  int operator +(int value) {
+    return getInstanceField() + value;
+  }
+
+  /*member: A2|staticField:
+   builder-name=staticField,
+   member-name=A2|staticField
+  */
+  static int staticField = A1.getStaticField();
+
+  /*member: A2|staticProperty:
+   builder-name=staticProperty,
+   member-name=A2|staticProperty
+  */
+  static int get staticProperty => A1.getStaticField();
+
+  /*member: A2|staticProperty=:
+   builder-name=staticProperty,
+   builder-params=[value],
+   member-name=A2|staticProperty=,
+   member-params=[value]
+  */
+  static void set staticProperty(int value) {
+    A1.setStaticField(value);
+  }
+}
+
+main() {}
diff --git a/pkg/front_end/test/extensions/data/static_members.dart b/pkg/front_end/test/extensions/data/static_members.dart
index 6247a80..aeda9d9 100644
--- a/pkg/front_end/test/extensions/data/static_members.dart
+++ b/pkg/front_end/test/extensions/data/static_members.dart
@@ -6,10 +6,11 @@
 
 /*class: A2:
  builder-name=A2,
- builder-onTypes=[A1],
- builder-supertype=Object,
- cls-name=A2,
- cls-supertype=Object
+ builder-onType=A1,
+ extension-members=[
+  static method1=A2|method1,
+  static method2=A2|method2],
+ extension-name=A2,extension-onType=A1
 */
 extension A2 on A1 {
   /*member: A2|method1:
@@ -35,12 +36,14 @@
 
 /*class: B2:
  builder-name=B2,
- builder-onTypes=[B1<T>],
- builder-supertype=Object,
+ builder-onType=B1<T>,
  builder-type-params=[T],
- cls-name=B2,
- cls-supertype=Object,
- cls-type-params=[T]
+ extension-members=[
+  static method1=B2|method1,
+  static method2=B2|method2],
+ extension-name=B2,
+ extension-onType=B1<T>,
+ extension-type-params=[T]
 */
 extension B2<T> on B1<T> {
   /*member: B2|method1:
diff --git a/pkg/front_end/test/extensions/data/super.dart b/pkg/front_end/test/extensions/data/super.dart
index 3f87ee3..21bd03a 100644
--- a/pkg/front_end/test/extensions/data/super.dart
+++ b/pkg/front_end/test/extensions/data/super.dart
@@ -8,10 +8,10 @@
 
 /*class: A2:
  builder-name=A2,
- builder-onTypes=[A1],
- builder-supertype=Object,
- cls-name=A2,
- cls-supertype=Object
+ builder-onType=A1,
+ extension-members=[method2=A2|method2],
+ extension-name=A2,
+ extension-onType=A1
 */
 extension A2 on A1 {
   /*member: A2|method2:
diff --git a/pkg/front_end/test/extensions/data/type_variables.dart b/pkg/front_end/test/extensions/data/type_variables.dart
index 320f51a..9283d71 100644
--- a/pkg/front_end/test/extensions/data/type_variables.dart
+++ b/pkg/front_end/test/extensions/data/type_variables.dart
@@ -6,12 +6,14 @@
 
 /*class: A2:
  builder-name=A2,
- builder-onTypes=[A1<T>],
- builder-supertype=Object,
+ builder-onType=A1<T>,
  builder-type-params=[T],
- cls-name=A2,
- cls-supertype=Object,
- cls-type-params=[T]
+ extension-members=[
+  method1=A2|method1,
+  method2=A2|method2],
+ extension-name=A2,
+ extension-onType=A1<T>,
+ extension-type-params=[T]
 */
 extension A2<T> on A1<T> {
   /*member: A2|method1:
diff --git a/pkg/front_end/test/extensions/data/unnamed_declarations.dart b/pkg/front_end/test/extensions/data/unnamed_declarations.dart
index 0123988..d36cf3d 100644
--- a/pkg/front_end/test/extensions/data/unnamed_declarations.dart
+++ b/pkg/front_end/test/extensions/data/unnamed_declarations.dart
@@ -6,10 +6,10 @@
 
 /*class: extension#0:
  builder-name=extension#0,
- builder-onTypes=[A1],
- builder-supertype=Object,
- cls-name=extension#0,
- cls-supertype=Object
+ builder-onType=A1,
+ extension-members=[method=extension#0|method],
+ extension-name=extension#0,
+ extension-onType=A1
 */
 extension on A1 {
   /*member: extension#0|method:
@@ -23,10 +23,10 @@
 
 /*class: extension#1:
  builder-name=extension#1,
- builder-onTypes=[A1],
- builder-supertype=Object,
- cls-name=extension#1,
- cls-supertype=Object
+ builder-onType=A1,
+ extension-members=[method=extension#1|method],
+ extension-name=extension#1,
+ extension-onType=A1
 */
 extension on A1 {
   /*member: extension#1|method:
@@ -42,12 +42,12 @@
 
 /*class: extension#2:
  builder-name=extension#2,
- builder-onTypes=[B1<T>],
- builder-supertype=Object,
+ builder-onType=B1<T>,
  builder-type-params=[T],
- cls-name=extension#2,
- cls-supertype=Object,
- cls-type-params=[T]
+ extension-members=[method=extension#2|method],
+ extension-name=extension#2,
+ extension-onType=B1<T>,
+ extension-type-params=[T]
 */
 extension <T> on B1<T> {
   /*member: extension#2|method:
@@ -61,13 +61,12 @@
   method() {}
 }
 
-// TODO(johnniwinther): Remove class type parameters.
 /*class: extension#3:
  builder-name=extension#3,
- builder-onTypes=[B1<A1>],
- builder-supertype=Object,
- cls-name=extension#3,
- cls-supertype=Object
+ builder-onType=B1<A1>,
+ extension-members=[method=extension#3|method],
+ extension-name=extension#3,
+ extension-onType=B1<A1>
 */
 extension on B1<A1> {
   /*member: extension#3|method:
@@ -79,15 +78,14 @@
   method() {}
 }
 
-// TODO(johnniwinther): Remove class type parameters.
 /*class: extension#4:
  builder-name=extension#4,
- builder-onTypes=[B1<T>],
- builder-supertype=Object,
+ builder-onType=B1<T>,
  builder-type-params=[T extends A1],
- cls-name=extension#4,
- cls-supertype=Object,
- cls-type-params=[T extends A1]
+ extension-members=[method=extension#4|method],
+ extension-name=extension#4,
+ extension-onType=B1<T>,
+ extension-type-params=[T extends A1]
 */
 extension <T extends A1> on B1<T> {
   /*member: extension#4|method:
diff --git a/pkg/front_end/test/extensions/data/use_as_type.dart b/pkg/front_end/test/extensions/data/use_as_type.dart
index 64c0297..f9e9b1d 100644
--- a/pkg/front_end/test/extensions/data/use_as_type.dart
+++ b/pkg/front_end/test/extensions/data/use_as_type.dart
@@ -6,24 +6,22 @@
 
 /*class: A2:
  builder-name=A2,
- builder-onTypes=[A1],
- builder-supertype=Object,
- cls-name=A2,
- cls-supertype=Object
- */
+ builder-onType=A1,
+ extension-name=A2,
+ extension-onType=A1
+*/
 extension A2 on A1 {}
 
 class B1<T> {}
 
 /*class: B2:
  builder-name=B2,
- builder-onTypes=[B1<T>],
- builder-supertype=Object,
+ builder-onType=B1<T>,
  builder-type-params=[T],
- cls-name=B2,
- cls-supertype=Object,
- cls-type-params=[T]
- */
+ extension-name=B2,
+ extension-onType=B1<T>,
+ extension-type-params=[T]
+*/
 extension B2<T> on B1<T> {}
 
 main() {
diff --git a/pkg/front_end/test/extensions/extensions_test.dart b/pkg/front_end/test/extensions/extensions_test.dart
index 5303f23..298ec22 100644
--- a/pkg/front_end/test/extensions/extensions_test.dart
+++ b/pkg/front_end/test/extensions/extensions_test.dart
@@ -4,6 +4,7 @@
 
 import 'dart:io' show Directory, Platform;
 import 'package:front_end/src/fasta/builder/builder.dart';
+import 'package:front_end/src/fasta/builder/extension_builder.dart';
 import 'package:front_end/src/fasta/kernel/kernel_builder.dart';
 import 'package:front_end/src/testing/id.dart' show ActualData, Id;
 import 'package:front_end/src/testing/features.dart';
@@ -43,6 +44,14 @@
   }
 
   @override
+  void computeExtensionData(InternalCompilerResult compilerResult,
+      Extension extension, Map<Id, ActualData<Features>> actualMap,
+      {bool verbose}) {
+    new ExtensionsDataExtractor(compilerResult, actualMap)
+        .computeForExtension(extension);
+  }
+
+  @override
   bool get supportsErrors => true;
 
   @override
@@ -71,6 +80,7 @@
   static const String builderSupertype = 'builder-supertype';
   static const String builderInterfaces = 'builder-interfaces';
   static const String builderOnTypes = 'builder-onTypes';
+  static const String builderOnType = 'builder-onType';
   static const String builderRequiredParameters = 'builder-params';
   static const String builderPositionalParameters = 'builder-pos-params';
   static const String builderNamedParameters = 'builder-named-params';
@@ -80,6 +90,11 @@
   static const String clsSupertype = 'cls-supertype';
   static const String clsInterfaces = 'cls-interfaces';
 
+  static const String extensionName = 'extension-name';
+  static const String extensionTypeParameters = 'extension-type-params';
+  static const String extensionOnType = 'extension-onType';
+  static const String extensionMembers = 'extension-members';
+
   static const String memberName = 'member-name';
   static const String memberTypeParameters = 'member-type-params';
   static const String memberRequiredParameters = 'member-params';
@@ -136,16 +151,47 @@
   }
 
   @override
-  Features computeMemberValue(Id id, Member member) {
-    if (!(member is Procedure && member.isExtensionMethod)) {
+  Features computeExtensionValue(Id id, Extension extension) {
+    ExtensionBuilder extensionBuilder =
+        lookupExtensionBuilder(compilerResult, extension);
+    if (!extensionBuilder.isExtension) {
       return null;
     }
-    String memberName = member.name.name;
-    String extensionName = memberName.substring(0, memberName.indexOf('|'));
-    memberName = memberName.substring(extensionName.length + 1);
-    Class cls = lookupClass(member.enclosingLibrary, extensionName);
-    MemberBuilder memberBuilder =
-        lookupClassMemberBuilder(compilerResult, cls, member, memberName);
+    Features features = new Features();
+    features[Tags.builderName] = extensionBuilder.name;
+    if (extensionBuilder.typeParameters != null) {
+      for (TypeVariableBuilder typeVariable
+          in extensionBuilder.typeParameters) {
+        features.addElement(Tags.builderTypeParameters,
+            typeVariableBuilderToText(typeVariable));
+      }
+    }
+    if (extensionBuilder.onType != null) {
+      features[Tags.builderOnType] = typeBuilderToText(extensionBuilder.onType);
+    }
+
+    features[Tags.extensionName] = extension.name;
+    if (extension.onType != null) {
+      features[Tags.extensionOnType] = typeToText(extension.onType);
+    }
+    for (TypeParameter typeParameter in extension.typeParameters) {
+      features.addElement(
+          Tags.extensionTypeParameters, typeParameterToText(typeParameter));
+    }
+    for (ExtensionMemberDescriptor descriptor in extension.members) {
+      features.addElement(
+          Tags.extensionMembers, extensionMethodDescriptorToText(descriptor));
+    }
+    return features;
+  }
+
+  @override
+  Features computeMemberValue(Id id, Member member) {
+    if (!member.isExtensionMember) {
+      return null;
+    }
+
+    MemberBuilder memberBuilder = lookupMemberBuilder(compilerResult, member);
     Features features = new Features();
     features[Tags.builderName] = memberBuilder.name;
     if (memberBuilder is FunctionBuilder) {
diff --git a/pkg/front_end/test/fasta/expression_test.dart b/pkg/front_end/test/fasta/expression_test.dart
index 82332e1..40ccfb4 100644
--- a/pkg/front_end/test/fasta/expression_test.dart
+++ b/pkg/front_end/test/fasta/expression_test.dart
@@ -203,9 +203,9 @@
         if (primary != secondary) {
           return fail(
               null,
-              "Multiple expectations don't match on $test:" +
-                  "\nFirst expectation:\n$actual\n" +
-                  "\nSecond expectation:\n$secondary\n");
+              "Multiple expectations don't match on $test:"
+              "\nFirst expectation:\n$actual\n"
+              "\nSecond expectation:\n$secondary\n");
         }
       }
     }
diff --git a/pkg/front_end/test/fasta/flow_analysis/flow_analysis_test.dart b/pkg/front_end/test/fasta/flow_analysis/flow_analysis_test.dart
index 7e8cd27..09d5720 100644
--- a/pkg/front_end/test/fasta/flow_analysis/flow_analysis_test.dart
+++ b/pkg/front_end/test/fasta/flow_analysis/flow_analysis_test.dart
@@ -7,6 +7,87 @@
 
 main() {
   group('API', () {
+    test('conditional_thenBegin promotes true branch', () {
+      var h = _Harness();
+      var x = h.addAssignedVar('x', 'int?');
+      h.flow.conditional_thenBegin(h.notNull(x)());
+      expect(h.flow.promotedType(x).type, 'int');
+      h.flow.conditional_elseBegin(_Expression());
+      expect(h.flow.promotedType(x), isNull);
+      h.flow.conditional_end(_Expression(), _Expression());
+      expect(h.flow.promotedType(x), isNull);
+      h.flow.finish();
+    });
+
+    test('conditional_elseBegin promotes false branch', () {
+      var h = _Harness();
+      var x = h.addAssignedVar('x', 'int?');
+      h.flow.conditional_thenBegin(h.eqNull(x)());
+      expect(h.flow.promotedType(x), isNull);
+      h.flow.conditional_elseBegin(_Expression());
+      expect(h.flow.promotedType(x).type, 'int');
+      h.flow.conditional_end(_Expression(), _Expression());
+      expect(h.flow.promotedType(x), isNull);
+      h.flow.finish();
+    });
+
+    test('conditional_end keeps promotions common to true and false branches',
+        () {
+      var h = _Harness();
+      var x = h.addAssignedVar('x', 'int?');
+      var y = h.addAssignedVar('x', 'int?');
+      var z = h.addAssignedVar('x', 'int?');
+      h.flow.conditional_thenBegin(_Expression());
+      h.promote(x, 'int');
+      h.promote(y, 'int');
+      h.flow.conditional_elseBegin(_Expression());
+      h.promote(x, 'int');
+      h.promote(z, 'int');
+      h.flow.conditional_end(_Expression(), _Expression());
+      expect(h.flow.promotedType(x).type, 'int');
+      expect(h.flow.promotedType(y), isNull);
+      expect(h.flow.promotedType(z), isNull);
+      h.flow.finish();
+    });
+
+    test('conditional joins true states', () {
+      // if (... ? (x != null && y != null) : (x != null && z != null)) {
+      //   promotes x, but not y or z
+      // }
+      var h = _Harness();
+      var x = h.addAssignedVar('x', 'int?');
+      var y = h.addAssignedVar('y', 'int?');
+      var z = h.addAssignedVar('z', 'int?');
+      h.if_(
+          h.conditional(h.expr, h.and(h.notNull(x), h.notNull(y)),
+              h.and(h.notNull(x), h.notNull(z))), () {
+        expect(h.flow.promotedType(x).type, 'int');
+        expect(h.flow.promotedType(y), isNull);
+        expect(h.flow.promotedType(z), isNull);
+      });
+      h.flow.finish();
+    });
+
+    test('conditional joins false states', () {
+      // if (... ? (x == null || y == null) : (x == null || z == null)) {
+      // } else {
+      //   promotes x, but not y or z
+      // }
+      var h = _Harness();
+      var x = h.addAssignedVar('x', 'int?');
+      var y = h.addAssignedVar('y', 'int?');
+      var z = h.addAssignedVar('z', 'int?');
+      h.ifElse(
+          h.conditional(h.expr, h.or(h.eqNull(x), h.eqNull(y)),
+              h.or(h.eqNull(x), h.eqNull(z))),
+          () {}, () {
+        expect(h.flow.promotedType(x).type, 'int');
+        expect(h.flow.promotedType(y), isNull);
+        expect(h.flow.promotedType(z), isNull);
+      });
+      h.flow.finish();
+    });
+
     test('conditionEqNull(notEqual: true) promotes true branch', () {
       var h = _Harness();
       var x = h.addAssignedVar('x', 'int?');
@@ -33,6 +114,47 @@
       h.flow.finish();
     });
 
+    test('doStatement_bodyBegin() un-promotes', () {
+      var h = _Harness();
+      var x = h.addAssignedVar('x', 'int?');
+      h.promote(x, 'int');
+      expect(h.flow.promotedType(x).type, 'int');
+      h.flow.doStatement_bodyBegin(_Statement(), {x});
+      expect(h.flow.promotedType(x), isNull);
+      h.flow.doStatement_conditionBegin();
+      h.flow.doStatement_end(_Expression());
+      h.flow.finish();
+    });
+
+    test('doStatement_conditionBegin() joins continue state', () {
+      var h = _Harness();
+      var x = h.addAssignedVar('x', 'int?');
+      var stmt = _Statement();
+      h.flow.doStatement_bodyBegin(stmt, {});
+      h.if_(h.notNull(x), () {
+        h.flow.handleContinue(stmt);
+      });
+      h.flow.handleExit();
+      expect(h.flow.isReachable, false);
+      expect(h.flow.promotedType(x), isNull);
+      h.flow.doStatement_conditionBegin();
+      expect(h.flow.isReachable, true);
+      expect(h.flow.promotedType(x).type, 'int');
+      h.flow.doStatement_end(_Expression());
+      h.flow.finish();
+    });
+
+    test('doStatement_end() promotes', () {
+      var h = _Harness();
+      var x = h.addAssignedVar('x', 'int?');
+      h.flow.doStatement_bodyBegin(_Statement(), {});
+      h.flow.doStatement_conditionBegin();
+      expect(h.flow.promotedType(x), isNull);
+      h.flow.doStatement_end(h.eqNull(x)());
+      expect(h.flow.promotedType(x).type, 'int');
+      h.flow.finish();
+    });
+
     test('finish checks proper nesting', () {
       var h = _Harness();
       var expr = _Expression();
@@ -50,15 +172,85 @@
     test('ifStatement_end(false) keeps else branch if then branch exits', () {
       var h = _Harness();
       var x = h.addAssignedVar('x', 'int?');
-      var expr = _Expression();
-      h.flow.conditionEqNull(expr, x);
-      h.flow.ifStatement_thenBegin(expr);
+      h.flow.ifStatement_thenBegin(h.eqNull(x)());
       h.flow.handleExit();
       h.flow.ifStatement_end(false);
       expect(h.flow.promotedType(x).type, 'int');
       h.flow.finish();
     });
 
+    test('logicalBinaryOp_rightBegin(isAnd: true) promotes in RHS', () {
+      var h = _Harness();
+      var x = h.addAssignedVar('x', 'int?');
+      h.flow.logicalBinaryOp_rightBegin(h.notNull(x)(), isAnd: true);
+      expect(h.flow.promotedType(x).type, 'int');
+      h.flow.logicalBinaryOp_end(_Expression(), _Expression(), isAnd: true);
+      h.flow.finish();
+    });
+
+    test('logicalBinaryOp_rightEnd(isAnd: true) keeps promotions from RHS', () {
+      var h = _Harness();
+      var x = h.addAssignedVar('x', 'int?');
+      h.flow.logicalBinaryOp_rightBegin(_Expression(), isAnd: true);
+      var wholeExpr = _Expression();
+      h.flow.logicalBinaryOp_end(wholeExpr, h.notNull(x)(), isAnd: true);
+      h.flow.ifStatement_thenBegin(wholeExpr);
+      expect(h.flow.promotedType(x).type, 'int');
+      h.flow.ifStatement_end(false);
+      h.flow.finish();
+    });
+
+    test('logicalBinaryOp_rightEnd(isAnd: false) keeps promotions from RHS',
+        () {
+      var h = _Harness();
+      var x = h.addAssignedVar('x', 'int?');
+      h.flow.logicalBinaryOp_rightBegin(_Expression(), isAnd: false);
+      var wholeExpr = _Expression();
+      h.flow.logicalBinaryOp_end(wholeExpr, h.eqNull(x)(), isAnd: false);
+      h.flow.ifStatement_thenBegin(wholeExpr);
+      h.flow.ifStatement_elseBegin();
+      expect(h.flow.promotedType(x).type, 'int');
+      h.flow.ifStatement_end(true);
+      h.flow.finish();
+    });
+
+    test('logicalBinaryOp_rightBegin(isAnd: false) promotes in RHS', () {
+      var h = _Harness();
+      var x = h.addAssignedVar('x', 'int?');
+      h.flow.logicalBinaryOp_rightBegin(h.eqNull(x)(), isAnd: false);
+      expect(h.flow.promotedType(x).type, 'int');
+      h.flow.logicalBinaryOp_end(_Expression(), _Expression(), isAnd: false);
+      h.flow.finish();
+    });
+
+    test('logicalBinaryOp(isAnd: true) joins promotions', () {
+      // if (x != null && y != null) {
+      //   promotes x and y
+      // }
+      var h = _Harness();
+      var x = h.addAssignedVar('x', 'int?');
+      var y = h.addAssignedVar('y', 'int?');
+      h.if_(h.and(h.notNull(x), h.notNull(y)), () {
+        expect(h.flow.promotedType(x).type, 'int');
+        expect(h.flow.promotedType(y).type, 'int');
+      });
+      h.flow.finish();
+    });
+
+    test('logicalBinaryOp(isAnd: false) joins promotions', () {
+      // if (x == null || y == null) {} else {
+      //   promotes x and y
+      // }
+      var h = _Harness();
+      var x = h.addAssignedVar('x', 'int?');
+      var y = h.addAssignedVar('y', 'int?');
+      h.ifElse(h.or(h.eqNull(x), h.eqNull(y)), () {}, () {
+        expect(h.flow.promotedType(x).type, 'int');
+        expect(h.flow.promotedType(y).type, 'int');
+      });
+      h.flow.finish();
+    });
+
     test('Infinite loop does not implicitly assign variables', () {
       var h = _Harness();
       var x = h.addUnassignedVar('x', 'int');
@@ -70,21 +262,10 @@
       expect(h.flow.isAssigned(x), false);
     });
 
-    void _promote(_Harness h, _Var variable, String type) {
-      // if (variable is! type) {
-      var isExpression = _Expression();
-      h.flow.isExpression_end(isExpression, variable, true, _Type(type));
-      h.flow.ifStatement_thenBegin(isExpression);
-      //   return;
-      h.flow.handleExit();
-      // }
-      h.flow.ifStatement_end(false);
-    }
-
     test('If(false) does not discard promotions', () {
       var h = _Harness();
       var x = h.addAssignedVar('x', 'Object');
-      _promote(h, x, 'int');
+      h.promote(x, 'int');
       expect(h.flow.promotedType(x).type, 'int');
       // if (false) {
       var falseExpression = _Expression();
@@ -506,6 +687,16 @@
   return matcher;
 }
 
+/// Representation of an expression to be visited by the test harness.  Calling
+/// the function causes the expression to be "visited" (in other words, the
+/// appropriate methods in [FlowAnalysis] are called in the appropriate order),
+/// and the [_Expression] object representing the whole expression is returned.
+///
+/// This is used by methods in [_Harness] as a lightweight way of building up
+/// complex sequences of calls to [FlowAnalysis] that represent large
+/// expressions.
+typedef _Expression LazyExpression();
+
 class _Expression {}
 
 class _Harness
@@ -519,6 +710,10 @@
     flow = FlowAnalysis<_Statement, _Expression, _Var, _Type>(this, this, this);
   }
 
+  /// Returns a [LazyExpression] representing an expression with now special
+  /// flow analysis semantics.
+  LazyExpression get expr => () => _Expression();
+
   _Var addAssignedVar(String name, String type) {
     var v = _Var(name, _Type(type));
     flow.add(v, assigned: true);
@@ -531,12 +726,72 @@
     return v;
   }
 
+  /// Given two [LazyExpression]s, produces a new [LazyExpression] representing
+  /// the result of combining them with `&&`.
+  LazyExpression and(LazyExpression lhs, LazyExpression rhs) {
+    return () {
+      var expr = _Expression();
+      flow.logicalBinaryOp_rightBegin(lhs(), isAnd: true);
+      flow.logicalBinaryOp_end(expr, rhs(), isAnd: true);
+      return expr;
+    };
+  }
+
+  /// Given three [LazyExpression]s, produces a new [LazyExpression]
+  /// representing the result of combining them with `?` and `:`.
+  LazyExpression conditional(
+      LazyExpression cond, LazyExpression ifTrue, LazyExpression ifFalse) {
+    return () {
+      var expr = _Expression();
+      flow.conditional_thenBegin(cond());
+      flow.conditional_elseBegin(ifTrue());
+      flow.conditional_end(expr, ifFalse());
+      return expr;
+    };
+  }
+
+  /// Creates a [LazyExpression] representing an `== null` check performed on
+  /// [variable].
+  LazyExpression eqNull(_Var variable) {
+    return () {
+      var expr = _Expression();
+      flow.conditionEqNull(expr, variable, notEqual: false);
+      return expr;
+    };
+  }
+
+  /// Invokes flow analysis of an `if` statement with no `else` part.
+  void if_(LazyExpression cond, void ifTrue()) {
+    flow.ifStatement_thenBegin(cond());
+    ifTrue();
+    flow.ifStatement_end(false);
+  }
+
+  /// Invokes flow analysis of an `if` statement with an `else` part.
+  void ifElse(LazyExpression cond, void ifTrue(), void ifFalse()) {
+    flow.ifStatement_thenBegin(cond());
+    ifTrue();
+    flow.ifStatement_elseBegin();
+    ifFalse();
+    flow.ifStatement_end(false);
+  }
+
   @override
   bool isLocalVariable(_Var variable) {
     // TODO(paulberry): make tests where this returns false
     return true;
   }
 
+  /// Creates a [LazyExpression] representing an `is!` check, checking whether
+  /// [variable] has the given [type].
+  LazyExpression isNotType(_Var variable, String type) {
+    return () {
+      var expr = _Expression();
+      flow.isExpression_end(expr, variable, true, _Type(type));
+      return expr;
+    };
+  }
+
   @override
   bool isPotentiallyMutatedInClosure(_Var variable) {
     // TODO(paulberry): make tests where this returns true
@@ -573,6 +828,32 @@
     return _subtypes[query] ?? fail('Unknown subtype query: $query');
   }
 
+  /// Creates a [LazyExpression] representing a `!= null` check performed on
+  /// [variable].
+  LazyExpression notNull(_Var variable) {
+    return () {
+      var expr = _Expression();
+      flow.conditionEqNull(expr, variable, notEqual: true);
+      return expr;
+    };
+  }
+
+  /// Given two [LazyExpression]s, produces a new [LazyExpression] representing
+  /// the result of combining them with `||`.
+  LazyExpression or(LazyExpression lhs, LazyExpression rhs) {
+    return () {
+      var expr = _Expression();
+      flow.logicalBinaryOp_rightBegin(lhs(), isAnd: false);
+      flow.logicalBinaryOp_end(expr, rhs(), isAnd: false);
+      return expr;
+    };
+  }
+
+  /// Causes [variable] to be promoted to [type].
+  void promote(_Var variable, String type) {
+    if_(isNotType(variable, type), flow.handleExit);
+  }
+
   @override
   _Type promoteToNonNull(_Type type) {
     if (type.type.endsWith('?')) {
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 9c0ac9b..f130cba 100644
--- a/pkg/front_end/test/fasta/generator_to_string_test.dart
+++ b/pkg/front_end/test/fasta/generator_to_string_test.dart
@@ -96,8 +96,8 @@
         new TypeParameter("T"), libraryBuilder);
     VariableDeclaration variable = new VariableDeclaration(null);
 
-    BodyBuilder helper = new BodyBuilder(libraryBuilder, null, null, null, null,
-        null, null, false, null, uri, null);
+    BodyBuilder helper = new BodyBuilder(
+        library: libraryBuilder, isDeclarationInstanceMember: false, uri: uri);
 
     Generator generator = new ThisAccessGenerator(helper, token, false, false);
 
diff --git a/pkg/front_end/test/fasta/messages_test.dart b/pkg/front_end/test/fasta/messages_test.dart
index a72f44a..e2f30c9 100644
--- a/pkg/front_end/test/fasta/messages_test.dart
+++ b/pkg/front_end/test/fasta/messages_test.dart
@@ -10,6 +10,8 @@
 
 import "dart:typed_data" show Uint8List;
 
+import 'package:kernel/ast.dart' show Location, Source;
+
 import "package:kernel/target/targets.dart" show TargetFlags;
 
 import "package:testing/testing.dart"
@@ -31,6 +33,9 @@
 import 'package:front_end/src/compute_platform_binaries_location.dart'
     show computePlatformBinariesLocation;
 
+import 'package:front_end/src/fasta/command_line_reporting.dart'
+    as command_line_reporting;
+
 import 'package:front_end/src/fasta/severity.dart'
     show Severity, severityEnumValues;
 
@@ -70,7 +75,9 @@
 
   final BatchCompiler compiler;
 
-  MessageTestSuite()
+  final bool fastOnly;
+
+  MessageTestSuite(this.fastOnly)
       : fileSystem = new MemoryFileSystem(Uri.parse("org-dartlang-fasta:///")),
         compiler = new BatchCompiler(null);
 
@@ -82,7 +89,8 @@
   Stream<MessageTestDescription> list(Chain suite) async* {
     Uri uri = suite.uri.resolve("messages.yaml");
     File file = new File.fromUri(uri);
-    YamlMap messages = loadYamlNode(await file.readAsString(), sourceUrl: uri);
+    String fileContent = file.readAsStringSync();
+    YamlMap messages = loadYamlNode(fileContent, sourceUrl: uri);
     for (String name in messages.keys) {
       YamlNode messageNode = messages.nodes[name];
       var message = messageNode.value;
@@ -96,28 +104,76 @@
       Severity severity;
       YamlNode badSeverity;
       YamlNode unnecessarySeverity;
-      YamlNode misspelledTemplate;
-      Set<String> misspelledTemplateWords;
-      YamlNode misspelledTip;
-      Set<String> misspelledTipWords;
+      List<String> spellingMessages;
+      const String spellingPostMessage = "\nIf the word(s) look okay, update "
+          "'spell_checking_list_messages.txt' or "
+          "'spell_checking_list_common.txt'.";
+
+      Source source;
+      List<String> formatSpellingMistakes(
+          spell.SpellingResult spellResult, int offset, String message) {
+        if (source == null) {
+          List<int> bytes = file.readAsBytesSync();
+          List<int> lineStarts = new List<int>();
+          int indexOf = 0;
+          while (indexOf >= 0) {
+            lineStarts.add(indexOf);
+            indexOf = bytes.indexOf(10, indexOf + 1);
+          }
+          lineStarts.add(bytes.length);
+          source = new Source(lineStarts, bytes, uri, uri);
+        }
+        List<String> result = new List<String>();
+        for (int i = 0; i < spellResult.misspelledWords.length; i++) {
+          Location location = source.getLocation(
+              uri, offset + spellResult.misspelledWordsOffset[i]);
+          result.add(command_line_reporting.formatErrorMessage(
+              source.getTextLine(location.line),
+              location,
+              spellResult.misspelledWords[i].length,
+              relativize(uri),
+              "$message: '${spellResult.misspelledWords[i]}'."));
+        }
+        return result;
+      }
 
       for (String key in message.keys) {
         YamlNode node = message.nodes[key];
         var value = node.value;
+        // When positions matter, use node.span.text.
+        // When using node.span.text, replace r"\n" with "\n\n" to replace two
+        // characters with two characters without actually having the string
+        // "backslash n".
         switch (key) {
           case "template":
-            Set<String> misspelled = spell.spellcheckString(value);
-            if (misspelled != null) {
-              misspelledTemplate = node;
-              misspelledTemplateWords = misspelled;
+            spell.SpellingResult spellingResult = spell.spellcheckString(
+                node.span.text.replaceAll(r"\n", "\n\n"),
+                dictionaries: const [
+                  spell.Dictionaries.common,
+                  spell.Dictionaries.cfeMessages
+                ]);
+            if (spellingResult.misspelledWords != null) {
+              spellingMessages ??= new List<String>();
+              spellingMessages.addAll(formatSpellingMistakes(
+                  spellingResult,
+                  node.span.start.offset,
+                  "Template likely has the following spelling mistake"));
             }
             break;
 
           case "tip":
-            Set<String> misspelled = spell.spellcheckString(value);
-            if (misspelled != null) {
-              misspelledTip = node;
-              misspelledTipWords = misspelled;
+            spell.SpellingResult spellingResult = spell.spellcheckString(
+                node.span.text.replaceAll(r"\n", "\n\n"),
+                dictionaries: const [
+                  spell.Dictionaries.common,
+                  spell.Dictionaries.cfeMessages
+                ]);
+            if (spellingResult.misspelledWords != null) {
+              spellingMessages ??= new List<String>();
+              spellingMessages.addAll(formatSpellingMistakes(
+                  spellingResult,
+                  node.span.start.offset,
+                  "Tip likely has the following spelling mistake"));
             }
             break;
 
@@ -228,15 +284,18 @@
             name, messageNode, example, problem);
       }
 
-      for (Example example in examples) {
-        yield createDescription(example.name, example, null);
-      }
-      // "Wrap" example as a part.
-      for (Example example in examples) {
-        yield createDescription(
-            "part_wrapped_${example.name}",
-            new PartWrapExample("part_wrapped_${example.name}", name, example),
-            null);
+      if (!fastOnly) {
+        for (Example example in examples) {
+          yield createDescription(example.name, example, null);
+        }
+        // "Wrap" example as a part.
+        for (Example example in examples) {
+          yield createDescription(
+              "part_wrapped_${example.name}",
+              new PartWrapExample(
+                  "part_wrapped_${example.name}", name, example),
+              null);
+        }
       }
 
       yield createDescription(
@@ -261,26 +320,12 @@
               ? "The 'ERROR' severity is the default and not necessary."
               : null,
           location: unnecessarySeverity?.span?.start);
-
       yield createDescription(
-          "misspelledTemplate",
+          "spelling",
           null,
-          misspelledTemplate != null
-              ? "The template likely has the following spelling mistake(s) "
-                  "in it: ${misspelledTemplateWords.toList()}. "
-                  "If the word(s) look okay, update 'spell_checking_list.txt'."
-              : null,
-          location: misspelledTemplate?.span?.start);
-
-      yield createDescription(
-          "misspelledTip",
-          null,
-          misspelledTip != null
-              ? "The tip likely has the following spelling mistake(s) in "
-                  "it: ${misspelledTipWords.toList()}. "
-                  "If the word(s) look okay, update 'spell_checking_list.txt'."
-              : null,
-          location: misspelledTip?.span?.start);
+          spellingMessages != null
+              ? spellingMessages.join("\n") + spellingPostMessage
+              : null);
 
       bool exampleAndAnalyzerCodeRequired = severity != Severity.context &&
           severity != Severity.internalProblem &&
@@ -603,7 +648,8 @@
 
 Future<MessageTestSuite> createContext(
     Chain suite, Map<String, String> environment) async {
-  return new MessageTestSuite();
+  final bool fastOnly = environment["fastOnly"] == "true";
+  return new MessageTestSuite(fastOnly);
 }
 
 String relativize(Uri uri) {
diff --git a/pkg/front_end/test/fasta/parser/type_info_test.dart b/pkg/front_end/test/fasta/parser/type_info_test.dart
index a81e0fa..1dd6051 100644
--- a/pkg/front_end/test/fasta/parser/type_info_test.dart
+++ b/pkg/front_end/test/fasta/parser/type_info_test.dart
@@ -2341,7 +2341,8 @@
           'handleType T null',
           'handleNoName )',
           'handleFormalParameterWithoutValue )',
-          'endFormalParameter null null ) FormalParameterKind.mandatory MemberKind.GeneralizedFunctionType',
+          'endFormalParameter null null ) FormalParameterKind.mandatory '
+              'MemberKind.GeneralizedFunctionType',
           'endFormalParameters 1 ( ) MemberKind.GeneralizedFunctionType',
           'endFunctionType Function null',
           'endTypeVariable > 0 extends',
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index f7c1885..13f7666 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -256,6 +256,8 @@
           environment["enableSpreadCollections"] != "false" && !legacyMode,
       ExperimentalFlag.extensionMethods:
           environment["enableExtensionMethods"] != "false" && !legacyMode,
+      ExperimentalFlag.nonNullable:
+          environment["enableNonNullable"] != "false" && !legacyMode,
     };
     var options = new ProcessedOptions(
         options: new CompilerOptions()
@@ -317,7 +319,7 @@
       process = await StdioProcess.run(context.vm.toFilePath(), args);
       print(process.output);
     } finally {
-      generated.parent.delete(recursive: true);
+      await generated.parent.delete(recursive: true);
     }
     return process.toResult();
   }
diff --git a/pkg/front_end/test/fasta/types/dill_hierachy_test.dart b/pkg/front_end/test/fasta/types/dill_hierachy_test.dart
index 08b6846..56053fa 100644
--- a/pkg/front_end/test/fasta/types/dill_hierachy_test.dart
+++ b/pkg/front_end/test/fasta/types/dill_hierachy_test.dart
@@ -119,7 +119,8 @@
         final DillLoader loader = target.loader;
         loader.appendLibraries(component);
         await target.buildOutlines();
-        ClassBuilder objectClass = loader.coreLibrary.getLocalMember("Object");
+        ClassBuilder objectClass =
+            loader.coreLibrary.lookupLocalMember("Object", required: true);
         ClassHierarchyBuilder hierarchy = new ClassHierarchyBuilder(
             objectClass, loader, new CoreTypes(component));
         Library library = component.libraries.last;
diff --git a/pkg/front_end/test/fasta/types/fasta_legacy_upper_bound_test.dart b/pkg/front_end/test/fasta/types/fasta_legacy_upper_bound_test.dart
index 1df8f75..dec96a2 100644
--- a/pkg/front_end/test/fasta/types/fasta_legacy_upper_bound_test.dart
+++ b/pkg/front_end/test/fasta/types/fasta_legacy_upper_bound_test.dart
@@ -47,7 +47,7 @@
     loader.appendLibraries(component);
     await target.buildOutlines();
     ClassBuilder objectClass =
-        loader.coreLibrary.getLocalMember("Object");
+        loader.coreLibrary.lookupLocalMember("Object", required: true);
     hierarchy = new ClassHierarchyBuilder(
         objectClass, loader, new CoreTypes(component));
   }
diff --git a/pkg/front_end/test/fasta/types/fasta_types_test.dart b/pkg/front_end/test/fasta/types/fasta_types_test.dart
index b09ff9f..f4dc886 100644
--- a/pkg/front_end/test/fasta/types/fasta_types_test.dart
+++ b/pkg/front_end/test/fasta/types/fasta_types_test.dart
@@ -52,7 +52,7 @@
     loader.appendLibraries(sdk);
     await target.buildOutlines();
     ClassBuilder objectClass =
-        loader.coreLibrary.getLocalMember("Object");
+        loader.coreLibrary.lookupLocalMember("Object", required: true);
     ClassHierarchyBuilder hierarchy =
         new ClassHierarchyBuilder(objectClass, loader, new CoreTypes(sdk));
     new FastaTypesTest(hierarchy, environment).run();
diff --git a/pkg/front_end/test/fasta/types/shared_type_tests.dart b/pkg/front_end/test/fasta/types/shared_type_tests.dart
index 37a45fd..2210802 100644
--- a/pkg/front_end/test/fasta/types/shared_type_tests.dart
+++ b/pkg/front_end/test/fasta/types/shared_type_tests.dart
@@ -284,7 +284,8 @@
     isNotSubtype('Typedef<void>', '() -> void');
     isSubtype('VoidFunction', '() -> void');
     isNotSubtype(
-        'DefaultTypes<void, void, List<void>, List<void>, int, (int) -> void, () -> int>',
+        'DefaultTypes<void, void, List<void>, List<void>, '
+            'int, (int) -> void, () -> int>',
         '() -> void');
     isNotSubtype('void', '() -> void');
 
diff --git a/pkg/front_end/test/fasta/types/subtypes_benchmark.dart b/pkg/front_end/test/fasta/types/subtypes_benchmark.dart
index 56aaef4..dc3e3f8 100644
--- a/pkg/front_end/test/fasta/types/subtypes_benchmark.dart
+++ b/pkg/front_end/test/fasta/types/subtypes_benchmark.dart
@@ -149,7 +149,8 @@
     final DillLoader loader = target.loader;
     loader.appendLibraries(c);
     await target.buildOutlines();
-    ClassBuilder objectClass = loader.coreLibrary.getLocalMember("Object");
+    ClassBuilder objectClass =
+        loader.coreLibrary.lookupLocalMember("Object", required: true);
     ClassHierarchyBuilder hierarchy =
         new ClassHierarchyBuilder(objectClass, loader, coreTypes);
 
diff --git a/pkg/front_end/test/fasta/types/type_parser.dart b/pkg/front_end/test/fasta/types/type_parser.dart
index 9a6281e..a40bbdf 100644
--- a/pkg/front_end/test/fasta/types/type_parser.dart
+++ b/pkg/front_end/test/fasta/types/type_parser.dart
@@ -249,7 +249,8 @@
 
   void expect(String string) {
     if (!identical(string, peek.stringValue)) {
-      throw "Expected '$string', but got '${peek.lexeme}'\n${computeLocation()}";
+      throw "Expected '$string', "
+          "but got '${peek.lexeme}'\n${computeLocation()}";
     }
     advance();
   }
@@ -332,7 +333,8 @@
 
   String parseName() {
     if (!peek.isIdentifier) {
-      throw "Expected a name, but got '${peek.stringValue}'\n${computeLocation()}";
+      throw "Expected a name, "
+          "but got '${peek.stringValue}'\n${computeLocation()}";
     }
     String result = peek.lexeme;
     advance();
diff --git a/pkg/front_end/test/fasta/unlinked_scope_test.dart b/pkg/front_end/test/fasta/unlinked_scope_test.dart
index 6366d5a..69e04e0 100644
--- a/pkg/front_end/test/fasta/unlinked_scope_test.dart
+++ b/pkg/front_end/test/fasta/unlinked_scope_test.dart
@@ -66,8 +66,13 @@
 class MockBodyBuilder extends BodyBuilder {
   MockBodyBuilder.internal(
       MockLibraryBuilder libraryBuilder, String name, Scope scope)
-      : super(libraryBuilder, libraryBuilder.mockProcedure(name), scope, scope,
-            null, null, null, false, null, libraryBuilder.uri, null);
+      : super(
+            library: libraryBuilder,
+            member: libraryBuilder.mockProcedure(name),
+            enclosingScope: scope,
+            formalParameterScope: scope,
+            isDeclarationInstanceMember: false,
+            uri: libraryBuilder.uri);
 
   MockBodyBuilder(Uri uri, String name, Scope scope)
       : this.internal(new MockLibraryBuilder(uri), name, scope);
diff --git a/pkg/front_end/test/hot_reload_e2e_test.dart b/pkg/front_end/test/hot_reload_e2e_test.dart
index b90b143..2b10afd 100644
--- a/pkg/front_end/test/hot_reload_e2e_test.dart
+++ b/pkg/front_end/test/hot_reload_e2e_test.dart
@@ -126,6 +126,7 @@
       Expect.equals(expectedLines, i);
     });
 
+    // ignore: unawaited_futures
     vm.stderr.transform(utf8.decoder).transform(splitter).toList().then((err) {
       Expect.isTrue(err.isEmpty, err.join('\n'));
     });
diff --git a/pkg/front_end/test/incremental_load_from_dill_test.dart b/pkg/front_end/test/incremental_load_from_dill_test.dart
index dd57da3..b88f426 100644
--- a/pkg/front_end/test/incremental_load_from_dill_test.dart
+++ b/pkg/front_end/test/incremental_load_from_dill_test.dart
@@ -206,8 +206,9 @@
     for (String filename in moduleSources.keys) {
       String data = moduleSources[filename];
       Uri uri = base.resolve(filename);
-      if (await fs.entityForUri(uri).exists())
+      if (await fs.entityForUri(uri).exists()) {
         throw "More than one entry for $filename";
+      }
       fs.entityForUri(uri).writeAsStringSync(data);
     }
   }
@@ -499,14 +500,16 @@
         countNonSyntheticPlatformLibraries(component);
     int syntheticLibraries = countSyntheticLibraries(component);
     if (world["expectsPlatform"] == true) {
-      if (nonSyntheticPlatformLibraries < 5)
+      if (nonSyntheticPlatformLibraries < 5) {
         throw "Expected to have at least 5 platform libraries "
             "(actually, the entire sdk), "
             "but got $nonSyntheticPlatformLibraries.";
+      }
     } else {
-      if (nonSyntheticPlatformLibraries != 0)
+      if (nonSyntheticPlatformLibraries != 0) {
         throw "Expected to have 0 platform libraries "
             "but got $nonSyntheticPlatformLibraries.";
+      }
     }
     if (world["expectedLibraryCount"] != null) {
       if (nonSyntheticLibraries - nonSyntheticPlatformLibraries !=
@@ -529,8 +532,9 @@
               entries.contains(lib.importUri) || entries.contains(lib.fileUri))
           .toList();
       if (entryLib.length != entries.length) {
-        throw "Expected the entries to become libraries. Got ${entryLib.length} "
-            "libraries for the expected ${entries.length} entries.";
+        throw "Expected the entries to become libraries. "
+            "Got ${entryLib.length} libraries for the expected "
+            "${entries.length} entries.";
       }
     }
     if (compiler.initializedFromDill != expectInitializeFromDill) {
diff --git a/pkg/front_end/test/language_versioning/data/package_default_version_is_wrong_3/.packages b/pkg/front_end/test/language_versioning/data/package_default_version_is_wrong_3/.packages
new file mode 100644
index 0000000..8fd141d
--- /dev/null
+++ b/pkg/front_end/test/language_versioning/data/package_default_version_is_wrong_3/.packages
@@ -0,0 +1 @@
+foo:lib/#dart=2.5&dart=arglebargle
\ No newline at end of file
diff --git a/pkg/front_end/test/language_versioning/data/package_default_version_is_wrong_3/lib/foo.dart b/pkg/front_end/test/language_versioning/data/package_default_version_is_wrong_3/lib/foo.dart
new file mode 100644
index 0000000..c669c23
--- /dev/null
+++ b/pkg/front_end/test/language_versioning/data/package_default_version_is_wrong_3/lib/foo.dart
@@ -0,0 +1,13 @@
+/*error: LanguageVersionInvalidInDotPackages*/
+// 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.
+
+/*library: languageVersion=2.8*/
+
+import 'foo2.dart';
+
+foo() {
+  print("Hello from foo!");
+  foo2();
+}
diff --git a/tests/modular/issue37523/def.dart b/pkg/front_end/test/language_versioning/data/package_default_version_is_wrong_3/lib/foo2.dart
similarity index 62%
copy from tests/modular/issue37523/def.dart
copy to pkg/front_end/test/language_versioning/data/package_default_version_is_wrong_3/lib/foo2.dart
index 3cda2b0..0e38837 100644
--- a/tests/modular/issue37523/def.dart
+++ b/pkg/front_end/test/language_versioning/data/package_default_version_is_wrong_3/lib/foo2.dart
@@ -1,15 +1,12 @@
+/*error: LanguageVersionInvalidInDotPackages*/
 // 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.
 
-class B {
-  const B();
-}
+// @dart = 2.4
 
-class A {
-  final B b;
-  const A(this.b);
-}
+/*library: languageVersion=2.4*/
 
-const ab = A(B());
-const b = B();
+foo2() {
+  print("Hello from foo2!");
+}
diff --git a/pkg/front_end/test/language_versioning/data/package_default_version_is_wrong_3/main.dart b/pkg/front_end/test/language_versioning/data/package_default_version_is_wrong_3/main.dart
new file mode 100644
index 0000000..cabb316
--- /dev/null
+++ b/pkg/front_end/test/language_versioning/data/package_default_version_is_wrong_3/main.dart
@@ -0,0 +1,16 @@
+// 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.
+
+// Set version of this file (not technically in package) explicitly to test as
+// much as possibly separately.
+
+// @dart = 2.4
+
+import 'package:foo/foo.dart';
+
+/*library: languageVersion=2.4*/
+
+main() {
+  foo();
+}
diff --git a/tests/modular/issue37523/modules.yaml b/pkg/front_end/test/language_versioning/data/package_default_version_is_wrong_3/pubspec.yaml
similarity index 74%
rename from tests/modular/issue37523/modules.yaml
rename to pkg/front_end/test/language_versioning/data/package_default_version_is_wrong_3/pubspec.yaml
index 23b5d70..ff98642 100644
--- a/tests/modular/issue37523/modules.yaml
+++ b/pkg/front_end/test/language_versioning/data/package_default_version_is_wrong_3/pubspec.yaml
@@ -2,7 +2,4 @@
 # 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.
 
-dependencies:
-  main: [def, expect]
-flags:
-  - constant-update-2018
\ No newline at end of file
+# Analyzer workaround, see https://github.com/dart-lang/sdk/issues/37513
\ No newline at end of file
diff --git a/pkg/front_end/test/language_versioning/data/parts_disagreeing_has_package_2/.packages b/pkg/front_end/test/language_versioning/data/parts_disagreeing_has_package_2/.packages
new file mode 100644
index 0000000..6442723
--- /dev/null
+++ b/pkg/front_end/test/language_versioning/data/parts_disagreeing_has_package_2/.packages
@@ -0,0 +1 @@
+foo:lib/#dart=2.5
\ No newline at end of file
diff --git a/pkg/front_end/test/language_versioning/data/parts_disagreeing_has_package_2/lib/foo.dart b/pkg/front_end/test/language_versioning/data/parts_disagreeing_has_package_2/lib/foo.dart
new file mode 100644
index 0000000..10a3c24
--- /dev/null
+++ b/pkg/front_end/test/language_versioning/data/parts_disagreeing_has_package_2/lib/foo.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.
+
+// The library and its part is both technically at language version 2.5,
+// but one is explicitly set, the other is not. That's an error.
+
+part /*error: LanguageVersionMismatchInPart*/ 'part.dart';
+
+/*library: languageVersion=2.5*/
+
+foo() {
+  /*error: MethodNotFound*/ bar();
+}
diff --git a/tests/modular/issue37523/def.dart b/pkg/front_end/test/language_versioning/data/parts_disagreeing_has_package_2/lib/part.dart
similarity index 67%
copy from tests/modular/issue37523/def.dart
copy to pkg/front_end/test/language_versioning/data/parts_disagreeing_has_package_2/lib/part.dart
index 3cda2b0..7c36bab 100644
--- a/tests/modular/issue37523/def.dart
+++ b/pkg/front_end/test/language_versioning/data/parts_disagreeing_has_package_2/lib/part.dart
@@ -2,14 +2,8 @@
 // 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 B {
-  const B();
-}
+// @dart = 2.5
 
-class A {
-  final B b;
-  const A(this.b);
-}
+part of 'foo.dart';
 
-const ab = A(B());
-const b = B();
+bar() {}
diff --git a/pkg/front_end/test/language_versioning/data/parts_disagreeing_has_package_2/main.dart b/pkg/front_end/test/language_versioning/data/parts_disagreeing_has_package_2/main.dart
new file mode 100644
index 0000000..16f9665
--- /dev/null
+++ b/pkg/front_end/test/language_versioning/data/parts_disagreeing_has_package_2/main.dart
@@ -0,0 +1,16 @@
+// 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.
+
+// Set version of this file (not technically in package) explicitly to test as
+// much as possibly separately.
+
+// @dart = 2.4
+
+import 'package:foo/foo.dart';
+
+/*library: languageVersion=2.4*/
+
+main() {
+  main();
+}
diff --git a/tests/modular/issue37523/modules.yaml b/pkg/front_end/test/language_versioning/data/parts_disagreeing_has_package_2/pubspec.yaml
similarity index 74%
copy from tests/modular/issue37523/modules.yaml
copy to pkg/front_end/test/language_versioning/data/parts_disagreeing_has_package_2/pubspec.yaml
index 23b5d70..ff98642 100644
--- a/tests/modular/issue37523/modules.yaml
+++ b/pkg/front_end/test/language_versioning/data/parts_disagreeing_has_package_2/pubspec.yaml
@@ -2,7 +2,4 @@
 # 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.
 
-dependencies:
-  main: [def, expect]
-flags:
-  - constant-update-2018
\ No newline at end of file
+# Analyzer workaround, see https://github.com/dart-lang/sdk/issues/37513
\ No newline at end of file
diff --git a/pkg/front_end/test/lint_test.dart b/pkg/front_end/test/lint_test.dart
new file mode 100644
index 0000000..7da98a7
--- /dev/null
+++ b/pkg/front_end/test/lint_test.dart
@@ -0,0 +1,144 @@
+// 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.
+
+import 'dart:async' show Future;
+
+import 'dart:io' show File;
+
+import 'dart:typed_data' show Uint8List;
+
+import 'package:front_end/src/fasta/parser.dart' show Parser;
+
+import 'package:front_end/src/fasta/parser/listener.dart' show Listener;
+
+import 'package:front_end/src/fasta/command_line_reporting.dart'
+    as command_line_reporting;
+
+import 'package:front_end/src/fasta/scanner/utf8_bytes_scanner.dart'
+    show Utf8BytesScanner;
+
+import 'package:front_end/src/scanner/token.dart' show Token;
+
+import 'package:front_end/src/scanner/token.dart';
+
+import 'package:kernel/kernel.dart';
+
+import 'package:testing/testing.dart'
+    show ChainContext, Result, Step, TestDescription, Chain, runMe;
+
+main([List<String> arguments = const []]) =>
+    runMe(arguments, createContext, "../testing.json");
+
+Future<Context> createContext(
+    Chain suite, Map<String, String> environment) async {
+  return new Context();
+}
+
+class Context extends ChainContext {
+  final List<Step> steps = const <Step>[
+    const LintTest(),
+  ];
+
+  // Override special handling of negative tests.
+  @override
+  Result processTestResult(
+      TestDescription description, Result result, bool last) {
+    return result;
+  }
+
+  List<int> rawBytes;
+  String cachedText;
+  List<int> lineStarts;
+  Uri uri;
+
+  void clear() {
+    rawBytes = null;
+    cachedText = null;
+    lineStarts = null;
+    uri = null;
+  }
+
+  String getErrorMessage(int offset, int squigglyLength, String message) {
+    Source source = new Source(lineStarts, rawBytes, uri, uri);
+    Location location = source.getLocation(uri, offset);
+    return command_line_reporting.formatErrorMessage(
+        source.getTextLine(location.line),
+        location,
+        squigglyLength,
+        uri.toString(),
+        message);
+  }
+}
+
+class LintTest extends Step<TestDescription, TestDescription, Context> {
+  const LintTest();
+
+  String get name => "lint test";
+
+  Future<Result<TestDescription>> run(
+      TestDescription description, Context context) async {
+    context.clear();
+    context.uri = description.uri;
+
+    File f = new File.fromUri(context.uri);
+    context.rawBytes = f.readAsBytesSync();
+
+    Uint8List bytes = new Uint8List(context.rawBytes.length + 1);
+    bytes.setRange(0, context.rawBytes.length, context.rawBytes);
+
+    Utf8BytesScanner scanner =
+        new Utf8BytesScanner(bytes, includeComments: true);
+    Token firstToken = scanner.tokenize();
+    context.lineStarts = scanner.lineStarts;
+
+    if (firstToken == null) return null;
+    List<String> problems;
+    LintListener lintListener =
+        new LintListener((int offset, int squigglyLength, String message) {
+      problems ??= new List<String>();
+      problems.add(context.getErrorMessage(offset, squigglyLength, message));
+    });
+    Parser parser = new Parser(lintListener);
+    parser.parseUnit(firstToken);
+
+    if (problems == null) {
+      return pass(description);
+    }
+    return fail(description, problems.join("\n\n"));
+  }
+}
+
+class LintListener extends Listener {
+  final Function(int offset, int squigglyLength, String message) onProblem;
+
+  LintListener(this.onProblem);
+
+  LatestType _latestType;
+
+  @override
+  void beginVariablesDeclaration(
+      Token token, Token lateToken, Token varFinalOrConst) {
+    if (!_latestType.type) {
+      onProblem(
+          varFinalOrConst.offset, varFinalOrConst.length, "No explicit type.");
+    }
+  }
+
+  @override
+  void handleType(Token beginToken, Token questionMark) {
+    _latestType = new LatestType(beginToken, true);
+  }
+
+  @override
+  void handleNoType(Token lastConsumed) {
+    _latestType = new LatestType(lastConsumed, false);
+  }
+}
+
+class LatestType {
+  final Token token;
+  bool type;
+
+  LatestType(this.token, this.type);
+}
diff --git a/pkg/front_end/test/lint_test.status b/pkg/front_end/test/lint_test.status
new file mode 100644
index 0000000..606ccfd
--- /dev/null
+++ b/pkg/front_end/test/lint_test.status
@@ -0,0 +1,13 @@
+# 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.md file.
+
+src/fasta/flow_analysis/flow_analysis: Fail
+src/fasta/kernel/body_builder: Fail
+src/fasta/kernel/expression_generator: Fail
+src/fasta/kernel/inference_visitor: Fail
+src/fasta/kernel/kernel_shadow_ast: Fail
+src/fasta/parser/parser: Fail
+src/fasta/type_inference/type_constraint_gatherer: Fail
+src/fasta/type_inference/type_inferrer: Fail
+src/fasta/type_inference/type_promotion: Fail
diff --git a/pkg/front_end/test/scanner_replacement_test.dart b/pkg/front_end/test/scanner_replacement_test.dart
index b0a979a..c05d86b 100644
--- a/pkg/front_end/test/scanner_replacement_test.dart
+++ b/pkg/front_end/test/scanner_replacement_test.dart
@@ -241,8 +241,9 @@
     fasta.Token token = firstToken;
     while (!token.isEof) {
       if (token is analyzer.BeginToken) {
-        if (token.lexeme != '<')
+        if (token.lexeme != '<') {
           expect(token.endGroup, isNotNull, reason: token.lexeme);
+        }
         if (token.endGroup != null) openerStack.add(token);
       } else if (openerStack.isNotEmpty && openerStack.last.endGroup == token) {
         analyzer.BeginToken beginToken = openerStack.removeLast();
diff --git a/pkg/front_end/test/scanner_test.dart b/pkg/front_end/test/scanner_test.dart
index 62de9dc..bd3ab0a 100644
--- a/pkg/front_end/test/scanner_test.dart
+++ b/pkg/front_end/test/scanner_test.dart
@@ -1397,8 +1397,8 @@
   }
 
   /**
-   * Assert that when scanned the given [source] contains a single identifier token
-   * with the same lexeme as the original source.
+   * Assert that when scanned the given [source] contains a single identifier
+   * token with the same lexeme as the original source.
    */
   void _assertNotKeywordToken(String source,
       {ScannerConfiguration configuration}) {
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
new file mode 100644
index 0000000..1475e26
--- /dev/null
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -0,0 +1,494 @@
+# 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.
+
+# Blank lines and comments are ignored.
+# Comments can also be inline like 'correct # this is ok'.
+# Note that at least one space before the hash is required.
+
+ahe
+ai
+aiki
+aka
+ansi
+ap
+api
+arg
+args
+argument1
+askesc
+ast
+asy
+atm
+automagically
+b
+b23d3b125e9d246e07a2b43b61740759a0dace
+backping
+bang
+bar
+baz
+bazel
+bb
+benchmarks
+bf
+bi
+bin
+bj
+blah
+blob
+bn
+bodied
+bof
+bom
+brianwilkerson
+bs
+bsd
+builder`s
+bulder
+c
+callee
+caller's
+callers
+came
+canonicalizer
+cant
+caret
+carets
+carriage
+cascades
+cast
+casted
+casts
+cfe
+ch
+char
+chars
+ci
+ck
+cl
+claim
+class's
+cls
+cn
+codebase
+codec
+codes
+com
+combinator
+combiner
+component's
+cond
+config
+configs
+constness
+contra
+core
+core's
+cr
+cut
+cwd
+d
+d11e
+dag
+danrubel
+daringfireball
+dartbug
+dartdoc
+dartlang
+ddc
+ddk
+dec
+decl
+del
+demangle
+demangled
+deps
+desc
+dev
+diff
+diffs
+digest
+digests
+dmitryas
+doc
+docs
+dom
+dpkg
+dq
+dummy
+e
+easy
+ecma
+ecosystem
+ed
+eek
+ef
+elem
+elt
+em
+emit
+emitted
+en
+env
+eof
+eq
+eval
+exp
+exportee
+exportees
+expr
+ext
+f
+fangorn
+fasta
+fe
+feff
+ff
+ffff
+ffi
+fishythefish
+floitsch
+fn
+fo
+foo
+foobar
+formed
+former
+frontend
+fs
+futured
+g
+gets
+gft
+git
+github
+glb
+gn
+googlesource
+goto
+gotos
+gt
+gypi
+gz
+gzip
+gzipped
+h
+hfs
+hillerstrom
+hoc
+href
+html
+https
+i
+id
+ideographic
+idn
+ids
+iff
+impl
+inc
+infos
+init
+ints
+io
+issuecomment
+j
+java
+jensj
+johnniwinther
+js
+json
+juxtaposition
+juxtapositions
+k
+k’s
+kernel's
+kernel2kernel
+klass
+kmillikin
+kustermann
+l
+lang
+leafp
+len
+lex
+lexemes
+lf
+lhs
+lib
+libs
+lm
+lry
+ls
+lt
+lvalue
+m
+markdown
+mb
+md
+me
+met
+meta
+method1a
+method1b
+method2a
+method2b
+method3a
+method3b
+mi
+min
+mk
+mm
+mn
+monomorphic
+msg
+n
+na
+nbsp
+ncs
+ncurses
+nd
+nextnext
+ni
+nj
+nk
+nnbd
+nr
+ns
+nsm
+nullability
+nullable
+o
+obj
+offs
+ogham
+op
+opt
+opts
+ordinal
+org
+os
+overshadowed
+p
+p1
+p2
+param
+params
+paren
+parens
+path
+pathos
+paulberry
+pay
+payload
+pdf
+per
+perf
+pi
+pkg
+pm
+pn
+pointwise
+pos
+postfix
+pre
+prebuilt
+prev
+printer
+printf
+println
+proc
+proto
+ps
+q
+q'i
+qi
+qm
+quad
+r
+r'\s
+radix
+ran
+re
+reach
+reassigned
+rebind
+rebuild
+recompiled
+recompiling
+recompute
+recomputed
+red
+redirectee
+reexports
+ref
+reflect
+reg
+rehash
+rejoin
+relativize
+reparse
+res
+rhs
+ri
+rn
+rnystrom
+s
+sb
+scheglov
+sdk's
+server
+service
+setaf
+sh
+shas
+si
+sigmund
+six
+size
+sj
+slash
+slb
+smi
+sn
+socket
+spec
+spec'ed
+sq
+src
+st
+stderr
+stdin
+stdio
+stdout
+stmt
+stub
+stubs
+stx
+sub
+subexpression
+subexpression's
+subexpressions
+subst
+substed
+superclasses
+superinitializer
+supernode
+supers
+svg
+sw
+synth
+t
+tear
+tearing
+tearoff
+tearoffs
+tell
+tells
+temp
+term
+termcap
+tex
+th
+ti
+tick
+ticker
+tid
+tiki
+tilde
+till
+tj
+tm
+tmp
+tn
+todo
+token's
+tokenize
+tokenized
+tput
+ts
+tty
+typeref
+u
+ui
+uint
+uint16
+uint32
+uint8
+un
+unalias
+uncomment
+unconstrained
+unequal
+unescape
+unexact
+unfinalized
+unfuture
+unfutured
+unlinked
+unlower
+unparsed
+update2018
+ur
+uri's
+url
+urls
+utf16
+utf8
+util
+utils
+v
+variable's
+variance
+variances
+vegorov
+vtab
+w
+wc
+weren't
+werror
+wiki
+wikipedia
+with1
+writeln
+wrt
+www
+x
+x0
+x00
+x10
+x10ffff
+x180
+x1b
+x1f
+x1ff
+x2
+x200
+x202
+x205
+x3
+x5
+x7
+xcodebuild
+xd
+xdbff
+xdc
+xdfff
+xi
+xm
+xn
+xor
+xterm
+xx
+xxxx
+y
+yaml
+yet
+yielding
+yields
+z
+zi
+zip
+zn
+zone
+zoned
diff --git a/pkg/front_end/test/spell_checking_list.txt b/pkg/front_end/test/spell_checking_list_common.txt
similarity index 79%
rename from pkg/front_end/test/spell_checking_list.txt
rename to pkg/front_end/test/spell_checking_list_common.txt
index 9d17af5..c608525 100644
--- a/pkg/front_end/test/spell_checking_list.txt
+++ b/pkg/front_end/test/spell_checking_list_common.txt
@@ -7,14 +7,7 @@
 # Note that at least one space before the hash is required.
 
 a
-a0x
-a1x
-a2x
-aa
-aaa
 abbreviations
-abc
-abcompile
 ability
 able
 abort
@@ -47,10 +40,8 @@
 accumulate
 accurate
 achieve
-across
 acting
 action
-actions
 active
 actual
 actually
@@ -77,29 +68,21 @@
 advancing
 advice
 affect
-affected
 affects
 after
 again
 against
 aggregate
 aggressively
-ahe
 ahead
-ai
-aiki
-aka
-albeit
 algebra
 algorithm
 algorithms
 alias
-alive
 all
 allocated
 allocating
 allocation
-allocations
 allow
 allowed
 allowing
@@ -135,10 +118,8 @@
 annotation
 annotations
 annotator
-anon
 anonymous
 another
-ansi
 answer
 anticipated
 antisymmetric
@@ -147,9 +128,6 @@
 anything
 anyway
 anywhere
-ap
-api
-app
 apparent
 appear
 appearance
@@ -170,19 +148,13 @@
 approach
 appropriate
 appropriately
-approval
 approximately
-approximation
 arbitrary
 are
 aren't
-arg
-args
 argument
-argument1
 arguments
 arithmetic
-arity
 arose
 around
 array
@@ -193,11 +165,9 @@
 ascii
 ask
 asked
-askesc
 asks
 aspects
 assert
-asserter
 assertion
 assertions
 asserts
@@ -216,12 +186,9 @@
 assumes
 assuming
 assumption
-ast
-asy
 async
 asynchronous
 at
-atm
 attach
 attached
 attempt
@@ -229,10 +196,7 @@
 attempting
 attempts
 attention
-auth
 authors
-autobianchi
-automagically
 automatically
 available
 average
@@ -244,17 +208,9 @@
 aware
 awareness
 away
-b
-b0x
-b1x
-b23d3b125e9d246e07a2b43b61740759a0dace
-b2x
-ba
 back
-backed
 backend
 backends
-backping
 backslash
 backslashes
 backspace
@@ -262,19 +218,9 @@
 backwards
 bad
 balanced
-bang
-bar
 base
 based
-bash
 basic
-bat
-batch
-baz
-bazel
-bb
-bbb
-bc
 be
 beat
 because
@@ -290,29 +236,19 @@
 behaves
 behavior
 behaviors
-behaviour
 behind
 being
 belong
 belongs
 below
-bench
-benchmark
-benchmarks
 beneficial
 benefit
-besides
 best
-beta
 bets
 better
 between
-bf
-bi
 big
-bigger
 bigint
-bin
 binaries
 binary
 bind
@@ -320,39 +256,26 @@
 bit
 bits
 bitwise
-bj
 black
 blacklisted
-blah
-blindly
-blob
 block
-blocked
 blocks
-blorp
 blue
-bn
-bodied
 bodies
 body
-bof
 bogus
 boils
-bom
 bool
 boolean
 booleans
-bootstrap
 bot
 both
-bots
 bottom
 bound
 boundary
 bounded
 boundless
 bounds
-bowtie
 box
 brace
 braces
@@ -361,34 +284,23 @@
 brackets
 branch
 branches
-brave
 break
 breaking
 breakpoint
 breaks
-brianwilkerson
 brittle
 broken
-brown
 browser
-bs
-bsd
 buffer
 bug
 bugs
 build
-builddir
 builder
-builder`s
 builders
 building
 builds
 built
 builtin
-bulder
-bulk
-bulk2
-bulkcompile
 bundle
 but
 by
@@ -396,28 +308,19 @@
 byte
 bytecode
 bytes
-c
-c's
 cache
 cached
 caching
-cafebabe
 calculate
 calculated
 calculates
 calculation
 call
-callable
 callback
 called
-callee
 caller
-caller's
-callers
 calling
 calls
-came
-camel
 can
 can't
 cancel
@@ -429,31 +332,22 @@
 canonicalization
 canonicalize
 canonicalized
-canonicalizer
-cant
 capabilities
 capability
 capital
-capitalized
 capture
+captured
+captures
 capturing
 care
 careful
 cares
-caret
-carets
-carriage
 carry
 cascade
-cascades
 cascading
 case
 cases
-casing
-cast
-casted
 casting
-casts
 catch
 catches
 categories
@@ -463,11 +357,7 @@
 caused
 causes
 causing
-cc
-ccc
 certain
-cfe
-ch
 chain
 chained
 chance
@@ -476,19 +366,14 @@
 changed
 changes
 changing
-char
 character
 characters
-charcode
-chars
-charset
 charts
 chase
 check
 checked
 checker
 checking
-checkout
 checks
 child
 children
@@ -498,16 +383,10 @@
 choosing
 chosen
 chunk
-ci
-circular
 circularities
 circularity
 circumstances
-ck
-cl
-claim
 class
-class's
 classes
 classic
 clause
@@ -516,17 +395,16 @@
 cleaned
 cleaning
 cleans
+cleanup
 clear
 cleared
 clearer
 clearing
 clearly
 clears
-cli
 client
 clients
 clone
-cloneable
 cloned
 cloner
 clones
@@ -539,17 +417,8 @@
 closing
 closure
 closures
-cls
 clue
-cmp
-cn
-cnn
 code
-codebase
-codec
-coded
-codepath
-codes
 collapses
 collect
 collected
@@ -558,20 +427,16 @@
 collections
 collector
 collects
-collisions
 colon
 colons
 color
 colorize
 colors
 column
-com
 combination
-combinator
 combinators
 combine
 combined
-combiner
 combines
 combining
 come
@@ -583,42 +448,31 @@
 commas
 comment
 comments
-commit
 common
 commonly
 compact
-companion
 comparable
 compare
 comparing
 comparison
-comparisons
 compatibility
 compatible
 compilation
-compilations
 compile
 compiled
 compiler
-compiler's
-compilercontext.runincontext
 compilers
 compiles
-compilesdk
 compiling
 complain
-complement
 complete
 completed
 completely
 completer
-completers
-completes
 completion
 complex
 compliance
 component
-component's
 components
 composed
 composite
@@ -638,19 +492,15 @@
 concrete
 concretely
 concurrent
-cond
 condition
 conditional
 conditionally
 conditions
-config
-configs
 configurable
 configuration
 configurations
 configure
 configuring
-confirm
 conflict
 conflicting
 conflicts
@@ -660,13 +510,11 @@
 connect
 connected
 connection
-consecutive
 consequence
 consequently
 conservatively
 consider
 considered
-considering
 considers
 consistency
 consistent
@@ -678,10 +526,8 @@
 constant
 constants
 constitutes
-constness
 constrain
 constrained
-constrains
 constraint
 constraints
 construct
@@ -690,10 +536,8 @@
 construction
 constructor
 constructor's
-constructor(s)
 constructors
 constructs
-consts
 constuctor
 consume
 consumed
@@ -713,8 +557,6 @@
 continued
 continues
 continuing
-contra
-contract
 contrast
 contravariance
 contravariant
@@ -724,8 +566,6 @@
 convenience
 convenient
 conventions
-conversion
-conversions
 convert
 converted
 convertible
@@ -738,8 +578,6 @@
 copy
 copying
 copyright
-core
-core's
 corner
 correct
 correcting
@@ -753,7 +591,6 @@
 could
 couldn't
 count
-count.#count
 counter
 counts
 couple
@@ -763,65 +600,37 @@
 cover
 covered
 covers
-cr
 crash
 crashed
-crashes
 crashing
 create
 created
 creates
 creating
 creation
-cumulative
 curly
 current
 currently
 custom
-cut
-cwd
 cyan
 cycle
 cycles
 cyclic
-d
-d11e
-dacoharkes
-daemon
-dag
-dangling
-danrubel
-daringfireball
 dart
-dart_runner
-dart:ffi
 dart2js
-dart2js_server
-dartanalyzer
-dartbug
-dartbug.com
-dartdoc
-dartfile
-dartlang
-dashes
+dartdevc
 data
 date
-day
-db
-ddc
-ddk
 dead
 deal
 dealing
 deals
 debug
 debugging
-dec
 decide
 decided
 deciding
 decimal
-decl
 declarable
 declarated
 declaration
@@ -839,7 +648,6 @@
 decrement
 deduced
 deep
-def
 default
 defaults
 defensive
@@ -858,7 +666,6 @@
 definitions
 degenerate
 degrade
-del
 delayed
 delegate
 delegates
@@ -869,29 +676,23 @@
 delimiter
 delimiters
 delta
-demangle
-demangled
 denote
 denoted
 denotes
 denoting
 depend
-depended
 dependence
 dependencies
 dependency
 dependent
 depending
 depends
-depfile
 deprecate
 deprecated
-deps
 depth
 derivation
 derive
 derived
-desc
 descendants
 describe
 described
@@ -921,33 +722,24 @@
 determined
 determines
 determining
-dev
 developer
 developers
 development
-deviation
 devices
 devise
 diagnostic
 diagnostics
-dictionary
 did
 didn't
 diet
-diff
 differ
 difference
 different
 differently
-differs
-diffs
 dig
-digest
-digests
 digit
 digits
 dill
-dillfile
 dir
 direct
 direction
@@ -956,25 +748,20 @@
 directly
 directories
 directory
-dirname
 disable
 disabled
 disabling
-disagree
 disambiguate
 disambiguated
 discard
 discarded
 discarding
 discards
-disconnect
 discover
 discovered
-discovering
 discovery
 disk
 dispatch
-dispatcher
 dispatches
 display
 displayed
@@ -986,23 +773,15 @@
 divide
 division
 divisor
-dmitryas
-dname
 do
-doc
-docs
-doctype
 document
 documentation
 documented
 documenting
 does
 doesn't
-doesnt
-dog
 doing
 dollar
-dom
 dominates
 don't
 done
@@ -1014,85 +793,54 @@
 doubt
 down
 downcast
-downcasts
 downside
-downstream
 downward
 downwards
-dpkg
-dq
 drive
 driver
 drop
 dropping
 due
-dummy
 dump
 dumped
-dumping
-dupe
 duplicate
 duplicated
 duplicates
 duplicating
 duplication
 duration
-durations
 during
 dust
-dyn
 dynamic
-e
-e.g
-e's
-e2e
 each
 eagerly
 earlier
 early
-ease
 easier
 easiest
-easy
-ec
-ecma
-ecosystem
-ed
 edge
 edges
 edit
 edition
 editor
-edits
-eek
-ef
 effect
 effective
 efficiency
-efficient
 effort
 either
-elapse
 elapsed
-elem
 element
 elements
 eligible
 eliminated
 elimination
 eliminator
-ell
 else
 elsewhere
-elt
-em
 embed
 embedded
 embeds
-emit
-emitted
 empty
-en
 enable
 enabled
 enables
@@ -1132,23 +880,15 @@
 entity's
 entries
 entry
-entrypoint
-entrypoints
 enum
-enum's
 enumerated
 enums
-env
 environment
-eof
-epoch
-eq
 equal
 equality
 equals
 equivalent
 equivalents
-err
 erroneous
 error
 errors
@@ -1158,7 +898,6 @@
 escaping
 essence
 etc
-eval
 evaluate
 evaluated
 evaluates
@@ -1172,9 +911,7 @@
 ever
 every
 everything
-everytime
 everywhere
-evicting
 evolution
 exact
 exactly
@@ -1189,32 +926,19 @@
 exclamation
 exclude
 excluded
-excludes
 excluding
 exclusive
-exe
 executable
-execute
 executed
 execution
 exercise
-exercised
-exercises
 exist
 existing
 exists
 exit
-exitcode
 exited
-exiting
-exits
-exp
 expand
-expanded
 expanding
-expands
-expansion
-expansive
 expect
 expectation
 expectations
@@ -1227,7 +951,6 @@
 experimentally
 experiments
 expired
-explain
 explanation
 explicit
 explicitly
@@ -1235,17 +958,13 @@
 exponential
 export
 exported
-exportee
-exportees
 exporter
 exporters
 exporting
 exports
 exposed
-expr
 expression
 expressions
-ext
 extend
 extended
 extending
@@ -1255,7 +974,6 @@
 extension
 extensions
 extent
-extern
 external
 externally
 extra
@@ -1263,8 +981,7 @@
 extraction
 extractor
 extraneous
-f
-fac
+face
 facilitate
 fact
 fact's
@@ -1279,40 +996,27 @@
 failures
 fake
 fall
-falling
 falls
 false
-fangorn
 far
 fashion
 fast
-fasta
 faster
 fatal
 favor
-favors
-fe
 feature
 features
 feed
 feel
-feff
 few
 fewer
-ff
-ffff
-ffi
-fibonacci
 field
-field's
 fieldname
 fields
 figure
 file
 filename
-filenames
 files
-filesystem
 fill
 filled
 fills
@@ -1327,7 +1031,6 @@
 finalizing
 finally
 find
-finder
 finding
 finds
 finish
@@ -1336,10 +1039,7 @@
 finishing
 finite
 first
-fishythefish
-fisk
 fit
-five
 fix
 fixed
 fixes
@@ -1351,16 +1051,11 @@
 flattened
 flexibility
 flexible
-floitsch
-floor
 flow
 flow's
 flush
 flutter
-flutter_runner
 flux
-fn
-fo
 fold
 folded
 folder
@@ -1368,13 +1063,8 @@
 followed
 following
 follows
-foo
-foobar
 for
-forbidden
 force
-forces
-foreign
 forest
 forget
 fork
@@ -1388,8 +1078,6 @@
 formatted
 formatter
 formatting
-formed
-former
 forms
 forward
 forwarded
@@ -1399,42 +1087,30 @@
 forwards
 found
 four
-fox
 fraction
 fragment
 frame
 frames
-framework
 free
 frequently
 fresh
 friendly
 from
 front
-frontend
-fs
-fulfill
 full
 fullname
 fully
 fun
-func
 function
 functionality
 functions
 further
 furthermore
 future
-futured
-futureor
-g
-gallery
-gamma
 gather
 gathered
 gatherer
 gathering
-gen
 general
 generalized
 generally
@@ -1442,37 +1118,26 @@
 generated
 generates
 generating
-generation
 generative
 generator
-generators
 generic
 generics
 get
-gets
 getter
 getters
-gft
 ghost
-git
-github
 give
 given
 gives
 giving
-glb
 gleaned
 global
 glorified
-gn
 go
 goes
 going
 good
-googlesource
 got
-goto
-gotos
 gotten
 governed
 gracefully
@@ -1482,15 +1147,12 @@
 greatest
 greatly
 green
-greeting
 grounded
 group
 grouping
 groups
 grow
 growable
-gt
-gtgt
 guaranteed
 guarantees
 guard
@@ -1498,15 +1160,7 @@
 guess
 guide
 guidelines
-gulp
-gunk
-gypi
-gz
-gzip
-gzipped
-h
 hack
-hackish
 had
 hair
 half
@@ -1522,7 +1176,6 @@
 happens
 hard
 hare
-harness
 has
 hash
 hasn't
@@ -1533,20 +1186,15 @@
 header
 headers
 heading
-hello
 help
 helper
 helpers
 hence
 here
 hermetic
-hest
 heuristic
-heuristics
 hex
 hexadecimal
-hfs
-hi
 hidden
 hide
 hides
@@ -1556,36 +1204,20 @@
 higher
 highest
 highlighted
-hillerstrom
 hint
-hints
 historically
-hoc
 hold
 holder
 holding
 holds
-home
 hood
 hooks
 host
-hosting
 hostnames
-hot
-hotreload
 how
 however
-href
-html
 http
-https
-hunk
-hurray
 hybrid
-i
-i'm
-ia
-id
 idea
 ideally
 ideas
@@ -1595,29 +1227,21 @@
 identifiers
 identify
 identity
-ideographic
-idn
-ids
 if
-iff
 ignore
 ignored
 ignores
 ignoring
-ikg
 illegal
-illustrate
 imitation
 immediate
 immediately
 immutable
-impl
 implement
 implementation
 implementations
 implemented
 implementing
-implementor
 implements
 implication
 implicit
@@ -1630,14 +1254,13 @@
 importer
 importing
 imports
+imposed
 imposes
 impossible
 improve
 improved
 in
 inbound
-inc
-inclosure
 include
 included
 includes
@@ -1650,11 +1273,9 @@
 incorrect
 incorrectly
 increase
-increased
 increases
 increment
 incremental
-incrementally
 indeed
 indent
 indentation
@@ -1670,7 +1291,6 @@
 indices
 indirect
 indirectly
-individual
 induce
 infer
 inference
@@ -1688,13 +1308,11 @@
 information
 informational
 informs
-infos
 inherit
 inheritable
 inheritance
 inherited
 inherits
-init
 initial
 initialization
 initialize
@@ -1717,10 +1335,8 @@
 insert
 inserted
 inserting
-insertion
 inserts
 inside
-inspect
 install
 installed
 instance
@@ -1734,9 +1350,7 @@
 instead
 instrumentation
 instrumented
-insufficient
 int
-intact
 integer
 integers
 integrated
@@ -1758,8 +1372,6 @@
 international
 interned
 interner
-internet
-interpolate
 interpolated
 interpolation
 interpret
@@ -1774,16 +1386,12 @@
 introduced
 introduces
 introducing
-ints
-inv
 invalid
 invalidate
 invalidated
 invalidates
-invalidating
 invariant
 invariantly
-invariants
 invert
 inverted
 investigate
@@ -1796,13 +1404,10 @@
 invoking
 involved
 involving
-io
 ir
 irrelevant
 is
 isn't
-isolate
-isolates
 issue
 issued
 issues
@@ -1811,57 +1416,36 @@
 item
 itemize
 items
-iter
 iterable
 iterate
 iteration
-iterations
 iterator
 its
 itself
-j
-java
 javascript
-jensj
-johnniwinther
 join
 joined
 joining
 joins
-js
-json
 judgment
 judgments
 jump
-jumped
 just
-juxtaposition
-juxtapositions
-k
-k’s
 keep
 keeping
 keeps
 kept
 kernel
-kernel's
-kernel2kernel
 key
 keys
 keyword
 keywords
 kind
 kinds
-klass
-kmillikin
 know
 knowing
 known
 knows
-ko
-kustermann
-l
-la
 label
 labeled
 labeler
@@ -1869,29 +1453,23 @@
 labels
 lack
 lacking
-lacks
 lands
-lang
 langauge
 language
 large
 larger
-largest
 last
 late
 later
+latest
 latter
 lax
 lazily
 lazy
-lc
-ld
-le
 lead
 leading
 leads
 leaf
-leafp
 leak
 leaking
 leaks
@@ -1904,55 +1482,42 @@
 legacy
 legal
 legally
-len
 length
 less
 let
 let's
-lets
 letter
 letters
 level
-lex
 lexeme
-lexemes
 lexical
 lexically
 lexicographical
-lf
-lhs
-lib
 libraries
-libraries.json
 library
 library's
-libs
 license
 licensing
 light
-lightly
+lightweight
 like
 likely
-likewise
 limit
 limited
 line
 linear
-linebreaks
 lines
 link
 linked
 linking
 links
 lint
-linux
 list
 listed
 listen
 listener
 listener's
 listeners
-listening
 lists
 literal
 literal's
@@ -1960,14 +1525,11 @@
 little
 live
 lived
-ll
-lm
 load
 loaded
 loader
 loaders
 loading
-loadlibrary
 loads
 local
 locally
@@ -1978,12 +1540,10 @@
 locations
 locked
 log
-logd
 logger
 logging
 logic
 logical
-logs
 long
 longer
 longest
@@ -1994,25 +1554,16 @@
 lookup
 lookups
 loop
-loopback
 looping
 loops
 loosely
 lost
 lot
-lots
 low
 lower
 lowercase
 lowered
 lowering
-lry
-ls
-lt
-lub
-lvalue
-m
-mac
 machine
 made
 magenta
@@ -2022,7 +1573,6 @@
 maintain
 major
 make
-maker
 makes
 making
 malformed
@@ -2036,7 +1586,6 @@
 mappings
 maps
 mark
-markdown
 marked
 marker
 markers
@@ -2052,15 +1601,10 @@
 math
 mathematical
 matter
-matters
 maturity
 max
 may
 maybe
-mb
-mc
-md
-me
 mean
 meaning
 meaningful
@@ -2068,7 +1612,6 @@
 meant
 measurably
 measure
-measured
 mechanism
 medium
 meet
@@ -2085,16 +1628,9 @@
 message
 messages
 messaging
-met
-meta
 metadata
 method
 methods
-metric
-metrics
-mf
-mi
-micro
 microseconds
 microtask
 mid
@@ -2102,7 +1638,6 @@
 might
 millisecond
 milliseconds
-min
 minimal
 minimum
 minor
@@ -2111,21 +1646,14 @@
 mirrors
 misleading
 mismatch
-mismatched
 mismatches
-miss
 missing
-misspelled
-mistake
 mix
 mixed
 mixes
 mixin
 mixin's
 mixins
-mk
-mm
-mn
 mock
 mode
 model
@@ -2145,8 +1673,6 @@
 modulo
 moment
 mongolian
-monomorphic
-month
 more
 most
 mostly
@@ -2155,7 +1681,6 @@
 moved
 moving
 ms
-msg
 much
 multi
 multiline
@@ -2172,15 +1697,9 @@
 mutations
 mutual
 mutually
-mx
 my
-mysdk
-n
-na
 naive
 name
-name.#name
-name.stack
 named
 namely
 names
@@ -2189,13 +1708,7 @@
 narrow
 narrower
 native
-native('native
-nativetype
 nature
-nbsp
-ncs
-ncurses
-nd
 nearest
 necessarily
 necessary
@@ -2203,7 +1716,6 @@
 needed
 needing
 needs
-negatable
 negate
 negated
 negation
@@ -2223,28 +1735,20 @@
 newlines
 newly
 next
-nextnext
-ni
 nice
 nicely
-ninja
-nj
-nk
-nnbd
 no
 nobody
 node
 nodes
 non
 none
-nonexisting
 nor
 normal
 normalize
 normalized
 normalizes
 normally
-nosuchmethod
 not
 notation
 note
@@ -2253,29 +1757,16 @@
 notice
 noticed
 notifies
-notion
 now
-nr
-ns
-nsm
 null
-nullability
-nullable
-nullary
 num
-num1%.3ms
 number
 numbers
-numerator
 numeric
-o
-obj
 object
 object's
 objects
-observable
 observation
-observatory
 observed
 obtain
 obtained
@@ -2289,14 +1780,10 @@
 odd
 of
 off
-offs
 offset
 offsets
 often
-ogham
-oh
 ok
-okay
 old
 older
 omit
@@ -2306,7 +1793,7 @@
 one
 ones
 only
-op
+onto
 open
 opener
 openers
@@ -2319,7 +1806,6 @@
 operator
 operators
 opposed
-opt
 optimistically
 optimization
 optimize
@@ -2328,14 +1814,10 @@
 optionally
 optionals
 options
-opts
 or
-oracle
 order
 ordering
-ordinal
 ordinary
-org
 organized
 origin
 original
@@ -2346,7 +1828,6 @@
 origins
 orphan
 orphaned
-os
 other
 others
 otherwise
@@ -2365,7 +1846,6 @@
 outside
 over
 overflow
-overlay
 overloadable
 overloaded
 overloading
@@ -2373,14 +1853,10 @@
 override
 overrides
 overriding
-overshadowed
 overwritten
 own
 owned
 owner
-p
-p1
-p2
 package
 packages
 pad
@@ -2392,13 +1868,8 @@
 pairs
 pairwise
 paragraph
-param
 parameter
 parameters
-parametrized
-params
-paren
-parens
 parent
 parent's
 parentheses
@@ -2412,13 +1883,11 @@
 parses
 parsing
 part
-part(s)
 partial
 partially
 participate
 particular
 parts
-party
 pass
 passed
 passing
@@ -2427,19 +1896,11 @@
 patch
 patched
 patches
-path
-pathos
+patching
 paths
 pattern
-paulberry
-pause
-pay
-payload
-pdf
 peek
-per
 percent
-perf
 perform
 performance
 performed
@@ -2447,30 +1908,22 @@
 performs
 perhaps
 period
-periodic
-periodically
 periods
 permissible
 permitted
 persistent
-person
 phase
 phased
 phases
-phrase
 physical
-pi
 pick
 picked
-pink
 pipeline
 pivot
-pkg
 place
 placed
 placeholder
 placeholders
-places
 plain
 plan
 platform
@@ -2479,15 +1932,11 @@
 please
 plethora
 plus
-pm
-pn
 point
 pointer
 pointers
 pointing
 points
-pointwise
-policy
 polymorphic
 pop
 popping
@@ -2495,8 +1944,6 @@
 populated
 port
 portion
-portions
-pos
 position
 positional
 positionals
@@ -2506,16 +1953,12 @@
 possible
 possibly
 post
-postfix
 postpone
 postponed
 potential
 potentially
-pp
 practice
 practices
-pre
-prebuilt
 precede
 preceded
 precedence
@@ -2536,8 +1979,6 @@
 prefix
 prefixed
 prefixes
-preliminary
-prematurely
 prepare
 prepared
 preparing
@@ -2552,9 +1993,7 @@
 preserving
 presumed
 pretend
-pretends
 pretty
-prev
 prevent
 prevented
 prevents
@@ -2565,10 +2004,7 @@
 principle
 print
 printed
-printer
-printf
 printing
-println
 prints
 prior
 priority
@@ -2578,7 +2014,6 @@
 problem
 problematic
 problems
-proc
 procedure
 procedures
 proceed
@@ -2587,11 +2022,9 @@
 processing
 produce
 produced
-producer
 produces
 producing
 production
-profiler
 profiling
 program
 program's
@@ -2606,30 +2039,23 @@
 promote
 promoted
 promoter
-promotes
 promotion
 promotions
-prop
 propagate
-propagated
 propagating
 proper
 properly
 properties
 property
-protected
-proto
 prototype
 proves
 provide
 provided
-provider
 provides
 providing
 provoked
 provokes
 pruning
-ps
 pseudo
 pub
 public
@@ -2637,7 +2063,6 @@
 published
 pull
 punctuation
-pure
 purely
 purpose
 purposely
@@ -2648,14 +2073,6 @@
 pushing
 put
 putting
-pv
-px
-py
-q
-q'i
-qi
-qm
-quad
 quadratic
 qualified
 qualifier
@@ -2664,28 +2081,17 @@
 query
 question
 queue
-quick
 quickly
 quite
-quot
 quote
 quotes
 quoting
-r
-r'\s
-r"\s
-radix
 raise
-ran
 random
 range
 rare
 rather
 raw
-rd
-re
-reach
-reachability
 reachable
 reached
 reaches
@@ -2697,15 +2103,11 @@
 reads
 ready
 real
-reality
 realized
 really
 reason
 reasonable
 reasons
-reassigned
-rebind
-rebuild
 receive
 receiver
 recent
@@ -2715,11 +2117,6 @@
 recognizes
 recommend
 recommendations
-recompile
-recompiled
-recompiling
-recompute
-recomputed
 record
 recorded
 recording
@@ -2734,22 +2131,15 @@
 recursing
 recursive
 recursively
-red
-redir
 redirect
 redirected
-redirectee
 redirecting
 redirection
-redirections
 redirects
 reduce
 reduced
-reducer
 reduces
 redundant
-reexports
-ref
 refactor
 refer
 reference
@@ -2757,16 +2147,10 @@
 references
 referencing
 referred
-referring
 refers
 refine
 refinement
-reflect
-reflectee
-reflective
-reg
 regardless
-regenerate
 region
 regions
 register
@@ -2775,13 +2159,10 @@
 registry
 regress
 regression
-regressions
 regular
-rehash
 reissue
 rejected
 rejects
-rejoin
 relate
 related
 relation
@@ -2789,11 +2170,9 @@
 relationship
 relationships
 relative
-relativize
 release
 relevant
 relies
-reload
 reloads
 rely
 relying
@@ -2811,10 +2190,8 @@
 removing
 rename
 renaming
-reparse
 repeated
 repeatedly
-repeating
 repetitions
 replace
 replaced
@@ -2822,7 +2199,6 @@
 replacing
 replicate
 replicating
-repo
 report
 reportable
 reported
@@ -2836,7 +2212,6 @@
 represented
 representing
 represents
-repro
 request
 requested
 require
@@ -2844,7 +2219,6 @@
 requirements
 requires
 requiring
-res
 rescan
 reserved
 reset
@@ -2855,14 +2229,11 @@
 resolver
 resolves
 resolving
-resource
 resources
 respect
-respected
 respective
 respectively
 respects
-response
 responsibility
 responsible
 rest
@@ -2877,7 +2248,6 @@
 resynthesize
 retain
 retained
-retains
 rethrow
 retrieve
 retrieved
@@ -2890,7 +2260,6 @@
 reuse
 reused
 reusing
-rev
 reverse
 reversed
 review
@@ -2901,15 +2270,11 @@
 rewriter
 rewriting
 rewritten
-rhs
-ri
 rid
 right
 rightfully
 rights
 rise
-rn
-rnystrom
 roll
 root
 roots
@@ -2924,7 +2289,6 @@
 running
 runs
 runtime
-s
 safe
 safely
 said
@@ -2936,9 +2300,7 @@
 satisfy
 save
 saved
-say
 says
-sb
 scalar
 scan
 scanned
@@ -2946,35 +2308,26 @@
 scanner's
 scanners
 scanning
-scans
-scheglov
 schema
 scheme
 schemes
 scope
 scopes
 scratch
-screen
 script
-scripts
 sdk
-sdk's
-sdksummary
 sealed
 search
 searched
 searches
 searching
 second
-secondary
-seconds
 section
 see
 seem
 seems
 seen
 sees
-segment
 segments
 select
 selected
@@ -3004,10 +2357,7 @@
 serializes
 serializing
 serious
-server
-service
 set
-setaf
 sets
 setter
 setters
@@ -3016,9 +2366,7 @@
 setup
 several
 severity
-sh
 shadow
-shadowed
 shadowing
 shake
 shaken
@@ -3028,25 +2376,19 @@
 share
 shared
 sharing
-shas
 shell
 shift
-shipped
 short
 shortcut
 shorten
-shot
 should
 shouldn't
 show
 shown
 shrink
-si
 side
-sigmund
 sign
 signal
-signalled
 signals
 signature
 signatures
@@ -3060,7 +2402,6 @@
 simplicity
 simplified
 simplifies
-simplify
 simplifying
 simply
 simulate
@@ -3070,20 +2411,14 @@
 single
 singular
 sink
-site
 sites
 situation
 situations
-six
-size
-sj
 skip
 skipped
 skipping
 skips
 slack
-slash
-slb
 slices
 slightly
 slow
@@ -3091,14 +2426,11 @@
 slows
 small
 smallest
-smi
-sn
 snapshot
 snapshots
 snippet
 snippets
 so
-socket
 solution
 solve
 solved
@@ -3106,7 +2438,6 @@
 some
 something
 sometimes
-somewhat
 somewhere
 soon
 sophisticated
@@ -3118,12 +2449,8 @@
 sources
 space
 spaces
-spacing
 span
 spanning
-spans
-spec
-spec'ed
 special
 specialize
 specialized
@@ -3136,25 +2463,15 @@
 specifying
 speed
 speedup
-spell
-spellcheck
-spelled
-spelling
-spent
 split
 splitter
-splitting
 spread
 spreadable
 spreads
-sq
-sqrt
 square
-src
-st
+squiggly
 stable
 stack
-stacktrace
 stage
 stamps
 standalone
@@ -3172,18 +2489,11 @@
 states
 static
 statically
-statics
 status
 stays
-std
-stderr
-stdin
-stdio
-stdout
 step
 steps
 still
-stmt
 stop
 stops
 stopwatch
@@ -3191,7 +2501,6 @@
 stored
 stores
 storing
-str
 straight
 strategy
 stray
@@ -3199,40 +2508,23 @@
 strictly
 string
 strings
-strip
 stripped
 strong
-strongest
 strongly
 struct
-struct<#name
-structs
 structural
 structure
-structures
-stub
-stub's
-stubs
 stuff
-stx
 style
-sub
 subclass
 subclassed
 subclasses
 subclassing
-subcommand
-subexpression
-subexpression's
-subexpressions
 subject
 sublist
-subscription
 subsequence
 subsequent
 subset
-subst
-substed
 substitute
 substituted
 substituting
@@ -3243,8 +2535,6 @@
 substructures
 subterms
 subtly
-subtool
-subtools
 subtract
 subtree
 subtrees
@@ -3265,27 +2555,15 @@
 suffix
 suggested
 suitable
-suite
-sum
 summaries
-summarization
 summarize
-summarized
 summarizes
 summary
 super
-super.namedconstructor
 superclass
-superclasses
-superinitializer
-superinterface
-supermixin
-supernode
-supers
 supertype
 supertype's
 supertypes
-supplement
 supplied
 supply
 support
@@ -3301,10 +2579,7 @@
 surrounding
 survives
 suspect
-svg
-sw
 swap
-swapped
 switch
 symbol
 symbols
@@ -3317,19 +2592,17 @@
 syntactical
 syntactically
 syntax
-synth
 synthesize
 synthesized
+synthesizing
 synthetic
 synthetically
 system
 systems
-t
 tab
 table
 tabs
 tag
-tags
 tail
 take
 taken
@@ -3340,22 +2613,11 @@
 targeting
 targets
 task
-team
-tear
-tearing
-tearoff
-tearoffs
 technically
 technique
-tell
-tells
-temp
 template
-templates
 temporarily
 temporary
-term
-termcap
 terminal
 terminal's
 terminals
@@ -3364,21 +2626,17 @@
 terminates
 terminating
 termination
-terminator
 terminology
 ternary
 test
 testcase
 testcases
 tested
-tester
 testing
 tests
-tex
 text
 texts
 textual
-th
 than
 that
 that's
@@ -3392,23 +2650,18 @@
 there's
 thereafter
 therefore
-thereof
 these
 they
 they're
 thin
-thing
 things
 think
 third
 this
-this.namedconstructor
-this.x
 those
 though
 three
 threshold
-threw
 throttle
 through
 throughout
@@ -3418,46 +2671,23 @@
 throws
 thumb
 thus
-ti
-tick
-ticker
-tid
-tiki
-tilde
-till
 time
-timeout
-timer
 times
-timing
-timings
 tip
-title
-tj
-tm
-tmp
-tn
 to
 today
-todo
 together
 token
-token's
-tokenize
-tokenized
 tokens
 too
 took
 tool
 tools
 top
-toplevel
 topologically
 tortoise
 total
 touched
-tpt
-tput
 trace
 traces
 tracing
@@ -3472,19 +2702,16 @@
 transformations
 transformed
 transformer
-transforming
 transient
 transition
 transitional
 transitions
 transitive
-transitively
 transitivity
 translate
 translated
 translates
 translating
-translation
 translator
 traversed
 treat
@@ -3493,93 +2720,58 @@
 treatment
 treats
 tree
-triangle
 trick
 tried
 tries
-trigger
 triggered
-triggers
 trim
 trimmed
-trimming
 trip
 triple
 triples
 triplet
 triplets
 trivial
-trivially
 true
 truly
 truncate
-truncated
 truncating
 truth
 try
 trying
-ts
-tt
-tty
 turn
 turned
 turning
 tv
 twice
 two
-txt
 type
-type3.#name
-typeargs
 typed
 typedef
 typedefs
-typeparam
-typeparambounds
-typeref
 types
 typically
 typing
-u
-ui
-uint
-uint16
-uint32
-uint8
-un
 unable
-unalias
 unary
-unassigned
-unavailable
 unbalanced
 unbind
-unbreak
 unchanged
 unclaimed
 unclear
-uncomment
-unconstrained
 undefined
 under
 underlying
 underscore
 understand
-unequal
-unescape
 unevaluated
-unexact
 unexpected
-unfinalized
 unfinished
 unforeseen
 unfortunate
-unfuture
-unfutured
 unhandled
 unhelpful
 unicode
-unification
 unified
 unifying
 unimplemented
@@ -3593,8 +2785,6 @@
 unknown
 unless
 unlike
-unlinked
-unlower
 unmatched
 unmentioned
 unmodifiable
@@ -3602,15 +2792,11 @@
 unnamed
 unnecessarily
 unnecessary
-unordered
-unparsed
 unpromoted
-unreachable
 unread
 unrecognized
 unrecoverable
 unreferenced
-unregistered
 unrelated
 unresolved
 unsafe
@@ -3626,7 +2812,6 @@
 unsupported
 unterminated
 until
-untransformed
 untranslatable
 untyped
 unused
@@ -3634,7 +2819,6 @@
 unwrapped
 up
 update
-update2018
 updated
 updater
 updaters
@@ -3642,15 +2826,9 @@
 updating
 upon
 upper
-uppercase
-upward
 upwards
-ur
 uri
-uri's
 uris
-url
-urls
 us
 usable
 usage
@@ -3661,17 +2839,9 @@
 users
 uses
 using
-usr
-usual
 utf
-utf16
-utf8
-util
 utilities
 utility
-utils
-v
-val
 valid
 validate
 validated
@@ -3685,14 +2855,8 @@
 values
 var
 variable
-variable's
 variables
-variance
-variances
-variants
 various
-vegorov
-verbatim
 verbose
 verification
 verified
@@ -3700,16 +2864,13 @@
 verifies
 verify
 verifying
-versa
 version
-versioning
 versions
 vertex
 vertical
 vertices
 very
 via
-vice
 view
 violate
 violates
@@ -3718,30 +2879,22 @@
 visible
 visit
 visited
+visiting
 visitor
 visual
 vm
-vm's
 void
 vowel
-vs
-vtab
-w
 wait
-waiting
 walk
 walked
-walt
 want
-wanted
-warmup
 warn
 warning
 warnings
 was
 wasn't
 way
-wc
 we
 we'd
 we'll
@@ -3749,12 +2902,9 @@
 we've
 web
 weight
-weird
 weirdness
 well
 were
-weren't
-werror
 what
 what's
 whatever
@@ -3767,24 +2917,17 @@
 which
 while
 white
-whitelist
 whitelisted
-whitelisting
 whitespace
 whole
 whose
 why
 widely
 width
-wiki
-wikipedia
-wil
 wildcard
 will
 windows
-wins
 with
-with1
 within
 without
 won't
@@ -3793,7 +2936,6 @@
 work
 workaround
 worker
-workflow
 working
 worklist
 works
@@ -3807,63 +2949,17 @@
 wraps
 writable
 write
-writeln
 writer
 writes
 writing
 written
 wrong
 wrote
-wrt
-www
-x
-x's
-x0
-x00
-x10
-x10ffff
-x180
-x1b
-x1f
-x1ff
-x2
-x200
-x202
-x205
-x3
-x5
-x7
-xcodebuild
-xd
-xdbff
-xdc
-xdfff
-xi
-xm
-xn
-xor
-xterm
-xx
-xxx
-xxxx
-y
-y's
-yaml
-year
 yellow
 yes
-yet
 yield
-yielding
-yields
 you
 you'll
 you're
 your
-z
 zero
-zi
-zip
-zn
-zone
-zoned
\ No newline at end of file
diff --git a/pkg/front_end/test/spell_checking_list_messages.txt b/pkg/front_end/test/spell_checking_list_messages.txt
new file mode 100644
index 0000000..0ed2f9a
--- /dev/null
+++ b/pkg/front_end/test/spell_checking_list_messages.txt
@@ -0,0 +1,51 @@
+# 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.
+
+# Blank lines and comments are ignored.
+# Comments can also be inline like 'correct # this is ok'.
+# Note that at least one space before the hash is required.
+
+b
+c
+compilercontext.runincontext
+compilesdk
+constructor(s)
+count.#count
+d
+dart_runner
+dart:ffi
+dart2js_server
+dartbug.com
+dname
+e.g
+enum's
+f
+field's
+flutter_runner
+futureor
+h
+libraries.json
+loadlibrary
+name.#name
+name.stack
+native('native
+nativetype
+nosuchmethod
+num1%.3ms
+o
+part(s)
+re
+sdksummary
+stacktrace
+struct<#name
+structs
+super.namedconstructor
+supermixin
+team
+this.namedconstructor
+this.x
+type3.#name
+u
+v
+x
\ No newline at end of file
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
new file mode 100644
index 0000000..794a2a1
--- /dev/null
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -0,0 +1,417 @@
+# 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.
+
+# Blank lines and comments are ignored.
+# Comments can also be inline like 'correct # this is ok'.
+# Note that at least one space before the hash is required.
+
+a0x
+a1x
+a2x
+aa
+aaa
+abc
+abcompile
+across
+actions
+affected
+albeit
+alive
+allocations
+anon
+app
+approval
+approximation
+arity
+asserter
+auth
+autobianchi
+b0x
+b1x
+b2x
+ba
+backed
+bash
+bat
+batch
+bbb
+bc
+bench
+benchmark
+besides
+beta
+bigger
+blindly
+blocked
+blorp
+bootstrap
+bots
+bowtie
+brave
+brown
+builddir
+bulk
+bulk2
+bulkcompile
+c's
+cafebabe
+callable
+camel
+capitalized
+casing
+cc
+ccc
+charcode
+charset
+checkout
+circular
+cli
+cloneable
+cmp
+cnn
+coded
+codepath
+collisions
+commit
+companion
+comparisons
+compilations
+compiler's
+complement
+completers
+completes
+confirm
+consecutive
+considering
+constrains
+consts
+contract
+conversion
+conversions
+crashes
+cumulative
+dacoharkes
+daemon
+dangling
+dartanalyzer
+dartfile
+dashes
+day
+db
+def
+depended
+depfile
+deviation
+dfast
+dictionaries
+dictionary
+differs
+dillfile
+dirname
+disagree
+disconnect
+discovering
+dispatcher
+doctype
+doesnt
+dog
+downcasts
+downstream
+dumping
+dupe
+durations
+dyn
+e's
+e2e
+ease
+ec
+edits
+efficient
+elapse
+ell
+entrypoint
+entrypoints
+epoch
+err
+everytime
+evicting
+excludes
+exe
+execute
+exercised
+exercises
+exitcode
+exiting
+exits
+expanded
+expands
+expansion
+expansive
+explain
+extern
+fac
+falling
+favors
+fibonacci
+filenames
+filesystem
+finder
+fisk
+five
+floor
+forbidden
+forces
+foreign
+fox
+framework
+fulfill
+func
+futures
+gallery
+gamma
+gen
+generation
+generators
+glb
+greeting
+gtgt
+gulp
+gunk
+hackish
+harness
+hello
+hest
+heuristics
+hi
+hints
+home
+hosting
+hot
+hotreload
+hunk
+hurray
+i'm
+ia
+ikg
+illustrate
+implementor
+inclosure
+increased
+incrementally
+individual
+insertion
+inspect
+insufficient
+intact
+internet
+interpolate
+inv
+invalidating
+invariants
+isolate
+isolates
+iter
+iterations
+jumped
+ko
+la
+lacks
+largest
+lc
+ld
+le
+lets
+lightly
+likewise
+linebreaks
+linux
+listening
+ll
+logd
+logs
+loopback
+lots
+lub
+mac
+maker
+matters
+mc
+measured
+metric
+metrics
+mf
+micro
+mismatched
+miss
+misspelled
+mistake
+mistakes
+month
+mx
+mysdk
+negatable
+ninja
+nonexisting
+notion
+nullary
+numerator
+observable
+observatory
+oh
+okay
+oracle
+overlay
+parametrized
+party
+pause
+periodic
+periodically
+person
+phrase
+pink
+places
+policy
+portions
+pp
+preliminary
+prematurely
+pretends
+producer
+profiler
+promotes
+prop
+propagated
+protected
+provider
+pure
+pv
+px
+py
+quick
+quot
+r"\s
+rd
+reachability
+reality
+recompile
+redir
+redirections
+reducer
+referring
+reflectee
+reflective
+regenerate
+regressions
+reload
+repeating
+repo
+repro
+resource
+respected
+response
+retains
+rev
+say
+scans
+screen
+scripts
+secondary
+seconds
+segment
+shadowed
+shipped
+shot
+signalled
+simplify
+site
+somewhat
+spans
+spell
+spellcheck
+spelled
+spelling
+spent
+splitting
+sqrt
+statics
+std
+str
+strip
+strongest
+structures
+stub's
+subcommand
+subscription
+subtool
+subtools
+suite
+sum
+summarization
+summarized
+superinterface
+supermixin
+supplement
+swapped
+tags
+team
+templates
+terminator
+tester
+thereof
+thing
+threw
+timeout
+timer
+timing
+timings
+title
+toplevel
+tpt
+transforming
+transitively
+translation
+triangle
+trigger
+triggers
+trimming
+trivially
+truncated
+tt
+txt
+typeargs
+typeparam
+typeparambounds
+unassigned
+unawaited
+unbreak
+unification
+unordered
+unreachable
+unregistered
+untransformed
+uppercase
+upward
+usr
+usual
+val
+variants
+verbatim
+versa
+versioning
+vice
+vm's
+vs
+waiting
+walt
+wanted
+warmup
+weird
+whitelist
+whitelisting
+wins
+workflow
+x's
+xxx
+y's
+year
diff --git a/pkg/front_end/test/spell_checking_utils.dart b/pkg/front_end/test/spell_checking_utils.dart
index a06a9ff..7c3c21774 100644
--- a/pkg/front_end/test/spell_checking_utils.dart
+++ b/pkg/front_end/test/spell_checking_utils.dart
@@ -4,25 +4,56 @@
 
 import 'dart:io';
 
-Set<String> _dictionary;
-
-Set<String> spellcheckString(String s, {bool splitAsCode: false}) {
-  Set<String> wrongWords;
-  _dictionary ??= _loadDictionary();
-  List<String> words = splitStringIntoWords(s, splitAsCode: splitAsCode);
-  for (int i = 0; i < words.length; i++) {
-    String word = words[i].toLowerCase();
-    if (!_dictionary.contains(word)) {
-      wrongWords ??= new Set<String>();
-      wrongWords.add(word);
-    }
-  }
-  return wrongWords;
+enum Dictionaries {
+  common,
+  cfeMessages,
+  cfeCode,
+  cfeTests,
 }
 
-Set<String> _loadDictionary() {
-  Set<String> dictionary = new Set<String>();
-  addWords(Uri uri) {
+Map<Dictionaries, Set<String>> loadedDictionaries;
+
+SpellingResult spellcheckString(String s,
+    {List<Dictionaries> dictionaries, bool splitAsCode: false}) {
+  dictionaries ??= const [Dictionaries.common];
+  ensureDictionariesLoaded(dictionaries);
+
+  List<String> wrongWords;
+  List<int> wrongWordsOffset;
+  List<int> wordOffsets = new List<int>();
+  List<String> words =
+      splitStringIntoWords(s, wordOffsets, splitAsCode: splitAsCode);
+  for (int i = 0; i < words.length; i++) {
+    String word = words[i].toLowerCase();
+    int offset = wordOffsets[i];
+    bool found = false;
+    for (int j = 0; j < dictionaries.length; j++) {
+      Dictionaries dictionaryType = dictionaries[j];
+      Set<String> dictionary = loadedDictionaries[dictionaryType];
+      if (dictionary.contains(word)) {
+        found = true;
+        break;
+      }
+    }
+    if (!found) {
+      wrongWords ??= new List<String>();
+      wrongWords.add(word);
+      wrongWordsOffset ??= new List<int>();
+      wrongWordsOffset.add(offset);
+    }
+  }
+  return new SpellingResult(wrongWords, wrongWordsOffset);
+}
+
+class SpellingResult {
+  final List<String> misspelledWords;
+  final List<int> misspelledWordsOffset;
+
+  SpellingResult(this.misspelledWords, this.misspelledWordsOffset);
+}
+
+void ensureDictionariesLoaded(List<Dictionaries> dictionaries) {
+  void addWords(Uri uri, Set<String> dictionary) {
     for (String word in File.fromUri(uri)
         .readAsStringSync()
         .split("\n")
@@ -39,17 +70,38 @@
     }
   }
 
-  // TODO(jensj): Split list into several:
-  // * A common one with correctly spelled words.
-  // * A special one for messages.yaml.
-  // * A special one for source code in 'src'.
-  // * A special one for source code not in 'src'.
-  // and allow the caller to specify the combination of lists we want to use.
-  addWords(Uri.base.resolve("pkg/front_end/test/spell_checking_list.txt"));
-  return dictionary;
+  loadedDictionaries ??= new Map<Dictionaries, Set<String>>();
+  for (int j = 0; j < dictionaries.length; j++) {
+    Dictionaries dictionaryType = dictionaries[j];
+    Set<String> dictionary = loadedDictionaries[dictionaryType];
+    if (dictionary == null) {
+      dictionary = new Set<String>();
+      loadedDictionaries[dictionaryType] = dictionary;
+      addWords(dictionaryToUri(dictionaryType), dictionary);
+    }
+  }
 }
 
-List<String> splitStringIntoWords(String s, {bool splitAsCode: false}) {
+Uri dictionaryToUri(Dictionaries dictionaryType) {
+  switch (dictionaryType) {
+    case Dictionaries.common:
+      return Uri.base
+          .resolve("pkg/front_end/test/spell_checking_list_common.txt");
+    case Dictionaries.cfeMessages:
+      return Uri.base
+          .resolve("pkg/front_end/test/spell_checking_list_messages.txt");
+    case Dictionaries.cfeCode:
+      return Uri.base
+          .resolve("pkg/front_end/test/spell_checking_list_code.txt");
+    case Dictionaries.cfeTests:
+      return Uri.base
+          .resolve("pkg/front_end/test/spell_checking_list_tests.txt");
+  }
+  throw "Unknown Dictionary";
+}
+
+List<String> splitStringIntoWords(String s, List<int> splitOffsets,
+    {bool splitAsCode: false}) {
   List<String> result = new List<String>();
   // Match whitespace and the characters "-", "=", "|", "/", ",".
   String regExpStringInner = r"\s-=\|\/,";
@@ -66,9 +118,27 @@
     regExp = "([$regExpStringInner]|(\\\\n))+";
   }
 
-  List<String> split = s.split(new RegExp(regExp));
+  Iterator<RegExpMatch> matchesIterator =
+      new RegExp(regExp).allMatches(s).iterator;
+  int latestMatch = 0;
+  List<String> split = new List<String>();
+  List<int> splitOffset = new List<int>();
+  while (matchesIterator.moveNext()) {
+    RegExpMatch match = matchesIterator.current;
+    if (match.start > latestMatch) {
+      split.add(s.substring(latestMatch, match.start));
+      splitOffset.add(latestMatch);
+    }
+    latestMatch = match.end;
+  }
+  if (s.length > latestMatch) {
+    split.add(s.substring(latestMatch, s.length));
+    splitOffset.add(latestMatch);
+  }
+
   for (int i = 0; i < split.length; i++) {
-    String word = split[i].trim();
+    String word = split[i];
+    int offset = splitOffset[i];
     if (word.isEmpty) continue;
     int start = 0;
     int end = word.length;
@@ -147,6 +217,7 @@
             }
             if (doSpecialCase) {
               result.add(word.substring(start, i));
+              splitOffsets.add(offset + start);
               start = i;
             }
           }
@@ -158,6 +229,7 @@
             if (nextUnit >= 97 && nextUnit <= 122) {
               // Next is not capitalized.
               result.add(word.substring(start, i));
+              splitOffsets.add(offset + start);
               start = i;
             }
           }
@@ -165,6 +237,7 @@
           // Starting a new camel case word.
           if (i > start) {
             result.add(word.substring(start, i));
+            splitOffsets.add(offset + start);
             start = i;
           }
         } else if (prevCapitalized && !thisCapitalized) {
@@ -176,6 +249,7 @@
           // End of string.
           if (i >= start) {
             result.add(word.substring(start, end));
+            splitOffsets.add(offset + start);
           }
         }
         prevCapitalized = thisCapitalized;
@@ -183,6 +257,7 @@
     } else {
       result.add(
           (changedStart || changedEnd) ? word.substring(start, end) : word);
+      splitOffsets.add(offset + start);
     }
   }
   return result;
diff --git a/pkg/front_end/test/spell_checking_utils_test.dart b/pkg/front_end/test/spell_checking_utils_test.dart
index dd4a3bc..202dc65 100644
--- a/pkg/front_end/test/spell_checking_utils_test.dart
+++ b/pkg/front_end/test/spell_checking_utils_test.dart
@@ -5,108 +5,95 @@
 import 'spell_checking_utils.dart';
 
 void main() {
-  _expectList(splitStringIntoWords("Hello world"), ["Hello", "world"]);
-  _expectList(splitStringIntoWords("Hello\nworld"), ["Hello", "world"]);
-  _expectList(splitStringIntoWords("Hello 'world'"), ["Hello", "world"]);
-  _expectList(splitStringIntoWords("It's fun"), ["It's", "fun"]);
-  _expectList(splitStringIntoWords("It's 'fun'"), ["It's", "fun"]);
-  _expectList(splitStringIntoWords("exit-code"), ["exit", "code"]);
-  _expectList(splitStringIntoWords("fatal=warning"), ["fatal", "warning"]);
-  _expectList(splitStringIntoWords("vm|none"), ["vm", "none"]);
-  _expectList(splitStringIntoWords("vm/none"), ["vm", "none"]);
-  _expectList(splitStringIntoWords("vm,none"), ["vm", "none"]);
-  _expectList(splitStringIntoWords("One or more word(s)"),
-      ["One", "or", "more", "word(s)"]);
-  _expectList(splitStringIntoWords("One or more words)"),
-      ["One", "or", "more", "words"]);
-  _expectList(
-      splitStringIntoWords("It's 'fun' times 100"), ["It's", "fun", "times"]);
+  expectSplit("Hello world", false, ["Hello", "world"], [0, 6]);
+  expectSplit("Hello  world", false, ["Hello", "world"], [0, 7]);
+  expectSplit("Hello\nworld", false, ["Hello", "world"], [0, 6]);
+  expectSplit("Hello 'world'", false, ["Hello", "world"], [0, 7]);
+  expectSplit("It's fun", false, ["It's", "fun"], [0, 5]);
+  expectSplit("It's 'fun'", false, ["It's", "fun"], [0, 6]);
+  expectSplit("exit-code", false, ["exit", "code"], [0, 5]);
+  expectSplit("fatal=warning", false, ["fatal", "warning"], [0, 6]);
+  expectSplit("vm|none", false, ["vm", "none"], [0, 3]);
+  expectSplit("vm/none", false, ["vm", "none"], [0, 3]);
+  expectSplit("vm,none", false, ["vm", "none"], [0, 3]);
+  expectSplit("One or more word(s)", false, ["One", "or", "more", "word(s)"],
+      [0, 4, 7, 12]);
+  expectSplit("One or more words)", false, ["One", "or", "more", "words"],
+      [0, 4, 7, 12]);
+  expectSplit(
+      "It's 'fun' times 100", false, ["It's", "fun", "times"], [0, 6, 11]);
 
-  _expectList(splitStringIntoWords("splitCamelCase", splitAsCode: false),
-      ["splitCamelCase"]);
-  _expectList(splitStringIntoWords("splitCamelCase", splitAsCode: true),
-      ["split", "Camel", "Case"]);
-  _expectList(splitStringIntoWords("logicalAnd_end", splitAsCode: true),
-      ["logical", "And", "end"]);
-  _expectList(splitStringIntoWords("TheCNNAlso", splitAsCode: true),
-      ["The", "CNN", "Also"]);
-  _expectList(splitStringIntoWords("LOGICAL_OR_PRECEDENCE", splitAsCode: true),
-      ["LOGICAL", "OR", "PRECEDENCE"]);
+  expectSplit("splitCamelCase", false, ["splitCamelCase"], [0]);
+  expectSplit("splitCamelCase", true, ["split", "Camel", "Case"], [0, 5, 10]);
+  expectSplit("logicalAnd_end", true, ["logical", "And", "end"], [0, 7, 11]);
+  expectSplit("TheCNNAlso", true, ["The", "CNN", "Also"], [0, 3, 6]);
+  expectSplit("LOGICAL_OR_PRECEDENCE", true, ["LOGICAL", "OR", "PRECEDENCE"],
+      [0, 8, 11]);
 
-  _expectList(splitStringIntoWords("ThisIsTheCNN", splitAsCode: true),
-      ["This", "Is", "The", "CNN"]);
+  expectSplit("ThisIsTheCNN", true, ["This", "Is", "The", "CNN"], [0, 4, 6, 9]);
 
   // Special-case "A".
-  _expectList(splitStringIntoWords("notAConstant", splitAsCode: true),
-      ["not", "A", "Constant"]);
-  _expectList(
-      splitStringIntoWords("notAC", splitAsCode: true), ["not", "A", "C"]);
-  _expectList(
-      splitStringIntoWords("split_etc", splitAsCode: false), ["split_etc"]);
-  _expectList(
-      splitStringIntoWords("split_etc", splitAsCode: true), ["split", "etc"]);
-  _expectList(
-      splitStringIntoWords("split:etc", splitAsCode: false), ["split:etc"]);
-  _expectList(
-      splitStringIntoWords("split:etc", splitAsCode: true), ["split", "etc"]);
+  expectSplit("notAConstant", true, ["not", "A", "Constant"], [0, 3, 4]);
+  expectSplit("notAC", true, ["not", "A", "C"], [0, 3, 4]);
+  expectSplit("split_etc", false, ["split_etc"], [0]);
+  expectSplit("split_etc", true, ["split", "etc"], [0, 6]);
+  expectSplit("split:etc", false, ["split:etc"], [0]);
+  expectSplit("split:etc", true, ["split", "etc"], [0, 6]);
 
-  _expectList(splitStringIntoWords("vm.none", splitAsCode: false), ["vm.none"]);
-  _expectList(
-      splitStringIntoWords("vm.none", splitAsCode: true), ["vm", "none"]);
+  expectSplit("vm.none", false, ["vm.none"], [0]);
+  expectSplit("vm.none", true, ["vm", "none"], [0, 3]);
 
-  _expectList(splitStringIntoWords("ActualData(foo, bar)", splitAsCode: false),
-      ["ActualData(foo", "bar"]);
-  _expectList(splitStringIntoWords("ActualData(foo, bar)", splitAsCode: true),
-      ["Actual", "Data", "foo", "bar"]);
+  expectSplit(
+      "ActualData(foo, bar)", false, ["ActualData(foo", "bar"], [0, 16]);
+  expectSplit("ActualData(foo, bar)", true, ["Actual", "Data", "foo", "bar"],
+      [0, 6, 11, 16]);
 
-  _expectList(
-      splitStringIntoWords("List<int>", splitAsCode: false), ["List<int"]);
-  _expectList(
-      splitStringIntoWords("List<int>", splitAsCode: true), ["List", "int"]);
+  expectSplit("List<int>", false, ["List<int"], [0]);
+  expectSplit("List<int>", true, ["List", "int"], [0, 5]);
 
-  _expectList(
-      splitStringIntoWords("Platform.environment['TERM']", splitAsCode: false),
-      ["Platform.environment['TERM"]);
-  _expectList(
-      splitStringIntoWords("Platform.environment['TERM']", splitAsCode: true),
-      ["Platform", "environment", "TERM"]);
+  expectSplit("Platform.environment['TERM']", false,
+      ["Platform.environment['TERM"], [0]);
+  expectSplit("Platform.environment['TERM']", true,
+      ["Platform", "environment", "TERM"], [0, 9, 22]);
 
-  _expectList(splitStringIntoWords("DART2JS_PLATFORM", splitAsCode: false),
-      ["DART2JS_PLATFORM"]);
-  _expectList(splitStringIntoWords("DART2JS_PLATFORM", splitAsCode: true),
-      ["DART2JS", "PLATFORM"]);
+  expectSplit("DART2JS_PLATFORM", false, ["DART2JS_PLATFORM"], [0]);
+  expectSplit("DART2JS_PLATFORM", true, ["DART2JS", "PLATFORM"], [0, 8]);
 
-  _expectList(splitStringIntoWords("Foo\\n", splitAsCode: false), ["Foo\\n"]);
-  _expectList(splitStringIntoWords("Foo\\n", splitAsCode: true), ["Foo"]);
+  expectSplit("Foo\\n", false, ["Foo\\n"], [0]);
+  expectSplit("Foo\\n", true, ["Foo"], [0]);
 
-  _expectList(
-      splitStringIntoWords("foo({bar})", splitAsCode: false), ["foo({bar"]);
-  _expectList(
-      splitStringIntoWords("foo({bar})", splitAsCode: true), ["foo", "bar"]);
+  expectSplit("foo({bar})", false, ["foo({bar"], [0]);
+  expectSplit("foo({bar})", true, ["foo", "bar"], [0, 5]);
 
-  _expectList(splitStringIntoWords("foo@bar", splitAsCode: false), ["foo@bar"]);
-  _expectList(
-      splitStringIntoWords("foo@bar", splitAsCode: true), ["foo", "bar"]);
+  expectSplit("foo@bar", false, ["foo@bar"], [0]);
+  expectSplit("foo@bar", true, ["foo", "bar"], [0, 4]);
 
-  _expectList(splitStringIntoWords("foo#bar", splitAsCode: false), ["foo#bar"]);
-  _expectList(
-      splitStringIntoWords("foo#bar", splitAsCode: true), ["foo", "bar"]);
+  expectSplit("foo#bar", false, ["foo#bar"], [0]);
+  expectSplit("foo#bar", true, ["foo", "bar"], [0, 4]);
 
-  _expectList(splitStringIntoWords("foo&bar", splitAsCode: false), ["foo&bar"]);
-  _expectList(
-      splitStringIntoWords("foo&bar", splitAsCode: true), ["foo", "bar"]);
+  expectSplit("foo&bar", false, ["foo&bar"], [0]);
+  expectSplit("foo&bar", true, ["foo", "bar"], [0, 4]);
 
-  _expectList(splitStringIntoWords("foo?bar", splitAsCode: false), ["foo?bar"]);
-  _expectList(
-      splitStringIntoWords("foo?bar", splitAsCode: true), ["foo", "bar"]);
+  expectSplit("foo?bar", false, ["foo?bar"], [0]);
+  expectSplit("foo?bar", true, ["foo", "bar"], [0, 4]);
 
   print("OK");
 }
 
-void _expectList(List<String> actual, List<String> expected) {
-  if (actual.length != expected.length)
-    throw "Not the same ($actual vs $expected)";
-  for (int i = 0; i < actual.length; i++) {
-    if (actual[i] != expected[i]) throw "Not the same ($actual vs $expected)";
+void expectSplit(String s, bool splitAsCode, List<String> expectedWords,
+    List<int> expectedOffsets) {
+  List<int> actualOffsets = new List<int>();
+  List<String> actualWords =
+      splitStringIntoWords(s, actualOffsets, splitAsCode: splitAsCode);
+  if (actualWords.length != expectedWords.length) {
+    throw "Not the same ($actualWords vs $expectedWords)";
+  }
+  for (int i = 0; i < actualWords.length; i++) {
+    if (actualWords[i] != expectedWords[i]) {
+      throw "Not the same ($actualWords vs $expectedWords)";
+    }
+    if (actualOffsets[i] != expectedOffsets[i]) {
+      throw "Not the same ($actualOffsets vs $expectedOffsets)";
+    }
   }
 }
diff --git a/pkg/front_end/test/spelling_test.dart b/pkg/front_end/test/spelling_test.dart
deleted file mode 100644
index d65ed1c..0000000
--- a/pkg/front_end/test/spelling_test.dart
+++ /dev/null
@@ -1,114 +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.
-
-import 'dart:async' show Future;
-
-import 'dart:io' show File;
-
-import 'dart:typed_data' show Uint8List;
-
-import 'package:front_end/src/fasta/scanner.dart' show ErrorToken;
-
-import 'package:front_end/src/fasta/scanner/utf8_bytes_scanner.dart'
-    show Utf8BytesScanner;
-
-import 'package:front_end/src/scanner/token.dart'
-    show Token, KeywordToken, BeginToken;
-import 'package:front_end/src/scanner/token.dart';
-
-import 'package:testing/testing.dart'
-    show Chain, ChainContext, Result, Step, TestDescription, runMe;
-
-import 'spell_checking_utils.dart' as spell;
-
-main([List<String> arguments = const []]) =>
-    runMe(arguments, createContext, "../testing.json");
-
-Future<Context> createContext(
-    Chain suite, Map<String, String> environment) async {
-  return new Context();
-}
-
-class Context extends ChainContext {
-  final List<Step> steps = const <Step>[
-    const SpellTest(),
-  ];
-
-  // Override special handling of negative tests.
-  @override
-  Result processTestResult(
-      TestDescription description, Result result, bool last) {
-    return result;
-  }
-}
-
-class SpellTest extends Step<TestDescription, TestDescription, Context> {
-  const SpellTest();
-
-  String get name => "spell test";
-
-  Future<Result<TestDescription>> run(
-      TestDescription description, Context context) async {
-    File f = new File.fromUri(description.uri);
-    List<int> rawBytes = f.readAsBytesSync();
-
-    Uint8List bytes = new Uint8List(rawBytes.length + 1);
-    bytes.setRange(0, rawBytes.length, rawBytes);
-
-    Utf8BytesScanner scanner =
-        new Utf8BytesScanner(bytes, includeComments: true);
-    Token firstToken = scanner.tokenize();
-    if (firstToken == null) return null;
-    Token token = firstToken;
-
-    List<String> errors;
-
-    while (token != null) {
-      if (token is ErrorToken) {
-        // For now just accept that.
-        return pass(description);
-      }
-      if (token.precedingComments != null) {
-        Token comment = token.precedingComments;
-        while (comment != null) {
-          Set<String> misspelled =
-              spell.spellcheckString(comment.lexeme, splitAsCode: true);
-          if (misspelled != null) {
-            errors ??= new List<String>();
-            errors.add("Misspelled words around offset ${comment.offset}: "
-                "${misspelled.toList()}");
-          }
-          comment = comment.next;
-        }
-      }
-      if (token is StringToken) {
-        Set<String> misspelled =
-            spell.spellcheckString(token.lexeme, splitAsCode: true);
-        if (misspelled != null) {
-          errors ??= new List<String>();
-          errors.add("Misspelled words around offset ${token.offset}: "
-              "${misspelled.toList()}");
-        }
-      } else if (token is KeywordToken || token is BeginToken) {
-        // Ignored.
-      } else if (token.runtimeType.toString() == "SimpleToken") {
-        // Ignored.
-      } else {
-        throw "Unsupported token type: ${token.runtimeType} ($token)";
-      }
-
-      if (token.isEof) break;
-
-      token = token.next;
-    }
-
-    if (errors == null) {
-      return pass(description);
-    } else {
-      // TODO(jensj): Point properly in the source code like compilation errors
-      // do.
-      return fail(description, errors.join("\n"));
-    }
-  }
-}
diff --git a/pkg/front_end/test/spelling_test_base.dart b/pkg/front_end/test/spelling_test_base.dart
new file mode 100644
index 0000000..274ac0e
--- /dev/null
+++ b/pkg/front_end/test/spelling_test_base.dart
@@ -0,0 +1,133 @@
+// 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.
+
+import 'dart:async' show Future;
+
+import 'dart:io' show File;
+
+import 'dart:typed_data' show Uint8List;
+
+import 'package:front_end/src/fasta/command_line_reporting.dart'
+    as command_line_reporting;
+
+import 'package:front_end/src/fasta/scanner.dart' show ErrorToken;
+
+import 'package:front_end/src/fasta/scanner/utf8_bytes_scanner.dart'
+    show Utf8BytesScanner;
+
+import 'package:front_end/src/scanner/token.dart'
+    show Token, KeywordToken, BeginToken;
+
+import 'package:front_end/src/scanner/token.dart';
+
+import 'package:kernel/kernel.dart';
+
+import 'package:testing/testing.dart'
+    show ChainContext, Result, Step, TestDescription;
+
+import 'spell_checking_utils.dart' as spell;
+
+abstract class Context extends ChainContext {
+  final List<Step> steps = const <Step>[
+    const SpellTest(),
+  ];
+
+  // Override special handling of negative tests.
+  @override
+  Result processTestResult(
+      TestDescription description, Result result, bool last) {
+    return result;
+  }
+
+  List<spell.Dictionaries> get dictionaries;
+}
+
+class SpellTest extends Step<TestDescription, TestDescription, Context> {
+  const SpellTest();
+
+  String get name => "spell test";
+
+  Future<Result<TestDescription>> run(
+      TestDescription description, Context context) async {
+    File f = new File.fromUri(description.uri);
+    List<int> rawBytes = f.readAsBytesSync();
+
+    Uint8List bytes = new Uint8List(rawBytes.length + 1);
+    bytes.setRange(0, rawBytes.length, rawBytes);
+
+    Utf8BytesScanner scanner =
+        new Utf8BytesScanner(bytes, includeComments: true);
+    Token firstToken = scanner.tokenize();
+    if (firstToken == null) return null;
+    Token token = firstToken;
+
+    List<String> errors;
+    Source source = new Source(
+        scanner.lineStarts, rawBytes, description.uri, description.uri);
+    void addErrorMessage(int offset, int squigglyLength, String message) {
+      errors ??= new List<String>();
+      Location location = source.getLocation(description.uri, offset);
+      errors.add(command_line_reporting.formatErrorMessage(
+          source.getTextLine(location.line),
+          location,
+          squigglyLength,
+          description.uri.toString(),
+          message));
+    }
+
+    while (token != null) {
+      if (token is ErrorToken) {
+        // For now just accept that.
+        return pass(description);
+      }
+      if (token.precedingComments != null) {
+        Token comment = token.precedingComments;
+        while (comment != null) {
+          spell.SpellingResult spellingResult = spell.spellcheckString(
+              comment.lexeme,
+              splitAsCode: true,
+              dictionaries: context.dictionaries);
+          if (spellingResult.misspelledWords != null) {
+            for (int i = 0; i < spellingResult.misspelledWords.length; i++) {
+              int offset =
+                  comment.offset + spellingResult.misspelledWordsOffset[i];
+              String word = spellingResult.misspelledWords[i];
+              addErrorMessage(offset, word.length, "Misspelled word '$word'.");
+            }
+          }
+          comment = comment.next;
+        }
+      }
+      if (token is StringToken) {
+        spell.SpellingResult spellingResult = spell.spellcheckString(
+            token.lexeme,
+            splitAsCode: true,
+            dictionaries: context.dictionaries);
+        if (spellingResult.misspelledWords != null) {
+          for (int i = 0; i < spellingResult.misspelledWords.length; i++) {
+            int offset = token.offset + spellingResult.misspelledWordsOffset[i];
+            String word = spellingResult.misspelledWords[i];
+            addErrorMessage(offset, word.length, "Misspelled word '$word'.");
+          }
+        }
+      } else if (token is KeywordToken || token is BeginToken) {
+        // Ignored.
+      } else if (token.runtimeType.toString() == "SimpleToken") {
+        // Ignored.
+      } else {
+        throw "Unsupported token type: ${token.runtimeType} ($token)";
+      }
+
+      if (token.isEof) break;
+
+      token = token.next;
+    }
+
+    if (errors == null) {
+      return pass(description);
+    } else {
+      return fail(description, errors.join("\n\n"));
+    }
+  }
+}
diff --git a/pkg/front_end/test/spelling_test_not_src_test.dart b/pkg/front_end/test/spelling_test_not_src_test.dart
new file mode 100644
index 0000000..e1f675a
--- /dev/null
+++ b/pkg/front_end/test/spelling_test_not_src_test.dart
@@ -0,0 +1,28 @@
+// 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.
+
+import 'dart:async' show Future;
+
+import 'package:testing/testing.dart' show Chain, runMe;
+
+import 'spelling_test_base.dart';
+
+import 'spell_checking_utils.dart' as spell;
+
+main([List<String> arguments = const []]) =>
+    runMe(arguments, createContext, "../testing.json");
+
+Future<Context> createContext(
+    Chain suite, Map<String, String> environment) async {
+  return new ContextTest();
+}
+
+class ContextTest extends Context {
+  @override
+  List<spell.Dictionaries> get dictionaries => const <spell.Dictionaries>[
+        spell.Dictionaries.common,
+        spell.Dictionaries.cfeCode,
+        spell.Dictionaries.cfeTests
+      ];
+}
diff --git a/pkg/front_end/test/spelling_test_src_test.dart b/pkg/front_end/test/spelling_test_src_test.dart
new file mode 100644
index 0000000..73cdc8d
--- /dev/null
+++ b/pkg/front_end/test/spelling_test_src_test.dart
@@ -0,0 +1,27 @@
+// 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.
+
+import 'dart:async' show Future;
+
+import 'package:testing/testing.dart' show Chain, runMe;
+
+import 'spelling_test_base.dart';
+
+import 'spell_checking_utils.dart' as spell;
+
+main([List<String> arguments = const []]) =>
+    runMe(arguments, createContext, "../testing.json");
+
+Future<Context> createContext(
+    Chain suite, Map<String, String> environment) async {
+  return new ContextSrc();
+}
+
+class ContextSrc extends Context {
+  @override
+  List<spell.Dictionaries> get dictionaries => const <spell.Dictionaries>[
+        spell.Dictionaries.common,
+        spell.Dictionaries.cfeCode
+      ];
+}
diff --git a/pkg/front_end/test/src/base/processed_options_test.dart b/pkg/front_end/test/src/base/processed_options_test.dart
index 0abc4cb..6634144 100644
--- a/pkg/front_end/test/src/base/processed_options_test.dart
+++ b/pkg/front_end/test/src/base/processed_options_test.dart
@@ -89,7 +89,7 @@
   test_getSdkSummary_summaryLocationProvided() async {
     var uri = Uri.parse('org-dartlang-test:///sdkSummary');
     writeMockSummaryTo(uri);
-    checkMockSummary(new CompilerOptions()
+    await checkMockSummary(new CompilerOptions()
       ..fileSystem = fileSystem
       ..sdkSummary = uri);
   }
diff --git a/pkg/front_end/test/static_types/data/greatest_lower_bound_for_future_or.dart b/pkg/front_end/test/static_types/data/greatest_lower_bound_for_future_or.dart
new file mode 100644
index 0000000..40e7d21
--- /dev/null
+++ b/pkg/front_end/test/static_types/data/greatest_lower_bound_for_future_or.dart
@@ -0,0 +1,78 @@
+// 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.
+
+// This test checks that the greatest lower bound between two types is
+// calculated correctly, in case one of them is a FutureOr.
+
+import 'dart:async';
+
+class Foo {}
+
+// -----------------------------------------------------------------------------
+
+// Tests rule GLB(FutureOr<A>, B) == GLB(A, B).
+void func1<T extends Foo>(T t) {
+  // Here and in the test cases below 'context' provides the typing context via
+  // the type of its parameter.  The context is imposed onto the return type of
+  // 'expr' that is a type-parameter type.  It leads to evaluation of GLB of the
+  // typing context and the bound of the type parameter.  The computed GLB is
+  // inserted as both the type argument and the return type of 'expr' by the
+  // type inference.
+  void context(FutureOr<T> x) {}
+  S expr<S extends Foo>() => /*Null*/ null;
+
+  // Type of the expression is GLB(FutureOr<T>, Foo) = T.
+  /*invoke: void*/ context(/*invoke: T*/ expr/*<T>*/());
+}
+
+// -----------------------------------------------------------------------------
+
+// Tests rule GLB(FutureOr<A>, Future<B>) == Future<GLB(A, B)>.
+void func2<T extends Foo>() {
+  void context(FutureOr<T> x) {}
+  S expr<S extends Future<Foo>>() => /*Null*/ null;
+
+  // Type of the expression is GLB(FutureOr<T>, Future<Foo>) = Future<T>.
+  /*invoke: void*/ context(/*invoke: Future<T>*/ expr/*<Future<T>>*/());
+}
+
+// -----------------------------------------------------------------------------
+
+// Tests rule GLB(A, FutureOr<B>) == GLB(B, A).
+void func3<T extends Foo>() {
+  void context(T x) {}
+  S expr<S extends FutureOr<Foo>>() => /*Null*/ null;
+
+  // Type of the expression is GLB(T, FutureOr<Foo>) = T.
+  /*invoke: void*/ context(/*invoke: T*/ expr/*<T>*/());
+}
+
+// -----------------------------------------------------------------------------
+
+// Tests rule GLB(Future<A>, FutureOr<B>) == Future<GLB(B, A)>.
+void func4<T extends Foo>() {
+  void context(Future<T> x) {}
+  S expr<S extends FutureOr<Foo>>() => /*Null*/ null;
+
+  // Type of the expression is GLB(Future<T>, FutureOr<Foo>) = Future<T>.
+  /*invoke: void*/ context(/*invoke: Future<T>*/ expr/*<Future<T>>*/());
+}
+
+// -----------------------------------------------------------------------------
+
+// Tests rule GLB(FutureOr<A>, FutureOr<B>) == FutureOr<GLB(A, B)> in the
+// non-trivial case when neither A <: B, nor B <: A.
+void func5<T extends Foo>() {
+  void context(FutureOr<FutureOr<T>> x) {}
+  S expr<S extends FutureOr<Future<Foo>>>() => /*Null*/ null;
+
+  // Type of the expression is GLB(FutureOr<FutureOr<T>>, FutureOr<Future<Foo>>)
+  // = FutureOr<Future<T>>.
+  /*invoke: void*/ context(
+      /*invoke: FutureOr<Future<T>>*/ expr/*<FutureOr<Future<T>>>*/());
+}
+
+// -----------------------------------------------------------------------------
+
+main() {}
diff --git a/pkg/front_end/test/static_types/data/issue37439.dart b/pkg/front_end/test/static_types/data/issue37439.dart
deleted file mode 100644
index 253ac53..0000000
--- a/pkg/front_end/test/static_types/data/issue37439.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.
-
-class A {}
-
-class B extends A {}
-
-Future<T> func1<T extends A>(T t) async {
-  // TODO(37439): We should infer 'T' instead of '<bottom>'.
-  return /*invoke: <bottom>*/ func2/*<<bottom>>*/(/*as: <bottom>*/ /*T*/ t);
-}
-
-T func2<T extends A>(T t) => /*T*/ t;
-
-main() async {
-  /*B*/ await /*invoke: Future<B>*/ func1/*<B>*/(/*B*/ B());
-}
diff --git a/pkg/front_end/test/type_labeler_test.dart b/pkg/front_end/test/type_labeler_test.dart
index d303273..c904fbd 100644
--- a/pkg/front_end/test/type_labeler_test.dart
+++ b/pkg/front_end/test/type_labeler_test.dart
@@ -220,7 +220,7 @@
   Constant bazFooFoo2Const = new InstanceConstant(bazClass.reference,
       [foo, foo2], {xField.reference: fooConst, yField.reference: foo2Const});
   check({
-    bazFooFoo2Const: "Baz<Foo/*1*/, Foo/*2*/> " +
+    bazFooFoo2Const: "Baz<Foo/*1*/, Foo/*2*/> "
         "{x: Foo/*1*/ {boo: true}, y: Foo/*2*/ {value: 2, next: null}}"
   }, 3);
 
diff --git a/pkg/front_end/testcases/extensions/direct_instance_access.dart b/pkg/front_end/testcases/extensions/direct_instance_access.dart
new file mode 100644
index 0000000..32094b5
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/direct_instance_access.dart
@@ -0,0 +1,199 @@
+// 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.
+
+class Class {
+  var field;
+}
+
+extension Extension on Class {
+  readGetter() {
+    return property;
+  }
+
+  writeSetterRequired(value) {
+    property = value;
+  }
+
+  writeSetterOptional([value]) {
+    property = value;
+  }
+
+  writeSetterNamed({value}) {
+    property = value;
+  }
+
+  get tearOffGetterNoArgs => readGetter;
+  get tearOffGetterRequired => writeSetterRequired;
+  get tearOffGetterOptional => writeSetterOptional;
+  get tearOffGetterNamed => writeSetterNamed;
+
+  get property => this.field;
+
+  set property(value) {
+    this.field = value;
+  }
+
+  invocations(value) {
+    readGetter();
+    writeSetterRequired(value);
+    writeSetterOptional();
+    writeSetterOptional(value);
+    writeSetterNamed();
+    writeSetterNamed(value: value);
+  }
+
+  tearOffs(value) {
+    var tearOffNoArgs = readGetter;
+    tearOffNoArgs();
+    var tearOffRequired = writeSetterRequired;
+    tearOffRequired(value);
+    var tearOffOptional = writeSetterOptional;
+    tearOffOptional();
+    tearOffOptional(value);
+    var tearOffNamed = writeSetterNamed;
+    tearOffNamed();
+    tearOffNamed(value: value);
+  }
+
+  getterCalls(value) {
+    tearOffGetterNoArgs();
+    tearOffGetterRequired(value);
+    tearOffGetterOptional();
+    tearOffGetterOptional(value);
+    tearOffGetterNamed();
+    tearOffGetterNamed(value: value);
+  }
+}
+
+class GenericClass<T> {
+  T field;
+}
+
+extension GenericExtension<T> on GenericClass<T> {
+  T readGetter() {
+    return property;
+  }
+
+  writeSetterRequired(T value) {
+    property = value;
+  }
+
+  writeSetterOptional([T value]) {
+   property = value;
+  }
+
+  writeSetterNamed({T value}) {
+    property = value;
+  }
+
+  genericWriteSetterRequired<S extends T>(S value) {
+   property = value;
+  }
+
+  genericWriteSetterOptional<S extends T>([S value]) {
+    property = value;
+  }
+
+  genericWriteSetterNamed<S extends T>({S value}) {
+   property = value;
+  }
+
+  T get property => this.field;
+
+  void set property(T value) {
+    this.field = value;
+  }
+
+  get tearOffGetterNoArgs => readGetter;
+  get tearOffGetterRequired => writeSetterRequired;
+  get tearOffGetterOptional => writeSetterOptional;
+  get tearOffGetterNamed => writeSetterNamed;
+  get tearOffGetterGenericRequired => genericWriteSetterRequired;
+  get tearOffGetterGenericOptional => genericWriteSetterOptional;
+  get tearOffGetterGenericNamed => genericWriteSetterNamed;
+
+  invocations<S extends T>(S value) {
+    readGetter();
+    writeSetterRequired(value);
+    writeSetterOptional();
+    writeSetterOptional(value);
+    writeSetterNamed();
+    writeSetterNamed(value: value);
+    // TODO(johnniwinther): Handle direct calls to generic methods. This
+    // requires inference to special-case the extension type parameters and
+    // perform a two-step type argument inference.
+    /*genericWriteSetterRequired(value);
+    genericWriteSetterRequired<T>(value);
+    genericWriteSetterRequired<S>(value);
+    genericWriteSetterOptional();
+    genericWriteSetterOptional<T>();
+    genericWriteSetterOptional<S>();
+    genericWriteSetterOptional(value);
+    genericWriteSetterOptional<T>(value);
+    genericWriteSetterOptional<S>(value);
+    genericWriteSetterNamed();
+    genericWriteSetterNamed<T>();
+    genericWriteSetterNamed<S>();
+    genericWriteSetterNamed(value: value);
+    genericWriteSetterNamed<T>(value: value);
+    genericWriteSetterNamed<S>(value: value);*/
+  }
+
+  tearOffs<S extends T>(S value) {
+    var tearOffNoArgs = readGetter;
+    tearOffNoArgs();
+    var tearOffRequired = writeSetterRequired;
+    tearOffRequired(value);
+    var tearOffOptional = writeSetterOptional;
+    tearOffOptional();
+    tearOffOptional(value);
+    var tearOffNamed = writeSetterNamed;
+    tearOffNamed();
+    tearOffNamed(value: value);
+    var genericTearOffRequired = genericWriteSetterRequired;
+    genericTearOffRequired(value);
+    genericTearOffRequired<T>(value);
+    genericTearOffRequired<S>(value);
+    var genericTearOffOptional = genericWriteSetterOptional;
+    genericTearOffOptional();
+    genericTearOffOptional<T>();
+    genericTearOffOptional<S>();
+    genericTearOffOptional(value);
+    genericTearOffOptional<T>(value);
+    genericTearOffOptional<S>(value);
+    var genericTearOffNamed = genericWriteSetterNamed;
+    genericTearOffNamed();
+    genericTearOffNamed<T>();
+    genericTearOffNamed<S>();
+    genericTearOffNamed(value: value);
+    genericTearOffNamed<T>(value: value);
+    genericTearOffNamed<S>(value: value);
+  }
+
+  getterCalls<S extends T>(S value) {
+    tearOffGetterNoArgs();
+    tearOffGetterRequired(value);
+    tearOffGetterOptional();
+    tearOffGetterOptional(value);
+    tearOffGetterNamed();
+    tearOffGetterNamed(value: value);
+    tearOffGetterGenericRequired(value);
+    tearOffGetterGenericRequired<T>(value);
+    tearOffGetterGenericRequired<S>(value);
+    tearOffGetterGenericOptional();
+    tearOffGetterGenericOptional<T>();
+    tearOffGetterGenericOptional<S>();
+    tearOffGetterGenericOptional(value);
+    tearOffGetterGenericOptional<T>(value);
+    tearOffGetterGenericOptional<S>(value);
+    tearOffGetterGenericNamed();
+    tearOffGetterGenericNamed<T>();
+    tearOffGetterGenericNamed<S>();
+    tearOffGetterGenericNamed(value: value);
+    tearOffGetterGenericNamed<T>(value: value);
+    tearOffGetterGenericNamed<S>(value: value);
+  }
+}
+
+main() {}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/extensions/direct_instance_access.dart.hierarchy.expect b/pkg/front_end/testcases/extensions/direct_instance_access.dart.hierarchy.expect
new file mode 100644
index 0000000..e70886a
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/direct_instance_access.dart.hierarchy.expect
@@ -0,0 +1,57 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Class:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Class.field
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Class.field
+
+GenericClass:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    GenericClass.field
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    GenericClass.field
diff --git a/pkg/front_end/testcases/extensions/direct_instance_access.dart.legacy.expect b/pkg/front_end/testcases/extensions/direct_instance_access.dart.legacy.expect
new file mode 100644
index 0000000..6763e94
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/direct_instance_access.dart.legacy.expect
@@ -0,0 +1,313 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:9:1: Error: This requires the 'extension-methods' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// extension Extension on Class {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:9:24: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// extension Extension on Class {
+//                        ^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:9:24: Error: 'Class' is already declared in this scope.
+// extension Extension on Class {
+//                        ^^^^^
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:5:7: Context: Previous declaration of 'Class'.
+// class Class {
+//       ^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:73:11: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// extension GenericExtension<T> on GenericClass<T> {
+//           ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:73:31: Error: Expected '{' before this.
+// extension GenericExtension<T> on GenericClass<T> {
+//                               ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:73:34: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// extension GenericExtension<T> on GenericClass<T> {
+//                                  ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:73:34: Error: 'GenericClass' is already declared in this scope.
+// extension GenericExtension<T> on GenericClass<T> {
+//                                  ^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:69:7: Context: Previous declaration of 'GenericClass'.
+// class GenericClass<T> {
+//       ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:9:1: Warning: Type 'extension' not found.
+// extension Extension on Class {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:9:21: Warning: Type 'on' not found.
+// extension Extension on Class {
+//                     ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:73:1: Warning: Type 'extension' not found.
+// extension GenericExtension<T> on GenericClass<T> {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:73:31: Warning: Type 'on' not found.
+// extension GenericExtension<T> on GenericClass<T> {
+//                               ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:9:1: Warning: 'extension' isn't a type.
+// extension Extension on Class {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:11:12: Warning: Getter not found: 'property'.
+//     return property;
+//            ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:15:5: Warning: Setter not found: 'property'.
+//     property = value;
+//     ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:19:5: Warning: Setter not found: 'property'.
+//     property = value;
+//     ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:23:5: Warning: Setter not found: 'property'.
+//     property = value;
+//     ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:26:3: Error: Expected ';' after this.
+//   get tearOffGetterNoArgs => readGetter;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:26:3: Warning: Getter not found: 'get'.
+//   get tearOffGetterNoArgs => readGetter;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:26:27: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   get tearOffGetterNoArgs => readGetter;
+//                           ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:27:3: Error: Expected ';' after this.
+//   get tearOffGetterRequired => writeSetterRequired;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:27:3: Warning: Getter not found: 'get'.
+//   get tearOffGetterRequired => writeSetterRequired;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:27:29: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   get tearOffGetterRequired => writeSetterRequired;
+//                             ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:28:3: Error: Expected ';' after this.
+//   get tearOffGetterOptional => writeSetterOptional;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:28:3: Warning: Getter not found: 'get'.
+//   get tearOffGetterOptional => writeSetterOptional;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:28:29: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   get tearOffGetterOptional => writeSetterOptional;
+//                             ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:29:3: Error: Expected ';' after this.
+//   get tearOffGetterNamed => writeSetterNamed;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:29:3: Warning: Getter not found: 'get'.
+//   get tearOffGetterNamed => writeSetterNamed;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:29:26: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   get tearOffGetterNamed => writeSetterNamed;
+//                          ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:31:3: Error: Expected ';' after this.
+//   get property => this.field;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:31:3: Warning: Getter not found: 'get'.
+//   get property => this.field;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:31:7: Error: Can't declare 'property' because it was already used in this scope.
+//   get property => this.field;
+//       ^^^^^^^^
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:11:12: Context: Previous use of 'property'.
+//     return property;
+//            ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:31:16: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   get property => this.field;
+//                ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:31:19: Error: Expected identifier, but got 'this'.
+//   get property => this.field;
+//                   ^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:33:3: Error: Unexpected token 'set'.
+//   set property(value) {
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:33:7: Error: Can't declare 'property' because it was already used in this scope.
+//   set property(value) {
+//       ^^^^^^^^
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:11:12: Context: Previous use of 'property'.
+//     return property;
+//            ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:34:5: Error: Expected identifier, but got 'this'.
+//     this.field = value;
+//     ^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:75:12: Warning: Getter not found: 'property'.
+//     return property;
+//            ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:79:5: Warning: Setter not found: 'property'.
+//     property = value;
+//     ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:83:4: Warning: Setter not found: 'property'.
+//    property = value;
+//    ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:87:5: Warning: Setter not found: 'property'.
+//     property = value;
+//     ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:91:4: Warning: Setter not found: 'property'.
+//    property = value;
+//    ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:95:5: Warning: Setter not found: 'property'.
+//     property = value;
+//     ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:99:4: Warning: Setter not found: 'property'.
+//    property = value;
+//    ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:102:5: Error: Expected ';' after this.
+//   T get property => this.field;
+//     ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:102:9: Error: Can't declare 'property' because it was already used in this scope.
+//   T get property => this.field;
+//         ^^^^^^^^
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:75:12: Context: Previous use of 'property'.
+//     return property;
+//            ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:102:18: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   T get property => this.field;
+//                  ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:102:21: Error: Expected identifier, but got 'this'.
+//   T get property => this.field;
+//                     ^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:104:8: Error: Expected ';' after this.
+//   void set property(T value) {
+//        ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:104:12: Error: Can't declare 'property' because it was already used in this scope.
+//   void set property(T value) {
+//            ^^^^^^^^
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:75:12: Context: Previous use of 'property'.
+//     return property;
+//            ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:105:5: Error: Expected identifier, but got 'this'.
+//     this.field = value;
+//     ^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:108:3: Error: Expected ';' after this.
+//   get tearOffGetterNoArgs => readGetter;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:108:27: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   get tearOffGetterNoArgs => readGetter;
+//                           ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:109:3: Error: Expected ';' after this.
+//   get tearOffGetterRequired => writeSetterRequired;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:109:29: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   get tearOffGetterRequired => writeSetterRequired;
+//                             ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:110:3: Error: Expected ';' after this.
+//   get tearOffGetterOptional => writeSetterOptional;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:110:29: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   get tearOffGetterOptional => writeSetterOptional;
+//                             ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:111:3: Error: Expected ';' after this.
+//   get tearOffGetterNamed => writeSetterNamed;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:111:26: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   get tearOffGetterNamed => writeSetterNamed;
+//                          ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:112:3: Error: Expected ';' after this.
+//   get tearOffGetterGenericRequired => genericWriteSetterRequired;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:112:36: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   get tearOffGetterGenericRequired => genericWriteSetterRequired;
+//                                    ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:113:3: Error: Expected ';' after this.
+//   get tearOffGetterGenericOptional => genericWriteSetterOptional;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:113:36: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   get tearOffGetterGenericOptional => genericWriteSetterOptional;
+//                                    ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:114:3: Error: Expected ';' after this.
+//   get tearOffGetterGenericNamed => genericWriteSetterNamed;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:114:33: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   get tearOffGetterGenericNamed => genericWriteSetterNamed;
+//                                 ^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field dynamic field = null;
+  synthetic constructor •() → self::Class*
+    : super core::Object::•()
+    ;
+}
+class GenericClass<T extends core::Object* = dynamic> extends core::Object {
+  generic-covariant-impl field self::GenericClass::T* field = null;
+  synthetic constructor •() → self::GenericClass<self::GenericClass::T*>*
+    : super core::Object::•()
+    ;
+}
+static field invalid-type Extension;
+static method GenericExtension<T extends core::Object* = dynamic>() → invalid-type {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/direct_instance_access.dart.legacy.transformed.expect b/pkg/front_end/testcases/extensions/direct_instance_access.dart.legacy.transformed.expect
new file mode 100644
index 0000000..6763e94
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/direct_instance_access.dart.legacy.transformed.expect
@@ -0,0 +1,313 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:9:1: Error: This requires the 'extension-methods' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// extension Extension on Class {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:9:24: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// extension Extension on Class {
+//                        ^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:9:24: Error: 'Class' is already declared in this scope.
+// extension Extension on Class {
+//                        ^^^^^
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:5:7: Context: Previous declaration of 'Class'.
+// class Class {
+//       ^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:73:11: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// extension GenericExtension<T> on GenericClass<T> {
+//           ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:73:31: Error: Expected '{' before this.
+// extension GenericExtension<T> on GenericClass<T> {
+//                               ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:73:34: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// extension GenericExtension<T> on GenericClass<T> {
+//                                  ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:73:34: Error: 'GenericClass' is already declared in this scope.
+// extension GenericExtension<T> on GenericClass<T> {
+//                                  ^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:69:7: Context: Previous declaration of 'GenericClass'.
+// class GenericClass<T> {
+//       ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:9:1: Warning: Type 'extension' not found.
+// extension Extension on Class {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:9:21: Warning: Type 'on' not found.
+// extension Extension on Class {
+//                     ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:73:1: Warning: Type 'extension' not found.
+// extension GenericExtension<T> on GenericClass<T> {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:73:31: Warning: Type 'on' not found.
+// extension GenericExtension<T> on GenericClass<T> {
+//                               ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:9:1: Warning: 'extension' isn't a type.
+// extension Extension on Class {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:11:12: Warning: Getter not found: 'property'.
+//     return property;
+//            ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:15:5: Warning: Setter not found: 'property'.
+//     property = value;
+//     ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:19:5: Warning: Setter not found: 'property'.
+//     property = value;
+//     ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:23:5: Warning: Setter not found: 'property'.
+//     property = value;
+//     ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:26:3: Error: Expected ';' after this.
+//   get tearOffGetterNoArgs => readGetter;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:26:3: Warning: Getter not found: 'get'.
+//   get tearOffGetterNoArgs => readGetter;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:26:27: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   get tearOffGetterNoArgs => readGetter;
+//                           ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:27:3: Error: Expected ';' after this.
+//   get tearOffGetterRequired => writeSetterRequired;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:27:3: Warning: Getter not found: 'get'.
+//   get tearOffGetterRequired => writeSetterRequired;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:27:29: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   get tearOffGetterRequired => writeSetterRequired;
+//                             ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:28:3: Error: Expected ';' after this.
+//   get tearOffGetterOptional => writeSetterOptional;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:28:3: Warning: Getter not found: 'get'.
+//   get tearOffGetterOptional => writeSetterOptional;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:28:29: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   get tearOffGetterOptional => writeSetterOptional;
+//                             ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:29:3: Error: Expected ';' after this.
+//   get tearOffGetterNamed => writeSetterNamed;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:29:3: Warning: Getter not found: 'get'.
+//   get tearOffGetterNamed => writeSetterNamed;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:29:26: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   get tearOffGetterNamed => writeSetterNamed;
+//                          ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:31:3: Error: Expected ';' after this.
+//   get property => this.field;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:31:3: Warning: Getter not found: 'get'.
+//   get property => this.field;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:31:7: Error: Can't declare 'property' because it was already used in this scope.
+//   get property => this.field;
+//       ^^^^^^^^
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:11:12: Context: Previous use of 'property'.
+//     return property;
+//            ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:31:16: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   get property => this.field;
+//                ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:31:19: Error: Expected identifier, but got 'this'.
+//   get property => this.field;
+//                   ^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:33:3: Error: Unexpected token 'set'.
+//   set property(value) {
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:33:7: Error: Can't declare 'property' because it was already used in this scope.
+//   set property(value) {
+//       ^^^^^^^^
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:11:12: Context: Previous use of 'property'.
+//     return property;
+//            ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:34:5: Error: Expected identifier, but got 'this'.
+//     this.field = value;
+//     ^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:75:12: Warning: Getter not found: 'property'.
+//     return property;
+//            ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:79:5: Warning: Setter not found: 'property'.
+//     property = value;
+//     ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:83:4: Warning: Setter not found: 'property'.
+//    property = value;
+//    ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:87:5: Warning: Setter not found: 'property'.
+//     property = value;
+//     ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:91:4: Warning: Setter not found: 'property'.
+//    property = value;
+//    ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:95:5: Warning: Setter not found: 'property'.
+//     property = value;
+//     ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:99:4: Warning: Setter not found: 'property'.
+//    property = value;
+//    ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:102:5: Error: Expected ';' after this.
+//   T get property => this.field;
+//     ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:102:9: Error: Can't declare 'property' because it was already used in this scope.
+//   T get property => this.field;
+//         ^^^^^^^^
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:75:12: Context: Previous use of 'property'.
+//     return property;
+//            ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:102:18: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   T get property => this.field;
+//                  ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:102:21: Error: Expected identifier, but got 'this'.
+//   T get property => this.field;
+//                     ^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:104:8: Error: Expected ';' after this.
+//   void set property(T value) {
+//        ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:104:12: Error: Can't declare 'property' because it was already used in this scope.
+//   void set property(T value) {
+//            ^^^^^^^^
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:75:12: Context: Previous use of 'property'.
+//     return property;
+//            ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:105:5: Error: Expected identifier, but got 'this'.
+//     this.field = value;
+//     ^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:108:3: Error: Expected ';' after this.
+//   get tearOffGetterNoArgs => readGetter;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:108:27: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   get tearOffGetterNoArgs => readGetter;
+//                           ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:109:3: Error: Expected ';' after this.
+//   get tearOffGetterRequired => writeSetterRequired;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:109:29: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   get tearOffGetterRequired => writeSetterRequired;
+//                             ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:110:3: Error: Expected ';' after this.
+//   get tearOffGetterOptional => writeSetterOptional;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:110:29: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   get tearOffGetterOptional => writeSetterOptional;
+//                             ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:111:3: Error: Expected ';' after this.
+//   get tearOffGetterNamed => writeSetterNamed;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:111:26: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   get tearOffGetterNamed => writeSetterNamed;
+//                          ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:112:3: Error: Expected ';' after this.
+//   get tearOffGetterGenericRequired => genericWriteSetterRequired;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:112:36: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   get tearOffGetterGenericRequired => genericWriteSetterRequired;
+//                                    ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:113:3: Error: Expected ';' after this.
+//   get tearOffGetterGenericOptional => genericWriteSetterOptional;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:113:36: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   get tearOffGetterGenericOptional => genericWriteSetterOptional;
+//                                    ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:114:3: Error: Expected ';' after this.
+//   get tearOffGetterGenericNamed => genericWriteSetterNamed;
+//   ^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:114:33: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   get tearOffGetterGenericNamed => genericWriteSetterNamed;
+//                                 ^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field dynamic field = null;
+  synthetic constructor •() → self::Class*
+    : super core::Object::•()
+    ;
+}
+class GenericClass<T extends core::Object* = dynamic> extends core::Object {
+  generic-covariant-impl field self::GenericClass::T* field = null;
+  synthetic constructor •() → self::GenericClass<self::GenericClass::T*>*
+    : super core::Object::•()
+    ;
+}
+static field invalid-type Extension;
+static method GenericExtension<T extends core::Object* = dynamic>() → invalid-type {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/direct_instance_access.dart.outline.expect b/pkg/front_end/testcases/extensions/direct_instance_access.dart.outline.expect
new file mode 100644
index 0000000..f7cedf9
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/direct_instance_access.dart.outline.expect
@@ -0,0 +1,76 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:9:1: Error: This requires the 'extension-methods' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// extension Extension on Class {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:9:24: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// extension Extension on Class {
+//                        ^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:9:24: Error: 'Class' is already declared in this scope.
+// extension Extension on Class {
+//                        ^^^^^
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:5:7: Context: Previous declaration of 'Class'.
+// class Class {
+//       ^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:73:11: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// extension GenericExtension<T> on GenericClass<T> {
+//           ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:73:31: Error: Expected '{' before this.
+// extension GenericExtension<T> on GenericClass<T> {
+//                               ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:73:34: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// extension GenericExtension<T> on GenericClass<T> {
+//                                  ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:73:34: Error: 'GenericClass' is already declared in this scope.
+// extension GenericExtension<T> on GenericClass<T> {
+//                                  ^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:69:7: Context: Previous declaration of 'GenericClass'.
+// class GenericClass<T> {
+//       ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:9:1: Warning: Type 'extension' not found.
+// extension Extension on Class {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:9:21: Warning: Type 'on' not found.
+// extension Extension on Class {
+//                     ^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:73:1: Warning: Type 'extension' not found.
+// extension GenericExtension<T> on GenericClass<T> {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_instance_access.dart:73:31: Warning: Type 'on' not found.
+// extension GenericExtension<T> on GenericClass<T> {
+//                               ^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field dynamic field;
+  synthetic constructor •() → self::Class*
+    ;
+}
+class GenericClass<T extends core::Object* = dynamic> extends core::Object {
+  generic-covariant-impl field self::GenericClass::T* field;
+  synthetic constructor •() → self::GenericClass<self::GenericClass::T*>*
+    ;
+}
+static field invalid-type Extension;
+static method GenericExtension<T extends core::Object* = dynamic>() → invalid-type
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/extensions/direct_instance_access.dart.strong.expect b/pkg/front_end/testcases/extensions/direct_instance_access.dart.strong.expect
new file mode 100644
index 0000000..eff6825
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/direct_instance_access.dart.strong.expect
@@ -0,0 +1,211 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field dynamic field = null;
+  synthetic constructor •() → self::Class*
+    : super core::Object::•()
+    ;
+}
+class GenericClass<T extends core::Object* = dynamic> extends core::Object {
+  generic-covariant-impl field self::GenericClass::T* field = null;
+  synthetic constructor •() → self::GenericClass<self::GenericClass::T*>*
+    : super core::Object::•()
+    ;
+}
+extension Extension on self::Class* {
+  method readGetter = self::Extension|readGetter;
+  method writeSetterRequired = self::Extension|writeSetterRequired;
+  method writeSetterOptional = self::Extension|writeSetterOptional;
+  method writeSetterNamed = self::Extension|writeSetterNamed;
+  get tearOffGetterNoArgs = self::Extension|get#tearOffGetterNoArgs;
+  get tearOffGetterRequired = self::Extension|get#tearOffGetterRequired;
+  get tearOffGetterOptional = self::Extension|get#tearOffGetterOptional;
+  get tearOffGetterNamed = self::Extension|get#tearOffGetterNamed;
+  get property = self::Extension|get#property;
+  method invocations = self::Extension|invocations;
+  method tearOffs = self::Extension|tearOffs;
+  method getterCalls = self::Extension|getterCalls;
+  set property = self::Extension|set#property;
+}
+extension GenericExtension<T extends core::Object* = dynamic> on self::GenericClass<T*>* {
+  method readGetter = self::GenericExtension|readGetter;
+  method writeSetterRequired = self::GenericExtension|writeSetterRequired;
+  method writeSetterOptional = self::GenericExtension|writeSetterOptional;
+  method writeSetterNamed = self::GenericExtension|writeSetterNamed;
+  method genericWriteSetterRequired = self::GenericExtension|genericWriteSetterRequired;
+  method genericWriteSetterOptional = self::GenericExtension|genericWriteSetterOptional;
+  method genericWriteSetterNamed = self::GenericExtension|genericWriteSetterNamed;
+  get property = self::GenericExtension|get#property;
+  get tearOffGetterNoArgs = self::GenericExtension|get#tearOffGetterNoArgs;
+  get tearOffGetterRequired = self::GenericExtension|get#tearOffGetterRequired;
+  get tearOffGetterOptional = self::GenericExtension|get#tearOffGetterOptional;
+  get tearOffGetterNamed = self::GenericExtension|get#tearOffGetterNamed;
+  get tearOffGetterGenericRequired = self::GenericExtension|get#tearOffGetterGenericRequired;
+  get tearOffGetterGenericOptional = self::GenericExtension|get#tearOffGetterGenericOptional;
+  get tearOffGetterGenericNamed = self::GenericExtension|get#tearOffGetterGenericNamed;
+  method invocations = self::GenericExtension|invocations;
+  method tearOffs = self::GenericExtension|tearOffs;
+  method getterCalls = self::GenericExtension|getterCalls;
+  set property = self::GenericExtension|set#property;
+}
+static method Extension|readGetter(final self::Class* #this) → dynamic {
+  return self::Extension|get#property(#this);
+}
+static method Extension|writeSetterRequired(final self::Class* #this, dynamic value) → dynamic {
+  self::Extension|set#property(#this, value);
+}
+static method Extension|writeSetterOptional(final self::Class* #this = #C1, [dynamic value = #C1]) → dynamic {
+  self::Extension|set#property(#this, value);
+}
+static method Extension|writeSetterNamed(final self::Class* #this = #C1, {dynamic value = #C1}) → dynamic {
+  self::Extension|set#property(#this, value);
+}
+static method Extension|get#tearOffGetterNoArgs(final self::Class* #this) → dynamic
+  return () → dynamic => self::Extension|readGetter(#this);
+static method Extension|get#tearOffGetterRequired(final self::Class* #this) → dynamic
+  return (dynamic value) → dynamic => self::Extension|writeSetterRequired(#this, value);
+static method Extension|get#tearOffGetterOptional(final self::Class* #this) → dynamic
+  return ([dynamic value = #C1]) → dynamic => self::Extension|writeSetterOptional(#this, value);
+static method Extension|get#tearOffGetterNamed(final self::Class* #this) → dynamic
+  return ({dynamic value = #C1}) → dynamic => self::Extension|writeSetterNamed(#this, value: value);
+static method Extension|get#property(final self::Class* #this) → dynamic
+  return #this.{self::Class::field};
+static method Extension|set#property(final self::Class* #this, dynamic value) → void {
+  #this.{self::Class::field} = value;
+}
+static method Extension|invocations(final self::Class* #this, dynamic value) → dynamic {
+  self::Extension|readGetter(#this);
+  self::Extension|writeSetterRequired(#this, value);
+  self::Extension|writeSetterOptional(#this);
+  self::Extension|writeSetterOptional(#this, value);
+  self::Extension|writeSetterNamed(#this);
+  self::Extension|writeSetterNamed(#this, value: value);
+}
+static method Extension|tearOffs(final self::Class* #this, dynamic value) → dynamic {
+  () →* dynamic tearOffNoArgs = () → dynamic => self::Extension|readGetter(#this);
+  tearOffNoArgs.call();
+  (dynamic) →* dynamic tearOffRequired = (dynamic value) → dynamic => self::Extension|writeSetterRequired(#this, value);
+  tearOffRequired.call(value);
+  ([dynamic]) →* dynamic tearOffOptional = ([dynamic value = #C1]) → dynamic => self::Extension|writeSetterOptional(#this, value);
+  tearOffOptional.call();
+  tearOffOptional.call(value);
+  ({value: dynamic}) →* dynamic tearOffNamed = ({dynamic value = #C1}) → dynamic => self::Extension|writeSetterNamed(#this, value: value);
+  tearOffNamed.call();
+  tearOffNamed.call(value: value);
+}
+static method Extension|getterCalls(final self::Class* #this, dynamic value) → dynamic {
+  self::Extension|get#tearOffGetterNoArgs(#this).call();
+  self::Extension|get#tearOffGetterRequired(#this).call(value);
+  self::Extension|get#tearOffGetterOptional(#this).call();
+  self::Extension|get#tearOffGetterOptional(#this).call(value);
+  self::Extension|get#tearOffGetterNamed(#this).call();
+  self::Extension|get#tearOffGetterNamed(#this).call(value: value);
+}
+static method GenericExtension|readGetter<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|readGetter::#T*>* #this) → self::GenericExtension|readGetter::#T* {
+  return self::GenericExtension|get#property<self::GenericExtension|readGetter::#T*>(#this);
+}
+static method GenericExtension|writeSetterRequired<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterRequired::#T*>* #this, self::GenericExtension|writeSetterRequired::#T* value) → dynamic {
+  self::GenericExtension|set#property<self::GenericExtension|writeSetterRequired::#T*>(#this, value);
+}
+static method GenericExtension|writeSetterOptional<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterOptional::#T*>* #this = #C1, [self::GenericExtension|writeSetterOptional::#T* value = #C1]) → dynamic {
+  self::GenericExtension|set#property<self::GenericExtension|writeSetterOptional::#T*>(#this, value);
+}
+static method GenericExtension|writeSetterNamed<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterNamed::#T*>* #this = #C1, {self::GenericExtension|writeSetterNamed::#T* value = #C1}) → dynamic {
+  self::GenericExtension|set#property<self::GenericExtension|writeSetterNamed::#T*>(#this, value);
+}
+static method GenericExtension|genericWriteSetterRequired<#T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterRequired::#T = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterRequired::#T*>* #this, self::GenericExtension|genericWriteSetterRequired::S value) → dynamic {
+  self::GenericExtension|set#property<self::GenericExtension|genericWriteSetterRequired::#T*>(#this, value);
+}
+static method GenericExtension|genericWriteSetterOptional<#T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterOptional::#T = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterOptional::#T*>* #this = #C1, [self::GenericExtension|genericWriteSetterOptional::S value = #C1]) → dynamic {
+  self::GenericExtension|set#property<self::GenericExtension|genericWriteSetterOptional::#T*>(#this, value);
+}
+static method GenericExtension|genericWriteSetterNamed<#T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterNamed::#T = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterNamed::#T*>* #this = #C1, {self::GenericExtension|genericWriteSetterNamed::S value = #C1}) → dynamic {
+  self::GenericExtension|set#property<self::GenericExtension|genericWriteSetterNamed::#T*>(#this, value);
+}
+static method GenericExtension|get#property<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#property::#T*>* #this) → self::GenericExtension|get#property::#T*
+  return #this.{self::GenericClass::field};
+static method GenericExtension|set#property<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|set#property::#T*>* #this, self::GenericExtension|set#property::#T* value) → void {
+  #this.{self::GenericClass::field} = value;
+}
+static method GenericExtension|get#tearOffGetterNoArgs<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterNoArgs::#T*>* #this) → dynamic
+  return () → self::GenericExtension|get#tearOffGetterNoArgs::#T* => self::GenericExtension|readGetter<self::GenericExtension|get#tearOffGetterNoArgs::#T*>(#this);
+static method GenericExtension|get#tearOffGetterRequired<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterRequired::#T*>* #this) → dynamic
+  return (self::GenericExtension|get#tearOffGetterRequired::#T* value) → dynamic => self::GenericExtension|writeSetterRequired<self::GenericExtension|get#tearOffGetterRequired::#T*>(#this, value);
+static method GenericExtension|get#tearOffGetterOptional<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterOptional::#T*>* #this) → dynamic
+  return ([self::GenericExtension|get#tearOffGetterOptional::#T* value = #C1]) → dynamic => self::GenericExtension|writeSetterOptional<self::GenericExtension|get#tearOffGetterOptional::#T*>(#this, value);
+static method GenericExtension|get#tearOffGetterNamed<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterNamed::#T*>* #this) → dynamic
+  return ({self::GenericExtension|get#tearOffGetterNamed::#T* value = #C1}) → dynamic => self::GenericExtension|writeSetterNamed<self::GenericExtension|get#tearOffGetterNamed::#T*>(#this, value: value);
+static method GenericExtension|get#tearOffGetterGenericRequired<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterGenericRequired::#T*>* #this) → dynamic
+  return <S extends self::GenericExtension|get#tearOffGetterGenericRequired::#T* = dynamic>(S value) → dynamic => self::GenericExtension|genericWriteSetterRequired<self::GenericExtension|get#tearOffGetterGenericRequired::#T*, S>(#this, value);
+static method GenericExtension|get#tearOffGetterGenericOptional<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterGenericOptional::#T*>* #this) → dynamic
+  return <S extends self::GenericExtension|get#tearOffGetterGenericOptional::#T* = dynamic>([S value = #C1]) → dynamic => self::GenericExtension|genericWriteSetterOptional<self::GenericExtension|get#tearOffGetterGenericOptional::#T*, S>(#this, value);
+static method GenericExtension|get#tearOffGetterGenericNamed<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterGenericNamed::#T*>* #this) → dynamic
+  return <S extends self::GenericExtension|get#tearOffGetterGenericNamed::#T* = dynamic>({S value = #C1}) → dynamic => self::GenericExtension|genericWriteSetterNamed<self::GenericExtension|get#tearOffGetterGenericNamed::#T*, S>(#this, value: value);
+static method GenericExtension|invocations<#T extends core::Object* = dynamic, S extends self::GenericExtension|invocations::#T = dynamic>(final self::GenericClass<self::GenericExtension|invocations::#T*>* #this, self::GenericExtension|invocations::S value) → dynamic {
+  self::GenericExtension|readGetter<self::GenericExtension|invocations::#T*>(#this);
+  self::GenericExtension|writeSetterRequired<self::GenericExtension|invocations::#T*>(#this, value);
+  self::GenericExtension|writeSetterOptional<self::GenericExtension|invocations::#T*>(#this);
+  self::GenericExtension|writeSetterOptional<self::GenericExtension|invocations::#T*>(#this, value);
+  self::GenericExtension|writeSetterNamed<self::GenericExtension|invocations::#T*>(#this);
+  self::GenericExtension|writeSetterNamed<self::GenericExtension|invocations::#T*>(#this, value: value);
+}
+static method GenericExtension|tearOffs<#T extends core::Object* = dynamic, S extends self::GenericExtension|tearOffs::#T = dynamic>(final self::GenericClass<self::GenericExtension|tearOffs::#T*>* #this, self::GenericExtension|tearOffs::S value) → dynamic {
+  () →* self::GenericExtension|tearOffs::#T* tearOffNoArgs = () → self::GenericExtension|tearOffs::#T* => self::GenericExtension|readGetter<self::GenericExtension|tearOffs::#T*>(#this);
+  tearOffNoArgs.call();
+  (self::GenericExtension|tearOffs::#T*) →* dynamic tearOffRequired = (self::GenericExtension|tearOffs::#T* value) → dynamic => self::GenericExtension|writeSetterRequired<self::GenericExtension|tearOffs::#T*>(#this, value);
+  tearOffRequired.call(value);
+  ([self::GenericExtension|tearOffs::#T*]) →* dynamic tearOffOptional = ([self::GenericExtension|tearOffs::#T* value = #C1]) → dynamic => self::GenericExtension|writeSetterOptional<self::GenericExtension|tearOffs::#T*>(#this, value);
+  tearOffOptional.call();
+  tearOffOptional.call(value);
+  ({value: self::GenericExtension|tearOffs::#T*}) →* dynamic tearOffNamed = ({self::GenericExtension|tearOffs::#T* value = #C1}) → dynamic => self::GenericExtension|writeSetterNamed<self::GenericExtension|tearOffs::#T*>(#this, value: value);
+  tearOffNamed.call();
+  tearOffNamed.call(value: value);
+  <S extends self::GenericExtension|tearOffs::#T* = dynamic>(S) →* dynamic genericTearOffRequired = <S extends self::GenericExtension|tearOffs::#T* = dynamic>(S value) → dynamic => self::GenericExtension|genericWriteSetterRequired<self::GenericExtension|tearOffs::#T*, S>(#this, value);
+  genericTearOffRequired.call<self::GenericExtension|tearOffs::S>(value);
+  genericTearOffRequired.call<self::GenericExtension|tearOffs::#T*>(value);
+  genericTearOffRequired.call<self::GenericExtension|tearOffs::S>(value);
+  <S extends self::GenericExtension|tearOffs::#T* = dynamic>([S]) →* dynamic genericTearOffOptional = <S extends self::GenericExtension|tearOffs::#T* = dynamic>([S value = #C1]) → dynamic => self::GenericExtension|genericWriteSetterOptional<self::GenericExtension|tearOffs::#T*, S>(#this, value);
+  genericTearOffOptional.call<self::GenericExtension|tearOffs::#T*>();
+  genericTearOffOptional.call<self::GenericExtension|tearOffs::#T*>();
+  genericTearOffOptional.call<self::GenericExtension|tearOffs::S>();
+  genericTearOffOptional.call<self::GenericExtension|tearOffs::S>(value);
+  genericTearOffOptional.call<self::GenericExtension|tearOffs::#T*>(value);
+  genericTearOffOptional.call<self::GenericExtension|tearOffs::S>(value);
+  <S extends self::GenericExtension|tearOffs::#T* = dynamic>({value: S}) →* dynamic genericTearOffNamed = <S extends self::GenericExtension|tearOffs::#T* = dynamic>({S value = #C1}) → dynamic => self::GenericExtension|genericWriteSetterNamed<self::GenericExtension|tearOffs::#T*, S>(#this, value: value);
+  genericTearOffNamed.call<self::GenericExtension|tearOffs::#T*>();
+  genericTearOffNamed.call<self::GenericExtension|tearOffs::#T*>();
+  genericTearOffNamed.call<self::GenericExtension|tearOffs::S>();
+  genericTearOffNamed.call<self::GenericExtension|tearOffs::S>(value: value);
+  genericTearOffNamed.call<self::GenericExtension|tearOffs::#T*>(value: value);
+  genericTearOffNamed.call<self::GenericExtension|tearOffs::S>(value: value);
+}
+static method GenericExtension|getterCalls<#T extends core::Object* = dynamic, S extends self::GenericExtension|getterCalls::#T = dynamic>(final self::GenericClass<self::GenericExtension|getterCalls::#T*>* #this, self::GenericExtension|getterCalls::S value) → dynamic {
+  self::GenericExtension|get#tearOffGetterNoArgs<self::GenericExtension|getterCalls::#T*>(#this).call();
+  self::GenericExtension|get#tearOffGetterRequired<self::GenericExtension|getterCalls::#T*>(#this).call(value);
+  self::GenericExtension|get#tearOffGetterOptional<self::GenericExtension|getterCalls::#T*>(#this).call();
+  self::GenericExtension|get#tearOffGetterOptional<self::GenericExtension|getterCalls::#T*>(#this).call(value);
+  self::GenericExtension|get#tearOffGetterNamed<self::GenericExtension|getterCalls::#T*>(#this).call();
+  self::GenericExtension|get#tearOffGetterNamed<self::GenericExtension|getterCalls::#T*>(#this).call(value: value);
+  self::GenericExtension|get#tearOffGetterGenericRequired<self::GenericExtension|getterCalls::#T*>(#this).call(value);
+  self::GenericExtension|get#tearOffGetterGenericRequired<self::GenericExtension|getterCalls::#T*>(#this).call<self::GenericExtension|getterCalls::#T*>(value);
+  self::GenericExtension|get#tearOffGetterGenericRequired<self::GenericExtension|getterCalls::#T*>(#this).call<self::GenericExtension|getterCalls::S>(value);
+  self::GenericExtension|get#tearOffGetterGenericOptional<self::GenericExtension|getterCalls::#T*>(#this).call();
+  self::GenericExtension|get#tearOffGetterGenericOptional<self::GenericExtension|getterCalls::#T*>(#this).call<self::GenericExtension|getterCalls::#T*>();
+  self::GenericExtension|get#tearOffGetterGenericOptional<self::GenericExtension|getterCalls::#T*>(#this).call<self::GenericExtension|getterCalls::S>();
+  self::GenericExtension|get#tearOffGetterGenericOptional<self::GenericExtension|getterCalls::#T*>(#this).call(value);
+  self::GenericExtension|get#tearOffGetterGenericOptional<self::GenericExtension|getterCalls::#T*>(#this).call<self::GenericExtension|getterCalls::#T*>(value);
+  self::GenericExtension|get#tearOffGetterGenericOptional<self::GenericExtension|getterCalls::#T*>(#this).call<self::GenericExtension|getterCalls::S>(value);
+  self::GenericExtension|get#tearOffGetterGenericNamed<self::GenericExtension|getterCalls::#T*>(#this).call();
+  self::GenericExtension|get#tearOffGetterGenericNamed<self::GenericExtension|getterCalls::#T*>(#this).call<self::GenericExtension|getterCalls::#T*>();
+  self::GenericExtension|get#tearOffGetterGenericNamed<self::GenericExtension|getterCalls::#T*>(#this).call<self::GenericExtension|getterCalls::S>();
+  self::GenericExtension|get#tearOffGetterGenericNamed<self::GenericExtension|getterCalls::#T*>(#this).call(value: value);
+  self::GenericExtension|get#tearOffGetterGenericNamed<self::GenericExtension|getterCalls::#T*>(#this).call<self::GenericExtension|getterCalls::#T*>(value: value);
+  self::GenericExtension|get#tearOffGetterGenericNamed<self::GenericExtension|getterCalls::#T*>(#this).call<self::GenericExtension|getterCalls::S>(value: value);
+}
+static method main() → dynamic {}
+
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/extensions/direct_instance_access.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/direct_instance_access.dart.strong.transformed.expect
new file mode 100644
index 0000000..eff6825
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/direct_instance_access.dart.strong.transformed.expect
@@ -0,0 +1,211 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field dynamic field = null;
+  synthetic constructor •() → self::Class*
+    : super core::Object::•()
+    ;
+}
+class GenericClass<T extends core::Object* = dynamic> extends core::Object {
+  generic-covariant-impl field self::GenericClass::T* field = null;
+  synthetic constructor •() → self::GenericClass<self::GenericClass::T*>*
+    : super core::Object::•()
+    ;
+}
+extension Extension on self::Class* {
+  method readGetter = self::Extension|readGetter;
+  method writeSetterRequired = self::Extension|writeSetterRequired;
+  method writeSetterOptional = self::Extension|writeSetterOptional;
+  method writeSetterNamed = self::Extension|writeSetterNamed;
+  get tearOffGetterNoArgs = self::Extension|get#tearOffGetterNoArgs;
+  get tearOffGetterRequired = self::Extension|get#tearOffGetterRequired;
+  get tearOffGetterOptional = self::Extension|get#tearOffGetterOptional;
+  get tearOffGetterNamed = self::Extension|get#tearOffGetterNamed;
+  get property = self::Extension|get#property;
+  method invocations = self::Extension|invocations;
+  method tearOffs = self::Extension|tearOffs;
+  method getterCalls = self::Extension|getterCalls;
+  set property = self::Extension|set#property;
+}
+extension GenericExtension<T extends core::Object* = dynamic> on self::GenericClass<T*>* {
+  method readGetter = self::GenericExtension|readGetter;
+  method writeSetterRequired = self::GenericExtension|writeSetterRequired;
+  method writeSetterOptional = self::GenericExtension|writeSetterOptional;
+  method writeSetterNamed = self::GenericExtension|writeSetterNamed;
+  method genericWriteSetterRequired = self::GenericExtension|genericWriteSetterRequired;
+  method genericWriteSetterOptional = self::GenericExtension|genericWriteSetterOptional;
+  method genericWriteSetterNamed = self::GenericExtension|genericWriteSetterNamed;
+  get property = self::GenericExtension|get#property;
+  get tearOffGetterNoArgs = self::GenericExtension|get#tearOffGetterNoArgs;
+  get tearOffGetterRequired = self::GenericExtension|get#tearOffGetterRequired;
+  get tearOffGetterOptional = self::GenericExtension|get#tearOffGetterOptional;
+  get tearOffGetterNamed = self::GenericExtension|get#tearOffGetterNamed;
+  get tearOffGetterGenericRequired = self::GenericExtension|get#tearOffGetterGenericRequired;
+  get tearOffGetterGenericOptional = self::GenericExtension|get#tearOffGetterGenericOptional;
+  get tearOffGetterGenericNamed = self::GenericExtension|get#tearOffGetterGenericNamed;
+  method invocations = self::GenericExtension|invocations;
+  method tearOffs = self::GenericExtension|tearOffs;
+  method getterCalls = self::GenericExtension|getterCalls;
+  set property = self::GenericExtension|set#property;
+}
+static method Extension|readGetter(final self::Class* #this) → dynamic {
+  return self::Extension|get#property(#this);
+}
+static method Extension|writeSetterRequired(final self::Class* #this, dynamic value) → dynamic {
+  self::Extension|set#property(#this, value);
+}
+static method Extension|writeSetterOptional(final self::Class* #this = #C1, [dynamic value = #C1]) → dynamic {
+  self::Extension|set#property(#this, value);
+}
+static method Extension|writeSetterNamed(final self::Class* #this = #C1, {dynamic value = #C1}) → dynamic {
+  self::Extension|set#property(#this, value);
+}
+static method Extension|get#tearOffGetterNoArgs(final self::Class* #this) → dynamic
+  return () → dynamic => self::Extension|readGetter(#this);
+static method Extension|get#tearOffGetterRequired(final self::Class* #this) → dynamic
+  return (dynamic value) → dynamic => self::Extension|writeSetterRequired(#this, value);
+static method Extension|get#tearOffGetterOptional(final self::Class* #this) → dynamic
+  return ([dynamic value = #C1]) → dynamic => self::Extension|writeSetterOptional(#this, value);
+static method Extension|get#tearOffGetterNamed(final self::Class* #this) → dynamic
+  return ({dynamic value = #C1}) → dynamic => self::Extension|writeSetterNamed(#this, value: value);
+static method Extension|get#property(final self::Class* #this) → dynamic
+  return #this.{self::Class::field};
+static method Extension|set#property(final self::Class* #this, dynamic value) → void {
+  #this.{self::Class::field} = value;
+}
+static method Extension|invocations(final self::Class* #this, dynamic value) → dynamic {
+  self::Extension|readGetter(#this);
+  self::Extension|writeSetterRequired(#this, value);
+  self::Extension|writeSetterOptional(#this);
+  self::Extension|writeSetterOptional(#this, value);
+  self::Extension|writeSetterNamed(#this);
+  self::Extension|writeSetterNamed(#this, value: value);
+}
+static method Extension|tearOffs(final self::Class* #this, dynamic value) → dynamic {
+  () →* dynamic tearOffNoArgs = () → dynamic => self::Extension|readGetter(#this);
+  tearOffNoArgs.call();
+  (dynamic) →* dynamic tearOffRequired = (dynamic value) → dynamic => self::Extension|writeSetterRequired(#this, value);
+  tearOffRequired.call(value);
+  ([dynamic]) →* dynamic tearOffOptional = ([dynamic value = #C1]) → dynamic => self::Extension|writeSetterOptional(#this, value);
+  tearOffOptional.call();
+  tearOffOptional.call(value);
+  ({value: dynamic}) →* dynamic tearOffNamed = ({dynamic value = #C1}) → dynamic => self::Extension|writeSetterNamed(#this, value: value);
+  tearOffNamed.call();
+  tearOffNamed.call(value: value);
+}
+static method Extension|getterCalls(final self::Class* #this, dynamic value) → dynamic {
+  self::Extension|get#tearOffGetterNoArgs(#this).call();
+  self::Extension|get#tearOffGetterRequired(#this).call(value);
+  self::Extension|get#tearOffGetterOptional(#this).call();
+  self::Extension|get#tearOffGetterOptional(#this).call(value);
+  self::Extension|get#tearOffGetterNamed(#this).call();
+  self::Extension|get#tearOffGetterNamed(#this).call(value: value);
+}
+static method GenericExtension|readGetter<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|readGetter::#T*>* #this) → self::GenericExtension|readGetter::#T* {
+  return self::GenericExtension|get#property<self::GenericExtension|readGetter::#T*>(#this);
+}
+static method GenericExtension|writeSetterRequired<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterRequired::#T*>* #this, self::GenericExtension|writeSetterRequired::#T* value) → dynamic {
+  self::GenericExtension|set#property<self::GenericExtension|writeSetterRequired::#T*>(#this, value);
+}
+static method GenericExtension|writeSetterOptional<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterOptional::#T*>* #this = #C1, [self::GenericExtension|writeSetterOptional::#T* value = #C1]) → dynamic {
+  self::GenericExtension|set#property<self::GenericExtension|writeSetterOptional::#T*>(#this, value);
+}
+static method GenericExtension|writeSetterNamed<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterNamed::#T*>* #this = #C1, {self::GenericExtension|writeSetterNamed::#T* value = #C1}) → dynamic {
+  self::GenericExtension|set#property<self::GenericExtension|writeSetterNamed::#T*>(#this, value);
+}
+static method GenericExtension|genericWriteSetterRequired<#T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterRequired::#T = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterRequired::#T*>* #this, self::GenericExtension|genericWriteSetterRequired::S value) → dynamic {
+  self::GenericExtension|set#property<self::GenericExtension|genericWriteSetterRequired::#T*>(#this, value);
+}
+static method GenericExtension|genericWriteSetterOptional<#T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterOptional::#T = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterOptional::#T*>* #this = #C1, [self::GenericExtension|genericWriteSetterOptional::S value = #C1]) → dynamic {
+  self::GenericExtension|set#property<self::GenericExtension|genericWriteSetterOptional::#T*>(#this, value);
+}
+static method GenericExtension|genericWriteSetterNamed<#T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterNamed::#T = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterNamed::#T*>* #this = #C1, {self::GenericExtension|genericWriteSetterNamed::S value = #C1}) → dynamic {
+  self::GenericExtension|set#property<self::GenericExtension|genericWriteSetterNamed::#T*>(#this, value);
+}
+static method GenericExtension|get#property<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#property::#T*>* #this) → self::GenericExtension|get#property::#T*
+  return #this.{self::GenericClass::field};
+static method GenericExtension|set#property<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|set#property::#T*>* #this, self::GenericExtension|set#property::#T* value) → void {
+  #this.{self::GenericClass::field} = value;
+}
+static method GenericExtension|get#tearOffGetterNoArgs<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterNoArgs::#T*>* #this) → dynamic
+  return () → self::GenericExtension|get#tearOffGetterNoArgs::#T* => self::GenericExtension|readGetter<self::GenericExtension|get#tearOffGetterNoArgs::#T*>(#this);
+static method GenericExtension|get#tearOffGetterRequired<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterRequired::#T*>* #this) → dynamic
+  return (self::GenericExtension|get#tearOffGetterRequired::#T* value) → dynamic => self::GenericExtension|writeSetterRequired<self::GenericExtension|get#tearOffGetterRequired::#T*>(#this, value);
+static method GenericExtension|get#tearOffGetterOptional<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterOptional::#T*>* #this) → dynamic
+  return ([self::GenericExtension|get#tearOffGetterOptional::#T* value = #C1]) → dynamic => self::GenericExtension|writeSetterOptional<self::GenericExtension|get#tearOffGetterOptional::#T*>(#this, value);
+static method GenericExtension|get#tearOffGetterNamed<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterNamed::#T*>* #this) → dynamic
+  return ({self::GenericExtension|get#tearOffGetterNamed::#T* value = #C1}) → dynamic => self::GenericExtension|writeSetterNamed<self::GenericExtension|get#tearOffGetterNamed::#T*>(#this, value: value);
+static method GenericExtension|get#tearOffGetterGenericRequired<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterGenericRequired::#T*>* #this) → dynamic
+  return <S extends self::GenericExtension|get#tearOffGetterGenericRequired::#T* = dynamic>(S value) → dynamic => self::GenericExtension|genericWriteSetterRequired<self::GenericExtension|get#tearOffGetterGenericRequired::#T*, S>(#this, value);
+static method GenericExtension|get#tearOffGetterGenericOptional<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterGenericOptional::#T*>* #this) → dynamic
+  return <S extends self::GenericExtension|get#tearOffGetterGenericOptional::#T* = dynamic>([S value = #C1]) → dynamic => self::GenericExtension|genericWriteSetterOptional<self::GenericExtension|get#tearOffGetterGenericOptional::#T*, S>(#this, value);
+static method GenericExtension|get#tearOffGetterGenericNamed<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterGenericNamed::#T*>* #this) → dynamic
+  return <S extends self::GenericExtension|get#tearOffGetterGenericNamed::#T* = dynamic>({S value = #C1}) → dynamic => self::GenericExtension|genericWriteSetterNamed<self::GenericExtension|get#tearOffGetterGenericNamed::#T*, S>(#this, value: value);
+static method GenericExtension|invocations<#T extends core::Object* = dynamic, S extends self::GenericExtension|invocations::#T = dynamic>(final self::GenericClass<self::GenericExtension|invocations::#T*>* #this, self::GenericExtension|invocations::S value) → dynamic {
+  self::GenericExtension|readGetter<self::GenericExtension|invocations::#T*>(#this);
+  self::GenericExtension|writeSetterRequired<self::GenericExtension|invocations::#T*>(#this, value);
+  self::GenericExtension|writeSetterOptional<self::GenericExtension|invocations::#T*>(#this);
+  self::GenericExtension|writeSetterOptional<self::GenericExtension|invocations::#T*>(#this, value);
+  self::GenericExtension|writeSetterNamed<self::GenericExtension|invocations::#T*>(#this);
+  self::GenericExtension|writeSetterNamed<self::GenericExtension|invocations::#T*>(#this, value: value);
+}
+static method GenericExtension|tearOffs<#T extends core::Object* = dynamic, S extends self::GenericExtension|tearOffs::#T = dynamic>(final self::GenericClass<self::GenericExtension|tearOffs::#T*>* #this, self::GenericExtension|tearOffs::S value) → dynamic {
+  () →* self::GenericExtension|tearOffs::#T* tearOffNoArgs = () → self::GenericExtension|tearOffs::#T* => self::GenericExtension|readGetter<self::GenericExtension|tearOffs::#T*>(#this);
+  tearOffNoArgs.call();
+  (self::GenericExtension|tearOffs::#T*) →* dynamic tearOffRequired = (self::GenericExtension|tearOffs::#T* value) → dynamic => self::GenericExtension|writeSetterRequired<self::GenericExtension|tearOffs::#T*>(#this, value);
+  tearOffRequired.call(value);
+  ([self::GenericExtension|tearOffs::#T*]) →* dynamic tearOffOptional = ([self::GenericExtension|tearOffs::#T* value = #C1]) → dynamic => self::GenericExtension|writeSetterOptional<self::GenericExtension|tearOffs::#T*>(#this, value);
+  tearOffOptional.call();
+  tearOffOptional.call(value);
+  ({value: self::GenericExtension|tearOffs::#T*}) →* dynamic tearOffNamed = ({self::GenericExtension|tearOffs::#T* value = #C1}) → dynamic => self::GenericExtension|writeSetterNamed<self::GenericExtension|tearOffs::#T*>(#this, value: value);
+  tearOffNamed.call();
+  tearOffNamed.call(value: value);
+  <S extends self::GenericExtension|tearOffs::#T* = dynamic>(S) →* dynamic genericTearOffRequired = <S extends self::GenericExtension|tearOffs::#T* = dynamic>(S value) → dynamic => self::GenericExtension|genericWriteSetterRequired<self::GenericExtension|tearOffs::#T*, S>(#this, value);
+  genericTearOffRequired.call<self::GenericExtension|tearOffs::S>(value);
+  genericTearOffRequired.call<self::GenericExtension|tearOffs::#T*>(value);
+  genericTearOffRequired.call<self::GenericExtension|tearOffs::S>(value);
+  <S extends self::GenericExtension|tearOffs::#T* = dynamic>([S]) →* dynamic genericTearOffOptional = <S extends self::GenericExtension|tearOffs::#T* = dynamic>([S value = #C1]) → dynamic => self::GenericExtension|genericWriteSetterOptional<self::GenericExtension|tearOffs::#T*, S>(#this, value);
+  genericTearOffOptional.call<self::GenericExtension|tearOffs::#T*>();
+  genericTearOffOptional.call<self::GenericExtension|tearOffs::#T*>();
+  genericTearOffOptional.call<self::GenericExtension|tearOffs::S>();
+  genericTearOffOptional.call<self::GenericExtension|tearOffs::S>(value);
+  genericTearOffOptional.call<self::GenericExtension|tearOffs::#T*>(value);
+  genericTearOffOptional.call<self::GenericExtension|tearOffs::S>(value);
+  <S extends self::GenericExtension|tearOffs::#T* = dynamic>({value: S}) →* dynamic genericTearOffNamed = <S extends self::GenericExtension|tearOffs::#T* = dynamic>({S value = #C1}) → dynamic => self::GenericExtension|genericWriteSetterNamed<self::GenericExtension|tearOffs::#T*, S>(#this, value: value);
+  genericTearOffNamed.call<self::GenericExtension|tearOffs::#T*>();
+  genericTearOffNamed.call<self::GenericExtension|tearOffs::#T*>();
+  genericTearOffNamed.call<self::GenericExtension|tearOffs::S>();
+  genericTearOffNamed.call<self::GenericExtension|tearOffs::S>(value: value);
+  genericTearOffNamed.call<self::GenericExtension|tearOffs::#T*>(value: value);
+  genericTearOffNamed.call<self::GenericExtension|tearOffs::S>(value: value);
+}
+static method GenericExtension|getterCalls<#T extends core::Object* = dynamic, S extends self::GenericExtension|getterCalls::#T = dynamic>(final self::GenericClass<self::GenericExtension|getterCalls::#T*>* #this, self::GenericExtension|getterCalls::S value) → dynamic {
+  self::GenericExtension|get#tearOffGetterNoArgs<self::GenericExtension|getterCalls::#T*>(#this).call();
+  self::GenericExtension|get#tearOffGetterRequired<self::GenericExtension|getterCalls::#T*>(#this).call(value);
+  self::GenericExtension|get#tearOffGetterOptional<self::GenericExtension|getterCalls::#T*>(#this).call();
+  self::GenericExtension|get#tearOffGetterOptional<self::GenericExtension|getterCalls::#T*>(#this).call(value);
+  self::GenericExtension|get#tearOffGetterNamed<self::GenericExtension|getterCalls::#T*>(#this).call();
+  self::GenericExtension|get#tearOffGetterNamed<self::GenericExtension|getterCalls::#T*>(#this).call(value: value);
+  self::GenericExtension|get#tearOffGetterGenericRequired<self::GenericExtension|getterCalls::#T*>(#this).call(value);
+  self::GenericExtension|get#tearOffGetterGenericRequired<self::GenericExtension|getterCalls::#T*>(#this).call<self::GenericExtension|getterCalls::#T*>(value);
+  self::GenericExtension|get#tearOffGetterGenericRequired<self::GenericExtension|getterCalls::#T*>(#this).call<self::GenericExtension|getterCalls::S>(value);
+  self::GenericExtension|get#tearOffGetterGenericOptional<self::GenericExtension|getterCalls::#T*>(#this).call();
+  self::GenericExtension|get#tearOffGetterGenericOptional<self::GenericExtension|getterCalls::#T*>(#this).call<self::GenericExtension|getterCalls::#T*>();
+  self::GenericExtension|get#tearOffGetterGenericOptional<self::GenericExtension|getterCalls::#T*>(#this).call<self::GenericExtension|getterCalls::S>();
+  self::GenericExtension|get#tearOffGetterGenericOptional<self::GenericExtension|getterCalls::#T*>(#this).call(value);
+  self::GenericExtension|get#tearOffGetterGenericOptional<self::GenericExtension|getterCalls::#T*>(#this).call<self::GenericExtension|getterCalls::#T*>(value);
+  self::GenericExtension|get#tearOffGetterGenericOptional<self::GenericExtension|getterCalls::#T*>(#this).call<self::GenericExtension|getterCalls::S>(value);
+  self::GenericExtension|get#tearOffGetterGenericNamed<self::GenericExtension|getterCalls::#T*>(#this).call();
+  self::GenericExtension|get#tearOffGetterGenericNamed<self::GenericExtension|getterCalls::#T*>(#this).call<self::GenericExtension|getterCalls::#T*>();
+  self::GenericExtension|get#tearOffGetterGenericNamed<self::GenericExtension|getterCalls::#T*>(#this).call<self::GenericExtension|getterCalls::S>();
+  self::GenericExtension|get#tearOffGetterGenericNamed<self::GenericExtension|getterCalls::#T*>(#this).call(value: value);
+  self::GenericExtension|get#tearOffGetterGenericNamed<self::GenericExtension|getterCalls::#T*>(#this).call<self::GenericExtension|getterCalls::#T*>(value: value);
+  self::GenericExtension|get#tearOffGetterGenericNamed<self::GenericExtension|getterCalls::#T*>(#this).call<self::GenericExtension|getterCalls::S>(value: value);
+}
+static method main() → dynamic {}
+
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/extensions/direct_static_access.dart b/pkg/front_end/testcases/extensions/direct_static_access.dart
new file mode 100644
index 0000000..5da64d7
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/direct_static_access.dart
@@ -0,0 +1,194 @@
+// 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.
+
+class Class<T> {
+  static var field;
+}
+
+extension Extension<T> on Class<T> {
+
+  static get property => Class.field;
+
+  static set property(value) {
+    Class.field = value;
+  }
+
+  static var field;
+
+  static readGetter() {
+    return property;
+  }
+
+  static writeSetterRequired(value) {
+    property = value;
+  }
+
+  static writeSetterOptional([value]) {
+    property = value;
+  }
+
+  static writeSetterNamed({value}) {
+    property = value;
+  }
+
+  static genericWriteSetterRequired<S>(S value) {
+    property = value;
+  }
+
+  static genericWriteSetterOptional<S>([S value]) {
+    property = value;
+  }
+
+  static genericWriteSetterNamed<S>({S value}) {
+    property = value;
+  }
+
+  static get tearOffGetterNoArgs => readGetter;
+  static get tearOffGetterRequired => writeSetterRequired;
+  static get tearOffGetterOptional => writeSetterOptional;
+  static get tearOffGetterNamed => writeSetterNamed;
+  static get tearOffGetterGenericRequired => genericWriteSetterRequired;
+  static get tearOffGetterGenericOptional => genericWriteSetterOptional;
+  static get tearOffGetterGenericNamed => genericWriteSetterNamed;
+
+  static invocationsFromStaticContext(int value) {
+    readGetter();
+    writeSetterRequired(value);
+    writeSetterOptional();
+    writeSetterOptional(value);
+    writeSetterNamed();
+    writeSetterNamed(value: value);
+    genericWriteSetterRequired(value);
+    genericWriteSetterRequired<int>(value);
+    genericWriteSetterOptional();
+    genericWriteSetterOptional<int>();
+    genericWriteSetterOptional(value);
+    genericWriteSetterOptional<int>(value);
+    genericWriteSetterNamed();
+    genericWriteSetterNamed<int>();
+    genericWriteSetterNamed(value: value);
+    genericWriteSetterNamed<int>(value: value);
+  }
+
+  static tearOffsFromStaticContext(int value) {
+    var tearOffNoArgs = readGetter;
+    tearOffNoArgs();
+    var tearOffRequired = writeSetterRequired;
+    tearOffRequired(value);
+    var tearOffOptional = writeSetterOptional;
+    tearOffOptional();
+    tearOffOptional(value);
+    var tearOffNamed = writeSetterNamed;
+    tearOffNamed();
+    tearOffNamed(value: value);
+    var tearOffGenericRequired = genericWriteSetterRequired;
+    tearOffGenericRequired(value);
+    tearOffGenericRequired<int>(value);
+    var tearOffGenericOptional = genericWriteSetterOptional;
+    tearOffGenericOptional();
+    tearOffGenericOptional<int>();
+    tearOffGenericOptional(value);
+    tearOffGenericOptional<int>(value);
+    var tearOffGenericNamed = genericWriteSetterNamed;
+    tearOffGenericNamed();
+    tearOffGenericNamed<int>();
+    tearOffGenericNamed(value: value);
+    tearOffGenericNamed<int>(value: value);
+  }
+
+  static fieldAccessFromStaticContext() {
+    field = property;
+    property = field;
+  }
+
+  static getterCallsFromStaticContext(int value) {
+    tearOffGetterNoArgs();
+    tearOffGetterRequired(value);
+    tearOffGetterOptional();
+    tearOffGetterOptional(value);
+    tearOffGetterNamed();
+    tearOffGetterNamed(value: value);
+    tearOffGetterGenericRequired(value);
+    tearOffGetterGenericRequired<int>(value);
+    tearOffGetterGenericOptional();
+    tearOffGetterGenericOptional<int>();
+    tearOffGetterGenericOptional(value);
+    tearOffGetterGenericOptional<int>(value);
+    tearOffGetterGenericNamed();
+    tearOffGetterGenericNamed<int>();
+    tearOffGetterGenericNamed(value: value);
+    tearOffGetterGenericNamed<int>(value: value);
+  }
+
+  invocationsFromInstanceContext(T value) {
+    readGetter();
+    writeSetterRequired(value);
+    writeSetterOptional();
+    writeSetterOptional(value);
+    writeSetterNamed();
+    writeSetterNamed(value: value);
+    genericWriteSetterRequired(value);
+    genericWriteSetterRequired<T>(value);
+    genericWriteSetterOptional();
+    genericWriteSetterOptional<T>();
+    genericWriteSetterOptional(value);
+    genericWriteSetterOptional<T>(value);
+    genericWriteSetterNamed();
+    genericWriteSetterNamed<T>();
+    genericWriteSetterNamed(value: value);
+    genericWriteSetterNamed<T>(value: value);
+  }
+
+  tearOffsFromInstanceContext(T value) {
+    var tearOffNoArgs = readGetter;
+    tearOffNoArgs();
+    var tearOffRequired = writeSetterRequired;
+    tearOffRequired(value);
+    var tearOffOptional = writeSetterOptional;
+    tearOffOptional();
+    tearOffOptional(value);
+    var tearOffNamed = writeSetterNamed;
+    tearOffNamed();
+    tearOffNamed(value: value);
+    var tearOffGenericRequired = genericWriteSetterRequired;
+    tearOffGenericRequired(value);
+    tearOffGenericRequired<T>(value);
+    var tearOffGenericOptional = genericWriteSetterOptional;
+    tearOffGenericOptional();
+    tearOffGenericOptional<T>();
+    tearOffGenericOptional(value);
+    tearOffGenericOptional<T>(value);
+    var tearOffGenericNamed = genericWriteSetterNamed;
+    tearOffGenericNamed();
+    tearOffGenericNamed<T>();
+    tearOffGenericNamed(value: value);
+    tearOffGenericNamed<T>(value: value);
+  }
+
+  fieldAccessFromInstanceContext() {
+    field = property;
+    property = field;
+  }
+
+  getterCallsFromInstanceContext(T value) {
+    tearOffGetterNoArgs();
+    tearOffGetterRequired(value);
+    tearOffGetterOptional();
+    tearOffGetterOptional(value);
+    tearOffGetterNamed();
+    tearOffGetterNamed(value: value);
+    tearOffGetterGenericRequired(value);
+    tearOffGetterGenericRequired<T>(value);
+    tearOffGetterGenericOptional();
+    tearOffGetterGenericOptional<T>();
+    tearOffGetterGenericOptional(value);
+    tearOffGetterGenericOptional<T>(value);
+    tearOffGetterGenericNamed();
+    tearOffGetterGenericNamed<T>();
+    tearOffGetterGenericNamed(value: value);
+    tearOffGetterGenericNamed<T>(value: value);
+  }
+}
+
+main() {}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/extensions/direct_static_access.dart.hierarchy.expect b/pkg/front_end/testcases/extensions/direct_static_access.dart.hierarchy.expect
new file mode 100644
index 0000000..1c0effd
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/direct_static_access.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Class:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Class.field
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Class.field
diff --git a/pkg/front_end/testcases/extensions/direct_static_access.dart.legacy.expect b/pkg/front_end/testcases/extensions/direct_static_access.dart.legacy.expect
new file mode 100644
index 0000000..35073da
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/direct_static_access.dart.legacy.expect
@@ -0,0 +1,366 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:9:11: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// extension Extension<T> on Class<T> {
+//           ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:9:24: Error: Expected '{' before this.
+// extension Extension<T> on Class<T> {
+//                        ^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:9:27: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// extension Extension<T> on Class<T> {
+//                           ^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:9:27: Error: 'Class' is already declared in this scope.
+// extension Extension<T> on Class<T> {
+//                           ^^^^^
+// pkg/front_end/testcases/extensions/direct_static_access.dart:5:7: Context: Previous declaration of 'Class'.
+// class Class<T> {
+//       ^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:9:1: Warning: Type 'extension' not found.
+// extension Extension<T> on Class<T> {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:9:24: Warning: Type 'on' not found.
+// extension Extension<T> on Class<T> {
+//                        ^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:11:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static get property => Class.field;
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:11:10: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   static get property => Class.field;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:11:10: Error: Expected ';' after this.
+//   static get property => Class.field;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:11:23: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   static get property => Class.field;
+//                       ^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:11:26: Error: Can't use 'Class' because it is declared more than once.
+//   static get property => Class.field;
+//                          ^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:13:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static set property(value) {
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:13:10: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   static set property(value) {
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:13:10: Error: Expected ';' after this.
+//   static set property(value) {
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:13:14: Error: 'property' is already declared in this scope.
+//   static set property(value) {
+//              ^^^^^^^^
+// pkg/front_end/testcases/extensions/direct_static_access.dart:11:14: Context: Previous declaration of 'property'.
+//   static get property => Class.field;
+//              ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:14:5: Error: Can't use 'Class' because it is declared more than once.
+//     Class.field = value;
+//     ^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:17:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static var field;
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:19:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static readGetter() {
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:23:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static writeSetterRequired(value) {
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:24:5: Warning: Setter not found: 'property'.
+//     property = value;
+//     ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:27:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static writeSetterOptional([value]) {
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:28:5: Warning: Setter not found: 'property'.
+//     property = value;
+//     ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:31:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static writeSetterNamed({value}) {
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:32:5: Warning: Setter not found: 'property'.
+//     property = value;
+//     ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:35:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static genericWriteSetterRequired<S>(S value) {
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:36:5: Warning: Setter not found: 'property'.
+//     property = value;
+//     ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:39:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static genericWriteSetterOptional<S>([S value]) {
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:40:5: Warning: Setter not found: 'property'.
+//     property = value;
+//     ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:43:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static genericWriteSetterNamed<S>({S value}) {
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:44:5: Warning: Setter not found: 'property'.
+//     property = value;
+//     ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:47:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static get tearOffGetterNoArgs => readGetter;
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:47:10: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   static get tearOffGetterNoArgs => readGetter;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:47:10: Error: 'get' is already declared in this scope.
+//   static get tearOffGetterNoArgs => readGetter;
+//          ^^^
+// pkg/front_end/testcases/extensions/direct_static_access.dart:11:10: Context: Previous declaration of 'get'.
+//   static get property => Class.field;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:47:10: Error: Expected ';' after this.
+//   static get tearOffGetterNoArgs => readGetter;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:47:34: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   static get tearOffGetterNoArgs => readGetter;
+//                                  ^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:48:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static get tearOffGetterRequired => writeSetterRequired;
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:48:10: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   static get tearOffGetterRequired => writeSetterRequired;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:48:10: Error: 'get' is already declared in this scope.
+//   static get tearOffGetterRequired => writeSetterRequired;
+//          ^^^
+// pkg/front_end/testcases/extensions/direct_static_access.dart:11:10: Context: Previous declaration of 'get'.
+//   static get property => Class.field;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:48:10: Error: Expected ';' after this.
+//   static get tearOffGetterRequired => writeSetterRequired;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:48:36: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   static get tearOffGetterRequired => writeSetterRequired;
+//                                    ^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:49:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static get tearOffGetterOptional => writeSetterOptional;
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:49:10: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   static get tearOffGetterOptional => writeSetterOptional;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:49:10: Error: 'get' is already declared in this scope.
+//   static get tearOffGetterOptional => writeSetterOptional;
+//          ^^^
+// pkg/front_end/testcases/extensions/direct_static_access.dart:11:10: Context: Previous declaration of 'get'.
+//   static get property => Class.field;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:49:10: Error: Expected ';' after this.
+//   static get tearOffGetterOptional => writeSetterOptional;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:49:36: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   static get tearOffGetterOptional => writeSetterOptional;
+//                                    ^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:50:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static get tearOffGetterNamed => writeSetterNamed;
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:50:10: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   static get tearOffGetterNamed => writeSetterNamed;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:50:10: Error: 'get' is already declared in this scope.
+//   static get tearOffGetterNamed => writeSetterNamed;
+//          ^^^
+// pkg/front_end/testcases/extensions/direct_static_access.dart:11:10: Context: Previous declaration of 'get'.
+//   static get property => Class.field;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:50:10: Error: Expected ';' after this.
+//   static get tearOffGetterNamed => writeSetterNamed;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:50:33: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   static get tearOffGetterNamed => writeSetterNamed;
+//                                 ^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:51:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static get tearOffGetterGenericRequired => genericWriteSetterRequired;
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:51:10: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   static get tearOffGetterGenericRequired => genericWriteSetterRequired;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:51:10: Error: 'get' is already declared in this scope.
+//   static get tearOffGetterGenericRequired => genericWriteSetterRequired;
+//          ^^^
+// pkg/front_end/testcases/extensions/direct_static_access.dart:11:10: Context: Previous declaration of 'get'.
+//   static get property => Class.field;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:51:10: Error: Expected ';' after this.
+//   static get tearOffGetterGenericRequired => genericWriteSetterRequired;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:51:43: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   static get tearOffGetterGenericRequired => genericWriteSetterRequired;
+//                                           ^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:52:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static get tearOffGetterGenericOptional => genericWriteSetterOptional;
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:52:10: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   static get tearOffGetterGenericOptional => genericWriteSetterOptional;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:52:10: Error: 'get' is already declared in this scope.
+//   static get tearOffGetterGenericOptional => genericWriteSetterOptional;
+//          ^^^
+// pkg/front_end/testcases/extensions/direct_static_access.dart:11:10: Context: Previous declaration of 'get'.
+//   static get property => Class.field;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:52:10: Error: Expected ';' after this.
+//   static get tearOffGetterGenericOptional => genericWriteSetterOptional;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:52:43: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   static get tearOffGetterGenericOptional => genericWriteSetterOptional;
+//                                           ^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:53:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static get tearOffGetterGenericNamed => genericWriteSetterNamed;
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:53:10: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   static get tearOffGetterGenericNamed => genericWriteSetterNamed;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:53:10: Error: 'get' is already declared in this scope.
+//   static get tearOffGetterGenericNamed => genericWriteSetterNamed;
+//          ^^^
+// pkg/front_end/testcases/extensions/direct_static_access.dart:11:10: Context: Previous declaration of 'get'.
+//   static get property => Class.field;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:53:10: Error: Expected ';' after this.
+//   static get tearOffGetterGenericNamed => genericWriteSetterNamed;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:53:40: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   static get tearOffGetterGenericNamed => genericWriteSetterNamed;
+//                                        ^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:55:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static invocationsFromStaticContext(int value) {
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:74:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static tearOffsFromStaticContext(int value) {
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:100:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static fieldAccessFromStaticContext() {
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:102:5: Warning: Setter not found: 'property'.
+//     property = field;
+//     ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:105:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static getterCallsFromStaticContext(int value) {
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:171:5: Warning: Setter not found: 'property'.
+//     property = field;
+//     ^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class<T extends core::Object* = dynamic> extends core::Object {
+  static field dynamic field = null;
+  synthetic constructor •() → self::Class<self::Class::T*>*
+    : super core::Object::•()
+    ;
+}
+static method Extension<T extends core::Object* = dynamic>() → invalid-type {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/direct_static_access.dart.legacy.transformed.expect b/pkg/front_end/testcases/extensions/direct_static_access.dart.legacy.transformed.expect
new file mode 100644
index 0000000..35073da
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/direct_static_access.dart.legacy.transformed.expect
@@ -0,0 +1,366 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:9:11: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// extension Extension<T> on Class<T> {
+//           ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:9:24: Error: Expected '{' before this.
+// extension Extension<T> on Class<T> {
+//                        ^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:9:27: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// extension Extension<T> on Class<T> {
+//                           ^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:9:27: Error: 'Class' is already declared in this scope.
+// extension Extension<T> on Class<T> {
+//                           ^^^^^
+// pkg/front_end/testcases/extensions/direct_static_access.dart:5:7: Context: Previous declaration of 'Class'.
+// class Class<T> {
+//       ^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:9:1: Warning: Type 'extension' not found.
+// extension Extension<T> on Class<T> {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:9:24: Warning: Type 'on' not found.
+// extension Extension<T> on Class<T> {
+//                        ^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:11:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static get property => Class.field;
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:11:10: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   static get property => Class.field;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:11:10: Error: Expected ';' after this.
+//   static get property => Class.field;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:11:23: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   static get property => Class.field;
+//                       ^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:11:26: Error: Can't use 'Class' because it is declared more than once.
+//   static get property => Class.field;
+//                          ^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:13:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static set property(value) {
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:13:10: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   static set property(value) {
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:13:10: Error: Expected ';' after this.
+//   static set property(value) {
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:13:14: Error: 'property' is already declared in this scope.
+//   static set property(value) {
+//              ^^^^^^^^
+// pkg/front_end/testcases/extensions/direct_static_access.dart:11:14: Context: Previous declaration of 'property'.
+//   static get property => Class.field;
+//              ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:14:5: Error: Can't use 'Class' because it is declared more than once.
+//     Class.field = value;
+//     ^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:17:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static var field;
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:19:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static readGetter() {
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:23:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static writeSetterRequired(value) {
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:24:5: Warning: Setter not found: 'property'.
+//     property = value;
+//     ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:27:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static writeSetterOptional([value]) {
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:28:5: Warning: Setter not found: 'property'.
+//     property = value;
+//     ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:31:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static writeSetterNamed({value}) {
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:32:5: Warning: Setter not found: 'property'.
+//     property = value;
+//     ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:35:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static genericWriteSetterRequired<S>(S value) {
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:36:5: Warning: Setter not found: 'property'.
+//     property = value;
+//     ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:39:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static genericWriteSetterOptional<S>([S value]) {
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:40:5: Warning: Setter not found: 'property'.
+//     property = value;
+//     ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:43:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static genericWriteSetterNamed<S>({S value}) {
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:44:5: Warning: Setter not found: 'property'.
+//     property = value;
+//     ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:47:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static get tearOffGetterNoArgs => readGetter;
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:47:10: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   static get tearOffGetterNoArgs => readGetter;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:47:10: Error: 'get' is already declared in this scope.
+//   static get tearOffGetterNoArgs => readGetter;
+//          ^^^
+// pkg/front_end/testcases/extensions/direct_static_access.dart:11:10: Context: Previous declaration of 'get'.
+//   static get property => Class.field;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:47:10: Error: Expected ';' after this.
+//   static get tearOffGetterNoArgs => readGetter;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:47:34: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   static get tearOffGetterNoArgs => readGetter;
+//                                  ^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:48:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static get tearOffGetterRequired => writeSetterRequired;
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:48:10: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   static get tearOffGetterRequired => writeSetterRequired;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:48:10: Error: 'get' is already declared in this scope.
+//   static get tearOffGetterRequired => writeSetterRequired;
+//          ^^^
+// pkg/front_end/testcases/extensions/direct_static_access.dart:11:10: Context: Previous declaration of 'get'.
+//   static get property => Class.field;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:48:10: Error: Expected ';' after this.
+//   static get tearOffGetterRequired => writeSetterRequired;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:48:36: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   static get tearOffGetterRequired => writeSetterRequired;
+//                                    ^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:49:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static get tearOffGetterOptional => writeSetterOptional;
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:49:10: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   static get tearOffGetterOptional => writeSetterOptional;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:49:10: Error: 'get' is already declared in this scope.
+//   static get tearOffGetterOptional => writeSetterOptional;
+//          ^^^
+// pkg/front_end/testcases/extensions/direct_static_access.dart:11:10: Context: Previous declaration of 'get'.
+//   static get property => Class.field;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:49:10: Error: Expected ';' after this.
+//   static get tearOffGetterOptional => writeSetterOptional;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:49:36: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   static get tearOffGetterOptional => writeSetterOptional;
+//                                    ^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:50:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static get tearOffGetterNamed => writeSetterNamed;
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:50:10: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   static get tearOffGetterNamed => writeSetterNamed;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:50:10: Error: 'get' is already declared in this scope.
+//   static get tearOffGetterNamed => writeSetterNamed;
+//          ^^^
+// pkg/front_end/testcases/extensions/direct_static_access.dart:11:10: Context: Previous declaration of 'get'.
+//   static get property => Class.field;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:50:10: Error: Expected ';' after this.
+//   static get tearOffGetterNamed => writeSetterNamed;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:50:33: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   static get tearOffGetterNamed => writeSetterNamed;
+//                                 ^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:51:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static get tearOffGetterGenericRequired => genericWriteSetterRequired;
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:51:10: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   static get tearOffGetterGenericRequired => genericWriteSetterRequired;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:51:10: Error: 'get' is already declared in this scope.
+//   static get tearOffGetterGenericRequired => genericWriteSetterRequired;
+//          ^^^
+// pkg/front_end/testcases/extensions/direct_static_access.dart:11:10: Context: Previous declaration of 'get'.
+//   static get property => Class.field;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:51:10: Error: Expected ';' after this.
+//   static get tearOffGetterGenericRequired => genericWriteSetterRequired;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:51:43: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   static get tearOffGetterGenericRequired => genericWriteSetterRequired;
+//                                           ^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:52:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static get tearOffGetterGenericOptional => genericWriteSetterOptional;
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:52:10: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   static get tearOffGetterGenericOptional => genericWriteSetterOptional;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:52:10: Error: 'get' is already declared in this scope.
+//   static get tearOffGetterGenericOptional => genericWriteSetterOptional;
+//          ^^^
+// pkg/front_end/testcases/extensions/direct_static_access.dart:11:10: Context: Previous declaration of 'get'.
+//   static get property => Class.field;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:52:10: Error: Expected ';' after this.
+//   static get tearOffGetterGenericOptional => genericWriteSetterOptional;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:52:43: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   static get tearOffGetterGenericOptional => genericWriteSetterOptional;
+//                                           ^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:53:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static get tearOffGetterGenericNamed => genericWriteSetterNamed;
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:53:10: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   static get tearOffGetterGenericNamed => genericWriteSetterNamed;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:53:10: Error: 'get' is already declared in this scope.
+//   static get tearOffGetterGenericNamed => genericWriteSetterNamed;
+//          ^^^
+// pkg/front_end/testcases/extensions/direct_static_access.dart:11:10: Context: Previous declaration of 'get'.
+//   static get property => Class.field;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:53:10: Error: Expected ';' after this.
+//   static get tearOffGetterGenericNamed => genericWriteSetterNamed;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:53:40: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   static get tearOffGetterGenericNamed => genericWriteSetterNamed;
+//                                        ^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:55:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static invocationsFromStaticContext(int value) {
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:74:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static tearOffsFromStaticContext(int value) {
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:100:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static fieldAccessFromStaticContext() {
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:102:5: Warning: Setter not found: 'property'.
+//     property = field;
+//     ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:105:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static getterCallsFromStaticContext(int value) {
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:171:5: Warning: Setter not found: 'property'.
+//     property = field;
+//     ^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class<T extends core::Object* = dynamic> extends core::Object {
+  static field dynamic field = null;
+  synthetic constructor •() → self::Class<self::Class::T*>*
+    : super core::Object::•()
+    ;
+}
+static method Extension<T extends core::Object* = dynamic>() → invalid-type {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/direct_static_access.dart.outline.expect b/pkg/front_end/testcases/extensions/direct_static_access.dart.outline.expect
new file mode 100644
index 0000000..e6826b8
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/direct_static_access.dart.outline.expect
@@ -0,0 +1,45 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:9:11: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// extension Extension<T> on Class<T> {
+//           ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:9:24: Error: Expected '{' before this.
+// extension Extension<T> on Class<T> {
+//                        ^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:9:27: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// extension Extension<T> on Class<T> {
+//                           ^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:9:27: Error: 'Class' is already declared in this scope.
+// extension Extension<T> on Class<T> {
+//                           ^^^^^
+// pkg/front_end/testcases/extensions/direct_static_access.dart:5:7: Context: Previous declaration of 'Class'.
+// class Class<T> {
+//       ^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:9:1: Warning: Type 'extension' not found.
+// extension Extension<T> on Class<T> {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/direct_static_access.dart:9:24: Warning: Type 'on' not found.
+// extension Extension<T> on Class<T> {
+//                        ^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class<T extends core::Object* = dynamic> extends core::Object {
+  static field dynamic field;
+  synthetic constructor •() → self::Class<self::Class::T*>*
+    ;
+}
+static method Extension<T extends core::Object* = dynamic>() → invalid-type
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/extensions/direct_static_access.dart.strong.expect b/pkg/front_end/testcases/extensions/direct_static_access.dart.strong.expect
new file mode 100644
index 0000000..1d70dc7
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/direct_static_access.dart.strong.expect
@@ -0,0 +1,220 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class<T extends core::Object* = dynamic> extends core::Object {
+  static field dynamic field = null;
+  synthetic constructor •() → self::Class<self::Class::T*>*
+    : super core::Object::•()
+    ;
+}
+extension Extension<T extends core::Object* = dynamic> on self::Class<T*>* {
+  static get property = get self::Extension|property;
+  static field field = self::Extension|field;
+  static method readGetter = self::Extension|readGetter;
+  static method writeSetterRequired = self::Extension|writeSetterRequired;
+  static method writeSetterOptional = self::Extension|writeSetterOptional;
+  static method writeSetterNamed = self::Extension|writeSetterNamed;
+  static method genericWriteSetterRequired = self::Extension|genericWriteSetterRequired;
+  static method genericWriteSetterOptional = self::Extension|genericWriteSetterOptional;
+  static method genericWriteSetterNamed = self::Extension|genericWriteSetterNamed;
+  static get tearOffGetterNoArgs = get self::Extension|tearOffGetterNoArgs;
+  static get tearOffGetterRequired = get self::Extension|tearOffGetterRequired;
+  static get tearOffGetterOptional = get self::Extension|tearOffGetterOptional;
+  static get tearOffGetterNamed = get self::Extension|tearOffGetterNamed;
+  static get tearOffGetterGenericRequired = get self::Extension|tearOffGetterGenericRequired;
+  static get tearOffGetterGenericOptional = get self::Extension|tearOffGetterGenericOptional;
+  static get tearOffGetterGenericNamed = get self::Extension|tearOffGetterGenericNamed;
+  static method invocationsFromStaticContext = self::Extension|invocationsFromStaticContext;
+  static method tearOffsFromStaticContext = self::Extension|tearOffsFromStaticContext;
+  static method fieldAccessFromStaticContext = self::Extension|fieldAccessFromStaticContext;
+  static method getterCallsFromStaticContext = self::Extension|getterCallsFromStaticContext;
+  method invocationsFromInstanceContext = self::Extension|invocationsFromInstanceContext;
+  method tearOffsFromInstanceContext = self::Extension|tearOffsFromInstanceContext;
+  method fieldAccessFromInstanceContext = self::Extension|fieldAccessFromInstanceContext;
+  method getterCallsFromInstanceContext = self::Extension|getterCallsFromInstanceContext;
+  static set property = set self::Extension|property;
+}
+static field dynamic Extension|field;
+static get Extension|property() → dynamic
+  return self::Class::field;
+static set Extension|property(dynamic value) → void {
+  self::Class::field = value;
+}
+static method Extension|readGetter() → dynamic {
+  return self::Extension|property;
+}
+static method Extension|writeSetterRequired(dynamic value) → dynamic {
+  self::Extension|property = value;
+}
+static method Extension|writeSetterOptional([dynamic value = #C1]) → dynamic {
+  self::Extension|property = value;
+}
+static method Extension|writeSetterNamed({dynamic value = #C1}) → dynamic {
+  self::Extension|property = value;
+}
+static method Extension|genericWriteSetterRequired<S extends core::Object* = dynamic>(self::Extension|genericWriteSetterRequired::S* value) → dynamic {
+  self::Extension|property = value;
+}
+static method Extension|genericWriteSetterOptional<S extends core::Object* = dynamic>([self::Extension|genericWriteSetterOptional::S* value = #C1]) → dynamic {
+  self::Extension|property = value;
+}
+static method Extension|genericWriteSetterNamed<S extends core::Object* = dynamic>({self::Extension|genericWriteSetterNamed::S* value = #C1}) → dynamic {
+  self::Extension|property = value;
+}
+static get Extension|tearOffGetterNoArgs() → dynamic
+  return #C2;
+static get Extension|tearOffGetterRequired() → dynamic
+  return #C3;
+static get Extension|tearOffGetterOptional() → dynamic
+  return #C4;
+static get Extension|tearOffGetterNamed() → dynamic
+  return #C5;
+static get Extension|tearOffGetterGenericRequired() → dynamic
+  return #C6;
+static get Extension|tearOffGetterGenericOptional() → dynamic
+  return #C7;
+static get Extension|tearOffGetterGenericNamed() → dynamic
+  return #C8;
+static method Extension|invocationsFromStaticContext(core::int* value) → dynamic {
+  self::Extension|readGetter();
+  self::Extension|writeSetterRequired(value);
+  self::Extension|writeSetterOptional();
+  self::Extension|writeSetterOptional(value);
+  self::Extension|writeSetterNamed();
+  self::Extension|writeSetterNamed(value: value);
+  self::Extension|genericWriteSetterRequired<core::int*>(value);
+  self::Extension|genericWriteSetterRequired<core::int*>(value);
+  self::Extension|genericWriteSetterOptional<dynamic>();
+  self::Extension|genericWriteSetterOptional<core::int*>();
+  self::Extension|genericWriteSetterOptional<core::int*>(value);
+  self::Extension|genericWriteSetterOptional<core::int*>(value);
+  self::Extension|genericWriteSetterNamed<dynamic>();
+  self::Extension|genericWriteSetterNamed<core::int*>();
+  self::Extension|genericWriteSetterNamed<core::int*>(value: value);
+  self::Extension|genericWriteSetterNamed<core::int*>(value: value);
+}
+static method Extension|tearOffsFromStaticContext(core::int* value) → dynamic {
+  () →* dynamic tearOffNoArgs = #C2;
+  tearOffNoArgs.call();
+  (dynamic) →* dynamic tearOffRequired = #C3;
+  tearOffRequired.call(value);
+  ([dynamic]) →* dynamic tearOffOptional = #C4;
+  tearOffOptional.call();
+  tearOffOptional.call(value);
+  ({value: dynamic}) →* dynamic tearOffNamed = #C5;
+  tearOffNamed.call();
+  tearOffNamed.call(value: value);
+  <S extends core::Object* = dynamic>(self::Extension|genericWriteSetterRequired::S*) →* dynamic tearOffGenericRequired = #C6;
+  tearOffGenericRequired.call<core::int*>(value);
+  tearOffGenericRequired.call<core::int*>(value);
+  <S extends core::Object* = dynamic>([self::Extension|genericWriteSetterOptional::S*]) →* dynamic tearOffGenericOptional = #C7;
+  tearOffGenericOptional.call<dynamic>();
+  tearOffGenericOptional.call<core::int*>();
+  tearOffGenericOptional.call<core::int*>(value);
+  tearOffGenericOptional.call<core::int*>(value);
+  <S extends core::Object* = dynamic>({value: self::Extension|genericWriteSetterNamed::S*}) →* dynamic tearOffGenericNamed = #C8;
+  tearOffGenericNamed.call<dynamic>();
+  tearOffGenericNamed.call<core::int*>();
+  tearOffGenericNamed.call<core::int*>(value: value);
+  tearOffGenericNamed.call<core::int*>(value: value);
+}
+static method Extension|fieldAccessFromStaticContext() → dynamic {
+  self::Extension|field = self::Extension|property;
+  self::Extension|property = self::Extension|field;
+}
+static method Extension|getterCallsFromStaticContext(core::int* value) → dynamic {
+  self::Extension|tearOffGetterNoArgs.call();
+  self::Extension|tearOffGetterRequired.call(value);
+  self::Extension|tearOffGetterOptional.call();
+  self::Extension|tearOffGetterOptional.call(value);
+  self::Extension|tearOffGetterNamed.call();
+  self::Extension|tearOffGetterNamed.call(value: value);
+  self::Extension|tearOffGetterGenericRequired.call(value);
+  self::Extension|tearOffGetterGenericRequired.call<core::int*>(value);
+  self::Extension|tearOffGetterGenericOptional.call();
+  self::Extension|tearOffGetterGenericOptional.call<core::int*>();
+  self::Extension|tearOffGetterGenericOptional.call(value);
+  self::Extension|tearOffGetterGenericOptional.call<core::int*>(value);
+  self::Extension|tearOffGetterGenericNamed.call();
+  self::Extension|tearOffGetterGenericNamed.call<core::int*>();
+  self::Extension|tearOffGetterGenericNamed.call(value: value);
+  self::Extension|tearOffGetterGenericNamed.call<core::int*>(value: value);
+}
+static method Extension|invocationsFromInstanceContext<#T extends core::Object* = dynamic>(final self::Class<self::Extension|invocationsFromInstanceContext::#T*>* #this, self::Extension|invocationsFromInstanceContext::#T* value) → dynamic {
+  self::Extension|readGetter();
+  self::Extension|writeSetterRequired(value);
+  self::Extension|writeSetterOptional();
+  self::Extension|writeSetterOptional(value);
+  self::Extension|writeSetterNamed();
+  self::Extension|writeSetterNamed(value: value);
+  self::Extension|genericWriteSetterRequired<self::Extension|invocationsFromInstanceContext::#T*>(value);
+  self::Extension|genericWriteSetterRequired<self::Extension|invocationsFromInstanceContext::#T*>(value);
+  self::Extension|genericWriteSetterOptional<dynamic>();
+  self::Extension|genericWriteSetterOptional<self::Extension|invocationsFromInstanceContext::#T*>();
+  self::Extension|genericWriteSetterOptional<self::Extension|invocationsFromInstanceContext::#T*>(value);
+  self::Extension|genericWriteSetterOptional<self::Extension|invocationsFromInstanceContext::#T*>(value);
+  self::Extension|genericWriteSetterNamed<dynamic>();
+  self::Extension|genericWriteSetterNamed<self::Extension|invocationsFromInstanceContext::#T*>();
+  self::Extension|genericWriteSetterNamed<self::Extension|invocationsFromInstanceContext::#T*>(value: value);
+  self::Extension|genericWriteSetterNamed<self::Extension|invocationsFromInstanceContext::#T*>(value: value);
+}
+static method Extension|tearOffsFromInstanceContext<#T extends core::Object* = dynamic>(final self::Class<self::Extension|tearOffsFromInstanceContext::#T*>* #this, self::Extension|tearOffsFromInstanceContext::#T* value) → dynamic {
+  () →* dynamic tearOffNoArgs = #C2;
+  tearOffNoArgs.call();
+  (dynamic) →* dynamic tearOffRequired = #C3;
+  tearOffRequired.call(value);
+  ([dynamic]) →* dynamic tearOffOptional = #C4;
+  tearOffOptional.call();
+  tearOffOptional.call(value);
+  ({value: dynamic}) →* dynamic tearOffNamed = #C5;
+  tearOffNamed.call();
+  tearOffNamed.call(value: value);
+  <S extends core::Object* = dynamic>(self::Extension|genericWriteSetterRequired::S*) →* dynamic tearOffGenericRequired = #C6;
+  tearOffGenericRequired.call<self::Extension|tearOffsFromInstanceContext::#T*>(value);
+  tearOffGenericRequired.call<self::Extension|tearOffsFromInstanceContext::#T*>(value);
+  <S extends core::Object* = dynamic>([self::Extension|genericWriteSetterOptional::S*]) →* dynamic tearOffGenericOptional = #C7;
+  tearOffGenericOptional.call<dynamic>();
+  tearOffGenericOptional.call<self::Extension|tearOffsFromInstanceContext::#T*>();
+  tearOffGenericOptional.call<self::Extension|tearOffsFromInstanceContext::#T*>(value);
+  tearOffGenericOptional.call<self::Extension|tearOffsFromInstanceContext::#T*>(value);
+  <S extends core::Object* = dynamic>({value: self::Extension|genericWriteSetterNamed::S*}) →* dynamic tearOffGenericNamed = #C8;
+  tearOffGenericNamed.call<dynamic>();
+  tearOffGenericNamed.call<self::Extension|tearOffsFromInstanceContext::#T*>();
+  tearOffGenericNamed.call<self::Extension|tearOffsFromInstanceContext::#T*>(value: value);
+  tearOffGenericNamed.call<self::Extension|tearOffsFromInstanceContext::#T*>(value: value);
+}
+static method Extension|fieldAccessFromInstanceContext<#T extends core::Object* = dynamic>(final self::Class<self::Extension|fieldAccessFromInstanceContext::#T*>* #this) → dynamic {
+  self::Extension|field = self::Extension|property;
+  self::Extension|property = self::Extension|field;
+}
+static method Extension|getterCallsFromInstanceContext<#T extends core::Object* = dynamic>(final self::Class<self::Extension|getterCallsFromInstanceContext::#T*>* #this, self::Extension|getterCallsFromInstanceContext::#T* value) → dynamic {
+  self::Extension|tearOffGetterNoArgs.call();
+  self::Extension|tearOffGetterRequired.call(value);
+  self::Extension|tearOffGetterOptional.call();
+  self::Extension|tearOffGetterOptional.call(value);
+  self::Extension|tearOffGetterNamed.call();
+  self::Extension|tearOffGetterNamed.call(value: value);
+  self::Extension|tearOffGetterGenericRequired.call(value);
+  self::Extension|tearOffGetterGenericRequired.call<self::Extension|getterCallsFromInstanceContext::#T*>(value);
+  self::Extension|tearOffGetterGenericOptional.call();
+  self::Extension|tearOffGetterGenericOptional.call<self::Extension|getterCallsFromInstanceContext::#T*>();
+  self::Extension|tearOffGetterGenericOptional.call(value);
+  self::Extension|tearOffGetterGenericOptional.call<self::Extension|getterCallsFromInstanceContext::#T*>(value);
+  self::Extension|tearOffGetterGenericNamed.call();
+  self::Extension|tearOffGetterGenericNamed.call<self::Extension|getterCallsFromInstanceContext::#T*>();
+  self::Extension|tearOffGetterGenericNamed.call(value: value);
+  self::Extension|tearOffGetterGenericNamed.call<self::Extension|getterCallsFromInstanceContext::#T*>(value: value);
+}
+static method main() → dynamic {}
+
+constants  {
+  #C1 = null
+  #C2 = tearoff self::Extension|readGetter
+  #C3 = tearoff self::Extension|writeSetterRequired
+  #C4 = tearoff self::Extension|writeSetterOptional
+  #C5 = tearoff self::Extension|writeSetterNamed
+  #C6 = tearoff self::Extension|genericWriteSetterRequired
+  #C7 = tearoff self::Extension|genericWriteSetterOptional
+  #C8 = tearoff self::Extension|genericWriteSetterNamed
+}
diff --git a/pkg/front_end/testcases/extensions/direct_static_access.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/direct_static_access.dart.strong.transformed.expect
new file mode 100644
index 0000000..1d70dc7
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/direct_static_access.dart.strong.transformed.expect
@@ -0,0 +1,220 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class<T extends core::Object* = dynamic> extends core::Object {
+  static field dynamic field = null;
+  synthetic constructor •() → self::Class<self::Class::T*>*
+    : super core::Object::•()
+    ;
+}
+extension Extension<T extends core::Object* = dynamic> on self::Class<T*>* {
+  static get property = get self::Extension|property;
+  static field field = self::Extension|field;
+  static method readGetter = self::Extension|readGetter;
+  static method writeSetterRequired = self::Extension|writeSetterRequired;
+  static method writeSetterOptional = self::Extension|writeSetterOptional;
+  static method writeSetterNamed = self::Extension|writeSetterNamed;
+  static method genericWriteSetterRequired = self::Extension|genericWriteSetterRequired;
+  static method genericWriteSetterOptional = self::Extension|genericWriteSetterOptional;
+  static method genericWriteSetterNamed = self::Extension|genericWriteSetterNamed;
+  static get tearOffGetterNoArgs = get self::Extension|tearOffGetterNoArgs;
+  static get tearOffGetterRequired = get self::Extension|tearOffGetterRequired;
+  static get tearOffGetterOptional = get self::Extension|tearOffGetterOptional;
+  static get tearOffGetterNamed = get self::Extension|tearOffGetterNamed;
+  static get tearOffGetterGenericRequired = get self::Extension|tearOffGetterGenericRequired;
+  static get tearOffGetterGenericOptional = get self::Extension|tearOffGetterGenericOptional;
+  static get tearOffGetterGenericNamed = get self::Extension|tearOffGetterGenericNamed;
+  static method invocationsFromStaticContext = self::Extension|invocationsFromStaticContext;
+  static method tearOffsFromStaticContext = self::Extension|tearOffsFromStaticContext;
+  static method fieldAccessFromStaticContext = self::Extension|fieldAccessFromStaticContext;
+  static method getterCallsFromStaticContext = self::Extension|getterCallsFromStaticContext;
+  method invocationsFromInstanceContext = self::Extension|invocationsFromInstanceContext;
+  method tearOffsFromInstanceContext = self::Extension|tearOffsFromInstanceContext;
+  method fieldAccessFromInstanceContext = self::Extension|fieldAccessFromInstanceContext;
+  method getterCallsFromInstanceContext = self::Extension|getterCallsFromInstanceContext;
+  static set property = set self::Extension|property;
+}
+static field dynamic Extension|field;
+static get Extension|property() → dynamic
+  return self::Class::field;
+static set Extension|property(dynamic value) → void {
+  self::Class::field = value;
+}
+static method Extension|readGetter() → dynamic {
+  return self::Extension|property;
+}
+static method Extension|writeSetterRequired(dynamic value) → dynamic {
+  self::Extension|property = value;
+}
+static method Extension|writeSetterOptional([dynamic value = #C1]) → dynamic {
+  self::Extension|property = value;
+}
+static method Extension|writeSetterNamed({dynamic value = #C1}) → dynamic {
+  self::Extension|property = value;
+}
+static method Extension|genericWriteSetterRequired<S extends core::Object* = dynamic>(self::Extension|genericWriteSetterRequired::S* value) → dynamic {
+  self::Extension|property = value;
+}
+static method Extension|genericWriteSetterOptional<S extends core::Object* = dynamic>([self::Extension|genericWriteSetterOptional::S* value = #C1]) → dynamic {
+  self::Extension|property = value;
+}
+static method Extension|genericWriteSetterNamed<S extends core::Object* = dynamic>({self::Extension|genericWriteSetterNamed::S* value = #C1}) → dynamic {
+  self::Extension|property = value;
+}
+static get Extension|tearOffGetterNoArgs() → dynamic
+  return #C2;
+static get Extension|tearOffGetterRequired() → dynamic
+  return #C3;
+static get Extension|tearOffGetterOptional() → dynamic
+  return #C4;
+static get Extension|tearOffGetterNamed() → dynamic
+  return #C5;
+static get Extension|tearOffGetterGenericRequired() → dynamic
+  return #C6;
+static get Extension|tearOffGetterGenericOptional() → dynamic
+  return #C7;
+static get Extension|tearOffGetterGenericNamed() → dynamic
+  return #C8;
+static method Extension|invocationsFromStaticContext(core::int* value) → dynamic {
+  self::Extension|readGetter();
+  self::Extension|writeSetterRequired(value);
+  self::Extension|writeSetterOptional();
+  self::Extension|writeSetterOptional(value);
+  self::Extension|writeSetterNamed();
+  self::Extension|writeSetterNamed(value: value);
+  self::Extension|genericWriteSetterRequired<core::int*>(value);
+  self::Extension|genericWriteSetterRequired<core::int*>(value);
+  self::Extension|genericWriteSetterOptional<dynamic>();
+  self::Extension|genericWriteSetterOptional<core::int*>();
+  self::Extension|genericWriteSetterOptional<core::int*>(value);
+  self::Extension|genericWriteSetterOptional<core::int*>(value);
+  self::Extension|genericWriteSetterNamed<dynamic>();
+  self::Extension|genericWriteSetterNamed<core::int*>();
+  self::Extension|genericWriteSetterNamed<core::int*>(value: value);
+  self::Extension|genericWriteSetterNamed<core::int*>(value: value);
+}
+static method Extension|tearOffsFromStaticContext(core::int* value) → dynamic {
+  () →* dynamic tearOffNoArgs = #C2;
+  tearOffNoArgs.call();
+  (dynamic) →* dynamic tearOffRequired = #C3;
+  tearOffRequired.call(value);
+  ([dynamic]) →* dynamic tearOffOptional = #C4;
+  tearOffOptional.call();
+  tearOffOptional.call(value);
+  ({value: dynamic}) →* dynamic tearOffNamed = #C5;
+  tearOffNamed.call();
+  tearOffNamed.call(value: value);
+  <S extends core::Object* = dynamic>(self::Extension|genericWriteSetterRequired::S*) →* dynamic tearOffGenericRequired = #C6;
+  tearOffGenericRequired.call<core::int*>(value);
+  tearOffGenericRequired.call<core::int*>(value);
+  <S extends core::Object* = dynamic>([self::Extension|genericWriteSetterOptional::S*]) →* dynamic tearOffGenericOptional = #C7;
+  tearOffGenericOptional.call<dynamic>();
+  tearOffGenericOptional.call<core::int*>();
+  tearOffGenericOptional.call<core::int*>(value);
+  tearOffGenericOptional.call<core::int*>(value);
+  <S extends core::Object* = dynamic>({value: self::Extension|genericWriteSetterNamed::S*}) →* dynamic tearOffGenericNamed = #C8;
+  tearOffGenericNamed.call<dynamic>();
+  tearOffGenericNamed.call<core::int*>();
+  tearOffGenericNamed.call<core::int*>(value: value);
+  tearOffGenericNamed.call<core::int*>(value: value);
+}
+static method Extension|fieldAccessFromStaticContext() → dynamic {
+  self::Extension|field = self::Extension|property;
+  self::Extension|property = self::Extension|field;
+}
+static method Extension|getterCallsFromStaticContext(core::int* value) → dynamic {
+  self::Extension|tearOffGetterNoArgs.call();
+  self::Extension|tearOffGetterRequired.call(value);
+  self::Extension|tearOffGetterOptional.call();
+  self::Extension|tearOffGetterOptional.call(value);
+  self::Extension|tearOffGetterNamed.call();
+  self::Extension|tearOffGetterNamed.call(value: value);
+  self::Extension|tearOffGetterGenericRequired.call(value);
+  self::Extension|tearOffGetterGenericRequired.call<core::int*>(value);
+  self::Extension|tearOffGetterGenericOptional.call();
+  self::Extension|tearOffGetterGenericOptional.call<core::int*>();
+  self::Extension|tearOffGetterGenericOptional.call(value);
+  self::Extension|tearOffGetterGenericOptional.call<core::int*>(value);
+  self::Extension|tearOffGetterGenericNamed.call();
+  self::Extension|tearOffGetterGenericNamed.call<core::int*>();
+  self::Extension|tearOffGetterGenericNamed.call(value: value);
+  self::Extension|tearOffGetterGenericNamed.call<core::int*>(value: value);
+}
+static method Extension|invocationsFromInstanceContext<#T extends core::Object* = dynamic>(final self::Class<self::Extension|invocationsFromInstanceContext::#T*>* #this, self::Extension|invocationsFromInstanceContext::#T* value) → dynamic {
+  self::Extension|readGetter();
+  self::Extension|writeSetterRequired(value);
+  self::Extension|writeSetterOptional();
+  self::Extension|writeSetterOptional(value);
+  self::Extension|writeSetterNamed();
+  self::Extension|writeSetterNamed(value: value);
+  self::Extension|genericWriteSetterRequired<self::Extension|invocationsFromInstanceContext::#T*>(value);
+  self::Extension|genericWriteSetterRequired<self::Extension|invocationsFromInstanceContext::#T*>(value);
+  self::Extension|genericWriteSetterOptional<dynamic>();
+  self::Extension|genericWriteSetterOptional<self::Extension|invocationsFromInstanceContext::#T*>();
+  self::Extension|genericWriteSetterOptional<self::Extension|invocationsFromInstanceContext::#T*>(value);
+  self::Extension|genericWriteSetterOptional<self::Extension|invocationsFromInstanceContext::#T*>(value);
+  self::Extension|genericWriteSetterNamed<dynamic>();
+  self::Extension|genericWriteSetterNamed<self::Extension|invocationsFromInstanceContext::#T*>();
+  self::Extension|genericWriteSetterNamed<self::Extension|invocationsFromInstanceContext::#T*>(value: value);
+  self::Extension|genericWriteSetterNamed<self::Extension|invocationsFromInstanceContext::#T*>(value: value);
+}
+static method Extension|tearOffsFromInstanceContext<#T extends core::Object* = dynamic>(final self::Class<self::Extension|tearOffsFromInstanceContext::#T*>* #this, self::Extension|tearOffsFromInstanceContext::#T* value) → dynamic {
+  () →* dynamic tearOffNoArgs = #C2;
+  tearOffNoArgs.call();
+  (dynamic) →* dynamic tearOffRequired = #C3;
+  tearOffRequired.call(value);
+  ([dynamic]) →* dynamic tearOffOptional = #C4;
+  tearOffOptional.call();
+  tearOffOptional.call(value);
+  ({value: dynamic}) →* dynamic tearOffNamed = #C5;
+  tearOffNamed.call();
+  tearOffNamed.call(value: value);
+  <S extends core::Object* = dynamic>(self::Extension|genericWriteSetterRequired::S*) →* dynamic tearOffGenericRequired = #C6;
+  tearOffGenericRequired.call<self::Extension|tearOffsFromInstanceContext::#T*>(value);
+  tearOffGenericRequired.call<self::Extension|tearOffsFromInstanceContext::#T*>(value);
+  <S extends core::Object* = dynamic>([self::Extension|genericWriteSetterOptional::S*]) →* dynamic tearOffGenericOptional = #C7;
+  tearOffGenericOptional.call<dynamic>();
+  tearOffGenericOptional.call<self::Extension|tearOffsFromInstanceContext::#T*>();
+  tearOffGenericOptional.call<self::Extension|tearOffsFromInstanceContext::#T*>(value);
+  tearOffGenericOptional.call<self::Extension|tearOffsFromInstanceContext::#T*>(value);
+  <S extends core::Object* = dynamic>({value: self::Extension|genericWriteSetterNamed::S*}) →* dynamic tearOffGenericNamed = #C8;
+  tearOffGenericNamed.call<dynamic>();
+  tearOffGenericNamed.call<self::Extension|tearOffsFromInstanceContext::#T*>();
+  tearOffGenericNamed.call<self::Extension|tearOffsFromInstanceContext::#T*>(value: value);
+  tearOffGenericNamed.call<self::Extension|tearOffsFromInstanceContext::#T*>(value: value);
+}
+static method Extension|fieldAccessFromInstanceContext<#T extends core::Object* = dynamic>(final self::Class<self::Extension|fieldAccessFromInstanceContext::#T*>* #this) → dynamic {
+  self::Extension|field = self::Extension|property;
+  self::Extension|property = self::Extension|field;
+}
+static method Extension|getterCallsFromInstanceContext<#T extends core::Object* = dynamic>(final self::Class<self::Extension|getterCallsFromInstanceContext::#T*>* #this, self::Extension|getterCallsFromInstanceContext::#T* value) → dynamic {
+  self::Extension|tearOffGetterNoArgs.call();
+  self::Extension|tearOffGetterRequired.call(value);
+  self::Extension|tearOffGetterOptional.call();
+  self::Extension|tearOffGetterOptional.call(value);
+  self::Extension|tearOffGetterNamed.call();
+  self::Extension|tearOffGetterNamed.call(value: value);
+  self::Extension|tearOffGetterGenericRequired.call(value);
+  self::Extension|tearOffGetterGenericRequired.call<self::Extension|getterCallsFromInstanceContext::#T*>(value);
+  self::Extension|tearOffGetterGenericOptional.call();
+  self::Extension|tearOffGetterGenericOptional.call<self::Extension|getterCallsFromInstanceContext::#T*>();
+  self::Extension|tearOffGetterGenericOptional.call(value);
+  self::Extension|tearOffGetterGenericOptional.call<self::Extension|getterCallsFromInstanceContext::#T*>(value);
+  self::Extension|tearOffGetterGenericNamed.call();
+  self::Extension|tearOffGetterGenericNamed.call<self::Extension|getterCallsFromInstanceContext::#T*>();
+  self::Extension|tearOffGetterGenericNamed.call(value: value);
+  self::Extension|tearOffGetterGenericNamed.call<self::Extension|getterCallsFromInstanceContext::#T*>(value: value);
+}
+static method main() → dynamic {}
+
+constants  {
+  #C1 = null
+  #C2 = tearoff self::Extension|readGetter
+  #C3 = tearoff self::Extension|writeSetterRequired
+  #C4 = tearoff self::Extension|writeSetterOptional
+  #C5 = tearoff self::Extension|writeSetterNamed
+  #C6 = tearoff self::Extension|genericWriteSetterRequired
+  #C7 = tearoff self::Extension|genericWriteSetterOptional
+  #C8 = tearoff self::Extension|genericWriteSetterNamed
+}
diff --git a/pkg/front_end/testcases/extensions/direct_static_access.dart.type_promotion.expect b/pkg/front_end/testcases/extensions/direct_static_access.dart.type_promotion.expect
new file mode 100644
index 0000000..5d34b36
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/direct_static_access.dart.type_promotion.expect
@@ -0,0 +1,6 @@
+pkg/front_end/testcases/extensions/direct_static_access.dart:101:11: Context: Write to field@408
+    field = property;
+          ^
+pkg/front_end/testcases/extensions/direct_static_access.dart:170:11: Context: Write to field@408
+    field = property;
+          ^
diff --git a/pkg/front_end/testcases/extensions/explicit_this.dart.strong.expect b/pkg/front_end/testcases/extensions/explicit_this.dart.strong.expect
index 391f9a2..0ea07bf 100644
--- a/pkg/front_end/testcases/extensions/explicit_this.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/explicit_this.dart.strong.expect
@@ -9,13 +9,16 @@
     ;
   method method1() → void {}
 }
-class A2 extends core::Object {
+extension A2 on self::A1* {
+  method method2 = self::A2|method2;
+  method method3 = self::A2|method3;
+  method method4 = self::A2|method4;
 }
-method A2|method2(final self::A1* #this) → void
+static method A2|method2(final self::A1* #this) → void
   return #this.{self::A1::method1}();
-method A2|method3(final self::A1* #this) → core::Object*
+static method A2|method3(final self::A1* #this) → core::Object*
   return #this.{self::A1::field};
-method A2|method4(final self::A1* #this, core::Object* o) → void {
+static method A2|method4(final self::A1* #this, core::Object* o) → void {
   #this.{self::A1::field} = o;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/explicit_this.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/explicit_this.dart.strong.transformed.expect
index 391f9a2..0ea07bf 100644
--- a/pkg/front_end/testcases/extensions/explicit_this.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/explicit_this.dart.strong.transformed.expect
@@ -9,13 +9,16 @@
     ;
   method method1() → void {}
 }
-class A2 extends core::Object {
+extension A2 on self::A1* {
+  method method2 = self::A2|method2;
+  method method3 = self::A2|method3;
+  method method4 = self::A2|method4;
 }
-method A2|method2(final self::A1* #this) → void
+static method A2|method2(final self::A1* #this) → void
   return #this.{self::A1::method1}();
-method A2|method3(final self::A1* #this) → core::Object*
+static method A2|method3(final self::A1* #this) → core::Object*
   return #this.{self::A1::field};
-method A2|method4(final self::A1* #this, core::Object* o) → void {
+static method A2|method4(final self::A1* #this, core::Object* o) → void {
   #this.{self::A1::field} = o;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/implicit_this.dart.strong.expect b/pkg/front_end/testcases/extensions/implicit_this.dart.strong.expect
index 391f9a2..0ea07bf 100644
--- a/pkg/front_end/testcases/extensions/implicit_this.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/implicit_this.dart.strong.expect
@@ -9,13 +9,16 @@
     ;
   method method1() → void {}
 }
-class A2 extends core::Object {
+extension A2 on self::A1* {
+  method method2 = self::A2|method2;
+  method method3 = self::A2|method3;
+  method method4 = self::A2|method4;
 }
-method A2|method2(final self::A1* #this) → void
+static method A2|method2(final self::A1* #this) → void
   return #this.{self::A1::method1}();
-method A2|method3(final self::A1* #this) → core::Object*
+static method A2|method3(final self::A1* #this) → core::Object*
   return #this.{self::A1::field};
-method A2|method4(final self::A1* #this, core::Object* o) → void {
+static method A2|method4(final self::A1* #this, core::Object* o) → void {
   #this.{self::A1::field} = o;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/implicit_this.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/implicit_this.dart.strong.transformed.expect
index 391f9a2..0ea07bf 100644
--- a/pkg/front_end/testcases/extensions/implicit_this.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/implicit_this.dart.strong.transformed.expect
@@ -9,13 +9,16 @@
     ;
   method method1() → void {}
 }
-class A2 extends core::Object {
+extension A2 on self::A1* {
+  method method2 = self::A2|method2;
+  method method3 = self::A2|method3;
+  method method4 = self::A2|method4;
 }
-method A2|method2(final self::A1* #this) → void
+static method A2|method2(final self::A1* #this) → void
   return #this.{self::A1::method1}();
-method A2|method3(final self::A1* #this) → core::Object*
+static method A2|method3(final self::A1* #this) → core::Object*
   return #this.{self::A1::field};
-method A2|method4(final self::A1* #this, core::Object* o) → void {
+static method A2|method4(final self::A1* #this, core::Object* o) → void {
   #this.{self::A1::field} = o;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/instance_members.dart.strong.expect b/pkg/front_end/testcases/extensions/instance_members.dart.strong.expect
index dfedda5..598e9a6 100644
--- a/pkg/front_end/testcases/extensions/instance_members.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/instance_members.dart.strong.expect
@@ -7,34 +7,40 @@
     : super core::Object::•()
     ;
 }
-class A2 extends core::Object {
-}
 class B1<T extends core::Object* = dynamic> extends core::Object {
   synthetic constructor •() → self::B1<self::B1::T*>*
     : super core::Object::•()
     ;
 }
-class B2<T extends core::Object* = dynamic> extends core::Object {
+extension A2 on self::A1* {
+  method method1 = self::A2|method1;
+  method method2 = self::A2|method2;
+  method method3 = self::A2|method3;
+  method method4 = self::A2|method4;
 }
-method A2|method1(final self::A1* #this) → self::A1* {
+extension B2<T extends core::Object* = dynamic> on self::B1<T*>* {
+  method method1 = self::B2|method1;
+  method method2 = self::B2|method2;
+}
+static method A2|method1(final self::A1* #this) → self::A1* {
   return #this;
 }
-method A2|method2<T extends core::Object* = dynamic>(final self::A1* #this, self::A2|method2::T* o) → self::A1* {
+static method A2|method2<T extends core::Object* = dynamic>(final self::A1* #this, self::A2|method2::T* o) → self::A1* {
   core::print(o);
   return #this;
 }
-method A2|method3<T extends core::Object* = dynamic>(final self::A1* #this = #C1, [self::A2|method3::T* o = #C1]) → self::A1* {
+static method A2|method3<T extends core::Object* = dynamic>(final self::A1* #this = #C1, [self::A2|method3::T* o = #C1]) → self::A1* {
   core::print(o);
   return #this;
 }
-method A2|method4<T extends core::Object* = dynamic>(final self::A1* #this = #C1, {self::A2|method4::T* o = #C1}) → self::A1* {
+static method A2|method4<T extends core::Object* = dynamic>(final self::A1* #this = #C1, {self::A2|method4::T* o = #C1}) → self::A1* {
   core::print(o);
   return #this;
 }
-method B2|method1<#T extends core::Object* = dynamic>(final self::B1<self::B2|method1::#T*>* #this) → self::B1<self::B2|method1::#T*>* {
+static method B2|method1<#T extends core::Object* = dynamic>(final self::B1<self::B2|method1::#T*>* #this) → self::B1<self::B2|method1::#T*>* {
   return #this;
 }
-method B2|method2<#T extends core::Object* = dynamic, S extends core::Object* = dynamic>(final self::B1<self::B2|method2::#T*>* #this, self::B2|method2::S* o) → self::B1<self::B2|method2::#T*>* {
+static method B2|method2<#T extends core::Object* = dynamic, S extends core::Object* = dynamic>(final self::B1<self::B2|method2::#T*>* #this, self::B2|method2::S* o) → self::B1<self::B2|method2::#T*>* {
   core::print(o);
   return #this;
 }
diff --git a/pkg/front_end/testcases/extensions/instance_members.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/instance_members.dart.strong.transformed.expect
index dfedda5..598e9a6 100644
--- a/pkg/front_end/testcases/extensions/instance_members.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/instance_members.dart.strong.transformed.expect
@@ -7,34 +7,40 @@
     : super core::Object::•()
     ;
 }
-class A2 extends core::Object {
-}
 class B1<T extends core::Object* = dynamic> extends core::Object {
   synthetic constructor •() → self::B1<self::B1::T*>*
     : super core::Object::•()
     ;
 }
-class B2<T extends core::Object* = dynamic> extends core::Object {
+extension A2 on self::A1* {
+  method method1 = self::A2|method1;
+  method method2 = self::A2|method2;
+  method method3 = self::A2|method3;
+  method method4 = self::A2|method4;
 }
-method A2|method1(final self::A1* #this) → self::A1* {
+extension B2<T extends core::Object* = dynamic> on self::B1<T*>* {
+  method method1 = self::B2|method1;
+  method method2 = self::B2|method2;
+}
+static method A2|method1(final self::A1* #this) → self::A1* {
   return #this;
 }
-method A2|method2<T extends core::Object* = dynamic>(final self::A1* #this, self::A2|method2::T* o) → self::A1* {
+static method A2|method2<T extends core::Object* = dynamic>(final self::A1* #this, self::A2|method2::T* o) → self::A1* {
   core::print(o);
   return #this;
 }
-method A2|method3<T extends core::Object* = dynamic>(final self::A1* #this = #C1, [self::A2|method3::T* o = #C1]) → self::A1* {
+static method A2|method3<T extends core::Object* = dynamic>(final self::A1* #this = #C1, [self::A2|method3::T* o = #C1]) → self::A1* {
   core::print(o);
   return #this;
 }
-method A2|method4<T extends core::Object* = dynamic>(final self::A1* #this = #C1, {self::A2|method4::T* o = #C1}) → self::A1* {
+static method A2|method4<T extends core::Object* = dynamic>(final self::A1* #this = #C1, {self::A2|method4::T* o = #C1}) → self::A1* {
   core::print(o);
   return #this;
 }
-method B2|method1<#T extends core::Object* = dynamic>(final self::B1<self::B2|method1::#T*>* #this) → self::B1<self::B2|method1::#T*>* {
+static method B2|method1<#T extends core::Object* = dynamic>(final self::B1<self::B2|method1::#T*>* #this) → self::B1<self::B2|method1::#T*>* {
   return #this;
 }
-method B2|method2<#T extends core::Object* = dynamic, S extends core::Object* = dynamic>(final self::B1<self::B2|method2::#T*>* #this, self::B2|method2::S* o) → self::B1<self::B2|method2::#T*>* {
+static method B2|method2<#T extends core::Object* = dynamic, S extends core::Object* = dynamic>(final self::B1<self::B2|method2::#T*>* #this, self::B2|method2::S* o) → self::B1<self::B2|method2::#T*>* {
   core::print(o);
   return #this;
 }
diff --git a/pkg/front_end/testcases/extensions/other_kinds.dart b/pkg/front_end/testcases/extensions/other_kinds.dart
new file mode 100644
index 0000000..21e21b4
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/other_kinds.dart
@@ -0,0 +1,40 @@
+// 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.
+
+class A1 {
+  int _instanceField;
+  int getInstanceField() => _instanceField;
+  void setInstanceField(int value) {
+    _instanceField = value;
+  }
+  static int _staticField = 0;
+  static int getStaticField() => _staticField;
+  static void setStaticField(int value) {
+    _staticField = value;
+  }
+}
+
+extension A2 on A1 {
+  int get instanceProperty => getInstanceField();
+
+  void set instanceProperty(int value) {
+    setInstanceField(value);
+  }
+
+  // TODO(johnniwinther): Test operator -() and operator -(val).
+
+  int operator +(int value) {
+    return getInstanceField() + value;
+  }
+
+  static int staticField = A1.getStaticField();
+
+  static int get staticProperty => A1.getStaticField();
+
+  static void set staticProperty(int value) {
+    A1.setStaticField(value);
+  }
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/other_kinds.dart.hierarchy.expect b/pkg/front_end/testcases/extensions/other_kinds.dart.hierarchy.expect
new file mode 100644
index 0000000..bb80724
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/other_kinds.dart.hierarchy.expect
@@ -0,0 +1,44 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A1.setStaticField
+    A1.getInstanceField
+    Object.runtimeType
+    Object._simpleInstanceOf
+    A1.getStaticField
+    A1._instanceField
+    Object._instanceOf
+    Object.noSuchMethod
+    A1._staticField
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    A1.setInstanceField
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A1._instanceField
+    A1._staticField
diff --git a/pkg/front_end/testcases/extensions/other_kinds.dart.legacy.expect b/pkg/front_end/testcases/extensions/other_kinds.dart.legacy.expect
new file mode 100644
index 0000000..b35bfc6
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/other_kinds.dart.legacy.expect
@@ -0,0 +1,161 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:18:1: Error: This requires the 'extension-methods' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// extension A2 on A1 {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:18:17: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// extension A2 on A1 {
+//                 ^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:18:17: Error: 'A1' is already declared in this scope.
+// extension A2 on A1 {
+//                 ^^
+// pkg/front_end/testcases/extensions/other_kinds.dart:5:7: Context: Previous declaration of 'A1'.
+// class A1 {
+//       ^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:18:1: Warning: Type 'extension' not found.
+// extension A2 on A1 {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:18:14: Warning: Type 'on' not found.
+// extension A2 on A1 {
+//              ^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:18:1: Warning: 'extension' isn't a type.
+// extension A2 on A1 {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:19:7: Error: Expected ';' after this.
+//   int get instanceProperty => getInstanceField();
+//       ^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:19:28: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   int get instanceProperty => getInstanceField();
+//                            ^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:19:31: Warning: Method not found: 'getInstanceField'.
+//   int get instanceProperty => getInstanceField();
+//                               ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:21:8: Error: Expected ';' after this.
+//   void set instanceProperty(int value) {
+//        ^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:21:12: Error: 'instanceProperty' is already declared in this scope.
+//   void set instanceProperty(int value) {
+//            ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/other_kinds.dart:19:11: Context: Previous declaration of 'instanceProperty'.
+//   int get instanceProperty => getInstanceField();
+//           ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:22:5: Warning: Method not found: 'setInstanceField'.
+//     setInstanceField(value);
+//     ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:27:7: Error: Expected ';' after this.
+//   int operator +(int value) {
+//       ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:27:16: Error: '+' is not a prefix operator.
+// Try removing '+'.
+//   int operator +(int value) {
+//                ^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:28:12: Warning: Method not found: 'getInstanceField'.
+//     return getInstanceField() + value;
+//            ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:29:3: Error: Expected ';' after this.
+//   }
+//   ^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:31:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static int staticField = A1.getStaticField();
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:31:28: Error: Can't use 'A1' because it is declared more than once.
+//   static int staticField = A1.getStaticField();
+//                            ^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:33:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static int get staticProperty => A1.getStaticField();
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:33:14: Error: 'get' is already declared in this scope.
+//   static int get staticProperty => A1.getStaticField();
+//              ^^^
+// pkg/front_end/testcases/extensions/other_kinds.dart:19:7: Context: Previous declaration of 'get'.
+//   int get instanceProperty => getInstanceField();
+//       ^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:33:14: Error: Expected ';' after this.
+//   static int get staticProperty => A1.getStaticField();
+//              ^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:33:33: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   static int get staticProperty => A1.getStaticField();
+//                                 ^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:33:36: Error: Can't use 'A1' because it is declared more than once.
+//   static int get staticProperty => A1.getStaticField();
+//                                    ^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:35:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static void set staticProperty(int value) {
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:35:15: Error: 'set' is already declared in this scope.
+//   static void set staticProperty(int value) {
+//               ^^^
+// pkg/front_end/testcases/extensions/other_kinds.dart:21:8: Context: Previous declaration of 'set'.
+//   void set instanceProperty(int value) {
+//        ^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:35:15: Error: Expected ';' after this.
+//   static void set staticProperty(int value) {
+//               ^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:35:19: Error: 'staticProperty' is already declared in this scope.
+//   static void set staticProperty(int value) {
+//                   ^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/other_kinds.dart:33:18: Context: Previous declaration of 'staticProperty'.
+//   static int get staticProperty => A1.getStaticField();
+//                  ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:36:5: Error: Can't use 'A1' because it is declared more than once.
+//     A1.setStaticField(value);
+//     ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A1 extends core::Object {
+  field core::int* _instanceField = null;
+  static field core::int* _staticField = 0;
+  synthetic constructor •() → self::A1*
+    : super core::Object::•()
+    ;
+  method getInstanceField() → core::int*
+    return this.{self::A1::_instanceField};
+  method setInstanceField(core::int* value) → void {
+    this.{self::A1::_instanceField} = value;
+  }
+  static method getStaticField() → core::int*
+    return self::A1::_staticField;
+  static method setStaticField(core::int* value) → void {
+    self::A1::_staticField = value;
+  }
+}
+static field invalid-type A2;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/other_kinds.dart.legacy.transformed.expect b/pkg/front_end/testcases/extensions/other_kinds.dart.legacy.transformed.expect
new file mode 100644
index 0000000..b35bfc6
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/other_kinds.dart.legacy.transformed.expect
@@ -0,0 +1,161 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:18:1: Error: This requires the 'extension-methods' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// extension A2 on A1 {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:18:17: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// extension A2 on A1 {
+//                 ^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:18:17: Error: 'A1' is already declared in this scope.
+// extension A2 on A1 {
+//                 ^^
+// pkg/front_end/testcases/extensions/other_kinds.dart:5:7: Context: Previous declaration of 'A1'.
+// class A1 {
+//       ^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:18:1: Warning: Type 'extension' not found.
+// extension A2 on A1 {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:18:14: Warning: Type 'on' not found.
+// extension A2 on A1 {
+//              ^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:18:1: Warning: 'extension' isn't a type.
+// extension A2 on A1 {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:19:7: Error: Expected ';' after this.
+//   int get instanceProperty => getInstanceField();
+//       ^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:19:28: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   int get instanceProperty => getInstanceField();
+//                            ^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:19:31: Warning: Method not found: 'getInstanceField'.
+//   int get instanceProperty => getInstanceField();
+//                               ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:21:8: Error: Expected ';' after this.
+//   void set instanceProperty(int value) {
+//        ^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:21:12: Error: 'instanceProperty' is already declared in this scope.
+//   void set instanceProperty(int value) {
+//            ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/other_kinds.dart:19:11: Context: Previous declaration of 'instanceProperty'.
+//   int get instanceProperty => getInstanceField();
+//           ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:22:5: Warning: Method not found: 'setInstanceField'.
+//     setInstanceField(value);
+//     ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:27:7: Error: Expected ';' after this.
+//   int operator +(int value) {
+//       ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:27:16: Error: '+' is not a prefix operator.
+// Try removing '+'.
+//   int operator +(int value) {
+//                ^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:28:12: Warning: Method not found: 'getInstanceField'.
+//     return getInstanceField() + value;
+//            ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:29:3: Error: Expected ';' after this.
+//   }
+//   ^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:31:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static int staticField = A1.getStaticField();
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:31:28: Error: Can't use 'A1' because it is declared more than once.
+//   static int staticField = A1.getStaticField();
+//                            ^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:33:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static int get staticProperty => A1.getStaticField();
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:33:14: Error: 'get' is already declared in this scope.
+//   static int get staticProperty => A1.getStaticField();
+//              ^^^
+// pkg/front_end/testcases/extensions/other_kinds.dart:19:7: Context: Previous declaration of 'get'.
+//   int get instanceProperty => getInstanceField();
+//       ^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:33:14: Error: Expected ';' after this.
+//   static int get staticProperty => A1.getStaticField();
+//              ^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:33:33: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   static int get staticProperty => A1.getStaticField();
+//                                 ^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:33:36: Error: Can't use 'A1' because it is declared more than once.
+//   static int get staticProperty => A1.getStaticField();
+//                                    ^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:35:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static void set staticProperty(int value) {
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:35:15: Error: 'set' is already declared in this scope.
+//   static void set staticProperty(int value) {
+//               ^^^
+// pkg/front_end/testcases/extensions/other_kinds.dart:21:8: Context: Previous declaration of 'set'.
+//   void set instanceProperty(int value) {
+//        ^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:35:15: Error: Expected ';' after this.
+//   static void set staticProperty(int value) {
+//               ^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:35:19: Error: 'staticProperty' is already declared in this scope.
+//   static void set staticProperty(int value) {
+//                   ^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/other_kinds.dart:33:18: Context: Previous declaration of 'staticProperty'.
+//   static int get staticProperty => A1.getStaticField();
+//                  ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:36:5: Error: Can't use 'A1' because it is declared more than once.
+//     A1.setStaticField(value);
+//     ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A1 extends core::Object {
+  field core::int* _instanceField = null;
+  static field core::int* _staticField = 0;
+  synthetic constructor •() → self::A1*
+    : super core::Object::•()
+    ;
+  method getInstanceField() → core::int*
+    return this.{self::A1::_instanceField};
+  method setInstanceField(core::int* value) → void {
+    this.{self::A1::_instanceField} = value;
+  }
+  static method getStaticField() → core::int*
+    return self::A1::_staticField;
+  static method setStaticField(core::int* value) → void {
+    self::A1::_staticField = value;
+  }
+}
+static field invalid-type A2;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/other_kinds.dart.outline.expect b/pkg/front_end/testcases/extensions/other_kinds.dart.outline.expect
new file mode 100644
index 0000000..a323fdb
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/other_kinds.dart.outline.expect
@@ -0,0 +1,49 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:18:1: Error: This requires the 'extension-methods' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// extension A2 on A1 {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:18:17: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// extension A2 on A1 {
+//                 ^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:18:17: Error: 'A1' is already declared in this scope.
+// extension A2 on A1 {
+//                 ^^
+// pkg/front_end/testcases/extensions/other_kinds.dart:5:7: Context: Previous declaration of 'A1'.
+// class A1 {
+//       ^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:18:1: Warning: Type 'extension' not found.
+// extension A2 on A1 {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/other_kinds.dart:18:14: Warning: Type 'on' not found.
+// extension A2 on A1 {
+//              ^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A1 extends core::Object {
+  field core::int* _instanceField;
+  static field core::int* _staticField;
+  synthetic constructor •() → self::A1*
+    ;
+  method getInstanceField() → core::int*
+    ;
+  method setInstanceField(core::int* value) → void
+    ;
+  static method getStaticField() → core::int*
+    ;
+  static method setStaticField(core::int* value) → void
+    ;
+}
+static field invalid-type A2;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/extensions/other_kinds.dart.strong.expect b/pkg/front_end/testcases/extensions/other_kinds.dart.strong.expect
new file mode 100644
index 0000000..6b24546
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/other_kinds.dart.strong.expect
@@ -0,0 +1,44 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A1 extends core::Object {
+  field core::int* _instanceField = null;
+  static field core::int* _staticField = 0;
+  synthetic constructor •() → self::A1*
+    : super core::Object::•()
+    ;
+  method getInstanceField() → core::int*
+    return this.{self::A1::_instanceField};
+  method setInstanceField(core::int* value) → void {
+    this.{self::A1::_instanceField} = value;
+  }
+  static method getStaticField() → core::int*
+    return self::A1::_staticField;
+  static method setStaticField(core::int* value) → void {
+    self::A1::_staticField = value;
+  }
+}
+extension A2 on self::A1* {
+  get instanceProperty = self::A2|get#instanceProperty;
+  operator + = self::A2|+;
+  static field staticField = self::A2|staticField;
+  static get staticProperty = get self::A2|staticProperty;
+  set instanceProperty = self::A2|set#instanceProperty;
+  static set staticProperty = set self::A2|staticProperty;
+}
+static field core::int* A2|staticField = self::A1::getStaticField();
+static method A2|get#instanceProperty(final self::A1* #this) → core::int*
+  return #this.{self::A1::getInstanceField}();
+static method A2|set#instanceProperty(final self::A1* #this, core::int* value) → void {
+  #this.{self::A1::setInstanceField}(value);
+}
+static method A2|+(final self::A1* #this, core::int* value) → core::int* {
+  return #this.{self::A1::getInstanceField}().{core::num::+}(value);
+}
+static get A2|staticProperty() → core::int*
+  return self::A1::getStaticField();
+static set A2|staticProperty(core::int* value) → void {
+  self::A1::setStaticField(value);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/other_kinds.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/other_kinds.dart.strong.transformed.expect
new file mode 100644
index 0000000..6b24546
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/other_kinds.dart.strong.transformed.expect
@@ -0,0 +1,44 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A1 extends core::Object {
+  field core::int* _instanceField = null;
+  static field core::int* _staticField = 0;
+  synthetic constructor •() → self::A1*
+    : super core::Object::•()
+    ;
+  method getInstanceField() → core::int*
+    return this.{self::A1::_instanceField};
+  method setInstanceField(core::int* value) → void {
+    this.{self::A1::_instanceField} = value;
+  }
+  static method getStaticField() → core::int*
+    return self::A1::_staticField;
+  static method setStaticField(core::int* value) → void {
+    self::A1::_staticField = value;
+  }
+}
+extension A2 on self::A1* {
+  get instanceProperty = self::A2|get#instanceProperty;
+  operator + = self::A2|+;
+  static field staticField = self::A2|staticField;
+  static get staticProperty = get self::A2|staticProperty;
+  set instanceProperty = self::A2|set#instanceProperty;
+  static set staticProperty = set self::A2|staticProperty;
+}
+static field core::int* A2|staticField = self::A1::getStaticField();
+static method A2|get#instanceProperty(final self::A1* #this) → core::int*
+  return #this.{self::A1::getInstanceField}();
+static method A2|set#instanceProperty(final self::A1* #this, core::int* value) → void {
+  #this.{self::A1::setInstanceField}(value);
+}
+static method A2|+(final self::A1* #this, core::int* value) → core::int* {
+  return #this.{self::A1::getInstanceField}().{core::num::+}(value);
+}
+static get A2|staticProperty() → core::int*
+  return self::A1::getStaticField();
+static set A2|staticProperty(core::int* value) → void {
+  self::A1::setStaticField(value);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/static_access.dart b/pkg/front_end/testcases/extensions/static_access.dart
new file mode 100644
index 0000000..c31ac01
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/static_access.dart
@@ -0,0 +1,25 @@
+// 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.
+
+class Class {}
+
+extension Extension on Class {
+  static method() {}
+  static genericMethod<T>(T t) {}
+  static get property => 42;
+  static set property(value) {}
+  static var field;
+}
+
+main() {
+  Extension.method();
+  Extension.genericMethod(42);
+  Extension.genericMethod<num>(42);
+  Extension.method;
+  Extension.genericMethod;
+  Extension.property;
+  Extension.property = 42;
+  Extension.field;
+  Extension.field = 42;
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/extensions/static_access.dart.hierarchy.expect b/pkg/front_end/testcases/extensions/static_access.dart.hierarchy.expect
new file mode 100644
index 0000000..f9ef17b
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/static_access.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Class:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/extensions/static_access.dart.legacy.expect b/pkg/front_end/testcases/extensions/static_access.dart.legacy.expect
new file mode 100644
index 0000000..3d580b0
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/static_access.dart.legacy.expect
@@ -0,0 +1,108 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/static_access.dart:7:1: Error: This requires the 'extension-methods' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// extension Extension on Class {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:7:24: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// extension Extension on Class {
+//                        ^^^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:7:24: Error: 'Class' is already declared in this scope.
+// extension Extension on Class {
+//                        ^^^^^
+// pkg/front_end/testcases/extensions/static_access.dart:5:7: Context: Previous declaration of 'Class'.
+// class Class {}
+//       ^^^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:7:1: Warning: Type 'extension' not found.
+// extension Extension on Class {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:7:21: Warning: Type 'on' not found.
+// extension Extension on Class {
+//                     ^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:7:1: Warning: 'extension' isn't a type.
+// extension Extension on Class {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:8:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static method() {}
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:9:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static genericMethod<T>(T t) {}
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:10:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static get property => 42;
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:10:10: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   static get property => 42;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:10:10: Error: Expected ';' after this.
+//   static get property => 42;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:10:23: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   static get property => 42;
+//                       ^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:11:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static set property(value) {}
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:11:10: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   static set property(value) {}
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:11:10: Error: Expected ';' after this.
+//   static set property(value) {}
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:11:14: Error: 'property' is already declared in this scope.
+//   static set property(value) {}
+//              ^^^^^^^^
+// pkg/front_end/testcases/extensions/static_access.dart:10:14: Context: Previous declaration of 'property'.
+//   static get property => 42;
+//              ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:12:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static var field;
+//   ^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class*
+    : super core::Object::•()
+    ;
+}
+static field invalid-type Extension;
+static method main() → dynamic {
+  self::Extension.method();
+  self::Extension.genericMethod(42);
+  self::Extension.genericMethod<core::num*>(42);
+  self::Extension.method;
+  self::Extension.genericMethod;
+  self::Extension.property;
+  self::Extension.property = 42;
+  self::Extension.field;
+  self::Extension.field = 42;
+}
diff --git a/pkg/front_end/testcases/extensions/static_access.dart.legacy.transformed.expect b/pkg/front_end/testcases/extensions/static_access.dart.legacy.transformed.expect
new file mode 100644
index 0000000..3d580b0
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/static_access.dart.legacy.transformed.expect
@@ -0,0 +1,108 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/static_access.dart:7:1: Error: This requires the 'extension-methods' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// extension Extension on Class {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:7:24: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// extension Extension on Class {
+//                        ^^^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:7:24: Error: 'Class' is already declared in this scope.
+// extension Extension on Class {
+//                        ^^^^^
+// pkg/front_end/testcases/extensions/static_access.dart:5:7: Context: Previous declaration of 'Class'.
+// class Class {}
+//       ^^^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:7:1: Warning: Type 'extension' not found.
+// extension Extension on Class {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:7:21: Warning: Type 'on' not found.
+// extension Extension on Class {
+//                     ^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:7:1: Warning: 'extension' isn't a type.
+// extension Extension on Class {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:8:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static method() {}
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:9:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static genericMethod<T>(T t) {}
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:10:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static get property => 42;
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:10:10: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   static get property => 42;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:10:10: Error: Expected ';' after this.
+//   static get property => 42;
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:10:23: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   static get property => 42;
+//                       ^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:11:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static set property(value) {}
+//   ^^^^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:11:10: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   static set property(value) {}
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:11:10: Error: Expected ';' after this.
+//   static set property(value) {}
+//          ^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:11:14: Error: 'property' is already declared in this scope.
+//   static set property(value) {}
+//              ^^^^^^^^
+// pkg/front_end/testcases/extensions/static_access.dart:10:14: Context: Previous declaration of 'property'.
+//   static get property => 42;
+//              ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:12:3: Error: Can't have modifier 'static' here.
+// Try removing 'static'.
+//   static var field;
+//   ^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class*
+    : super core::Object::•()
+    ;
+}
+static field invalid-type Extension;
+static method main() → dynamic {
+  self::Extension.method();
+  self::Extension.genericMethod(42);
+  self::Extension.genericMethod<core::num*>(42);
+  self::Extension.method;
+  self::Extension.genericMethod;
+  self::Extension.property;
+  self::Extension.property = 42;
+  self::Extension.field;
+  self::Extension.field = 42;
+}
diff --git a/pkg/front_end/testcases/extensions/static_access.dart.outline.expect b/pkg/front_end/testcases/extensions/static_access.dart.outline.expect
new file mode 100644
index 0000000..8334102
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/static_access.dart.outline.expect
@@ -0,0 +1,39 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/static_access.dart:7:1: Error: This requires the 'extension-methods' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// extension Extension on Class {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:7:24: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// extension Extension on Class {
+//                        ^^^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:7:24: Error: 'Class' is already declared in this scope.
+// extension Extension on Class {
+//                        ^^^^^
+// pkg/front_end/testcases/extensions/static_access.dart:5:7: Context: Previous declaration of 'Class'.
+// class Class {}
+//       ^^^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:7:1: Warning: Type 'extension' not found.
+// extension Extension on Class {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/static_access.dart:7:21: Warning: Type 'on' not found.
+// extension Extension on Class {
+//                     ^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class*
+    ;
+}
+static field invalid-type Extension;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/extensions/static_access.dart.strong.expect b/pkg/front_end/testcases/extensions/static_access.dart.strong.expect
new file mode 100644
index 0000000..9056365
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/static_access.dart.strong.expect
@@ -0,0 +1,38 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class*
+    : super core::Object::•()
+    ;
+}
+extension Extension on self::Class* {
+  static method method = self::Extension|method;
+  static method genericMethod = self::Extension|genericMethod;
+  static get property = get self::Extension|property;
+  static field field = self::Extension|field;
+  static set property = set self::Extension|property;
+}
+static field dynamic Extension|field;
+static method Extension|method() → dynamic {}
+static method Extension|genericMethod<T extends core::Object* = dynamic>(self::Extension|genericMethod::T* t) → dynamic {}
+static get Extension|property() → dynamic
+  return 42;
+static set Extension|property(dynamic value) → void {}
+static method main() → dynamic {
+  self::Extension|method();
+  self::Extension|genericMethod<core::int*>(42);
+  self::Extension|genericMethod<core::num*>(42);
+  #C1;
+  #C2;
+  self::Extension|property;
+  self::Extension|property = 42;
+  self::Extension|field;
+  self::Extension|field = 42;
+}
+
+constants  {
+  #C1 = tearoff self::Extension|method
+  #C2 = tearoff self::Extension|genericMethod
+}
diff --git a/pkg/front_end/testcases/extensions/static_access.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/static_access.dart.strong.transformed.expect
new file mode 100644
index 0000000..9056365
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/static_access.dart.strong.transformed.expect
@@ -0,0 +1,38 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class*
+    : super core::Object::•()
+    ;
+}
+extension Extension on self::Class* {
+  static method method = self::Extension|method;
+  static method genericMethod = self::Extension|genericMethod;
+  static get property = get self::Extension|property;
+  static field field = self::Extension|field;
+  static set property = set self::Extension|property;
+}
+static field dynamic Extension|field;
+static method Extension|method() → dynamic {}
+static method Extension|genericMethod<T extends core::Object* = dynamic>(self::Extension|genericMethod::T* t) → dynamic {}
+static get Extension|property() → dynamic
+  return 42;
+static set Extension|property(dynamic value) → void {}
+static method main() → dynamic {
+  self::Extension|method();
+  self::Extension|genericMethod<core::int*>(42);
+  self::Extension|genericMethod<core::num*>(42);
+  #C1;
+  #C2;
+  self::Extension|property;
+  self::Extension|property = 42;
+  self::Extension|field;
+  self::Extension|field = 42;
+}
+
+constants  {
+  #C1 = tearoff self::Extension|method
+  #C2 = tearoff self::Extension|genericMethod
+}
diff --git a/pkg/front_end/testcases/extensions/type_variables.dart.strong.expect b/pkg/front_end/testcases/extensions/type_variables.dart.strong.expect
index 26ba3ea..4f6a8d5 100644
--- a/pkg/front_end/testcases/extensions/type_variables.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/type_variables.dart.strong.expect
@@ -7,12 +7,14 @@
     : super core::Object::•()
     ;
 }
-class A2<T extends core::Object* = dynamic> extends core::Object {
+extension A2<T extends core::Object* = dynamic> on self::A1<T*>* {
+  method method1 = self::A2|method1;
+  method method2 = self::A2|method2;
 }
-method A2|method1<#T extends core::Object* = dynamic, S extends self::A2|method1::#T = dynamic>(final self::A1<self::A2|method1::#T*>* #this) → self::A1<self::A2|method1::#T*>* {
+static method A2|method1<#T extends core::Object* = dynamic, S extends self::A2|method1::#T = dynamic>(final self::A1<self::A2|method1::#T*>* #this) → self::A1<self::A2|method1::#T*>* {
   return #this;
 }
-method A2|method2<#T extends core::Object* = dynamic, S extends self::A1<self::A2|method2::#T>* = self::A1<dynamic>*>(final self::A1<self::A2|method2::#T*>* #this, self::A2|method2::S* o) → self::A1<self::A2|method2::#T*>* {
+static method A2|method2<#T extends core::Object* = dynamic, S extends self::A1<self::A2|method2::#T>* = dynamic>(final self::A1<self::A2|method2::#T*>* #this, self::A2|method2::S* o) → self::A1<self::A2|method2::#T*>* {
   core::print(o);
   core::print(self::A2|method2::#T*);
   core::print(self::A2|method2::S*);
diff --git a/pkg/front_end/testcases/extensions/type_variables.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/type_variables.dart.strong.transformed.expect
index 26ba3ea..4f6a8d5 100644
--- a/pkg/front_end/testcases/extensions/type_variables.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/type_variables.dart.strong.transformed.expect
@@ -7,12 +7,14 @@
     : super core::Object::•()
     ;
 }
-class A2<T extends core::Object* = dynamic> extends core::Object {
+extension A2<T extends core::Object* = dynamic> on self::A1<T*>* {
+  method method1 = self::A2|method1;
+  method method2 = self::A2|method2;
 }
-method A2|method1<#T extends core::Object* = dynamic, S extends self::A2|method1::#T = dynamic>(final self::A1<self::A2|method1::#T*>* #this) → self::A1<self::A2|method1::#T*>* {
+static method A2|method1<#T extends core::Object* = dynamic, S extends self::A2|method1::#T = dynamic>(final self::A1<self::A2|method1::#T*>* #this) → self::A1<self::A2|method1::#T*>* {
   return #this;
 }
-method A2|method2<#T extends core::Object* = dynamic, S extends self::A1<self::A2|method2::#T>* = self::A1<dynamic>*>(final self::A1<self::A2|method2::#T*>* #this, self::A2|method2::S* o) → self::A1<self::A2|method2::#T*>* {
+static method A2|method2<#T extends core::Object* = dynamic, S extends self::A1<self::A2|method2::#T>* = dynamic>(final self::A1<self::A2|method2::#T*>* #this, self::A2|method2::S* o) → self::A1<self::A2|method2::#T*>* {
   core::print(o);
   core::print(self::A2|method2::#T*);
   core::print(self::A2|method2::S*);
diff --git a/pkg/front_end/testcases/extensions/use_this.dart.strong.expect b/pkg/front_end/testcases/extensions/use_this.dart.strong.expect
index b8887f9..442c519 100644
--- a/pkg/front_end/testcases/extensions/use_this.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/use_this.dart.strong.expect
@@ -7,26 +7,30 @@
     : super core::Object::•()
     ;
 }
-class A2 extends core::Object {
-}
 class B1<T extends core::Object* = dynamic> extends core::Object {
   synthetic constructor •() → self::B1<self::B1::T*>*
     : super core::Object::•()
     ;
 }
-class B2<T extends core::Object* = dynamic> extends core::Object {
+extension A2 on self::A1* {
+  method method1 = self::A2|method1;
+  method method2 = self::A2|method2;
 }
-method A2|method1(final self::A1* #this) → self::A1* {
+extension B2<T extends core::Object* = dynamic> on self::B1<T*>* {
+  method method1 = self::B2|method1;
+  method method2 = self::B2|method2;
+}
+static method A2|method1(final self::A1* #this) → self::A1* {
   return #this;
 }
-method A2|method2<T extends core::Object* = dynamic>(final self::A1* #this, self::A2|method2::T* o) → self::A1* {
+static method A2|method2<T extends core::Object* = dynamic>(final self::A1* #this, self::A2|method2::T* o) → self::A1* {
   core::print(o);
   return #this;
 }
-method B2|method1<#T extends core::Object* = dynamic>(final self::B1<self::B2|method1::#T*>* #this) → self::B1<self::B2|method1::#T*>* {
+static method B2|method1<#T extends core::Object* = dynamic>(final self::B1<self::B2|method1::#T*>* #this) → self::B1<self::B2|method1::#T*>* {
   return #this;
 }
-method B2|method2<#T extends core::Object* = dynamic, S extends core::Object* = dynamic>(final self::B1<self::B2|method2::#T*>* #this, self::B2|method2::S* o) → self::B1<self::B2|method2::#T*>* {
+static method B2|method2<#T extends core::Object* = dynamic, S extends core::Object* = dynamic>(final self::B1<self::B2|method2::#T*>* #this, self::B2|method2::S* o) → self::B1<self::B2|method2::#T*>* {
   core::print(o);
   return #this;
 }
diff --git a/pkg/front_end/testcases/extensions/use_this.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/use_this.dart.strong.transformed.expect
index b8887f9..442c519 100644
--- a/pkg/front_end/testcases/extensions/use_this.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/use_this.dart.strong.transformed.expect
@@ -7,26 +7,30 @@
     : super core::Object::•()
     ;
 }
-class A2 extends core::Object {
-}
 class B1<T extends core::Object* = dynamic> extends core::Object {
   synthetic constructor •() → self::B1<self::B1::T*>*
     : super core::Object::•()
     ;
 }
-class B2<T extends core::Object* = dynamic> extends core::Object {
+extension A2 on self::A1* {
+  method method1 = self::A2|method1;
+  method method2 = self::A2|method2;
 }
-method A2|method1(final self::A1* #this) → self::A1* {
+extension B2<T extends core::Object* = dynamic> on self::B1<T*>* {
+  method method1 = self::B2|method1;
+  method method2 = self::B2|method2;
+}
+static method A2|method1(final self::A1* #this) → self::A1* {
   return #this;
 }
-method A2|method2<T extends core::Object* = dynamic>(final self::A1* #this, self::A2|method2::T* o) → self::A1* {
+static method A2|method2<T extends core::Object* = dynamic>(final self::A1* #this, self::A2|method2::T* o) → self::A1* {
   core::print(o);
   return #this;
 }
-method B2|method1<#T extends core::Object* = dynamic>(final self::B1<self::B2|method1::#T*>* #this) → self::B1<self::B2|method1::#T*>* {
+static method B2|method1<#T extends core::Object* = dynamic>(final self::B1<self::B2|method1::#T*>* #this) → self::B1<self::B2|method1::#T*>* {
   return #this;
 }
-method B2|method2<#T extends core::Object* = dynamic, S extends core::Object* = dynamic>(final self::B1<self::B2|method2::#T*>* #this, self::B2|method2::S* o) → self::B1<self::B2|method2::#T*>* {
+static method B2|method2<#T extends core::Object* = dynamic, S extends core::Object* = dynamic>(final self::B1<self::B2|method2::#T*>* #this, self::B2|method2::S* o) → self::B1<self::B2|method2::#T*>* {
   core::print(o);
   return #this;
 }
diff --git a/pkg/front_end/testcases/general/extension_methods.dart.strong.expect b/pkg/front_end/testcases/general/extension_methods.dart.strong.expect
index 8aa0e39..ed1bc06 100644
--- a/pkg/front_end/testcases/general/extension_methods.dart.strong.expect
+++ b/pkg/front_end/testcases/general/extension_methods.dart.strong.expect
@@ -21,9 +21,10 @@
   get one() → core::int*
     return 1;
 }
-class E extends core::Object {
+extension E on self::C* {
+  get two = self::E|get#two;
 }
-method E|two(final self::C* #this) → core::int*
+static method E|get#two(final self::C* #this) → core::int*
   return 2;
 static method main() → dynamic {
   self::C* c = new self::C::•();
diff --git a/pkg/front_end/testcases/general/extension_methods.dart.strong.transformed.expect b/pkg/front_end/testcases/general/extension_methods.dart.strong.transformed.expect
index 8aa0e39..ed1bc06 100644
--- a/pkg/front_end/testcases/general/extension_methods.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/extension_methods.dart.strong.transformed.expect
@@ -21,9 +21,10 @@
   get one() → core::int*
     return 1;
 }
-class E extends core::Object {
+extension E on self::C* {
+  get two = self::E|get#two;
 }
-method E|two(final self::C* #this) → core::int*
+static method E|get#two(final self::C* #this) → core::int*
   return 2;
 static method main() → dynamic {
   self::C* c = new self::C::•();
diff --git a/pkg/front_end/testcases/general/issue37776.dart b/pkg/front_end/testcases/general/issue37776.dart
new file mode 100644
index 0000000..49b4f52
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue37776.dart
@@ -0,0 +1,17 @@
+// 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.
+
+// This test checks that the bug reported at http://dartbug.com/37776 is fixed.
+
+class X {
+  const X.foo();
+}
+
+class X {
+  const X.foo();
+}
+
+void main() {
+  const X.foo();
+}
diff --git a/pkg/front_end/testcases/general/issue37776.dart.hierarchy.expect b/pkg/front_end/testcases/general/issue37776.dart.hierarchy.expect
new file mode 100644
index 0000000..8e2b7bf
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue37776.dart.hierarchy.expect
@@ -0,0 +1,53 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+X:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+X:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/general/issue37776.dart.legacy.expect b/pkg/front_end/testcases/general/issue37776.dart.legacy.expect
new file mode 100644
index 0000000..860f0b8
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue37776.dart.legacy.expect
@@ -0,0 +1,33 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue37776.dart:11:7: Error: 'X' is already declared in this scope.
+// class X {
+//       ^
+// pkg/front_end/testcases/general/issue37776.dart:7:7: Context: Previous declaration of 'X'.
+// class X {
+//       ^
+//
+// pkg/front_end/testcases/general/issue37776.dart:16:9: Warning: Method not found: 'X.foo'.
+//   const X.foo();
+//         ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class X#1 extends core::Object {
+  const constructor foo() → self::X#1*
+    : super core::Object::•()
+    ;
+}
+class X extends core::Object {
+  const constructor foo() → self::X*
+    : super core::Object::•()
+    ;
+}
+static method main() → void {
+  invalid-expression "pkg/front_end/testcases/general/issue37776.dart:16:9: Error: Method not found: 'X.foo'.
+  const X.foo();
+        ^^^";
+}
diff --git a/pkg/front_end/testcases/general/issue37776.dart.legacy.transformed.expect b/pkg/front_end/testcases/general/issue37776.dart.legacy.transformed.expect
new file mode 100644
index 0000000..860f0b8
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue37776.dart.legacy.transformed.expect
@@ -0,0 +1,33 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue37776.dart:11:7: Error: 'X' is already declared in this scope.
+// class X {
+//       ^
+// pkg/front_end/testcases/general/issue37776.dart:7:7: Context: Previous declaration of 'X'.
+// class X {
+//       ^
+//
+// pkg/front_end/testcases/general/issue37776.dart:16:9: Warning: Method not found: 'X.foo'.
+//   const X.foo();
+//         ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class X#1 extends core::Object {
+  const constructor foo() → self::X#1*
+    : super core::Object::•()
+    ;
+}
+class X extends core::Object {
+  const constructor foo() → self::X*
+    : super core::Object::•()
+    ;
+}
+static method main() → void {
+  invalid-expression "pkg/front_end/testcases/general/issue37776.dart:16:9: Error: Method not found: 'X.foo'.
+  const X.foo();
+        ^^^";
+}
diff --git a/pkg/front_end/testcases/general/issue37776.dart.outline.expect b/pkg/front_end/testcases/general/issue37776.dart.outline.expect
new file mode 100644
index 0000000..bb2fbfa
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue37776.dart.outline.expect
@@ -0,0 +1,26 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue37776.dart:11:7: Error: 'X' is already declared in this scope.
+// class X {
+//       ^
+// pkg/front_end/testcases/general/issue37776.dart:7:7: Context: Previous declaration of 'X'.
+// class X {
+//       ^
+//
+import self as self;
+import "dart:core" as core;
+
+class X#1 extends core::Object {
+  const constructor foo() → self::X#1*
+    : super core::Object::•()
+    ;
+}
+class X extends core::Object {
+  const constructor foo() → self::X*
+    : super core::Object::•()
+    ;
+}
+static method main() → void
+  ;
diff --git a/pkg/front_end/testcases/general/issue37776.dart.strong.expect b/pkg/front_end/testcases/general/issue37776.dart.strong.expect
new file mode 100644
index 0000000..481a71d
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue37776.dart.strong.expect
@@ -0,0 +1,33 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue37776.dart:11:7: Error: 'X' is already declared in this scope.
+// class X {
+//       ^
+// pkg/front_end/testcases/general/issue37776.dart:7:7: Context: Previous declaration of 'X'.
+// class X {
+//       ^
+//
+// pkg/front_end/testcases/general/issue37776.dart:16:9: Error: Method not found: 'X.foo'.
+//   const X.foo();
+//         ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class X#1 extends core::Object {
+  const constructor foo() → self::X#1*
+    : super core::Object::•()
+    ;
+}
+class X extends core::Object {
+  const constructor foo() → self::X*
+    : super core::Object::•()
+    ;
+}
+static method main() → void {
+  invalid-expression "pkg/front_end/testcases/general/issue37776.dart:16:9: Error: Method not found: 'X.foo'.
+  const X.foo();
+        ^^^";
+}
diff --git a/pkg/front_end/testcases/general/issue37776.dart.strong.transformed.expect b/pkg/front_end/testcases/general/issue37776.dart.strong.transformed.expect
new file mode 100644
index 0000000..481a71d
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue37776.dart.strong.transformed.expect
@@ -0,0 +1,33 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue37776.dart:11:7: Error: 'X' is already declared in this scope.
+// class X {
+//       ^
+// pkg/front_end/testcases/general/issue37776.dart:7:7: Context: Previous declaration of 'X'.
+// class X {
+//       ^
+//
+// pkg/front_end/testcases/general/issue37776.dart:16:9: Error: Method not found: 'X.foo'.
+//   const X.foo();
+//         ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class X#1 extends core::Object {
+  const constructor foo() → self::X#1*
+    : super core::Object::•()
+    ;
+}
+class X extends core::Object {
+  const constructor foo() → self::X*
+    : super core::Object::•()
+    ;
+}
+static method main() → void {
+  invalid-expression "pkg/front_end/testcases/general/issue37776.dart:16:9: Error: Method not found: 'X.foo'.
+  const X.foo();
+        ^^^";
+}
diff --git a/pkg/front_end/testcases/legacy.status b/pkg/front_end/testcases/legacy.status
index 1a8f9a3..e137a5e 100644
--- a/pkg/front_end/testcases/legacy.status
+++ b/pkg/front_end/testcases/legacy.status
@@ -5,6 +5,7 @@
 # Status file for the legacy_test.dart test suite. This is testing generating
 # Kernel ASTs in legacy mode (Dart 1.0).
 
+extensions/static_access: RuntimeError
 general/DeltaBlue: Fail # Fasta and dartk disagree on static initializers
 general/ambiguous_exports: RuntimeError # Expected, this file exports two main methods.
 general/await_in_non_async: RuntimeError # Expected.
@@ -21,6 +22,7 @@
 general/function_type_recovery: Fail
 general/incomplete_field_formal_parameter: Fail # Fasta doesn't recover well
 general/invocations: Fail
+general/issue37776: RuntimeError
 general/micro: Fail # External method marked abstract.
 general/minimum_int: Crash # Min int literal not supported in non-strong mode.
 general/mixin_constructors_with_default_values: RuntimeError # Expected
diff --git a/pkg/front_end/testcases/nnbd/late.dart b/pkg/front_end/testcases/nnbd/late.dart
new file mode 100644
index 0000000..d98c122
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/late.dart
@@ -0,0 +1,21 @@
+// 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.
+
+late int lateStaticField;
+late final int finalLateStaticField;
+
+class Class {
+  late int lateInstanceField;
+  late final int finalLateInstanceField = 0;
+
+  static late int lateStaticField;
+  static late final int finalLateStaticField = 0;
+
+  method() {
+    late int lateVariable;
+    late final int lateFinalVariable = 0;
+  }
+}
+
+main() {}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/nnbd/late.dart.hierarchy.expect b/pkg/front_end/testcases/nnbd/late.dart.hierarchy.expect
new file mode 100644
index 0000000..57d69c5
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/late.dart.hierarchy.expect
@@ -0,0 +1,47 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Class:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Class.lateInstanceField
+    Class.finalLateStaticField
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Class.method
+    Class.int
+    Class.late
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Class.finalLateInstanceField
+    Object._simpleInstanceOfFalse
+    Class.lateStaticField
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Class.lateInstanceField
+    Class.int
+    Class.late
+    Class.lateStaticField
diff --git a/pkg/front_end/testcases/nnbd/late.dart.legacy.expect b/pkg/front_end/testcases/nnbd/late.dart.legacy.expect
new file mode 100644
index 0000000..ce1db3e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/late.dart.legacy.expect
@@ -0,0 +1,194 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/late.dart:5:6: Error: Expected ';' after this.
+// late int lateStaticField;
+//      ^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:5:10: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+// late int lateStaticField;
+//          ^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:6:1: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+// late final int finalLateStaticField;
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:6:1: Error: Expected ';' after this.
+// late final int finalLateStaticField;
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:6:16: Error: The final variable 'finalLateStaticField' must be initialized.
+// Try adding an initializer ('= <expression>') to the declaration.
+// late final int finalLateStaticField;
+//                ^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:9:8: Error: Expected ';' after this.
+//   late int lateInstanceField;
+//        ^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:9:12: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   late int lateInstanceField;
+//            ^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:10:3: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   late final int finalLateInstanceField = 0;
+//   ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:10:3: Error: Expected ';' after this.
+//   late final int finalLateInstanceField = 0;
+//   ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:12:15: Error: Expected ';' after this.
+//   static late int lateStaticField;
+//               ^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:12:15: Error: 'int' is already declared in this scope.
+//   static late int lateStaticField;
+//               ^^^
+// pkg/front_end/testcases/nnbd/late.dart:9:8: Context: Previous declaration of 'int'.
+//   late int lateInstanceField;
+//        ^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:12:19: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   static late int lateStaticField;
+//                   ^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:13:10: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   static late final int finalLateStaticField = 0;
+//          ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:13:10: Error: Expected ';' after this.
+//   static late final int finalLateStaticField = 0;
+//          ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:13:10: Error: 'late' is already declared in this scope.
+//   static late final int finalLateStaticField = 0;
+//          ^^^^
+// pkg/front_end/testcases/nnbd/late.dart:10:3: Context: Previous declaration of 'late'.
+//   late final int finalLateInstanceField = 0;
+//   ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:9:3: Warning: 'late' isn't a type.
+//   late int lateInstanceField;
+//   ^^^^
+// pkg/front_end/testcases/nnbd/late.dart:9:3: Context: This isn't a type.
+//   late int lateInstanceField;
+//   ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:10:14: Warning: 'int' isn't a type.
+//   late final int finalLateInstanceField = 0;
+//              ^^^
+// pkg/front_end/testcases/nnbd/late.dart:10:14: Context: This isn't a type.
+//   late final int finalLateInstanceField = 0;
+//              ^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:12:10: Warning: 'late' isn't a type.
+//   static late int lateStaticField;
+//          ^^^^
+// pkg/front_end/testcases/nnbd/late.dart:12:10: Context: This isn't a type.
+//   static late int lateStaticField;
+//          ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:13:21: Warning: 'int' isn't a type.
+//   static late final int finalLateStaticField = 0;
+//                     ^^^
+// pkg/front_end/testcases/nnbd/late.dart:13:21: Context: This isn't a type.
+//   static late final int finalLateStaticField = 0;
+//                     ^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:5:1: Warning: 'late' isn't a type.
+// late int lateStaticField;
+// ^^^^
+// pkg/front_end/testcases/nnbd/late.dart:6:1: Context: This isn't a type.
+// late final int finalLateStaticField;
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:6:12: Warning: 'int' isn't a type.
+// late final int finalLateStaticField;
+//            ^^^
+// pkg/front_end/testcases/nnbd/late.dart:5:6: Context: This isn't a type.
+// late int lateStaticField;
+//      ^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:5:1: Warning: 'late' isn't a type.
+// late int lateStaticField;
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:6:12: Warning: 'int' isn't a type.
+// late final int finalLateStaticField;
+//            ^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:9:3: Error: Can't use 'late' because it is declared more than once.
+//   late int lateInstanceField;
+//   ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:10:14: Error: Can't use 'int' because it is declared more than once.
+//   late final int finalLateInstanceField = 0;
+//              ^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:12:10: Error: Can't use 'late' because it is declared more than once.
+//   static late int lateStaticField;
+//          ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:13:21: Error: Can't use 'int' because it is declared more than once.
+//   static late final int finalLateStaticField = 0;
+//                     ^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:16:5: Error: Can't use 'late' because it is declared more than once.
+//     late int lateVariable;
+//     ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:16:10: Error: Expected ';' after this.
+//     late int lateVariable;
+//          ^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:16:14: Warning: Getter not found: 'lateVariable'.
+//     late int lateVariable;
+//              ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:17:5: Error: Expected ';' after this.
+//     late final int lateFinalVariable = 0;
+//     ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:17:5: Error: Can't use 'late' because it is declared more than once.
+//     late final int lateFinalVariable = 0;
+//     ^
+//
+// pkg/front_end/testcases/nnbd/late.dart:17:16: Warning: 'int' isn't a type.
+//     late final int lateFinalVariable = 0;
+//                ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field invalid-type int = null;
+  field dynamic lateInstanceField = null;
+  field dynamic late = null;
+  final field invalid-type finalLateInstanceField = 0;
+  field dynamic lateStaticField = null;
+  final field invalid-type finalLateStaticField = 0;
+  synthetic constructor •() → self::Class*
+    : super core::Object::•()
+    ;
+  method method() → dynamic {
+    invalid-type int;
+    this.lateVariable;
+    invalid-expression "pkg/front_end/testcases/nnbd/late.dart:17:5: Error: Can't use 'late' because it is declared more than once.
+    late final int lateFinalVariable = 0;
+    ^";
+    final invalid-type lateFinalVariable = 0;
+  }
+}
+static field invalid-type int;
+static field dynamic lateStaticField;
+static field dynamic late;
+static final field invalid-type finalLateStaticField;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/late.dart.legacy.transformed.expect b/pkg/front_end/testcases/nnbd/late.dart.legacy.transformed.expect
new file mode 100644
index 0000000..ce1db3e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/late.dart.legacy.transformed.expect
@@ -0,0 +1,194 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/late.dart:5:6: Error: Expected ';' after this.
+// late int lateStaticField;
+//      ^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:5:10: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+// late int lateStaticField;
+//          ^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:6:1: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+// late final int finalLateStaticField;
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:6:1: Error: Expected ';' after this.
+// late final int finalLateStaticField;
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:6:16: Error: The final variable 'finalLateStaticField' must be initialized.
+// Try adding an initializer ('= <expression>') to the declaration.
+// late final int finalLateStaticField;
+//                ^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:9:8: Error: Expected ';' after this.
+//   late int lateInstanceField;
+//        ^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:9:12: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   late int lateInstanceField;
+//            ^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:10:3: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   late final int finalLateInstanceField = 0;
+//   ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:10:3: Error: Expected ';' after this.
+//   late final int finalLateInstanceField = 0;
+//   ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:12:15: Error: Expected ';' after this.
+//   static late int lateStaticField;
+//               ^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:12:15: Error: 'int' is already declared in this scope.
+//   static late int lateStaticField;
+//               ^^^
+// pkg/front_end/testcases/nnbd/late.dart:9:8: Context: Previous declaration of 'int'.
+//   late int lateInstanceField;
+//        ^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:12:19: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   static late int lateStaticField;
+//                   ^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:13:10: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   static late final int finalLateStaticField = 0;
+//          ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:13:10: Error: Expected ';' after this.
+//   static late final int finalLateStaticField = 0;
+//          ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:13:10: Error: 'late' is already declared in this scope.
+//   static late final int finalLateStaticField = 0;
+//          ^^^^
+// pkg/front_end/testcases/nnbd/late.dart:10:3: Context: Previous declaration of 'late'.
+//   late final int finalLateInstanceField = 0;
+//   ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:9:3: Warning: 'late' isn't a type.
+//   late int lateInstanceField;
+//   ^^^^
+// pkg/front_end/testcases/nnbd/late.dart:9:3: Context: This isn't a type.
+//   late int lateInstanceField;
+//   ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:10:14: Warning: 'int' isn't a type.
+//   late final int finalLateInstanceField = 0;
+//              ^^^
+// pkg/front_end/testcases/nnbd/late.dart:10:14: Context: This isn't a type.
+//   late final int finalLateInstanceField = 0;
+//              ^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:12:10: Warning: 'late' isn't a type.
+//   static late int lateStaticField;
+//          ^^^^
+// pkg/front_end/testcases/nnbd/late.dart:12:10: Context: This isn't a type.
+//   static late int lateStaticField;
+//          ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:13:21: Warning: 'int' isn't a type.
+//   static late final int finalLateStaticField = 0;
+//                     ^^^
+// pkg/front_end/testcases/nnbd/late.dart:13:21: Context: This isn't a type.
+//   static late final int finalLateStaticField = 0;
+//                     ^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:5:1: Warning: 'late' isn't a type.
+// late int lateStaticField;
+// ^^^^
+// pkg/front_end/testcases/nnbd/late.dart:6:1: Context: This isn't a type.
+// late final int finalLateStaticField;
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:6:12: Warning: 'int' isn't a type.
+// late final int finalLateStaticField;
+//            ^^^
+// pkg/front_end/testcases/nnbd/late.dart:5:6: Context: This isn't a type.
+// late int lateStaticField;
+//      ^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:5:1: Warning: 'late' isn't a type.
+// late int lateStaticField;
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:6:12: Warning: 'int' isn't a type.
+// late final int finalLateStaticField;
+//            ^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:9:3: Error: Can't use 'late' because it is declared more than once.
+//   late int lateInstanceField;
+//   ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:10:14: Error: Can't use 'int' because it is declared more than once.
+//   late final int finalLateInstanceField = 0;
+//              ^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:12:10: Error: Can't use 'late' because it is declared more than once.
+//   static late int lateStaticField;
+//          ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:13:21: Error: Can't use 'int' because it is declared more than once.
+//   static late final int finalLateStaticField = 0;
+//                     ^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:16:5: Error: Can't use 'late' because it is declared more than once.
+//     late int lateVariable;
+//     ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:16:10: Error: Expected ';' after this.
+//     late int lateVariable;
+//          ^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:16:14: Warning: Getter not found: 'lateVariable'.
+//     late int lateVariable;
+//              ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:17:5: Error: Expected ';' after this.
+//     late final int lateFinalVariable = 0;
+//     ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:17:5: Error: Can't use 'late' because it is declared more than once.
+//     late final int lateFinalVariable = 0;
+//     ^
+//
+// pkg/front_end/testcases/nnbd/late.dart:17:16: Warning: 'int' isn't a type.
+//     late final int lateFinalVariable = 0;
+//                ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field invalid-type int = null;
+  field dynamic lateInstanceField = null;
+  field dynamic late = null;
+  final field invalid-type finalLateInstanceField = 0;
+  field dynamic lateStaticField = null;
+  final field invalid-type finalLateStaticField = 0;
+  synthetic constructor •() → self::Class*
+    : super core::Object::•()
+    ;
+  method method() → dynamic {
+    invalid-type int;
+    this.lateVariable;
+    invalid-expression "pkg/front_end/testcases/nnbd/late.dart:17:5: Error: Can't use 'late' because it is declared more than once.
+    late final int lateFinalVariable = 0;
+    ^";
+    final invalid-type lateFinalVariable = 0;
+  }
+}
+static field invalid-type int;
+static field dynamic lateStaticField;
+static field dynamic late;
+static final field invalid-type finalLateStaticField;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/late.dart.outline.expect b/pkg/front_end/testcases/nnbd/late.dart.outline.expect
new file mode 100644
index 0000000..0c33cf6
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/late.dart.outline.expect
@@ -0,0 +1,140 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/late.dart:5:6: Error: Expected ';' after this.
+// late int lateStaticField;
+//      ^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:5:10: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+// late int lateStaticField;
+//          ^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:6:1: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+// late final int finalLateStaticField;
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:6:1: Error: Expected ';' after this.
+// late final int finalLateStaticField;
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:6:16: Error: The final variable 'finalLateStaticField' must be initialized.
+// Try adding an initializer ('= <expression>') to the declaration.
+// late final int finalLateStaticField;
+//                ^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:9:8: Error: Expected ';' after this.
+//   late int lateInstanceField;
+//        ^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:9:12: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   late int lateInstanceField;
+//            ^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:10:3: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   late final int finalLateInstanceField = 0;
+//   ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:10:3: Error: Expected ';' after this.
+//   late final int finalLateInstanceField = 0;
+//   ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:12:15: Error: Expected ';' after this.
+//   static late int lateStaticField;
+//               ^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:12:15: Error: 'int' is already declared in this scope.
+//   static late int lateStaticField;
+//               ^^^
+// pkg/front_end/testcases/nnbd/late.dart:9:8: Context: Previous declaration of 'int'.
+//   late int lateInstanceField;
+//        ^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:12:19: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   static late int lateStaticField;
+//                   ^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:13:10: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//   static late final int finalLateStaticField = 0;
+//          ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:13:10: Error: Expected ';' after this.
+//   static late final int finalLateStaticField = 0;
+//          ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:13:10: Error: 'late' is already declared in this scope.
+//   static late final int finalLateStaticField = 0;
+//          ^^^^
+// pkg/front_end/testcases/nnbd/late.dart:10:3: Context: Previous declaration of 'late'.
+//   late final int finalLateInstanceField = 0;
+//   ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:9:3: Warning: 'late' isn't a type.
+//   late int lateInstanceField;
+//   ^^^^
+// pkg/front_end/testcases/nnbd/late.dart:9:3: Context: This isn't a type.
+//   late int lateInstanceField;
+//   ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:10:14: Warning: 'int' isn't a type.
+//   late final int finalLateInstanceField = 0;
+//              ^^^
+// pkg/front_end/testcases/nnbd/late.dart:10:14: Context: This isn't a type.
+//   late final int finalLateInstanceField = 0;
+//              ^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:12:10: Warning: 'late' isn't a type.
+//   static late int lateStaticField;
+//          ^^^^
+// pkg/front_end/testcases/nnbd/late.dart:12:10: Context: This isn't a type.
+//   static late int lateStaticField;
+//          ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:13:21: Warning: 'int' isn't a type.
+//   static late final int finalLateStaticField = 0;
+//                     ^^^
+// pkg/front_end/testcases/nnbd/late.dart:13:21: Context: This isn't a type.
+//   static late final int finalLateStaticField = 0;
+//                     ^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:5:1: Warning: 'late' isn't a type.
+// late int lateStaticField;
+// ^^^^
+// pkg/front_end/testcases/nnbd/late.dart:6:1: Context: This isn't a type.
+// late final int finalLateStaticField;
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/late.dart:6:12: Warning: 'int' isn't a type.
+// late final int finalLateStaticField;
+//            ^^^
+// pkg/front_end/testcases/nnbd/late.dart:5:6: Context: This isn't a type.
+// late int lateStaticField;
+//      ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field invalid-type int;
+  field dynamic lateInstanceField;
+  field dynamic late;
+  final field invalid-type finalLateInstanceField;
+  field dynamic lateStaticField;
+  final field invalid-type finalLateStaticField;
+  synthetic constructor •() → self::Class*
+    ;
+  method method() → dynamic
+    ;
+}
+static field invalid-type int;
+static field dynamic lateStaticField;
+static field dynamic late;
+static final field invalid-type finalLateStaticField;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/late.dart.strong.expect b/pkg/front_end/testcases/nnbd/late.dart.strong.expect
new file mode 100644
index 0000000..2315067
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/late.dart.strong.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  late field core::int* lateInstanceField = null;
+  late final field core::int* finalLateInstanceField = 0;
+  late static field core::int* lateStaticField = null;
+  late static final field core::int* finalLateStaticField = 0;
+  synthetic constructor •() → self::Class*
+    : super core::Object::•()
+    ;
+  method method() → dynamic {
+    late core::int* lateVariable;
+    late final core::int* lateFinalVariable = 0;
+  }
+}
+late static field core::int* lateStaticField;
+late static final field core::int* finalLateStaticField;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/late.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/late.dart.strong.transformed.expect
new file mode 100644
index 0000000..2315067
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/late.dart.strong.transformed.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  late field core::int* lateInstanceField = null;
+  late final field core::int* finalLateInstanceField = 0;
+  late static field core::int* lateStaticField = null;
+  late static final field core::int* finalLateStaticField = 0;
+  synthetic constructor •() → self::Class*
+    : super core::Object::•()
+    ;
+  method method() → dynamic {
+    late core::int* lateVariable;
+    late final core::int* lateFinalVariable = 0;
+  }
+}
+late static field core::int* lateStaticField;
+late static final field core::int* finalLateStaticField;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.expect b/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.expect
index 77fe6d8..f6ff7b9 100644
--- a/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.expect
@@ -2,26 +2,6 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/nullable_param.dart:5:6: Error: This requires the 'non-nullable' experiment to be enabled.
-// Try enabling this experiment by adding it to the command line when compiling and running.
-//   int? field;
-//      ^
-//
-// pkg/front_end/testcases/nnbd/nullable_param.dart:6:6: Error: This requires the 'non-nullable' experiment to be enabled.
-// Try enabling this experiment by adding it to the command line when compiling and running.
-//   int? bar(int? x);
-//      ^
-//
-// pkg/front_end/testcases/nnbd/nullable_param.dart:6:15: Error: This requires the 'non-nullable' experiment to be enabled.
-// Try enabling this experiment by adding it to the command line when compiling and running.
-//   int? bar(int? x);
-//               ^
-//
-// pkg/front_end/testcases/nnbd/nullable_param.dart:17:54: Error: This requires the 'non-nullable' experiment to be enabled.
-// Try enabling this experiment by adding it to the command line when compiling and running.
-// int test_nullable_function_type_formal_param({int f()? : null}) {
-//                                                      ^
-//
 // pkg/front_end/testcases/nnbd/nullable_param.dart:4:7: Error: The non-abstract class 'Foo' is missing implementations for these members:
 //  - Foo.bar
 // Try to either
diff --git a/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.transformed.expect
index 77fe6d8..f6ff7b9 100644
--- a/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.transformed.expect
@@ -2,26 +2,6 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/nullable_param.dart:5:6: Error: This requires the 'non-nullable' experiment to be enabled.
-// Try enabling this experiment by adding it to the command line when compiling and running.
-//   int? field;
-//      ^
-//
-// pkg/front_end/testcases/nnbd/nullable_param.dart:6:6: Error: This requires the 'non-nullable' experiment to be enabled.
-// Try enabling this experiment by adding it to the command line when compiling and running.
-//   int? bar(int? x);
-//      ^
-//
-// pkg/front_end/testcases/nnbd/nullable_param.dart:6:15: Error: This requires the 'non-nullable' experiment to be enabled.
-// Try enabling this experiment by adding it to the command line when compiling and running.
-//   int? bar(int? x);
-//               ^
-//
-// pkg/front_end/testcases/nnbd/nullable_param.dart:17:54: Error: This requires the 'non-nullable' experiment to be enabled.
-// Try enabling this experiment by adding it to the command line when compiling and running.
-// int test_nullable_function_type_formal_param({int f()? : null}) {
-//                                                      ^
-//
 // pkg/front_end/testcases/nnbd/nullable_param.dart:4:7: Error: The non-abstract class 'Foo' is missing implementations for these members:
 //  - Foo.bar
 // Try to either
diff --git a/pkg/front_end/testcases/nnbd/required.dart b/pkg/front_end/testcases/nnbd/required.dart
new file mode 100644
index 0000000..9939da5
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/required.dart
@@ -0,0 +1,18 @@
+// 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.
+
+method({int a, required int b, required final int c}) {}
+
+class Class {
+  method({int a, required int b, required final int c, required covariant final int d}) {}
+}
+
+// TODO(johnniwinther): Pass the required property to the function types.
+typedef Typedef1 = Function({int a, required int b});
+
+typedef Typedef2({int a, required int b});
+
+Function({int a, required int b}) field;
+
+main() {}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/nnbd/required.dart.hierarchy.expect b/pkg/front_end/testcases/nnbd/required.dart.hierarchy.expect
new file mode 100644
index 0000000..339927f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/required.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Class:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Class.method
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/nnbd/required.dart.legacy.expect b/pkg/front_end/testcases/nnbd/required.dart.legacy.expect
new file mode 100644
index 0000000..06bd55a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/required.dart.legacy.expect
@@ -0,0 +1,74 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/required.dart:5:29: Error: Expected '}' before this.
+// method({int a, required int b, required final int c}) {}
+//                             ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:8:31: Error: Expected '}' before this.
+//   method({int a, required int b, required final int c, required covariant final int d}) {}
+//                               ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:12:50: Error: Expected '}' before this.
+// typedef Typedef1 = Function({int a, required int b});
+//                                                  ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:14:39: Error: Expected '}' before this.
+// typedef Typedef2({int a, required int b});
+//                                       ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:16:31: Error: Expected '}' before this.
+// Function({int a, required int b}) field;
+//                               ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:5:16: Warning: Type 'required' not found.
+// method({int a, required int b, required final int c}) {}
+//                ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/required.dart:8:18: Warning: Type 'required' not found.
+//   method({int a, required int b, required final int c, required covariant final int d}) {}
+//                  ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/required.dart:12:37: Warning: Type 'required' not found.
+// typedef Typedef1 = Function({int a, required int b});
+//                                     ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/required.dart:14:26: Warning: Type 'required' not found.
+// typedef Typedef2({int a, required int b});
+//                          ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/required.dart:16:18: Warning: Type 'required' not found.
+// Function({int a, required int b}) field;
+//                  ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/required.dart:5:16: Warning: 'required' isn't a type.
+// method({int a, required int b, required final int c}) {}
+//                ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/required.dart:8:18: Warning: 'required' isn't a type.
+//   method({int a, required int b, required final int c, required covariant final int d}) {}
+//                  ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/required.dart:16:18: Warning: 'required' isn't a type.
+// Function({int a, required int b}) field;
+//                  ^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef Typedef1 = ({a: core::int*, int: invalid-type}) →* dynamic;
+typedef Typedef2 = ({a: core::int*, int: invalid-type}) →* dynamic;
+class Class extends core::Object {
+  synthetic constructor •() → self::Class*
+    : super core::Object::•()
+    ;
+  method method({core::int* a = #C1, invalid-type int = #C1}) → dynamic {}
+}
+static field ({a: core::int*, int: invalid-type}) →* dynamic field;
+static method method({core::int* a = #C1, invalid-type int = #C1}) → dynamic {}
+static method main() → dynamic {}
+
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/nnbd/required.dart.legacy.transformed.expect b/pkg/front_end/testcases/nnbd/required.dart.legacy.transformed.expect
new file mode 100644
index 0000000..06bd55a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/required.dart.legacy.transformed.expect
@@ -0,0 +1,74 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/required.dart:5:29: Error: Expected '}' before this.
+// method({int a, required int b, required final int c}) {}
+//                             ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:8:31: Error: Expected '}' before this.
+//   method({int a, required int b, required final int c, required covariant final int d}) {}
+//                               ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:12:50: Error: Expected '}' before this.
+// typedef Typedef1 = Function({int a, required int b});
+//                                                  ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:14:39: Error: Expected '}' before this.
+// typedef Typedef2({int a, required int b});
+//                                       ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:16:31: Error: Expected '}' before this.
+// Function({int a, required int b}) field;
+//                               ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:5:16: Warning: Type 'required' not found.
+// method({int a, required int b, required final int c}) {}
+//                ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/required.dart:8:18: Warning: Type 'required' not found.
+//   method({int a, required int b, required final int c, required covariant final int d}) {}
+//                  ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/required.dart:12:37: Warning: Type 'required' not found.
+// typedef Typedef1 = Function({int a, required int b});
+//                                     ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/required.dart:14:26: Warning: Type 'required' not found.
+// typedef Typedef2({int a, required int b});
+//                          ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/required.dart:16:18: Warning: Type 'required' not found.
+// Function({int a, required int b}) field;
+//                  ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/required.dart:5:16: Warning: 'required' isn't a type.
+// method({int a, required int b, required final int c}) {}
+//                ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/required.dart:8:18: Warning: 'required' isn't a type.
+//   method({int a, required int b, required final int c, required covariant final int d}) {}
+//                  ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/required.dart:16:18: Warning: 'required' isn't a type.
+// Function({int a, required int b}) field;
+//                  ^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef Typedef1 = ({a: core::int*, int: invalid-type}) →* dynamic;
+typedef Typedef2 = ({a: core::int*, int: invalid-type}) →* dynamic;
+class Class extends core::Object {
+  synthetic constructor •() → self::Class*
+    : super core::Object::•()
+    ;
+  method method({core::int* a = #C1, invalid-type int = #C1}) → dynamic {}
+}
+static field ({a: core::int*, int: invalid-type}) →* dynamic field;
+static method method({core::int* a = #C1, invalid-type int = #C1}) → dynamic {}
+static method main() → dynamic {}
+
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/nnbd/required.dart.outline.expect b/pkg/front_end/testcases/nnbd/required.dart.outline.expect
new file mode 100644
index 0000000..156e7c1
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/required.dart.outline.expect
@@ -0,0 +1,60 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/required.dart:5:29: Error: Expected '}' before this.
+// method({int a, required int b, required final int c}) {}
+//                             ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:8:31: Error: Expected '}' before this.
+//   method({int a, required int b, required final int c, required covariant final int d}) {}
+//                               ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:12:50: Error: Expected '}' before this.
+// typedef Typedef1 = Function({int a, required int b});
+//                                                  ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:14:39: Error: Expected '}' before this.
+// typedef Typedef2({int a, required int b});
+//                                       ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:16:31: Error: Expected '}' before this.
+// Function({int a, required int b}) field;
+//                               ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:5:16: Warning: Type 'required' not found.
+// method({int a, required int b, required final int c}) {}
+//                ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/required.dart:8:18: Warning: Type 'required' not found.
+//   method({int a, required int b, required final int c, required covariant final int d}) {}
+//                  ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/required.dart:12:37: Warning: Type 'required' not found.
+// typedef Typedef1 = Function({int a, required int b});
+//                                     ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/required.dart:14:26: Warning: Type 'required' not found.
+// typedef Typedef2({int a, required int b});
+//                          ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/required.dart:16:18: Warning: Type 'required' not found.
+// Function({int a, required int b}) field;
+//                  ^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef Typedef1 = ({a: core::int*, int: invalid-type}) →* dynamic;
+typedef Typedef2 = ({a: core::int*, int: invalid-type}) →* dynamic;
+class Class extends core::Object {
+  synthetic constructor •() → self::Class*
+    ;
+  method method({core::int* a, invalid-type int}) → dynamic
+    ;
+}
+static field ({a: core::int*, int: invalid-type}) →* dynamic field;
+static method method({core::int* a, invalid-type int}) → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/required.dart.strong.expect b/pkg/front_end/testcases/nnbd/required.dart.strong.expect
new file mode 100644
index 0000000..7ba4cd1
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/required.dart.strong.expect
@@ -0,0 +1,19 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef Typedef1 = ({a: core::int*, required b: core::int*}) →* dynamic;
+typedef Typedef2 = ({a: core::int*, required b: core::int*}) →* dynamic;
+class Class extends core::Object {
+  synthetic constructor •() → self::Class*
+    : super core::Object::•()
+    ;
+  method method({core::int* a = #C1, required core::int* b = #C1, required final core::int* c = #C1, required covariant final core::int* d = #C1}) → dynamic {}
+}
+static field ({a: core::int*, required b: core::int*}) →* dynamic field;
+static method method({core::int* a = #C1, required core::int* b = #C1, required final core::int* c = #C1}) → dynamic {}
+static method main() → dynamic {}
+
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/nnbd/required.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/required.dart.strong.transformed.expect
new file mode 100644
index 0000000..7ba4cd1
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/required.dart.strong.transformed.expect
@@ -0,0 +1,19 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef Typedef1 = ({a: core::int*, required b: core::int*}) →* dynamic;
+typedef Typedef2 = ({a: core::int*, required b: core::int*}) →* dynamic;
+class Class extends core::Object {
+  synthetic constructor •() → self::Class*
+    : super core::Object::•()
+    ;
+  method method({core::int* a = #C1, required core::int* b = #C1, required final core::int* c = #C1, required covariant final core::int* d = #C1}) → dynamic {}
+}
+static field ({a: core::int*, required b: core::int*}) →* dynamic field;
+static method method({core::int* a = #C1, required core::int* b = #C1, required final core::int* c = #C1}) → dynamic {}
+static method main() → dynamic {}
+
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/regress/issue_31180.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31180.dart.strong.expect
index b503b42..6877d8d 100644
--- a/pkg/front_end/testcases/regress/issue_31180.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31180.dart.strong.expect
@@ -2,15 +2,17 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/regress/issue_31180.dart:6:16: Error: Expected an identifier, but got '['.
+// pkg/front_end/testcases/regress/issue_31180.dart:6:14: Error: The method '[]' isn't defined for the class 'Null'.
+// Try correcting the name to the name of an existing method, or defining a method named '[]'.
 //   return null?.[1];
-//                ^
+//              ^^
 //
 import self as self;
 
 static method bad() → dynamic {
-  return invalid-expression "pkg/front_end/testcases/regress/issue_31180.dart:6:16: Error: Expected an identifier, but got '['.
+  return invalid-expression "pkg/front_end/testcases/regress/issue_31180.dart:6:14: Error: The method '[]' isn't defined for the class 'Null'.
+Try correcting the name to the name of an existing method, or defining a method named '[]'.
   return null?.[1];
-               ^";
+             ^^";
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31180.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31180.dart.strong.transformed.expect
index b503b42..6877d8d 100644
--- a/pkg/front_end/testcases/regress/issue_31180.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31180.dart.strong.transformed.expect
@@ -2,15 +2,17 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/regress/issue_31180.dart:6:16: Error: Expected an identifier, but got '['.
+// pkg/front_end/testcases/regress/issue_31180.dart:6:14: Error: The method '[]' isn't defined for the class 'Null'.
+// Try correcting the name to the name of an existing method, or defining a method named '[]'.
 //   return null?.[1];
-//                ^
+//              ^^
 //
 import self as self;
 
 static method bad() → dynamic {
-  return invalid-expression "pkg/front_end/testcases/regress/issue_31180.dart:6:16: Error: Expected an identifier, but got '['.
+  return invalid-expression "pkg/front_end/testcases/regress/issue_31180.dart:6:14: Error: The method '[]' isn't defined for the class 'Null'.
+Try correcting the name to the name of an existing method, or defining a method named '[]'.
   return null?.[1];
-               ^";
+             ^^";
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index 80b9301..d52e841 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -31,6 +31,7 @@
 general/invalid_type: TypeCheckError
 general/invocations: RuntimeError
 general/issue34899: TypeCheckError
+general/issue37776: RuntimeError
 general/micro: RuntimeError
 general/mixin_application_override: ExpectationFileMismatch # Too many errors.
 general/mixin_application_override: TypeCheckError
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index b2a5c08..6913fc8 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -8,9 +8,13 @@
 
 expression/eval: TextSerializationFailure # Was: Pass
 expression/main: TextSerializationFailure # Was: Pass
-extensions/instance_members: TextSerializationFailure
-extensions/implicit_this: TextSerializationFailure
 extensions/explicit_this: TextSerializationFailure
+extensions/implicit_this: TextSerializationFailure
+extensions/direct_instance_access: TextSerializationFailure
+extensions/direct_static_access: TextSerializationFailure
+extensions/instance_members: TextSerializationFailure
+extensions/other_kinds: TextSerializationFailure
+extensions/static_access: TextSerializationFailure
 extensions/type_variables: TextSerializationFailure
 extensions/use_this: TextSerializationFailure
 general/abstract_members: TypeCheckError
@@ -138,6 +142,7 @@
 general/issue35875: TextSerializationFailure
 general/issue37027: TextSerializationFailure
 general/issue37381: TextSerializationFailure
+general/issue37776: TextSerializationFailure
 general/literals: TextSerializationFailure # Was: Pass
 general/local_generic_function: TextSerializationFailure # Was: Pass
 general/magic_const: TextSerializationFailure # Was: Pass
@@ -804,7 +809,9 @@
 instantiate_to_bound/typedef_raw_in_bound: TextSerializationFailure # Was: Pass
 instantiate_to_bound/typedef_super_bounded_type: TextSerializationFailure # Was: Pass
 new_const_insertion/simple: TextSerializationFailure # Was: Pass
+nnbd/late: TextSerializationFailure
 nnbd/nullable_param: TextSerializationFailure
+nnbd/required: TextSerializationFailure
 no_such_method_forwarders/abstract_accessors_from_field: TextSerializationFailure # Was: Pass
 no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in: TextSerializationFailure # Was: Pass
 no_such_method_forwarders/abstract_accessors_from_field_one_defined: TextSerializationFailure # Was: Pass
diff --git a/pkg/front_end/testing.json b/pkg/front_end/testing.json
index 0c35782..3f10468 100644
--- a/pkg/front_end/testing.json
+++ b/pkg/front_end/testing.json
@@ -221,16 +221,44 @@
     },
 
     {
-      "name": "spelling_test",
+      "name": "lint_test",
       "kind": "Chain",
-      "source": "test/spelling_test.dart",
+      "source": "test/lint_test.dart",
+      "path": "lib/",
+      "status": "test/lint_test.status",
+      "pattern": [
+        ".*\\.dart$"
+      ],
+      "exclude": [
+        "src/fasta/fasta_codes_generated\\.dart$"
+      ]
+    },
+
+    {
+      "name": "spelling_test_src_test",
+      "kind": "Chain",
+      "source": "test/spelling_test_src_test.dart",
+      "path": "lib/",
+      "status": "test/spelling_test.status",
+      "pattern": [
+        ".*\\.dart$"
+      ],
+      "exclude": [
+        "src/fasta/fasta_codes_generated\\.dart$"
+      ]
+    },
+
+    {
+      "name": "spelling_test_not_src_test",
+      "kind": "Chain",
+      "source": "test/spelling_test_not_src_test.dart",
       "path": ".",
       "status": "test/spelling_test.status",
       "pattern": [
         ".*\\.dart$"
       ],
       "exclude": [
-        "src/fasta/fasta_codes_generated\\.dart$",
+        "lib/",
         "test/fasta/super_mixins_test\\.dart$",
         "test/fasta/types/subtypes_benchmark\\.dart$",
         "test/fasta/unlinked_scope_test\\.dart$",
@@ -373,7 +401,7 @@
 
   "analyze": {
 
-    "options": "analysis_options.yaml",
+    "options": "analysis_options_no_lints.yaml",
 
     "uris": [
       "lib/",
diff --git a/pkg/front_end/tool/_fasta/abcompile.dart b/pkg/front_end/tool/_fasta/abcompile.dart
index fcaf2bd..4ccde2a 100644
--- a/pkg/front_end/tool/_fasta/abcompile.dart
+++ b/pkg/front_end/tool/_fasta/abcompile.dart
@@ -180,6 +180,7 @@
 
   Process process = await Process.start(Platform.executable, procArgs,
       workingDirectory: workingDirPath);
+  // ignore: unawaited_futures
   stderr.addStream(process.stderr);
   StreamSubscription<String> stdOutSubscription;
   stdOutSubscription = process.stdout
diff --git a/pkg/front_end/tool/_fasta/additional_targets.dart b/pkg/front_end/tool/_fasta/additional_targets.dart
index 9dd557e..6e9399a 100644
--- a/pkg/front_end/tool/_fasta/additional_targets.dart
+++ b/pkg/front_end/tool/_fasta/additional_targets.dart
@@ -8,6 +8,8 @@
 
 import 'package:compiler/src/kernel/dart2js_target.dart' show Dart2jsTarget;
 
+import 'package:dev_compiler/src/kernel/target.dart' show DevCompilerTarget;
+
 import 'package:vm/target/install.dart' as vm_target_install
     show installAdditionalTargets;
 
@@ -18,5 +20,6 @@
       (TargetFlags flags) => new Dart2jsTarget("dart2js", flags);
   targets["dart2js_server"] =
       (TargetFlags flags) => new Dart2jsTarget("dart2js_server", flags);
+  targets["dartdevc"] = (TargetFlags flags) => new DevCompilerTarget(flags);
   vm_target_install.installAdditionalTargets();
 }
diff --git a/pkg/front_end/tool/_fasta/command_line.dart b/pkg/front_end/tool/_fasta/command_line.dart
index d6c0bbf..98ea35d 100644
--- a/pkg/front_end/tool/_fasta/command_line.dart
+++ b/pkg/front_end/tool/_fasta/command_line.dart
@@ -401,11 +401,30 @@
 
   final Uri sdk = options["--sdk"] ?? options["--compile-sdk"];
 
+  String computePlatformDillName() {
+    switch (target.name) {
+      case 'dartdevc':
+        return 'dartdevc.dill';
+      case 'dart2js':
+        return 'dart2js_platform.dill';
+      case 'dart2js_server':
+        return 'dart2js_platform.dill';
+      case 'vm':
+        return legacyMode ? 'vm_platform.dill' : "vm_platform_strong.dill";
+      case 'none':
+        return "vm_platform_strong.dill";
+      default:
+        throwCommandLineProblem(
+            'Target "${target.name}" requires an explicit --platform option.');
+    }
+    return null;
+  }
+
   final Uri platform = compileSdk
       ? null
       : (options["--platform"] ??
-          computePlatformBinariesLocation(forceBuildDir: true).resolve(
-              legacyMode ? "vm_platform.dill" : "vm_platform_strong.dill"));
+          computePlatformBinariesLocation(forceBuildDir: true)
+              .resolve(computePlatformDillName()));
 
   CompilerOptions compilerOptions = new CompilerOptions()
     ..compileSdk = compileSdk
diff --git a/pkg/front_end/tool/_fasta/generate_messages.dart b/pkg/front_end/tool/_fasta/generate_messages.dart
index 1da6852..dba3a10 100644
--- a/pkg/front_end/tool/_fasta/generate_messages.dart
+++ b/pkg/front_end/tool/_fasta/generate_messages.dart
@@ -42,6 +42,8 @@
 // Instead modify 'pkg/front_end/messages.yaml' and run
 // 'pkg/front_end/tool/fasta generate-messages' to update.
 
+// ignore_for_file: lines_longer_than_80_chars
+
 part of fasta.codes;
 """);
 
diff --git a/pkg/front_end/tool/_fasta/log_collector.dart b/pkg/front_end/tool/_fasta/log_collector.dart
index 31aee1b..b35250d 100644
--- a/pkg/front_end/tool/_fasta/log_collector.dart
+++ b/pkg/front_end/tool/_fasta/log_collector.dart
@@ -48,7 +48,7 @@
     return badRequest(request, HttpStatus.badRequest,
         "Malformed JSON data: type should be 'crash'.");
   }
-  request.response.close();
+  await request.response.close();
   String year = "${time.year}".padLeft(4, "0");
   String month = "${time.month}".padLeft(2, "0");
   String day = "${time.day}".padLeft(2, "0");
diff --git a/pkg/front_end/tool/fasta_perf.dart b/pkg/front_end/tool/fasta_perf.dart
index 624c3ac..577d582 100644
--- a/pkg/front_end/tool/fasta_perf.dart
+++ b/pkg/front_end/tool/fasta_perf.dart
@@ -148,7 +148,9 @@
 
   inputSize = 0;
   // adjust size because there is a null-terminator on the contents.
-  for (var source in files.values) inputSize += (source.length - 1);
+  for (var source in files.values) {
+    inputSize += (source.length - 1);
+  }
   print('input size: $inputSize chars');
   var loadTime = loadTimer.elapsedMicroseconds - scanTimer.elapsedMicroseconds;
   report('load', loadTime);
@@ -227,7 +229,7 @@
     {bool compileSdk: true, bool legacyMode: false}) async {
   // TODO(sigmund): this is here only to compute the input size,
   // we should extract the input size from the frontend instead.
-  scanReachableFiles(entryUri);
+  await scanReachableFiles(entryUri);
 
   var timer = new Stopwatch()..start();
   var options = new CompilerOptions()
@@ -256,10 +258,10 @@
 /// Report that metric [name] took [time] micro-seconds to process
 /// [inputSize] characters.
 void report(String name, int time) {
-  var sb = new StringBuffer();
-  var padding = ' ' * (20 - name.length);
+  StringBuffer sb = new StringBuffer();
+  String padding = ' ' * (20 - name.length);
   sb.write('$name:$padding $time us, ${time ~/ 1000} ms');
-  var invSpeed = (time * 1000 / inputSize).toStringAsFixed(2);
+  String invSpeed = (time * 1000 / inputSize).toStringAsFixed(2);
   sb.write(', $invSpeed ns/char');
   print('$sb');
 }
diff --git a/pkg/front_end/tool/perf.dart b/pkg/front_end/tool/perf.dart
index b216937..5e5dad1 100644
--- a/pkg/front_end/tool/perf.dart
+++ b/pkg/front_end/tool/perf.dart
@@ -134,10 +134,10 @@
 /// Report that metric [name] took [time] micro-seconds to process
 /// [inputSize] characters.
 void report(String name, int time) {
-  var sb = new StringBuffer();
-  var padding = ' ' * (20 - name.length);
+  StringBuffer sb = new StringBuffer();
+  String padding = ' ' * (20 - name.length);
   sb.write('$name:$padding $time us, ${time ~/ 1000} ms');
-  var invSpeed = (time * 1000 / inputSize).toStringAsFixed(2);
+  String invSpeed = (time * 1000 / inputSize).toStringAsFixed(2);
   sb.write(', $invSpeed ns/char');
   print('$sb');
 }
@@ -184,7 +184,9 @@
   loadTimer.stop();
 
   inputSize = 0;
-  for (var s in files) inputSize += s.contents.data.length;
+  for (var s in files) {
+    inputSize += s.contents.data.length;
+  }
   print('input size: ${inputSize} chars');
   var loadTime = loadTimer.elapsedMicroseconds - scanTimer.elapsedMicroseconds;
   report('load', loadTime);
diff --git a/pkg/front_end/tool/smoke_test_quick.dart b/pkg/front_end/tool/smoke_test_quick.dart
new file mode 100644
index 0000000..1448d38
--- /dev/null
+++ b/pkg/front_end/tool/smoke_test_quick.dart
@@ -0,0 +1,68 @@
+// 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.
+
+import 'dart:io';
+
+final String repoDir = _computeRepoDir();
+
+String get dartVm => Platform.executable;
+
+main(List<String> args) async {
+  Stopwatch stopwatch = new Stopwatch()..start();
+  List<Future> futures = new List<Future>();
+  futures.add(run(
+    "pkg/front_end/test/fasta/messages_test.dart",
+    ["-DfastOnly=true"],
+  ));
+  futures.add(run("pkg/front_end/test/spelling_test_not_src_test.dart", []));
+  futures.add(run("pkg/front_end/test/spelling_test_src_test.dart", []));
+  futures.add(run("pkg/front_end/test/lint_test.dart", []));
+  await Future.wait(futures);
+  print("\n-----------------------\n");
+  print("Done with exitcode $exitCode in ${stopwatch.elapsedMilliseconds} ms");
+}
+
+Future<void> run(String script, List<String> scriptArguments,
+    {bool filter: true}) async {
+  List<String> arguments = [];
+  arguments.add("$script");
+  arguments.addAll(scriptArguments);
+
+  Stopwatch stopwatch = new Stopwatch()..start();
+  ProcessResult result =
+      await Process.run(dartVm, arguments, workingDirectory: repoDir);
+  String runWhat = "${dartVm} ${arguments.join(' ')}";
+  if (result.exitCode != 0) {
+    exitCode = result.exitCode;
+    print("-----");
+    print("Running: $runWhat: "
+        "Failed with exit code ${result.exitCode} "
+        "in ${stopwatch.elapsedMilliseconds} ms.");
+    String stdout = result.stdout.toString();
+    if (filter) {
+      List<String> lines = stdout.split("\n");
+      int lastIgnored = -1;
+      for (int i = 0; i < lines.length; i++) {
+        if (lines[i].startsWith("[ ")) lastIgnored = i;
+      }
+      lines.removeRange(0, lastIgnored + 1);
+      stdout = lines.join("\n");
+    }
+    stdout = stdout.trim();
+    if (stdout.isNotEmpty) {
+      print(stdout);
+      print("-----");
+    }
+  } else {
+    print("Running: $runWhat: Done in ${stopwatch.elapsedMilliseconds} ms.");
+  }
+}
+
+String _computeRepoDir() {
+  ProcessResult result = Process.runSync(
+      'git', ['rev-parse', '--show-toplevel'],
+      runInShell: true,
+      workingDirectory: new File.fromUri(Platform.script).parent.path);
+  return (result.stdout as String).trim();
+}
diff --git a/pkg/js/README.md b/pkg/js/README.md
index 1aec699..9ea9884 100644
--- a/pkg/js/README.md
+++ b/pkg/js/README.md
@@ -1,16 +1,27 @@
-Methods and annotations to specify interoperability with JavaScript APIs.
+Use this package when you want to call JavaScript APIs from Dart code, or vice versa.
 
-### Example
+This package's main library, `js`, provides annotations and functions
+that let you specify how your Dart code interoperates with JavaScript code.
+The Dart-to-JavaScript compilers — dartdevc and dart2js — recognize these
+annotations, using them to connect your Dart code with JavaScript.
+
+**Important:** This library supercedes `dart:js`, so don't import `dart:js`.
+Instead, import `package:js/js.dart`.
+
+A second library in this package, `js_util`, provides low-level utilities
+that you can use when it isn't possible to wrap JavaScript with a static, annotated API.
+
+
+## Example
 
 See the [Chart.js Dart API](https://github.com/google/chartjs.dart/) for an
 end-to-end example.
 
-### Usage
+## Usage
 
-All Dart code interacting with JavaScript should use the utilities provided with
-`package:js`. Developers should avoid importing `dart:js` directly.
+The following examples show how to handle common interoperability tasks.
 
-#### Calling methods
+### Calling JavaScript functions
 
 ```dart
 @JS()
@@ -23,7 +34,7 @@
 external String stringify(Object obj);
 ```
 
-#### Classes and Namespaces
+### Using JavaScript namespaces and classes
 
 ```dart
 @JS('google.maps')
@@ -52,7 +63,7 @@
 }
 ```
 
-#### JavaScript object literals
+### Passing object literals to JavaScript
 
 Many JavaScript APIs take an object literal as an argument. For example:
 ```js
@@ -88,18 +99,14 @@
 }
 ```
 
-#### Passing functions to JavaScript
+### Making a Dart function callable from JavaScript
 
-If you are passing a Dart function to a JavaScript API as an argument , you must
-wrap it using `allowInterop` or `allowInteropCaptureThis`. **Warning** There is
-a behavior difference between the Dart2JS and DDC compilers. When compiled with
-DDC there will be no errors despite missing `allowInterop` calls, because DDC
-uses JS calling semantics by default. When compiling with Dart2JS the
-`allowInterop` utility must be used.
+If you pass a Dart function to a JavaScript API as an argument,
+wrap the Dart function using `allowInterop()` or `allowInteropCaptureThis()`.
 
-#### Making a Dart function callable from JavaScript
+**Warning:** Although dart2js requires `allowInterop()`, dartdevc does not.
 
-To provide a Dart function callable from JavaScript by name use a setter
+To make a Dart function callable from JavaScript _by name_, use a setter
 annotated with `@JS()`.
 
 ```dart
@@ -126,35 +133,44 @@
 }
 ```
 
+## Reporting issues
+
+Please file bugs and feature requests on the [SDK issue tracker][issues].
+
+[issues]: https://goo.gl/j3rzs0
+
+
 ## Known limitations and bugs
 
-### Differences betwenn Dart2JS and DDC
+<!-- [TODO: add intro. perhaps move this to another page?] -->
+
+### Differences between dart2js and dartdevc
 
 Dart's production and development JavaScript compilers use different calling
 conventions and type representation, and therefore have different challenges in
-JavaScript interop. There are currently some know differences in behavior and
+JavaScript interop. There are currently some known differences in behavior and
 bugs in one or both compilers.
 
-#### allowInterop is required in Dart2JS, optional in DDC
+#### allowInterop is required in dart2js, optional in dartdevc
 
 DDC uses the same calling conventions as JavaScript and so Dart functions passed
-as callbacks can be invoked without modification. In Dart2JS the calling
-conventions are different and so `allowInterop` or `allowInteropCaptureThis`
+as callbacks can be invoked without modification. In dart2js the calling
+conventions are different and so `allowInterop()` or `allowInteropCaptureThis()`
 must be used for any callback.
 
-**Workaround:**: Always use `allowInterop` even when not required in DDC.
+**Workaround:**: Always use `allowInterop()` even when not required in dartdevc.
 
 #### Callbacks allow extra ignored arguments in DDC
 
 In JavaScript a caller may pass any number of "extra" arguments to a function
-and they will be ignored. DDC follows this behavior, Dart2JS will have a runtime
+and they will be ignored. dartdevc follows this behavior, dart2js will have a runtime
 error if a function is invoked with more arguments than expected.
 
 **Workaround:** Write functions that take the same number of arguments as will
 be passed from JavaScript. If the number is variable use optional positional
 arguments.
 
-#### DDC and Dart2JS have different representation for Maps
+#### Dartdevc and dart2js have different representation for Maps
 
 Passing a `Map<String, String>` as an argument to a JavaScript function will
 have different behavior depending on the compiler. Calling something like
@@ -163,20 +179,20 @@
 **Workaround:** Only pass object literals instead of Maps as arguments. For json
 specifically use `jsonEncode` in Dart rather than a JS alternative.
 
-#### Missing validation for anonymous factory constructors in DDC
+#### Missing validation for anonymous factory constructors in dartdevc
 
-When using an `@anonymous` class to create JavaScript object literals Dart2JS
-will enforce that only named arguments are used, while DDC will allow positional
+When using an `@anonymous` class to create JavaScript object literals dart2js
+will enforce that only named arguments are used, while dartdevc will allow positional
 arguments but may generate incorrect code.
 
 **Workaround:** Try builds in both development and release mode to get the full
 scope of static validation.
 
-### Sharp Edges
+### Common problems
 
-Dart and JavaScript have different semantics and common patterns which makes it
-easy to make some mistakes, and difficult for the tools to provide safety. These
-sharp edges are known pitfalls.
+Dart and JavaScript have different semantics and common patterns, which makes it
+easy to make some mistakes and difficult for the tools to provide safety. These
+common problems are also known as _sharp edges_.
 
 #### Lack of runtime type checking
 
@@ -205,9 +221,3 @@
 **Workaround:** Avoid importing `dart:js` and only use the `package:js` provided
 approach. To handle object literals use `@anonymous` on an `@JS()` annotated
 class.
-
-## Reporting issues
-
-Please file bugs and features requests on the [SDK issue tracker][issues].
-
-[issues]: https://goo.gl/j3rzs0
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index df1c4c0..267cdf4 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -139,7 +139,7 @@
 
 type ComponentFile {
   UInt32 magic = 0x90ABCDEF;
-  UInt32 formatVersion = 28;
+  UInt32 formatVersion = 29;
   List<String> problemsAsJson; // Described in problems.md.
   Library[] libraries;
   UriSource sourceMap;
@@ -340,8 +340,8 @@
   UriReference fileUri;
   FileOffset fileOffset;
   FileOffset fileEndOffset;
-  Byte flags (isFinal, isConst, isStatic, hasImplicitGetter, hasImplicitSetter,
-              isCovariant, isGenericCovariantImpl);
+  UInt flags (isFinal, isConst, isStatic, hasImplicitGetter, hasImplicitSetter,
+                isCovariant, isGenericCovariantImpl, isLate, isExtensionMember);
   Name name;
   List<Expression> annotations;
   DartType type;
@@ -381,10 +381,9 @@
   FileOffset fileOffset; // Offset of the procedure name.
   FileOffset fileEndOffset;
   Byte kind; // Index into the ProcedureKind enum above.
-  Byte flags (isStatic, isAbstract, isExternal, isConst, isForwardingStub,
-              isForwardingSemiStub,
-              isRedirectingFactoryConstructor,
-              isNoSuchMethodForwarder);
+  Uint flags (isStatic, isAbstract, isExternal, isConst, isForwardingStub,
+              isForwardingSemiStub, isRedirectingFactoryConstructor,
+              isNoSuchMethodForwarder, isExtensionMember);
   Name name;
   List<Expression> annotations;
   // Only present if the 'isForwardingStub' flag is set.
@@ -1173,7 +1172,7 @@
   List<Expression> annotations;
 
   Byte flags (isFinal, isConst, isFieldFormal, isCovariant,
-              isInScope, isGenericCovariantImpl);
+              isInScope, isGenericCovariantImpl, isLate, isRequired);
   // For named parameters, this is the parameter name.
   // For other variables, the name is cosmetic, may be empty,
   // and is not necessarily unique.
@@ -1253,6 +1252,7 @@
 type NamedDartType {
   StringReference name;
   DartType type;
+  Byte flags (isRequired);
 }
 
 type TypeParameterType extends DartType {
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index da28c4c..6fdda00 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -352,6 +352,7 @@
 
   final List<Typedef> typedefs;
   final List<Class> classes;
+  final List<Extension> extensions;
   final List<Procedure> procedures;
   final List<Field> fields;
 
@@ -363,6 +364,7 @@
       List<LibraryPart> parts,
       List<Typedef> typedefs,
       List<Class> classes,
+      List<Extension> extensions,
       List<Procedure> procedures,
       List<Field> fields,
       this.fileUri,
@@ -372,6 +374,7 @@
         this.parts = parts ?? <LibraryPart>[],
         this.typedefs = typedefs ?? <Typedef>[],
         this.classes = classes ?? <Class>[],
+        this.extensions = extensions ?? <Extension>[],
         this.procedures = procedures ?? <Procedure>[],
         this.fields = fields ?? <Field>[],
         super(reference) {
@@ -380,6 +383,7 @@
     setParents(this.parts, this);
     setParents(this.typedefs, this);
     setParents(this.classes, this);
+    setParents(this.extensions, this);
     setParents(this.procedures, this);
     setParents(this.fields, this);
   }
@@ -412,6 +416,11 @@
     classes.add(class_);
   }
 
+  void addExtension(Extension extension) {
+    extension.parent = this;
+    extensions.add(extension);
+  }
+
   void addField(Field field) {
     field.parent = this;
     fields.add(field);
@@ -1105,6 +1114,129 @@
   }
 }
 
+/// Declaration of an extension.
+///
+/// The members are converted into top-level procedures and only accessible
+/// by reference in the [Extension] node.
+class Extension extends NamedNode implements FileUriNode {
+  /// Name of the extension.
+  ///
+  /// If unnamed, the extension will be given a synthesized name by the
+  /// front end.
+  String name;
+
+  /// The URI of the source file this class was loaded from.
+  Uri fileUri;
+
+  /// Type parameters declared on the extension.
+  final List<TypeParameter> typeParameters;
+
+  /// The type in the 'on clause' of the extension declaration.
+  ///
+  /// For instance A in:
+  ///
+  ///   class A {}
+  ///   extension B on A {}
+  ///
+  DartType onType;
+
+  /// The members declared by the extension.
+  ///
+  /// The members are converted into top-level members and only accessible
+  /// by reference through [ExtensionMemberDescriptor].
+  final List<ExtensionMemberDescriptor> members;
+
+  Extension(
+      {this.name,
+      List<TypeParameter> typeParameters,
+      this.onType,
+      List<Reference> members,
+      this.fileUri,
+      Reference reference})
+      : this.typeParameters = typeParameters ?? <TypeParameter>[],
+        this.members = members ?? <ExtensionMemberDescriptor>[],
+        super(reference);
+
+  Library get enclosingLibrary => parent;
+
+  @override
+  accept(TreeVisitor v) => v.visitExtension(this);
+
+  @override
+  visitChildren(Visitor v) {}
+
+  @override
+  transformChildren(Transformer v) => v.visitExtension(this);
+}
+
+/// Information about an member declaration in an extension.
+class ExtensionMemberDescriptor {
+  /// The name of the extension member.
+  ///
+  /// The name of the generated top-level member is mangled to ensure
+  /// uniqueness. This name is used to lookup an extension method the
+  /// extension itself.
+  Name name;
+
+  /// [ProcedureKind] kind of the original member, if the extension is a
+  /// [Procedure] and `null` otherwise.
+  ///
+  /// This can be either `Method`, `Getter`, `Setter`, or `Operator`.
+  ///
+  /// An extension method is converted into a regular top-level method. For
+  /// instance:
+  ///
+  ///     class A {
+  ///       var foo;
+  ///     }
+  ///     extension B on A {
+  ///       get bar => this.foo;
+  ///     }
+  ///
+  /// will be converted into
+  ///
+  ///     class A {}
+  ///     B|get#bar(A #this) => #this.foo;
+  ///
+  /// where `B|get#bar` is the synthesized name of the top-level method and
+  /// `#this` is the synthesized parameter that holds represents `this`.
+  ///
+  ProcedureKind kind;
+
+  int flags = 0;
+
+  /// Reference to the top-level member created for the extension method.
+  Reference member;
+
+  ExtensionMemberDescriptor(
+      {this.name,
+      this.kind,
+      bool isStatic: false,
+      bool isExternal: false,
+      this.member}) {
+    this.isStatic = isStatic;
+    this.isExternal = isExternal;
+  }
+
+  /// Return `true` if the extension method was declared as `static`.
+  bool get isStatic => flags & Procedure.FlagStatic != 0;
+
+  /// Return `true` if the extension method was declared as `external`.
+  bool get isExternal => flags & Procedure.FlagExternal != 0;
+
+  void set isStatic(bool value) {
+    flags = value
+        ? (flags | Procedure.FlagStatic)
+        : (flags & ~Procedure.FlagStatic);
+  }
+
+  void set isExternal(bool value) {
+    flags = value
+        ? (flags | Procedure.FlagExternal)
+        : (flags & ~Procedure.FlagExternal);
+  }
+}
+
 // ------------------------------------------------------------------------
 //                            MEMBERS
 // ------------------------------------------------------------------------
@@ -1187,6 +1319,19 @@
   bool get isExternal;
   void set isExternal(bool value);
 
+  /// If `true` this member is compiled from a member declared in an extension
+  /// declaration.
+  ///
+  /// For instance `field`, `method1` and `method2` in:
+  ///
+  ///     extension A on B {
+  ///       static var field;
+  ///       B method1() => this;
+  ///       static B method2() => new B();
+  ///     }
+  ///
+  bool get isExtensionMember;
+
   /// The body of the procedure or constructor, or `null` if this is a field.
   FunctionNode get function => null;
 
@@ -1228,6 +1373,7 @@
       bool isStatic: false,
       bool hasImplicitGetter,
       bool hasImplicitSetter,
+      bool isLate: false,
       int transformerFlags: 0,
       Uri fileUri,
       Reference reference})
@@ -1238,6 +1384,7 @@
     this.isFinal = isFinal;
     this.isConst = isConst;
     this.isStatic = isStatic;
+    this.isLate = isLate;
     this.hasImplicitGetter = hasImplicitGetter ?? !isStatic;
     this.hasImplicitSetter = hasImplicitSetter ?? (!isStatic && !isFinal);
     this.transformerFlags = transformerFlags;
@@ -1250,6 +1397,8 @@
   static const int FlagHasImplicitSetter = 1 << 4;
   static const int FlagCovariant = 1 << 5;
   static const int FlagGenericCovariantImpl = 1 << 6;
+  static const int FlagLate = 1 << 7;
+  static const int FlagExtensionMember = 1 << 8;
 
   /// Whether the field is declared with the `covariant` keyword.
   bool get isCovariant => flags & FlagCovariant != 0;
@@ -1258,6 +1407,9 @@
   bool get isConst => flags & FlagConst != 0;
   bool get isStatic => flags & FlagStatic != 0;
 
+  @override
+  bool get isExtensionMember => flags & FlagExtensionMember != 0;
+
   /// If true, a getter should be generated for this field.
   ///
   /// If false, there may or may not exist an explicit getter in the same class
@@ -1285,6 +1437,9 @@
   /// [DispatchCategory] for details.
   bool get isGenericCovariantImpl => flags & FlagGenericCovariantImpl != 0;
 
+  /// Whether the field is declared with the `late` keyword.
+  bool get isLate => flags & FlagLate != 0;
+
   void set isCovariant(bool value) {
     flags = value ? (flags | FlagCovariant) : (flags & ~FlagCovariant);
   }
@@ -1301,6 +1456,11 @@
     flags = value ? (flags | FlagStatic) : (flags & ~FlagStatic);
   }
 
+  void set isExtensionMember(bool value) {
+    flags =
+        value ? (flags | FlagExtensionMember) : (flags & ~FlagExtensionMember);
+  }
+
   void set hasImplicitGetter(bool value) {
     flags = value
         ? (flags | FlagHasImplicitGetter)
@@ -1319,6 +1479,10 @@
         : (flags & ~FlagGenericCovariantImpl);
   }
 
+  void set isLate(bool value) {
+    flags = value ? (flags | FlagLate) : (flags & ~FlagLate);
+  }
+
   /// True if the field is neither final nor const.
   bool get isMutable => flags & (FlagFinal | FlagConst) == 0;
   bool get isInstanceMember => !isStatic;
@@ -1426,6 +1590,9 @@
   bool get hasGetter => false;
   bool get hasSetter => false;
 
+  @override
+  bool get isExtensionMember => false;
+
   accept(MemberVisitor v) => v.visitConstructor(this);
 
   acceptReference(MemberReferenceVisitor v) =>
@@ -1550,6 +1717,9 @@
   bool get hasGetter => false;
   bool get hasSetter => false;
 
+  @override
+  bool get isExtensionMember => false;
+
   bool get isUnresolved => targetReference == null;
 
   Member get target => targetReference?.asMember;
@@ -1649,7 +1819,7 @@
       bool isConst: false,
       bool isForwardingStub: false,
       bool isForwardingSemiStub: false,
-      bool isExtensionMethod: false,
+      bool isExtensionMember: false,
       int transformerFlags: 0,
       Uri fileUri,
       Reference reference,
@@ -1662,7 +1832,7 @@
             isConst: isConst,
             isForwardingStub: isForwardingStub,
             isForwardingSemiStub: isForwardingSemiStub,
-            isExtensionMethod: isExtensionMethod,
+            isExtensionMember: isExtensionMember,
             transformerFlags: transformerFlags,
             fileUri: fileUri,
             reference: reference,
@@ -1678,7 +1848,7 @@
       bool isConst: false,
       bool isForwardingStub: false,
       bool isForwardingSemiStub: false,
-      bool isExtensionMethod: false,
+      bool isExtensionMember: false,
       int transformerFlags: 0,
       Uri fileUri,
       Reference reference,
@@ -1692,7 +1862,7 @@
     this.isConst = isConst;
     this.isForwardingStub = isForwardingStub;
     this.isForwardingSemiStub = isForwardingSemiStub;
-    this.isExtensionMethod = isExtensionMethod;
+    this.isExtensionMember = isExtensionMember;
     this.transformerFlags = transformerFlags;
   }
 
@@ -1705,7 +1875,7 @@
   // TODO(29841): Remove this flag after the issue is resolved.
   static const int FlagRedirectingFactoryConstructor = 1 << 6;
   static const int FlagNoSuchMethodForwarder = 1 << 7;
-  static const int FlagExtensionMethod = 1 << 8;
+  static const int FlagExtensionMember = 1 << 8;
 
   bool get isStatic => flags & FlagStatic != 0;
   bool get isAbstract => flags & FlagAbstract != 0;
@@ -1742,17 +1912,8 @@
 
   bool get isNoSuchMethodForwarder => flags & FlagNoSuchMethodForwarder != 0;
 
-  /// If `true` this procedure is compiled from a method declared in
-  /// an extension declaration.
-  ///
-  /// For instance `method1` and `method2` in:
-  ///
-  ///     extension A on B {
-  ///       B method1() => this;
-  ///       static B method2() => new B();
-  ///     }
-  ///
-  bool get isExtensionMethod => flags & FlagExtensionMethod != 0;
+  @override
+  bool get isExtensionMember => flags & FlagExtensionMember != 0;
 
   void set isStatic(bool value) {
     flags = value ? (flags | FlagStatic) : (flags & ~FlagStatic);
@@ -1793,9 +1954,9 @@
         : (flags & ~FlagNoSuchMethodForwarder);
   }
 
-  void set isExtensionMethod(bool value) {
+  void set isExtensionMember(bool value) {
     flags =
-        value ? (flags | FlagExtensionMethod) : (flags & ~FlagExtensionMethod);
+        value ? (flags | FlagExtensionMember) : (flags & ~FlagExtensionMember);
   }
 
   bool get isInstanceMember => !isStatic;
@@ -2137,7 +2298,7 @@
   static DartType _getTypeOfVariable(VariableDeclaration node) => node.type;
 
   static NamedType _getNamedTypeOfVariable(VariableDeclaration node) {
-    return new NamedType(node.name, node.type);
+    return new NamedType(node.name, node.type, isRequired: node.isRequired);
   }
 
   FunctionType get functionType {
@@ -4616,7 +4777,9 @@
       bool isFinal: false,
       bool isConst: false,
       bool isFieldFormal: false,
-      bool isCovariant: false}) {
+      bool isCovariant: false,
+      bool isLate: false,
+      bool isRequired: false}) {
     assert(type != null);
     initializer?.parent = this;
     if (flags != -1) {
@@ -4626,6 +4789,8 @@
       this.isConst = isConst;
       this.isFieldFormal = isFieldFormal;
       this.isCovariant = isCovariant;
+      this.isLate = isLate;
+      this.isRequired = isRequired;
     }
   }
 
@@ -4634,12 +4799,16 @@
       {bool isFinal: true,
       bool isConst: false,
       bool isFieldFormal: false,
+      bool isLate: false,
+      bool isRequired: false,
       this.type: const DynamicType()}) {
     assert(type != null);
     initializer?.parent = this;
     this.isFinal = isFinal;
     this.isConst = isConst;
     this.isFieldFormal = isFieldFormal;
+    this.isLate = isLate;
+    this.isRequired = isRequired;
   }
 
   static const int FlagFinal = 1 << 0; // Must match serialized bit positions.
@@ -4648,6 +4817,8 @@
   static const int FlagCovariant = 1 << 3;
   static const int FlagInScope = 1 << 4; // Temporary flag used by verifier.
   static const int FlagGenericCovariantImpl = 1 << 5;
+  static const int FlagLate = 1 << 6;
+  static const int FlagRequired = 1 << 7;
 
   bool get isFinal => flags & FlagFinal != 0;
   bool get isConst => flags & FlagConst != 0;
@@ -4668,6 +4839,18 @@
   /// [DispatchCategory] for details.
   bool get isGenericCovariantImpl => flags & FlagGenericCovariantImpl != 0;
 
+  /// Whether the variable is declared with the `late` keyword.
+  ///
+  /// The `late` modifier is only supported on local variables and not on
+  /// parameters.
+  bool get isLate => flags & FlagLate != 0;
+
+  /// Whether the parameter is declared with the `required` keyword.
+  ///
+  /// The `required` modifier is only supported on named parameters and not on
+  /// positional parameters and local variables.
+  bool get isRequired => flags & FlagRequired != 0;
+
   void set isFinal(bool value) {
     flags = value ? (flags | FlagFinal) : (flags & ~FlagFinal);
   }
@@ -4691,6 +4874,14 @@
         : (flags & ~FlagGenericCovariantImpl);
   }
 
+  void set isLate(bool value) {
+    flags = value ? (flags | FlagLate) : (flags & ~FlagLate);
+  }
+
+  void set isRequired(bool value) {
+    flags = value ? (flags | FlagRequired) : (flags & ~FlagRequired);
+  }
+
   void addAnnotation(Expression annotation) {
     if (annotations.isEmpty) {
       annotations = <Expression>[];
@@ -5223,17 +5414,24 @@
 
 /// A named parameter in [FunctionType].
 class NamedType extends Node implements Comparable<NamedType> {
+  // Flag used for serialization if [isRequired].
+  static const int FlagRequiredNamedType = 1 << 0;
+
   final String name;
   final DartType type;
+  final bool isRequired;
 
-  NamedType(this.name, this.type);
+  NamedType(this.name, this.type, {this.isRequired: false});
 
   bool operator ==(Object other) {
-    return other is NamedType && name == other.name && type == other.type;
+    return other is NamedType &&
+        name == other.name &&
+        type == other.type &&
+        isRequired == other.isRequired;
   }
 
   int get hashCode {
-    return name.hashCode * 31 + type.hashCode * 37;
+    return name.hashCode * 31 + type.hashCode * 37 + isRequired.hashCode * 41;
   }
 
   int compareTo(NamedType other) => name.compareTo(other.name);
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index aca0b12..a66a437 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -1084,7 +1084,7 @@
     var fileUri = readUriReference();
     int fileOffset = readOffset();
     int fileEndOffset = readOffset();
-    int flags = readByte();
+    int flags = readUInt();
     var name = readName();
     var annotations = readAnnotationList(node);
     assert(() {
@@ -1178,7 +1178,7 @@
     var fileEndOffset = readOffset();
     int kindIndex = readByte();
     var kind = ProcedureKind.values[kindIndex];
-    var flags = readByte();
+    var flags = readUInt();
     var name = readName();
     var annotations = readAnnotationList(node);
     assert(() {
@@ -1950,7 +1950,11 @@
   }
 
   NamedType readNamedType() {
-    return new NamedType(readStringReference(), readDartType());
+    String name = readStringReference();
+    DartType type = readDartType();
+    int flags = readByte();
+    return new NamedType(name, type,
+        isRequired: (flags & NamedType.FlagRequiredNamedType) != 0);
   }
 
   DartType readDartTypeOption() {
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index 8a5762b..824c145 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -75,6 +75,7 @@
   }
 
   void writeByte(int byte) {
+    assert((byte & 0xFF) == byte);
     _sink.addByte(byte);
   }
 
@@ -1163,7 +1164,7 @@
     writeOffset(node.fileOffset);
     writeOffset(node.fileEndOffset);
     writeByte(node.kind.index);
-    writeByte(node.flags);
+    writeUInt30(node.flags);
     writeName(node.name ?? _emptyName);
     writeAnnotationList(node.annotations);
     writeNullAllowedReference(node.forwardingStubSuperTargetReference);
@@ -1187,7 +1188,7 @@
     writeUriReference(node.fileUri);
     writeOffset(node.fileOffset);
     writeOffset(node.fileEndOffset);
-    writeByte(node.flags);
+    writeUInt30(node.flags);
     writeName(node.name);
     writeAnnotationList(node.annotations);
     writeNode(node.type);
@@ -2064,6 +2065,8 @@
   void visitNamedType(NamedType node) {
     writeStringReference(node.name);
     writeNode(node.type);
+    int flags = (node.isRequired ? NamedType.FlagRequiredNamedType : 0);
+    writeByte(flags);
   }
 
   @override
@@ -2091,6 +2094,12 @@
     writeOptionalNode(node.defaultType);
   }
 
+  @override
+  void visitExtension(Extension node) {
+    // TODO(johnniwinther): Support serialization of extension nodes.
+    throw new UnsupportedError('serialization of extension nodes');
+  }
+
   // ================================================================
   // These are nodes that are never serialized directly.  Reaching one
   // during serialization is an error.
diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart
index c84eba7..3fcad11 100644
--- a/pkg/kernel/lib/binary/tag.dart
+++ b/pkg/kernel/lib/binary/tag.dart
@@ -150,7 +150,7 @@
   /// Internal version of kernel binary format.
   /// Bump it when making incompatible changes in kernel binaries.
   /// Keep in sync with runtime/vm/kernel_binary.h, pkg/kernel/binary.md.
-  static const int BinaryFormatVersion = 28;
+  static const int BinaryFormatVersion = 29;
 }
 
 abstract class ConstantTag {
diff --git a/pkg/kernel/lib/clone.dart b/pkg/kernel/lib/clone.dart
index 2c7df60..62b3a7b 100644
--- a/pkg/kernel/lib/clone.dart
+++ b/pkg/kernel/lib/clone.dart
@@ -52,6 +52,10 @@
     throw 'Cloning of classes is not implemented';
   }
 
+  TreeNode visitExtension(Extension node) {
+    throw 'Cloning of extensions is not implemented';
+  }
+
   // The currently active file uri where we are cloning [TreeNode]s from.  If
   // this is set to `null` we cannot clone file offsets to newly created nodes.
   // The [_cloneFileOffset] helper function will ensure this.
@@ -472,6 +476,7 @@
         isFinal: node.isFinal,
         isConst: node.isConst,
         isStatic: node.isStatic,
+        isLate: node.isLate,
         hasImplicitGetter: node.hasImplicitGetter,
         hasImplicitSetter: node.hasImplicitSetter,
         transformerFlags: node.transformerFlags,
diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart
index eef51ff..dd19365 100644
--- a/pkg/kernel/lib/text/ast_to_text.dart
+++ b/pkg/kernel/lib/text/ast_to_text.dart
@@ -145,6 +145,7 @@
       new NormalNamer<VariableDeclaration>('#t');
   final Namer<Member> members = new NormalNamer<Member>('#m');
   final Namer<Class> classes = new NormalNamer<Class>('#class');
+  final Namer<Extension> extensions = new NormalNamer<Extension>('#extension');
   final Namer<Library> libraries = new NormalNamer<Library>('#lib');
   final Namer<TypeParameter> typeParameters =
       new NormalNamer<TypeParameter>('#T');
@@ -156,6 +157,7 @@
   nameVariable(VariableDeclaration node) => variables.getName(node);
   nameMember(Member node) => members.getName(node);
   nameClass(Class node) => classes.getName(node);
+  nameExtension(Extension node) => extensions.getName(node);
   nameLibrary(Library node) => libraries.getName(node);
   nameTypeParameter(TypeParameter node) => typeParameters.getName(node);
   nameSwitchCase(SwitchCase node) => labels.getName(node);
@@ -285,6 +287,10 @@
     return node.name ?? syntheticNames.nameClass(node);
   }
 
+  String getExtensionName(Extension node) {
+    return node.name ?? syntheticNames.nameExtension(node);
+  }
+
   String getClassReference(Class node) {
     if (node == null) return '<No Class>';
     String name = getClassName(node);
@@ -417,6 +423,7 @@
     library.parts.forEach(writeNode);
     library.typedefs.forEach(writeNode);
     library.classes.forEach(writeNode);
+    library.extensions.forEach(writeNode);
     library.fields.forEach(writeNode);
     library.procedures.forEach(writeNode);
   }
@@ -1015,6 +1022,7 @@
   visitField(Field node) {
     writeAnnotationList(node.annotations);
     writeIndentation();
+    writeModifier(node.isLate, 'late');
     writeModifier(node.isStatic, 'static');
     writeModifier(node.isCovariant, 'covariant');
     writeModifier(node.isGenericCovariantImpl, 'generic-covariant-impl');
@@ -1138,6 +1146,46 @@
     endLine('}');
   }
 
+  visitExtension(Extension node) {
+    writeIndentation();
+    writeWord('extension');
+    writeWord(getExtensionName(node));
+    writeTypeParameterList(node.typeParameters);
+    writeSpaced('on');
+    writeType(node.onType);
+    var endLineString = ' {';
+    if (node.enclosingLibrary.fileUri != node.fileUri) {
+      endLineString += ' // from ${node.fileUri}';
+    }
+    endLine(endLineString);
+    ++indentation;
+    node.members.forEach((ExtensionMemberDescriptor descriptor) {
+      writeIndentation();
+      writeModifier(descriptor.isExternal, 'external');
+      writeModifier(descriptor.isStatic, 'static');
+      if (descriptor.member.asMember is Procedure) {
+        writeWord(procedureKindToString(descriptor.kind));
+      } else {
+        writeWord('field');
+      }
+      writeName(descriptor.name);
+      writeSpaced('=');
+      Member member = descriptor.member.asMember;
+      if (member is Procedure) {
+        if (member.isGetter) {
+          writeWord('get');
+        } else if (member.isSetter) {
+          writeWord('set');
+        }
+      }
+      writeMemberReferenceFromReference(descriptor.member);
+      endLine(';');
+    });
+    --indentation;
+    writeIndentation();
+    endLine('}');
+  }
+
   visitTypedef(Typedef node) {
     writeAnnotationList(node.annotations);
     writeIndentation();
@@ -1873,6 +1921,8 @@
     if (showOffsets) writeWord("[${node.fileOffset}]");
     if (showMetadata) writeMetadata(node);
     writeAnnotationList(node.annotations, separateLines: false);
+    writeModifier(node.isLate, 'late');
+    writeModifier(node.isRequired, 'required');
     writeModifier(node.isCovariant, 'covariant');
     writeModifier(node.isGenericCovariantImpl, 'generic-covariant-impl');
     writeModifier(node.isFinal, 'final');
@@ -1993,6 +2043,7 @@
   }
 
   visitNamedType(NamedType node) {
+    writeModifier(node.isRequired, 'required');
     writeWord(node.name);
     writeSymbol(':');
     writeSpace();
diff --git a/pkg/kernel/lib/text/text_serialization_verifier.dart b/pkg/kernel/lib/text/text_serialization_verifier.dart
index 3fed367..b29e0e0 100644
--- a/pkg/kernel/lib/text/text_serialization_verifier.dart
+++ b/pkg/kernel/lib/text/text_serialization_verifier.dart
@@ -606,6 +606,12 @@
   }
 
   @override
+  void visitExtension(Extension node) {
+    storeLastSeenUriAndOffset(node);
+    node.visitChildren(this);
+  }
+
+  @override
   void visitRedirectingFactoryConstructor(RedirectingFactoryConstructor node) {
     storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
diff --git a/pkg/kernel/lib/type_algebra.dart b/pkg/kernel/lib/type_algebra.dart
index a8d41d4..d847558 100644
--- a/pkg/kernel/lib/type_algebra.dart
+++ b/pkg/kernel/lib/type_algebra.dart
@@ -136,7 +136,8 @@
   DartType substitute(DartType type) => substitution.substituteType(type);
 
   NamedType substituteNamed(NamedType type) =>
-      new NamedType(type.name, substitute(type.type));
+      new NamedType(type.name, substitute(type.type),
+          isRequired: type.isRequired);
 
   Supertype substituteSuper(Supertype type) {
     return substitution.substituteSupertype(type);
@@ -409,7 +410,7 @@
     int before = useCounter;
     var type = visit(node.type);
     if (useCounter == before) return node;
-    return new NamedType(node.name, type);
+    return new NamedType(node.name, type, isRequired: node.isRequired);
   }
 
   DartType visit(DartType node) => node.accept(this);
diff --git a/pkg/kernel/lib/visitor.dart b/pkg/kernel/lib/visitor.dart
index e016e0a..bdea433 100644
--- a/pkg/kernel/lib/visitor.dart
+++ b/pkg/kernel/lib/visitor.dart
@@ -233,6 +233,7 @@
 
   // Classes
   R visitClass(Class node) => defaultTreeNode(node);
+  R visitExtension(Extension node) => defaultTreeNode(node);
 
   // Initializers
   R defaultInitializer(Initializer node) => defaultTreeNode(node);
diff --git a/pkg/kernel/pubspec.yaml b/pkg/kernel/pubspec.yaml
index 397b746..87a9c54 100644
--- a/pkg/kernel/pubspec.yaml
+++ b/pkg/kernel/pubspec.yaml
@@ -1,7 +1,7 @@
 name: kernel
 # Currently, kernel API is not stable and users should
 # not depend on semver semantics when depending on this package.
-version: 0.3.20
+version: 0.3.22
 author: Dart Team <misc@dartlang.org>
 description: Dart IR (Intermediate Representation)
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/kernel
diff --git a/pkg/nnbd_migration/lib/src/already_migrated_code_decorator.dart b/pkg/nnbd_migration/lib/src/already_migrated_code_decorator.dart
new file mode 100644
index 0000000..af4fd5d
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/already_migrated_code_decorator.dart
@@ -0,0 +1,69 @@
+// 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.
+
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:nnbd_migration/src/decorated_type.dart';
+import 'package:nnbd_migration/src/nullability_node.dart';
+
+/// This class transforms ordinary [DartType]s into their corresponding
+/// [DecoratedType]s, assuming the [DartType]s come from code that has already
+/// been migrated to NNBD.
+class AlreadyMigratedCodeDecorator {
+  final NullabilityGraph _graph;
+
+  AlreadyMigratedCodeDecorator(this._graph);
+
+  /// Transforms [type], which should have come from code that has already been
+  /// migrated to NNBD, into the corresponding [DecoratedType].
+  DecoratedType decorate(DartType type) {
+    if (type.isVoid || type.isDynamic) {
+      return DecoratedType(type, _graph.always);
+    }
+    var nullabilitySuffix = (type as TypeImpl).nullabilitySuffix;
+    if (nullabilitySuffix == NullabilitySuffix.question) {
+      // TODO(paulberry): add support for depending on already-migrated packages
+      // containing nullable types.
+      throw UnimplementedError(
+          'Migration depends on an already-migrated nullable type');
+    } else {
+      // Currently, all types passed to this method have nullability suffix `star`
+      // because (a) we don't yet have a migrated SDK, and (b) we haven't added
+      // support to the migrator for analyzing packages that have already been
+      // migrated with NNBD enabled.
+      // TODO(paulberry): fix this assertion when things change.
+      assert(nullabilitySuffix == NullabilitySuffix.star);
+    }
+    if (type is FunctionType) {
+      if (type.typeFormals.isNotEmpty) {
+        throw UnimplementedError('Decorating generic function type');
+      }
+      var positionalParameters = <DecoratedType>[];
+      var namedParameters = <String, DecoratedType>{};
+      for (var parameter in type.parameters) {
+        if (parameter.isPositional) {
+          positionalParameters.add(decorate(parameter.type));
+        } else {
+          namedParameters[parameter.name] = decorate(parameter.type);
+        }
+      }
+      return DecoratedType(type, _graph.never,
+          returnType: decorate(type.returnType),
+          namedParameters: namedParameters,
+          positionalParameters: positionalParameters);
+    } else if (type is InterfaceType) {
+      if (type.typeParameters.isNotEmpty) {
+        // TODO(paulberry)
+        throw UnimplementedError('Decorating ${type.displayName}');
+      }
+      return DecoratedType(type, _graph.never);
+    } else if (type is TypeParameterType) {
+      return DecoratedType(type, _graph.never);
+    } else {
+      // TODO(paulberry)
+      throw UnimplementedError(
+          'Unable to decorate already-migrated type $type');
+    }
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/decorated_type.dart b/pkg/nnbd_migration/lib/src/decorated_type.dart
index 41ebf51..81327fa 100644
--- a/pkg/nnbd_migration/lib/src/decorated_type.dart
+++ b/pkg/nnbd_migration/lib/src/decorated_type.dart
@@ -4,6 +4,7 @@
 
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' show SourceEdit;
 import 'package:nnbd_migration/src/nullability_node.dart';
@@ -13,6 +14,14 @@
 /// tracking the (unmigrated) [DartType], we track the [ConstraintVariable]s
 /// indicating whether the type, and the types that compose it, are nullable.
 class DecoratedType {
+  /// Mapping from type parameter elements to the decorated types of those type
+  /// parameters' bounds.
+  ///
+  /// This expando only applies to type parameters whose enclosing element is
+  /// `null`.  Type parameters whose enclosing element is not `null` should be
+  /// stored in [Variables._decoratedTypeParameterBounds].
+  static final _decoratedTypeParameterBounds = Expando<DecoratedType>();
+
   final DartType type;
 
   final NullabilityNode node;
@@ -35,11 +44,16 @@
   /// TODO(paulberry): how should we handle generic typedefs?
   final List<DecoratedType> typeArguments;
 
+  /// If `this` is a function type, the [DecoratedType] of each of the bounds of
+  /// its type parameters.
+  final List<DecoratedType> typeFormalBounds;
+
   DecoratedType(this.type, this.node,
       {this.returnType,
       this.positionalParameters = const [],
       this.namedParameters = const {},
-      this.typeArguments = const []}) {
+      this.typeArguments = const [],
+      this.typeFormalBounds = const []}) {
     assert(() {
       assert(node != null);
       var type = this.type;
@@ -47,11 +61,21 @@
         assert(returnType == null);
         assert(positionalParameters.isEmpty);
         assert(namedParameters.isEmpty);
+        assert(typeFormalBounds.isEmpty);
         assert(typeArguments.length == type.typeArguments.length);
         for (int i = 0; i < typeArguments.length; i++) {
           assert(typeArguments[i].type == type.typeArguments[i]);
         }
       } else if (type is FunctionType) {
+        assert(typeFormalBounds.length == type.typeFormals.length);
+        for (int i = 0; i < typeFormalBounds.length; i++) {
+          var declaredBound = type.typeFormals[i].bound;
+          if (declaredBound == null) {
+            assert(typeFormalBounds[i].type.isDartCoreObject);
+          } else {
+            assert(typeFormalBounds[i].type == declaredBound);
+          }
+        }
         assert(returnType.type == type.returnType);
         int positionalParameterCount = 0;
         int namedParameterCount = 0;
@@ -73,78 +97,18 @@
         assert(positionalParameters.isEmpty);
         assert(namedParameters.isEmpty);
         assert(typeArguments.isEmpty);
+        assert(typeFormalBounds.isEmpty);
       } else {
         assert(returnType == null);
         assert(positionalParameters.isEmpty);
         assert(namedParameters.isEmpty);
         assert(typeArguments.isEmpty);
+        assert(typeFormalBounds.isEmpty);
       }
       return true;
     }());
   }
 
-  /// Creates a [DecoratedType] corresponding to the given [element], which is
-  /// presumed to have come from code that is already migrated.
-  factory DecoratedType.forElement(Element element, NullabilityGraph graph) {
-    DecoratedType decorate(DartType type) {
-      if (type.isVoid || type.isDynamic) {
-        return DecoratedType(type, graph.always);
-      }
-      assert((type as TypeImpl).nullabilitySuffix ==
-          NullabilitySuffix.star); // TODO(paulberry)
-      if (type is FunctionType) {
-        var positionalParameters = <DecoratedType>[];
-        var namedParameters = <String, DecoratedType>{};
-        for (var parameter in type.parameters) {
-          if (parameter.isPositional) {
-            positionalParameters.add(decorate(parameter.type));
-          } else {
-            namedParameters[parameter.name] = decorate(parameter.type);
-          }
-        }
-        return DecoratedType(type, graph.never,
-            returnType: decorate(type.returnType),
-            namedParameters: namedParameters,
-            positionalParameters: positionalParameters);
-      } else if (type is InterfaceType) {
-        if (type.typeParameters.isNotEmpty) {
-          // TODO(paulberry)
-          throw UnimplementedError('Decorating ${type.displayName}');
-        }
-        return DecoratedType(type, graph.never);
-      } else if (type is TypeParameterType) {
-        return DecoratedType(type, graph.never);
-      } else {
-        throw type.runtimeType; // TODO(paulberry)
-      }
-    }
-
-    // Sanity check:
-    // Ensure the element is not from a library that is being migrated.
-    // If this assertion fires, it probably means that the NodeBuilder failed to
-    // generate the appropriate decorated type for the element when it was
-    // visiting the source file.
-    if (graph.isBeingMigrated(element.source)) {
-      throw 'Internal Error: DecorateType.forElement should not be called'
-          ' for elements being migrated: ${element.runtimeType} :: $element';
-    }
-
-    DecoratedType decoratedType;
-    if (element is ExecutableElement) {
-      decoratedType = decorate(element.type);
-    } else if (element is TopLevelVariableElement) {
-      decoratedType = decorate(element.type);
-    } else if (element is TypeParameterElement) {
-      // By convention, type parameter elements are decorated with the type of
-      // their bounds.
-      decoratedType = decorate(element.bound ?? DynamicTypeImpl.instance);
-    } else {
-      // TODO(paulberry)
-      throw UnimplementedError('Decorating ${element.runtimeType}');
-    }
-    return decoratedType;
-  }
-
   /// Creates a decorated type corresponding to [type], with fresh nullability
   /// nodes everywhere that don't correspond to any source location.  These
   /// nodes can later be unioned with other nodes.
@@ -194,6 +158,23 @@
         'DecoratedType.forImplicitType(${type.runtimeType})');
   }
 
+  /// Creates a [DecoratedType] for a synthetic type parameter, to be used
+  /// during comparison of generic function types.
+  DecoratedType._forTypeParameterSubstitution(
+      TypeParameterElementImpl parameter)
+      : type = TypeParameterTypeImpl(parameter),
+        node = null,
+        returnType = null,
+        positionalParameters = const [],
+        namedParameters = const {},
+        typeArguments = const [],
+        typeFormalBounds = const [] {
+    // We'll be storing the type parameter bounds in
+    // [_decoratedTypeParameterBounds] so the type parameter needs to have an
+    // enclosing element of `null`.
+    assert(parameter.enclosingElement == null);
+  }
+
   /// If `this` represents an interface type, returns the substitution necessary
   /// to produce this type using the class's type as a starting point.
   /// Otherwise throws an exception.
@@ -223,6 +204,84 @@
     }
   }
 
+  @override
+  bool operator ==(Object other) {
+    if (other is DecoratedType) {
+      if (!identical(this.node, other.node)) return false;
+      var thisType = this.type;
+      var otherType = other.type;
+      if (thisType is FunctionType && otherType is FunctionType) {
+        if (thisType.normalParameterTypes.length !=
+            otherType.normalParameterTypes.length) {
+          return false;
+        }
+        if (thisType.typeFormals.length != otherType.typeFormals.length) {
+          return false;
+        }
+        var thisReturnType = this.returnType;
+        var otherReturnType = other.returnType;
+        var thisPositionalParameters = this.positionalParameters;
+        var otherPositionalParameters = other.positionalParameters;
+        var thisNamedParameters = this.namedParameters;
+        var otherNamedParameters = other.namedParameters;
+        if (!_compareTypeFormalLists(
+            thisType.typeFormals, otherType.typeFormals)) {
+          // Create a fresh set of type variables and substitute so we can
+          // compare safely.
+          var thisSubstitution = <TypeParameterElement, DecoratedType>{};
+          var otherSubstitution = <TypeParameterElement, DecoratedType>{};
+          var newParameters = <TypeParameterElement>[];
+          for (int i = 0; i < thisType.typeFormals.length; i++) {
+            var newParameter = TypeParameterElementImpl.synthetic(
+                thisType.typeFormals[i].name);
+            newParameters.add(newParameter);
+            var newParameterType =
+                DecoratedType._forTypeParameterSubstitution(newParameter);
+            thisSubstitution[thisType.typeFormals[i]] = newParameterType;
+            otherSubstitution[otherType.typeFormals[i]] = newParameterType;
+          }
+          for (int i = 0; i < thisType.typeFormals.length; i++) {
+            var thisBound =
+                this.typeFormalBounds[i].substitute(thisSubstitution);
+            var otherBound =
+                other.typeFormalBounds[i].substitute(otherSubstitution);
+            if (thisBound != otherBound) return false;
+            recordTypeParameterBound(newParameters[i], thisBound);
+          }
+          // TODO(paulberry): need to substitute bounds and compare them.
+          thisReturnType = thisReturnType.substitute(thisSubstitution);
+          otherReturnType = otherReturnType.substitute(otherSubstitution);
+          thisPositionalParameters =
+              _substituteList(thisPositionalParameters, thisSubstitution);
+          otherPositionalParameters =
+              _substituteList(otherPositionalParameters, otherSubstitution);
+          thisNamedParameters =
+              _substituteMap(thisNamedParameters, thisSubstitution);
+          otherNamedParameters =
+              _substituteMap(otherNamedParameters, otherSubstitution);
+        }
+        if (thisReturnType != otherReturnType) return false;
+        if (!_compareLists(
+            thisPositionalParameters, otherPositionalParameters)) {
+          return false;
+        }
+        if (!_compareMaps(thisNamedParameters, otherNamedParameters)) {
+          return false;
+        }
+        return true;
+      } else if (thisType is InterfaceType && otherType is InterfaceType) {
+        if (thisType.element != otherType.element) return false;
+        if (!_compareLists(this.typeArguments, other.typeArguments)) {
+          return false;
+        }
+        return true;
+      } else {
+        return thisType == otherType;
+      }
+    }
+    return false;
+  }
+
   /// Converts one function type into another by substituting the given
   /// [argumentTypes] for the function's generic parameters.
   DecoratedType instantiate(List<DecoratedType> argumentTypes) {
@@ -364,6 +423,72 @@
             returnType._substitute(substitution, undecoratedResult.returnType),
         positionalParameters: newPositionalParameters);
   }
+
+  List<DecoratedType> _substituteList(List<DecoratedType> list,
+      Map<TypeParameterElement, DecoratedType> substitution) {
+    return list.map((t) => t.substitute(substitution)).toList();
+  }
+
+  Map<String, DecoratedType> _substituteMap(Map<String, DecoratedType> map,
+      Map<TypeParameterElement, DecoratedType> substitution) {
+    var result = <String, DecoratedType>{};
+    for (var entry in map.entries) {
+      result[entry.key] = entry.value.substitute(substitution);
+    }
+    return result;
+  }
+
+  /// Retrieves the decorated bound of the given [typeParameter].
+  ///
+  /// [typeParameter] must have an enclosing element of `null`.  Type parameters
+  /// whose enclosing element is not `null` are tracked by the [Variables]
+  /// class.
+  static DecoratedType decoratedTypeParameterBound(
+      TypeParameterElement typeParameter) {
+    assert(typeParameter.enclosingElement == null);
+    return _decoratedTypeParameterBounds[typeParameter];
+  }
+
+  /// Stores he decorated bound of the given [typeParameter].
+  ///
+  /// [typeParameter] must have an enclosing element of `null`.  Type parameters
+  /// whose enclosing element is not `null` are tracked by the [Variables]
+  /// class.
+  static void recordTypeParameterBound(
+      TypeParameterElement typeParameter, DecoratedType bound) {
+    assert(typeParameter.enclosingElement == null);
+    _decoratedTypeParameterBounds[typeParameter] = bound;
+  }
+
+  static bool _compareLists(
+      List<DecoratedType> list1, List<DecoratedType> list2) {
+    if (identical(list1, list2)) return true;
+    if (list1.length != list2.length) return false;
+    for (int i = 0; i < list1.length; i++) {
+      if (list1[i] != list2[i]) return false;
+    }
+    return true;
+  }
+
+  static bool _compareMaps(
+      Map<String, DecoratedType> map1, Map<String, DecoratedType> map2) {
+    if (identical(map1, map2)) return true;
+    if (map1.length != map2.length) return false;
+    for (var entry in map1.entries) {
+      if (entry.value != map2[entry.key]) return false;
+    }
+    return true;
+  }
+
+  static bool _compareTypeFormalLists(List<TypeParameterElement> formals1,
+      List<TypeParameterElement> formals2) {
+    if (identical(formals1, formals2)) return true;
+    if (formals1.length != formals2.length) return false;
+    for (int i = 0; i < formals1.length; i++) {
+      if (!identical(formals1[i], formals2[i])) return false;
+    }
+    return true;
+  }
 }
 
 /// A [DecoratedType] based on a type annotation appearing explicitly in the
diff --git a/pkg/nnbd_migration/lib/src/decorated_type_operations.dart b/pkg/nnbd_migration/lib/src/decorated_type_operations.dart
index d39bcbf..088cc91 100644
--- a/pkg/nnbd_migration/lib/src/decorated_type_operations.dart
+++ b/pkg/nnbd_migration/lib/src/decorated_type_operations.dart
@@ -7,14 +7,17 @@
 import 'package:front_end/src/fasta/flow_analysis/flow_analysis.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';
 
 /// [TypeOperations] that works with [DecoratedType]s.
 class DecoratedTypeOperations
     implements TypeOperations<VariableElement, DecoratedType> {
   final TypeSystem _typeSystem;
   final VariableRepository _variableRepository;
+  final NullabilityGraph _graph;
 
-  DecoratedTypeOperations(this._typeSystem, this._variableRepository);
+  DecoratedTypeOperations(
+      this._typeSystem, this._variableRepository, this._graph);
 
   @override
   bool isLocalVariable(VariableElement element) {
@@ -23,7 +26,7 @@
 
   @override
   bool isSameType(DecoratedType type1, DecoratedType type2) {
-    throw new UnimplementedError('TODO(paulberry)');
+    return type1 == type2;
   }
 
   @override
@@ -33,7 +36,7 @@
 
   @override
   DecoratedType promoteToNonNull(DecoratedType type) {
-    throw new UnimplementedError('TODO(paulberry)');
+    return type.withNode(_graph.never);
   }
 
   @override
diff --git a/pkg/nnbd_migration/lib/src/edge_builder.dart b/pkg/nnbd_migration/lib/src/edge_builder.dart
index 6b58890..2748382 100644
--- a/pkg/nnbd_migration/lib/src/edge_builder.dart
+++ b/pkg/nnbd_migration/lib/src/edge_builder.dart
@@ -7,13 +7,14 @@
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/element/handle.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
 import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:front_end/src/fasta/flow_analysis/flow_analysis.dart';
 import 'package:meta/meta.dart';
 import 'package:nnbd_migration/nnbd_migration.dart';
 import 'package:nnbd_migration/src/conditional_discard.dart';
@@ -23,8 +24,12 @@
 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/utilities/annotation_tracker.dart';
+import 'package:nnbd_migration/src/utilities/permissive_mode.dart';
 import 'package:nnbd_migration/src/utilities/scoped_set.dart';
 
+import 'decorated_type_operations.dart';
+
 /// Test class mixing in _AssignmentChecker, to allow [checkAssignment] to be
 /// more easily unit tested.
 @visibleForTesting
@@ -74,7 +79,10 @@
 /// variables that will determine its nullability.  For `visit...` methods that
 /// don't visit expressions, `null` will be returned.
 class EdgeBuilder extends GeneralizingAstVisitor<DecoratedType>
-    with _AssignmentChecker {
+    with
+        _AssignmentChecker,
+        PermissiveModeVisitor<DecoratedType>,
+        AnnotationTracker<DecoratedType> {
   final TypeSystem _typeSystem;
 
   final InheritanceManager3 _inheritanceManager;
@@ -93,6 +101,15 @@
   @override
   final DecoratedClassHierarchy _decoratedClassHierarchy;
 
+  /// If we are visiting a function body or initializer, instance of flow
+  /// analysis.  Otherwise `null`.
+  FlowAnalysis<Statement, Expression, VariableElement, DecoratedType>
+      _flowAnalysis;
+
+  /// If we are visiting a function body or initializer, assigned variable
+  /// information  used in flow analysis.  Otherwise `null`.
+  AssignedVariables<Statement, VariableElement> _assignedVariables;
+
   /// For convenience, a [DecoratedType] representing non-nullable `Object`.
   final DecoratedType _notNullType;
 
@@ -112,6 +129,13 @@
   /// return statements.
   DecoratedType _currentFunctionType;
 
+  /// The [DecoratedType] of the innermost list or set literal being visited, or
+  /// `null` if the visitor is not inside any function or method.
+  ///
+  /// This is needed to construct the appropriate nullability constraints for
+  /// ui as code list elements.
+  DecoratedType _currentLiteralType;
+
   /// Information about the most recently visited binary expression whose
   /// boolean value could possibly affect nullability analysis.
   _ConditionInfo _conditionInfo;
@@ -125,14 +149,20 @@
   final _guards = <NullabilityNode>[];
 
   /// The scope of locals (parameters, variables) that are post-dominated by the
-  /// current node as we walk the AST. We use a [ScopedSet] so that outer
+  /// current node as we walk the AST. We use a [_ScopedLocalSet] so that outer
   /// scopes may track their post-dominators separately from inner scopes.
   ///
   /// Note that this is not guaranteed to be complete. It is used to make hard
   /// edges on a best-effort basis.
   final _postDominatedLocals = _ScopedLocalSet();
 
-  NullabilityNode _lastConditionalNode;
+  /// Map whose keys are expressions of the form `a?.b` on the LHS of
+  /// assignments, and whose values are the nullability nodes corresponding to
+  /// the expression preceding `?.`.  These are needed in order to properly
+  /// analyze expressions like `a?.b += c`, since the type of the compound
+  /// assignment is nullable if the type of the expression preceding `?.` is
+  /// nullable.
+  final Map<Expression, NullabilityNode> _conditionalNodes = {};
 
   EdgeBuilder(TypeProvider typeProvider, this._typeSystem, this._variables,
       this._graph, this._source, this.listener)
@@ -211,7 +241,7 @@
 
   @override
   DecoratedType visitAssertStatement(AssertStatement node) {
-    _handleAssignment(node.condition, _notNullType);
+    _checkExpressionNotNull(node.condition);
     if (identical(_conditionInfo?.condition, node.condition)) {
       var intentNode = _conditionInfo.trueDemonstratesNonNullIntent;
       if (intentNode != null && _conditionInfo.postDominatingIntent) {
@@ -231,11 +261,10 @@
       _unimplemented(node, 'Assignment with operator ${node.operator.lexeme}');
     }
     _postDominatedLocals.removeReferenceFromAllScopes(node.leftHandSide);
-    var leftType = node.leftHandSide.accept(this);
-    var conditionalNode = _lastConditionalNode;
-    _lastConditionalNode = null;
-    var expressionType = _handleAssignment(node.rightHandSide, leftType);
-    if (_isConditionalExpression(node.leftHandSide)) {
+    var expressionType = _handleAssignment(node.rightHandSide,
+        destinationExpression: node.leftHandSide);
+    var conditionalNode = _conditionalNodes[node.leftHandSide];
+    if (conditionalNode != null) {
       expressionType = expressionType.withNode(
           NullabilityNode.forLUB(conditionalNode, expressionType.node));
       _variables.recordDecoratedExpressionType(node, expressionType);
@@ -262,26 +291,36 @@
       var leftType = node.leftOperand.accept(this);
       node.rightOperand.accept(this);
       if (node.rightOperand is NullLiteral) {
-        // TODO(paulberry): figure out what the rules for isPure should be.
         // TODO(paulberry): only set falseChecksNonNull in unconditional
         // control flow
-        bool isPure = node.leftOperand is SimpleIdentifier;
+        bool notEqual = operatorType == TokenType.BANG_EQ;
+        bool isPure = false;
+        var leftOperand = node.leftOperand;
+        if (leftOperand is SimpleIdentifier) {
+          // TODO(paulberry): figure out what the rules for isPure should be.
+          isPure = true;
+          var element = leftOperand.staticElement;
+          if (element is VariableElement) {
+            _flowAnalysis.conditionEqNull(node, element, notEqual: notEqual);
+          }
+        }
         var conditionInfo = _ConditionInfo(node,
             isPure: isPure,
             postDominatingIntent:
                 _postDominatedLocals.isReferenceInScope(node.leftOperand),
             trueGuard: leftType.node,
             falseDemonstratesNonNullIntent: leftType.node);
-        _conditionInfo = operatorType == TokenType.EQ_EQ
-            ? conditionInfo
-            : conditionInfo.not(node);
+        _conditionInfo = notEqual ? conditionInfo.not(node) : conditionInfo;
       }
       return _nonNullableBoolType;
     } else if (operatorType == TokenType.AMPERSAND_AMPERSAND ||
         operatorType == TokenType.BAR_BAR) {
-      _handleAssignment(node.leftOperand, _notNullType);
+      bool isAnd = operatorType == TokenType.AMPERSAND_AMPERSAND;
+      _checkExpressionNotNull(node.leftOperand);
+      _flowAnalysis.logicalBinaryOp_rightBegin(node.leftOperand, isAnd: isAnd);
       _postDominatedLocals.doScoped(
-          action: () => _handleAssignment(node.rightOperand, _notNullType));
+          action: () => _checkExpressionNotNull(node.rightOperand));
+      _flowAnalysis.logicalBinaryOp_end(node, node.rightOperand, isAnd: isAnd);
       return _nonNullableBoolType;
     } else if (operatorType == TokenType.QUESTION_QUESTION) {
       DecoratedType expressionType;
@@ -299,7 +338,7 @@
       _variables.recordDecoratedExpressionType(node, expressionType);
       return expressionType;
     } else if (operatorType.isUserDefinableOperator) {
-      _handleAssignment(node.leftOperand, _notNullType);
+      _checkExpressionNotNull(node.leftOperand);
       var callee = node.staticElement;
       assert(!(callee is ClassMemberElement &&
           (callee.enclosingElement as ClassElement)
@@ -309,7 +348,8 @@
       var calleeType = getOrComputeElementType(callee);
       // TODO(paulberry): substitute if necessary
       assert(calleeType.positionalParameters.length > 0); // TODO(paulberry)
-      _handleAssignment(node.rightOperand, calleeType.positionalParameters[0]);
+      _handleAssignment(node.rightOperand,
+          destinationType: calleeType.positionalParameters[0]);
       return _fixNumericTypes(calleeType.returnType, node.staticType);
     } else {
       // TODO(paulberry)
@@ -322,11 +362,14 @@
 
   @override
   DecoratedType visitBooleanLiteral(BooleanLiteral node) {
+    _flowAnalysis.booleanLiteral(node, node.value);
     return DecoratedType(node.staticType, _graph.never);
   }
 
   @override
   DecoratedType visitBreakStatement(BreakStatement node) {
+    _flowAnalysis.handleBreak(FlowAnalysisHelper.getLabelTarget(
+        node, node.label?.staticElement as LabelElement));
     // Later statements no longer post-dominate the declarations because we
     // exited (or, in parent scopes, conditionally exited).
     // TODO(mfairhurst): don't clear post-dominators beyond the current loop.
@@ -343,6 +386,22 @@
   }
 
   @override
+  DecoratedType visitCatchClause(CatchClause node) {
+    node.exceptionType?.accept(this);
+    for (var identifier in [
+      node.exceptionParameter,
+      node.stackTraceParameter
+    ]) {
+      if (identifier != null) {
+        _flowAnalysis.add(identifier.staticElement as VariableElement,
+            assigned: true);
+      }
+    }
+    node.body.accept(this);
+    return null;
+  }
+
+  @override
   DecoratedType visitClassDeclaration(ClassDeclaration node) {
     node.members.accept(this);
     return null;
@@ -382,7 +441,7 @@
 
   @override
   DecoratedType visitConditionalExpression(ConditionalExpression node) {
-    _handleAssignment(node.condition, _notNullType);
+    _checkExpressionNotNull(node.condition);
 
     DecoratedType thenType;
     DecoratedType elseType;
@@ -393,8 +452,11 @@
     // Note: we don't have to create a scope for each branch because they can't
     // define variables.
     _postDominatedLocals.doScoped(action: () {
+      _flowAnalysis.conditional_thenBegin(node.condition);
       thenType = node.thenExpression.accept(this);
+      _flowAnalysis.conditional_elseBegin(node.thenExpression);
       elseType = node.elseExpression.accept(this);
+      _flowAnalysis.conditional_end(node, node.elseExpression);
     });
 
     var overallType = _decorateUpperOrLowerBound(
@@ -420,13 +482,15 @@
   @override
   DecoratedType visitConstructorFieldInitializer(
       ConstructorFieldInitializer node) {
-    _handleAssignment(
-        node.expression, getOrComputeElementType(node.fieldName.staticElement));
+    _handleAssignment(node.expression,
+        destinationType: getOrComputeElementType(node.fieldName.staticElement));
     return null;
   }
 
   @override
   DecoratedType visitContinueStatement(ContinueStatement node) {
+    _flowAnalysis.handleContinue(FlowAnalysisHelper.getLabelTarget(
+        node, node.label?.staticElement as LabelElement));
     // Later statements no longer post-dominate the declarations because we
     // exited (or, in parent scopes, conditionally exited).
     // TODO(mfairhurst): don't clear post-dominators beyond the current loop.
@@ -450,8 +514,8 @@
             OptionalFormalParameterOrigin(_source, node.offset));
       }
     } else {
-      _handleAssignment(
-          defaultValue, getOrComputeElementType(node.declaredElement),
+      _handleAssignment(defaultValue,
+          destinationType: getOrComputeElementType(node.declaredElement),
           canInsertChecks: false);
     }
     return null;
@@ -459,8 +523,11 @@
 
   @override
   DecoratedType visitDoStatement(DoStatement node) {
+    _flowAnalysis.doStatement_bodyBegin(node, _assignedVariables[node]);
     node.body.accept(this);
-    _handleAssignment(node.condition, _notNullType);
+    _flowAnalysis.doStatement_conditionBegin();
+    _checkExpressionNotNull(node.condition);
+    _flowAnalysis.doStatement_end(node.condition);
     return null;
   }
 
@@ -477,7 +544,22 @@
           'ExpressionFunctionBody with no current function '
           '(parent is ${node.parent.runtimeType})');
     }
-    _handleAssignment(node.expression, _currentFunctionType.returnType);
+    _handleAssignment(node.expression,
+        destinationType: _currentFunctionType.returnType);
+    return null;
+  }
+
+  @override
+  DecoratedType visitFieldDeclaration(FieldDeclaration node) {
+    node.metadata.accept(this);
+    _createFlowAnalysis(node);
+    try {
+      node.fields.accept(this);
+    } finally {
+      _flowAnalysis.finish();
+      _flowAnalysis = null;
+      _assignedVariables = null;
+    }
     return null;
   }
 
@@ -497,64 +579,52 @@
   }
 
   @override
+  DecoratedType visitForElement(ForElement node) {
+    _handleForLoopParts(node.forLoopParts, node.body);
+    return null;
+  }
+
+  @override
   DecoratedType visitForStatement(ForStatement node) {
-    // TODO do special condition handling
-    // TODO do create true/false guards?
-    // Create a scope of for new initializers etc, which includes previous
-    // post-dominators.
-    _postDominatedLocals.doScoped(
-        copyCurrent: true,
-        action: () {
-          final parts = node.forLoopParts;
-          if (parts is ForParts) {
-            if (parts is ForPartsWithDeclarations) {
-              parts.variables.accept(this);
-            }
-            if (parts is ForPartsWithExpression) {
-              parts.initialization.accept(this);
-            }
-            parts.condition.accept(this);
-          }
-          if (parts is ForEachParts) {
-            parts.iterable.accept(this);
-          }
-
-          // The condition may fail/iterable may be empty, so the body does not
-          // post-dominate the parts, or the outer scope.
-          _postDominatedLocals.popScope();
-          _postDominatedLocals.pushScope();
-
-          if (parts is ForParts) {
-            parts.updaters.accept(this);
-          }
-
-          node.body.accept(this);
-        });
+    _handleForLoopParts(node.forLoopParts, node.body);
     return null;
   }
 
   @override
   DecoratedType visitFunctionDeclaration(FunctionDeclaration node) {
-    node.functionExpression.parameters?.accept(this);
-    assert(_currentFunctionType == null);
-    _currentFunctionType =
-        _variables.decoratedElementType(node.declaredElement);
-    // Initialize a new postDominator scope that contains only the parameters.
-    try {
-      _postDominatedLocals.doScoped(
-          elements: node.functionExpression.declaredElement.parameters,
-          action: () => node.functionExpression.body.accept(this));
-    } finally {
-      _currentFunctionType = null;
+    if (_flowAnalysis != null) {
+      // This is a local function.
+      node.functionExpression.accept(this);
+    } else {
+      _createFlowAnalysis(node.functionExpression.body);
+      // Initialize a new postDominator scope that contains only the parameters.
+      try {
+        node.functionExpression.accept(this);
+      } finally {
+        _flowAnalysis.finish();
+        _flowAnalysis = null;
+        _assignedVariables = null;
+      }
     }
     return null;
   }
 
   @override
   DecoratedType visitFunctionExpression(FunctionExpression node) {
-    // TODO(brianwilkerson)
     // TODO(mfairhurst): enable edge builder "_insideFunction" hard edge tests.
-    _unimplemented(node, 'FunctionExpression');
+    node.parameters?.accept(this);
+    _addParametersToFlowAnalysis(node.parameters);
+    var previousFunctionType = _currentFunctionType;
+    _currentFunctionType =
+        _variables.decoratedElementType(node.declaredElement);
+    try {
+      _postDominatedLocals.doScoped(
+          elements: node.declaredElement.parameters,
+          action: () => node.body.accept(this));
+      return _currentFunctionType;
+    } finally {
+      _currentFunctionType = previousFunctionType;
+    }
   }
 
   @override
@@ -566,10 +636,8 @@
   }
 
   @override
-  DecoratedType visitIfStatement(IfStatement node) {
-    // TODO(paulberry): should the use of a boolean in an if-statement be
-    // treated like an implicit `assert(b != null)`?  Probably.
-    _handleAssignment(node.condition, _notNullType);
+  DecoratedType visitIfElement(IfElement node) {
+    _checkExpressionNotNull(node.condition);
     NullabilityNode trueGuard;
     NullabilityNode falseGuard;
     if (identical(_conditionInfo?.condition, node.condition)) {
@@ -582,6 +650,45 @@
       _guards.add(trueGuard);
     }
     try {
+      _postDominatedLocals.doScoped(
+          action: () => _handleCollectionElement(node.thenElement));
+    } finally {
+      if (trueGuard != null) {
+        _guards.removeLast();
+      }
+    }
+    if (node.elseElement != null) {
+      if (falseGuard != null) {
+        _guards.add(falseGuard);
+      }
+      try {
+        _postDominatedLocals.doScoped(
+            action: () => _handleCollectionElement(node.elseElement));
+      } finally {
+        if (falseGuard != null) {
+          _guards.removeLast();
+        }
+      }
+    }
+    return null;
+  }
+
+  @override
+  DecoratedType visitIfStatement(IfStatement node) {
+    _checkExpressionNotNull(node.condition);
+    NullabilityNode trueGuard;
+    NullabilityNode falseGuard;
+    if (identical(_conditionInfo?.condition, node.condition)) {
+      trueGuard = _conditionInfo.trueGuard;
+      falseGuard = _conditionInfo.falseGuard;
+      _variables.recordConditionalDiscard(_source, node,
+          ConditionalDiscard(trueGuard, falseGuard, _conditionInfo.isPure));
+    }
+    if (trueGuard != null) {
+      _guards.add(trueGuard);
+    }
+    try {
+      _flowAnalysis.ifStatement_thenBegin(node.condition);
       // We branched, so create a new scope for post-dominators.
       _postDominatedLocals.doScoped(
           action: () => node.thenStatement.accept(this));
@@ -593,11 +700,16 @@
     if (falseGuard != null) {
       _guards.add(falseGuard);
     }
+    var elseStatement = node.elseStatement;
     try {
-      // We branched, so create a new scope for post-dominators.
-      _postDominatedLocals.doScoped(
-          action: () => node.elseStatement?.accept(this));
+      if (elseStatement != null) {
+        _flowAnalysis.ifStatement_elseBegin();
+        // We branched, so create a new scope for post-dominators.
+        _postDominatedLocals.doScoped(
+            action: () => node.elseStatement?.accept(this));
+      }
     } finally {
+      _flowAnalysis.ifStatement_end(elseStatement != null);
       if (falseGuard != null) {
         _guards.removeLast();
       }
@@ -610,7 +722,7 @@
     DecoratedType targetType;
     var target = node.realTarget;
     if (target != null) {
-      targetType = _handleAssignment(target, _notNullType);
+      targetType = _checkExpressionNotNull(target);
     }
     var callee = node.staticElement;
     if (callee == null) {
@@ -619,7 +731,8 @@
     }
     var calleeType = getOrComputeElementType(callee, targetType: targetType);
     // TODO(paulberry): substitute if necessary
-    _handleAssignment(node.index, calleeType.positionalParameters[0]);
+    _handleAssignment(node.index,
+        destinationType: calleeType.positionalParameters[0]);
     if (node.inSetterContext()) {
       return calleeType.positionalParameters[1];
     } else {
@@ -671,6 +784,13 @@
   }
 
   @override
+  DecoratedType visitLabel(Label node) {
+    // Labels are identifiers but they don't have types so we don't need to
+    // visit them directly.
+    return null;
+  }
+
+  @override
   DecoratedType visitLibraryDirective(LibraryDirective node) {
     // skip directives
     return null;
@@ -691,15 +811,12 @@
       if (typeArgumentType == null) {
         _unimplemented(node, 'Could not compute type argument type');
       }
-      for (var element in node.elements) {
-        if (element is Expression) {
-          _handleAssignment(element, typeArgumentType);
-        } else {
-          // Handle spread and control flow elements.
-          element.accept(this);
-          // TODO(brianwilkerson)
-          _unimplemented(node, 'Spread or control flow element');
-        }
+      final previousLiteralType = _currentLiteralType;
+      try {
+        _currentLiteralType = typeArgumentType;
+        node.elements.forEach(_handleCollectionElement);
+      } finally {
+        _currentLiteralType = previousLiteralType;
       }
       return DecoratedType(listType, _graph.never,
           typeArguments: [typeArgumentType]);
@@ -726,7 +843,7 @@
         targetType = target.accept(this);
       } else {
         _checkNonObjectMember(node.methodName.name); // TODO(paulberry)
-        targetType = _handleAssignment(target, _notNullType);
+        targetType = _checkExpressionNotNull(target);
       }
     }
     var callee = node.methodName.staticElement;
@@ -755,23 +872,6 @@
   }
 
   @override
-  DecoratedType visitNode(AstNode node) {
-    if (listener != null) {
-      try {
-        return super.visitNode(node);
-      } catch (exception, stackTrace) {
-        listener.addDetail('''
-$exception
-
-$stackTrace''');
-        return null;
-      }
-    } else {
-      return super.visitNode(node);
-    }
-  }
-
-  @override
   DecoratedType visitNullLiteral(NullLiteral node) {
     return _nullType;
   }
@@ -786,7 +886,7 @@
     var operatorType = node.operator.type;
     if (operatorType == TokenType.PLUS_PLUS ||
         operatorType == TokenType.MINUS_MINUS) {
-      _handleAssignment(node.operand, _notNullType);
+      _checkExpressionNotNull(node.operand);
       var callee = node.staticElement;
       if (callee is ClassMemberElement &&
           (callee.enclosingElement as ClassElement).typeParameters.isNotEmpty) {
@@ -818,7 +918,7 @@
 
   @override
   DecoratedType visitPrefixExpression(PrefixExpression node) {
-    var targetType = _handleAssignment(node.operand, _notNullType);
+    var targetType = _checkExpressionNotNull(node.operand);
     var operatorType = node.operator.type;
     if (operatorType == TokenType.BANG) {
       return _nonNullableBoolType;
@@ -870,18 +970,16 @@
             returnType.type.isDartAsyncFutureOr) &&
         node.thisOrAncestorOfType<FunctionBody>().isAsynchronous &&
         !returnValue.staticType.isDartAsyncFuture) {
-      returnType = returnType.typeArguments?.first;
-      if (returnType == null) {
-        return null;
-      }
+      returnType = returnType.typeArguments.first;
     }
     if (returnValue == null) {
       _checkAssignment(null,
           source: _nullType, destination: returnType, hard: false);
     } else {
-      _handleAssignment(returnValue, returnType);
+      _handleAssignment(returnValue, destinationType: returnType);
     }
 
+    _flowAnalysis.handleExit();
     // Later statements no longer post-dominate the declarations because we
     // exited (or, in parent scopes, conditionally exited).
     // TODO(mfairhurst): don't clear post-dominators beyond the current function.
@@ -905,7 +1003,7 @@
           _variables.decoratedTypeAnnotation(_source, typeArguments[0]);
       for (var element in node.elements) {
         if (element is Expression) {
-          _handleAssignment(element, elementType);
+          _handleAssignment(element, destinationType: elementType);
         } else {
           // Handle spread and control flow elements.
           element.accept(this);
@@ -922,8 +1020,8 @@
           _variables.decoratedTypeAnnotation(_source, typeArguments[1]);
       for (var element in node.elements) {
         if (element is MapLiteralEntry) {
-          _handleAssignment(element.key, keyType);
-          _handleAssignment(element.value, valueType);
+          _handleAssignment(element.key, destinationType: keyType);
+          _handleAssignment(element.value, destinationType: valueType);
         } else {
           // Handle spread and control flow elements.
           element.accept(this);
@@ -943,9 +1041,13 @@
   @override
   DecoratedType visitSimpleIdentifier(SimpleIdentifier node) {
     var staticElement = node.staticElement;
-    if (staticElement is ParameterElement ||
-        staticElement is LocalVariableElement ||
-        staticElement is FunctionElement ||
+    if (staticElement is VariableElement) {
+      if (!node.inDeclarationContext()) {
+        var promotedType = _flowAnalysis.promotedType(staticElement);
+        if (promotedType != null) return promotedType;
+      }
+      return getOrComputeElementType(staticElement);
+    } else if (staticElement is FunctionElement ||
         staticElement is MethodElement) {
       return getOrComputeElementType(staticElement);
     } else if (staticElement is PropertyAccessorElement) {
@@ -991,6 +1093,21 @@
   }
 
   @override
+  DecoratedType visitTopLevelVariableDeclaration(
+      TopLevelVariableDeclaration node) {
+    node.metadata.accept(this);
+    _createFlowAnalysis(node);
+    try {
+      node.variables.accept(this);
+    } finally {
+      _flowAnalysis.finish();
+      _flowAnalysis = null;
+      _assignedVariables = null;
+    }
+    return null;
+  }
+
+  @override
   DecoratedType visitTypeName(TypeName typeName) {
     var typeArguments = typeName.typeArguments?.arguments;
     var element = typeName.name.staticElement;
@@ -1006,13 +1123,15 @@
         for (int i = 0; i < instantiatedType.typeArguments.length; i++) {
           _unionDecoratedTypes(
               instantiatedType.typeArguments[i],
-              _variables.decoratedElementType(element.typeParameters[i]),
+              _variables.decoratedTypeParameterBound(element.typeParameters[i]),
               origin);
         }
       } else {
         for (int i = 0; i < typeArguments.length; i++) {
           DecoratedType bound;
-          bound = _variables.decoratedElementType(element.typeParameters[i]);
+          bound =
+              _variables.decoratedTypeParameterBound(element.typeParameters[i]);
+          assert(bound != null);
           var argumentType =
               _variables.decoratedTypeAnnotation(_source, typeArguments[i]);
           if (argumentType == null) {
@@ -1034,6 +1153,8 @@
     for (var variable in node.variables) {
       variable.metadata.accept(this);
       var initializer = variable.initializer;
+      _flowAnalysis.add(variable.declaredElement,
+          assigned: initializer != null);
       if (initializer != null) {
         var destinationType = getOrComputeElementType(variable.declaredElement);
         if (typeAnnotation == null) {
@@ -1045,24 +1166,57 @@
           _unionDecoratedTypes(initializerType, destinationType,
               InitializerInferenceOrigin(_source, variable.name.offset));
         } else {
-          _handleAssignment(initializer, destinationType);
+          _handleAssignment(initializer, destinationType: destinationType);
         }
       }
     }
-    _postDominatedLocals
-        .addAll(node.variables.map((variable) => variable.declaredElement));
+
+    // Track post-dominators, except we cannot make hard edges to multi
+    // declarations. Consider:
+    //
+    // int? x = null, y = 0;
+    // y.toDouble();
+    //
+    // We cannot make a hard edge from y to never in this case.
+    if (node.variables.length == 1) {
+      _postDominatedLocals.add(node.variables.single.declaredElement);
+    }
+
     return null;
   }
 
   @override
   DecoratedType visitWhileStatement(WhileStatement node) {
-    // TODO do special condition handling
-    // TODO do create true/false guards?
-    _handleAssignment(node.condition, _notNullType);
+    // Note: we do not create guards. A null check here is *very* unlikely to be
+    // unnecessary after analysis.
+    _flowAnalysis.whileStatement_conditionBegin(_assignedVariables[node]);
+    _checkExpressionNotNull(node.condition);
+    _flowAnalysis.whileStatement_bodyBegin(node, node.condition);
     _postDominatedLocals.doScoped(action: () => node.body.accept(this));
+    _flowAnalysis.whileStatement_end();
     return null;
   }
 
+  void _addParametersToFlowAnalysis(FormalParameterList parameters) {
+    if (parameters != null) {
+      for (var parameter in parameters.parameters) {
+        _flowAnalysis.add(parameter.declaredElement, assigned: true);
+      }
+    }
+  }
+
+  /// Visits [expression] and generates the appropriate edge to assert that its
+  /// value is non-null.
+  ///
+  /// Returns the decorated type of [expression].
+  DecoratedType _checkExpressionNotNull(Expression expression) {
+    // Note: it's not necessary for `destinationType` to precisely match the
+    // type of the expression, since all we are doing is causing a single graph
+    // edge to be built; it is sufficient to pass in any decorated type whose
+    // node is `never`.
+    return _handleAssignment(expression, destinationType: _notNullType);
+  }
+
   /// Double checks that [name] is not the name of a method or getter declared
   /// on [Object].
   ///
@@ -1086,6 +1240,17 @@
     }
   }
 
+  void _createFlowAnalysis(AstNode node) {
+    assert(_flowAnalysis == null);
+    assert(_assignedVariables == null);
+    _flowAnalysis =
+        FlowAnalysis<Statement, Expression, VariableElement, DecoratedType>(
+            const AnalyzerNodeOperations(),
+            DecoratedTypeOperations(_typeSystem, _variables, _graph),
+            AnalyzerFunctionBodyAccess(node is FunctionBody ? node : null));
+    _assignedVariables = FlowAnalysisHelper.computeAssignedVariables(node);
+  }
+
   DecoratedType _decorateUpperOrLowerBound(AstNode astNode, DartType type,
       DecoratedType left, DecoratedType right, bool isLUB,
       {NullabilityNode node}) {
@@ -1189,14 +1354,38 @@
     // TODO(paulberry): once we've wired up flow analysis, return promoted
     // bounds if applicable.
     return _variables
-        .decoratedElementType((type.type as TypeParameterType).element);
+        .decoratedTypeParameterBound((type.type as TypeParameterType).element);
   }
 
   /// Creates the necessary constraint(s) for an assignment of the given
   /// [expression] to a destination whose type is [destinationType].
-  DecoratedType _handleAssignment(
-      Expression expression, DecoratedType destinationType,
-      {bool canInsertChecks = true}) {
+  ///
+  /// Optionally, the caller may supply a [destinationExpression] instead of
+  /// [destinationType].  In this case, then the type comes from visiting the
+  /// destination expression.  If the destination expression refers to a local
+  /// variable, we mark it as assigned in flow analysis at the proper time.
+  DecoratedType _handleAssignment(Expression expression,
+      {DecoratedType destinationType,
+      Expression destinationExpression,
+      bool canInsertChecks = true}) {
+    assert(
+        (destinationExpression == null) != (destinationType == null),
+        'Either destinationExpression or destinationType should be supplied, '
+        'but not both');
+    VariableElement destinationLocalVariable;
+    if (destinationType == null) {
+      if (destinationExpression is SimpleIdentifier) {
+        var element = destinationExpression.staticElement;
+        if (element is VariableElement) {
+          destinationLocalVariable = element;
+        }
+      }
+      if (destinationLocalVariable != null) {
+        destinationType = getOrComputeElementType(destinationLocalVariable);
+      } else {
+        destinationType = destinationExpression.accept(this);
+      }
+    }
     var sourceType = expression.accept(this);
     if (sourceType == null) {
       throw StateError('No type computed for ${expression.runtimeType} '
@@ -1211,9 +1400,21 @@
         source: sourceType,
         destination: destinationType,
         hard: _postDominatedLocals.isReferenceInScope(expression));
+    if (destinationLocalVariable != null) {
+      _flowAnalysis.write(destinationLocalVariable);
+    }
     return sourceType;
   }
 
+  DecoratedType _handleCollectionElement(CollectionElement element) {
+    if (element is Expression) {
+      assert(_currentLiteralType != null);
+      return _handleAssignment(element, destinationType: _currentLiteralType);
+    } else {
+      return element.accept(this);
+    }
+  }
+
   void _handleConstructorRedirection(
       FormalParameterList parameters, ConstructorName redirectedConstructor) {
     var callee = redirectedConstructor.staticElement;
@@ -1244,6 +1445,8 @@
     returnType?.accept(this);
     parameters?.accept(this);
     _currentFunctionType = _variables.decoratedElementType(declaredElement);
+    _createFlowAnalysis(body);
+    _addParametersToFlowAnalysis(parameters);
     // Push a scope of post-dominated declarations on the stack.
     _postDominatedLocals.pushScope(elements: declaredElement.parameters);
     try {
@@ -1328,11 +1531,42 @@
         }
       }
     } finally {
+      _flowAnalysis.finish();
+      _flowAnalysis = null;
+      _assignedVariables = null;
       _currentFunctionType = null;
       _postDominatedLocals.popScope();
     }
   }
 
+  void _handleForLoopParts(ForLoopParts parts, AstNode body) {
+    if (parts is ForParts) {
+      if (parts is ForPartsWithDeclarations) {
+        parts.variables?.accept(this);
+      } else if (parts is ForPartsWithExpression) {
+        parts.initialization?.accept(this);
+      }
+      if (parts.condition != null) {
+        _checkExpressionNotNull(parts.condition);
+      }
+    } else if (parts is ForEachParts) {
+      if (parts is ForEachPartsWithDeclaration) {
+        _flowAnalysis.add(parts.loopVariable.declaredElement, assigned: true);
+      }
+      _checkExpressionNotNull(parts.iterable);
+    }
+
+    // The condition may fail/iterable may be empty, so the body gets a new
+    // post-dominator scope.
+    _postDominatedLocals.doScoped(action: () {
+      body.accept(this);
+
+      if (parts is ForParts) {
+        parts.updaters.accept(this);
+      }
+    });
+  }
+
   /// Creates the necessary constraint(s) for an [argumentList] when invoking an
   /// executable element whose type is [calleeType].
   ///
@@ -1392,7 +1626,7 @@
         }
         parameterType = calleeType.positionalParameters[i++];
       }
-      _handleAssignment(expression, parameterType);
+      _handleAssignment(expression, destinationType: parameterType);
     }
     // Any parameters not supplied must be optional.
     for (var entry in calleeType.namedParameters.entries) {
@@ -1411,7 +1645,7 @@
       targetType = target.accept(this);
     } else {
       _checkNonObjectMember(propertyName.name); // TODO(paulberry)
-      targetType = _handleAssignment(target, _notNullType);
+      targetType = _checkExpressionNotNull(target);
     }
     var callee = propertyName.staticElement;
     if (callee == null) {
@@ -1422,7 +1656,7 @@
     // TODO(paulberry): substitute if necessary
     if (propertyName.inSetterContext()) {
       if (isConditional) {
-        _lastConditionalNode = targetType.node;
+        _conditionalNodes[node] = targetType.node;
       }
       return calleeType.positionalParameters[0];
     } else {
@@ -1469,7 +1703,6 @@
     } else {
       return false;
     }
-    return false;
   }
 
   NullabilityNode _nullabilityNodeForGLB(
diff --git a/pkg/nnbd_migration/lib/src/node_builder.dart b/pkg/nnbd_migration/lib/src/node_builder.dart
index 306ac47..7bcf440 100644
--- a/pkg/nnbd_migration/lib/src/node_builder.dart
+++ b/pkg/nnbd_migration/lib/src/node_builder.dart
@@ -17,6 +17,8 @@
 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/utilities/annotation_tracker.dart';
+import 'package:nnbd_migration/src/utilities/permissive_mode.dart';
 
 import 'edge_origin.dart';
 
@@ -26,7 +28,10 @@
 /// the static type of the element declared by the visited node, along with the
 /// constraint variables that will determine its nullability.  For `visit...`
 /// methods that don't visit declarations, `null` will be returned.
-class NodeBuilder extends GeneralizingAstVisitor<DecoratedType> {
+class NodeBuilder extends GeneralizingAstVisitor<DecoratedType>
+    with
+        PermissiveModeVisitor<DecoratedType>,
+        AnnotationTracker<DecoratedType> {
   /// Constraint variables and decorated types are stored here.
   final VariableRecorder _variables;
 
@@ -43,6 +48,11 @@
   /// seen so far.  Otherwise `null`.
   List<DecoratedType> _positionalParameters;
 
+  /// If the type parameters of a function or method are being visited, the
+  /// [DecoratedType]s of the bounds of the function's type formals that have
+  /// been seen so far.  Otherwise `null`.
+  List<DecoratedType> _typeFormalBounds;
+
   final NullabilityMigrationListener /*?*/ listener;
 
   final NullabilityGraph _graph;
@@ -129,11 +139,11 @@
         node.declaredElement,
         node.metadata,
         null,
+        null,
         node.parameters,
         node.initializers,
         node.body,
-        node.redirectedConstructor,
-        node);
+        node.redirectedConstructor);
     return null;
   }
 
@@ -180,11 +190,18 @@
         node.declaredElement,
         node.metadata,
         node.returnType,
+        node.functionExpression.typeParameters,
         node.functionExpression.parameters,
         null,
         node.functionExpression.body,
-        null,
-        node);
+        null);
+    return null;
+  }
+
+  @override
+  DecoratedType visitFunctionExpression(FunctionExpression node) {
+    _handleExecutableDeclaration(node.declaredElement, null, null,
+        node.typeParameters, node.parameters, null, node.body, null);
     return null;
   }
 
@@ -203,8 +220,15 @@
 
   @override
   DecoratedType visitMethodDeclaration(MethodDeclaration node) {
-    _handleExecutableDeclaration(node.declaredElement, node.metadata,
-        node.returnType, node.parameters, null, node.body, null, node);
+    _handleExecutableDeclaration(
+        node.declaredElement,
+        node.metadata,
+        node.returnType,
+        node.typeParameters,
+        node.parameters,
+        null,
+        node.body,
+        null);
     return null;
   }
 
@@ -220,23 +244,6 @@
   }
 
   @override
-  DecoratedType visitNode(AstNode node) {
-    if (listener != null) {
-      try {
-        return super.visitNode(node);
-      } catch (exception, stackTrace) {
-        listener.addDetail('''
-$exception
-
-$stackTrace''');
-        return null;
-      }
-    } else {
-      return super.visitNode(node);
-    }
-  }
-
-  @override
   DecoratedType visitSimpleFormalParameter(SimpleFormalParameter node) {
     return _handleFormalParameter(node, node.type, null, null);
   }
@@ -346,7 +353,8 @@
           AlwaysNullableTypeOrigin(_source, node.offset));
       decoratedBound = DecoratedType(_typeProvider.objectType, nullabilityNode);
     }
-    _variables.recordDecoratedElementType(element, decoratedBound);
+    _typeFormalBounds?.add(decoratedBound);
+    _variables.recordDecoratedTypeParameterBound(element, decoratedBound);
     return null;
   }
 
@@ -387,12 +395,12 @@
       ExecutableElement declaredElement,
       NodeList<Annotation> metadata,
       TypeAnnotation returnType,
+      TypeParameterList typeParameters,
       FormalParameterList parameters,
       NodeList<ConstructorInitializer> initializers,
       FunctionBody body,
-      ConstructorName redirectedConstructor,
-      AstNode enclosingNode) {
-    metadata.accept(this);
+      ConstructorName redirectedConstructor) {
+    metadata?.accept(this);
     var functionType = declaredElement.type;
     DecoratedType decoratedReturnType;
     if (returnType != null) {
@@ -409,14 +417,18 @@
     }
     var previousPositionalParameters = _positionalParameters;
     var previousNamedParameters = _namedParameters;
+    var previousTypeFormalBounds = _typeFormalBounds;
     _positionalParameters = [];
     _namedParameters = {};
+    _typeFormalBounds = [];
     DecoratedType decoratedFunctionType;
     try {
+      typeParameters?.accept(this);
       parameters?.accept(this);
       redirectedConstructor?.accept(this);
       initializers?.accept(this);
       decoratedFunctionType = DecoratedType(functionType, _graph.never,
+          typeFormalBounds: _typeFormalBounds,
           returnType: decoratedReturnType,
           positionalParameters: _positionalParameters,
           namedParameters: _namedParameters);
@@ -424,6 +436,7 @@
     } finally {
       _positionalParameters = previousPositionalParameters;
       _namedParameters = previousNamedParameters;
+      _typeFormalBounds = previousTypeFormalBounds;
     }
     _variables.recordDecoratedElementType(
         declaredElement, decoratedFunctionType);
@@ -548,6 +561,10 @@
       Source source, TypeAnnotation node, DecoratedTypeAnnotation type,
       {bool potentialModification: true});
 
+  /// Stores he decorated bound of the given [typeParameter].
+  void recordDecoratedTypeParameterBound(
+      TypeParameterElement typeParameter, DecoratedType bound);
+
   /// 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).
@@ -580,6 +597,9 @@
   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(
diff --git a/pkg/nnbd_migration/lib/src/nullability_node.dart b/pkg/nnbd_migration/lib/src/nullability_node.dart
index 81bd9e6..96ef894 100644
--- a/pkg/nnbd_migration/lib/src/nullability_node.dart
+++ b/pkg/nnbd_migration/lib/src/nullability_node.dart
@@ -410,15 +410,14 @@
   /// variable being eliminated by the substitution, and [innerNode] is the
   /// nullability node for the type being substituted in its place.
   ///
-  /// [innerNode] may be `null`.  TODO(paulberry): when?
-  ///
-  /// Additional constraints are recorded in [constraints] as necessary to make
-  /// the new nullability node behave consistently with the old nodes.
-  /// TODO(paulberry): this should become unnecessary once constraint solving is
-  /// performed directly using [NullabilityNode] objects.
+  /// If either [innerNode] or [outerNode] is `null`, then the other node is
+  /// returned.
   factory NullabilityNode.forSubstitution(
-          NullabilityNode innerNode, NullabilityNode outerNode) =
-      NullabilityNodeForSubstitution._;
+      NullabilityNode innerNode, NullabilityNode outerNode) {
+    if (innerNode == null) return outerNode;
+    if (outerNode == null) return innerNode;
+    return NullabilityNodeForSubstitution._(innerNode, outerNode);
+  }
 
   /// Creates a [NullabilityNode] representing the nullability of a type
   /// annotation appearing explicitly in the user's program.
diff --git a/pkg/nnbd_migration/lib/src/utilities/annotation_tracker.dart b/pkg/nnbd_migration/lib/src/utilities/annotation_tracker.dart
new file mode 100644
index 0000000..39d8fc9
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/utilities/annotation_tracker.dart
@@ -0,0 +1,62 @@
+// 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.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:nnbd_migration/src/utilities/permissive_mode.dart';
+
+/// Mixin that verifies (via assertion checks) that a visitor does not miss any
+/// annotations when processing a compilation unit.
+///
+/// Mixing in this class should have very low overhead when assertions are
+/// disabled.
+mixin AnnotationTracker<T> on AstVisitor<T>, PermissiveModeVisitor<T> {
+  static _AnnotationTracker _annotationTracker;
+
+  @override
+  T visitAnnotation(Annotation node) {
+    assert(() {
+      _annotationTracker._nodeVisited(node);
+      return true;
+    }());
+    return super.visitAnnotation(node);
+  }
+
+  @override
+  T visitCompilationUnit(CompilationUnit node) {
+    T result;
+    reportExceptionsIfPermissive(() {
+      _AnnotationTracker oldAnnotationTracker;
+      assert(() {
+        oldAnnotationTracker = _annotationTracker;
+        _annotationTracker = _AnnotationTracker();
+        node.accept(_annotationTracker);
+        return true;
+      }());
+      try {
+        result = super.visitCompilationUnit(node);
+        assert(_annotationTracker._nodes.isEmpty,
+            'Annotation nodes not visited: ${_annotationTracker._nodes}');
+      } finally {
+        _annotationTracker = oldAnnotationTracker;
+      }
+    });
+    return result;
+  }
+}
+
+class _AnnotationTracker extends RecursiveAstVisitor<void> {
+  final Set<Annotation> _nodes = {};
+
+  @override
+  void visitAnnotation(Annotation node) {
+    _nodes.add(node);
+  }
+
+  void _nodeVisited(Annotation node) {
+    if (!_nodes.remove(node)) {
+      throw StateError('Visited unexpected annotation $node');
+    }
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/utilities/permissive_mode.dart b/pkg/nnbd_migration/lib/src/utilities/permissive_mode.dart
new file mode 100644
index 0000000..3e22f97
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/utilities/permissive_mode.dart
@@ -0,0 +1,51 @@
+// 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.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:nnbd_migration/nnbd_migration.dart';
+
+/// Mixin that catches exceptions when visiting an AST recursively, and reports
+/// them to an optional listener.  This is used to implement the migration
+/// tool's "permissive mode".
+///
+/// If the [listener] is `null`, exceptions are not caught.
+mixin PermissiveModeVisitor<T> on GeneralizingAstVisitor<T> {
+  NullabilityMigrationListener /*?*/ get listener;
+
+  /// Executes [callback].  If [listener] is not `null`, and an exception
+  /// occurs, the exception is caught and reported to the [listener].
+  void reportExceptionsIfPermissive(void callback()) {
+    if (listener != null) {
+      try {
+        return callback();
+      } catch (exception, stackTrace) {
+        _reportException(exception, stackTrace);
+      }
+    } else {
+      callback();
+    }
+  }
+
+  @override
+  T visitNode(AstNode node) {
+    if (listener != null) {
+      try {
+        return super.visitNode(node);
+      } catch (exception, stackTrace) {
+        _reportException(exception, stackTrace);
+        return null;
+      }
+    } else {
+      return super.visitNode(node);
+    }
+  }
+
+  void _reportException(Object exception, StackTrace stackTrace) {
+    listener.addDetail('''
+$exception
+
+$stackTrace''');
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/utilities/scoped_set.dart b/pkg/nnbd_migration/lib/src/utilities/scoped_set.dart
index 972f590..1169def 100644
--- a/pkg/nnbd_migration/lib/src/utilities/scoped_set.dart
+++ b/pkg/nnbd_migration/lib/src/utilities/scoped_set.dart
@@ -2,8 +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:analyzer/dart/element/element.dart';
-
 /// Tracks scopes of instances to be used by the [EdgeBuilder] for certain
 /// analyses.
 ///
@@ -22,20 +20,13 @@
   /// Get the current scope. Private so as not to expose to clients.
   Set<T> get _currentScope => _scopeStack.last;
 
-  /// Add an element to the current scope (and not its parent scopes).
+  /// Add element to the current scope (and not its parent scopes).
   void add(T element) {
     if (_scopeStack.isNotEmpty) {
       _currentScope.add(element);
     }
   }
 
-  /// Add many elements to the current scope (and not its parent scopes).
-  void addAll(Iterable<T> elements) {
-    if (_scopeStack.isNotEmpty) {
-      _currentScope.addAll(elements);
-    }
-  }
-
   /// Clear each scope in the stack (the stack itself is not affected).
   ///
   /// This is useful in post-dominator analysis. Upon non-convergent branching,
diff --git a/pkg/nnbd_migration/lib/src/variables.dart b/pkg/nnbd_migration/lib/src/variables.dart
index ccb4aec..acd3a68 100644
--- a/pkg/nnbd_migration/lib/src/variables.dart
+++ b/pkg/nnbd_migration/lib/src/variables.dart
@@ -5,7 +5,9 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/handle.dart';
+import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:nnbd_migration/src/already_migrated_code_decorator.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';
@@ -18,6 +20,8 @@
 
   final _decoratedElementTypes = <Element, DecoratedType>{};
 
+  final _decoratedTypeParameterBounds = <Element, DecoratedType>{};
+
   final _decoratedDirectSupertypes =
       <ClassElement, Map<ClassElement, DecoratedType>>{};
 
@@ -26,7 +30,10 @@
 
   final _potentialModifications = <Source, List<PotentialModification>>{};
 
-  Variables(this._graph);
+  final AlreadyMigratedCodeDecorator _alreadyMigratedCodeDecorator;
+
+  Variables(this._graph)
+      : _alreadyMigratedCodeDecorator = AlreadyMigratedCodeDecorator(_graph);
 
   @override
   Map<ClassElement, DecoratedType> decoratedDirectSupertypes(
@@ -37,8 +44,12 @@
   }
 
   @override
-  DecoratedType decoratedElementType(Element element) =>
-      _decoratedElementTypes[element] ??= _createDecoratedElementType(element);
+  DecoratedType decoratedElementType(Element element) {
+    assert(element is! TypeParameterElement,
+        'Use decoratedTypeParameterBound instead');
+    return _decoratedElementTypes[element] ??=
+        _createDecoratedElementType(element);
+  }
 
   @override
   DecoratedType decoratedTypeAnnotation(
@@ -57,6 +68,35 @@
     return decoratedTypeAnnotation;
   }
 
+  @override
+  DecoratedType decoratedTypeParameterBound(
+      TypeParameterElement typeParameter) {
+    if (typeParameter.enclosingElement == null) {
+      var decoratedType =
+          DecoratedType.decoratedTypeParameterBound(typeParameter);
+      if (decoratedType == null) {
+        throw StateError(
+            'A decorated type for the bound of $typeParameter should '
+            'have been stored by the NodeBuilder via recordTypeParameterBound');
+      }
+      return decoratedType;
+    } else {
+      var decoratedType = _decoratedTypeParameterBounds[typeParameter];
+      if (decoratedType == null) {
+        if (_graph.isBeingMigrated(typeParameter.library.source)) {
+          throw StateError(
+              'A decorated type for the bound of $typeParameter should '
+              'have been stored by the NodeBuilder via '
+              'recordTypeParameterBound');
+        }
+        decoratedType = _alreadyMigratedCodeDecorator
+            .decorate(typeParameter.bound ?? DynamicTypeImpl.instance);
+        _decoratedTypeParameterBounds[typeParameter] = decoratedType;
+      }
+      return decoratedType;
+    }
+  }
+
   Map<Source, List<PotentialModification>> getPotentialModifications() =>
       _potentialModifications;
 
@@ -82,6 +122,8 @@
 
   void recordDecoratedElementType(Element element, DecoratedType type) {
     assert(() {
+      assert(element is! TypeParameterElement,
+          'Use recordDecoratedTypeParameterBound instead');
       var library = element.library;
       if (library == null) {
         // No problem; the element is probably a parameter of a function type
@@ -105,6 +147,16 @@
   }
 
   @override
+  void recordDecoratedTypeParameterBound(
+      TypeParameterElement typeParameter, DecoratedType bound) {
+    if (typeParameter.enclosingElement == null) {
+      DecoratedType.recordTypeParameterBound(typeParameter, bound);
+    } else {
+      _decoratedTypeParameterBounds[typeParameter] = bound;
+    }
+  }
+
+  @override
   void recordExpressionChecks(
       Source source, Expression expression, ExpressionChecks checks) {
     _addPotentialModification(source, checks);
@@ -169,12 +221,24 @@
     (_potentialModifications[source] ??= []).add(potentialModification);
   }
 
+  /// Creates a decorated type for the given [element], which should come from
+  /// an already-migrated library (or the SDK).
   DecoratedType _createDecoratedElementType(Element element) {
     if (_graph.isBeingMigrated(element.library.source)) {
       throw StateError('A decorated type for $element should have been stored '
           'by the NodeBuilder via recordDecoratedElementType');
     }
-    return DecoratedType.forElement(element, _graph);
+
+    DecoratedType decoratedType;
+    if (element is ExecutableElement) {
+      decoratedType = _alreadyMigratedCodeDecorator.decorate(element.type);
+    } else if (element is TopLevelVariableElement) {
+      decoratedType = _alreadyMigratedCodeDecorator.decorate(element.type);
+    } else {
+      // TODO(paulberry)
+      throw UnimplementedError('Decorating ${element.runtimeType}');
+    }
+    return decoratedType;
   }
 
   /// Creates an entry [_decoratedDirectSupertypes] for an already-migrated
diff --git a/pkg/nnbd_migration/test/already_migrated_code_decorator_test.dart b/pkg/nnbd_migration/test/already_migrated_code_decorator_test.dart
new file mode 100644
index 0000000..f55a4bd
--- /dev/null
+++ b/pkg/nnbd_migration/test/already_migrated_code_decorator_test.dart
@@ -0,0 +1,125 @@
+// 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.
+
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/testing/test_type_provider.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:nnbd_migration/src/already_migrated_code_decorator.dart';
+import 'package:nnbd_migration/src/decorated_type.dart';
+import 'package:nnbd_migration/src/nullability_node.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(_AlreadyMigratedCodeDecoratorTest);
+  });
+}
+
+@reflectiveTest
+class _AlreadyMigratedCodeDecoratorTest {
+  final TypeProvider typeProvider;
+
+  final AlreadyMigratedCodeDecorator decorator;
+
+  final NullabilityGraphForTesting graph;
+
+  factory _AlreadyMigratedCodeDecoratorTest() {
+    return _AlreadyMigratedCodeDecoratorTest._(NullabilityGraphForTesting());
+  }
+
+  _AlreadyMigratedCodeDecoratorTest._(this.graph)
+      : typeProvider = TestTypeProvider(),
+        decorator = AlreadyMigratedCodeDecorator(graph);
+
+  void checkDynamic(DecoratedType decoratedType) {
+    expect(decoratedType.type, same(typeProvider.dynamicType));
+    expect(decoratedType.node, same(graph.always));
+  }
+
+  void checkInt(DecoratedType decoratedType) {
+    expect(decoratedType.type, typeProvider.intType);
+    expect(decoratedType.node, same(graph.never));
+  }
+
+  void checkTypeParameter(
+      DecoratedType decoratedType, TypeParameterElementImpl expectedElement) {
+    var type = decoratedType.type as TypeParameterTypeImpl;
+    expect(type.element, same(expectedElement));
+    expect(decoratedType.node, same(graph.never));
+  }
+
+  void checkVoid(DecoratedType decoratedType) {
+    expect(decoratedType.type, same(typeProvider.voidType));
+    expect(decoratedType.node, same(graph.always));
+  }
+
+  DecoratedType decorate(DartType type) {
+    var decoratedType = decorator.decorate(type);
+    expect(decoratedType.type, same(type));
+    return decoratedType;
+  }
+
+  test_decorate_dynamic() {
+    checkDynamic(decorate(typeProvider.dynamicType));
+  }
+
+  test_decorate_functionType_named_parameter() {
+    checkDynamic(
+        decorate(FunctionTypeImpl.synthetic(typeProvider.voidType, [], [
+      ParameterElementImpl.synthetic(
+          'x', typeProvider.dynamicType, ParameterKind.NAMED)
+    ])).namedParameters['x']);
+  }
+
+  test_decorate_functionType_ordinary_parameter() {
+    checkDynamic(
+        decorate(FunctionTypeImpl.synthetic(typeProvider.voidType, [], [
+      ParameterElementImpl.synthetic(
+          'x', typeProvider.dynamicType, ParameterKind.REQUIRED)
+    ])).positionalParameters[0]);
+  }
+
+  test_decorate_functionType_positional_parameter() {
+    checkDynamic(
+        decorate(FunctionTypeImpl.synthetic(typeProvider.voidType, [], [
+      ParameterElementImpl.synthetic(
+          'x', typeProvider.dynamicType, ParameterKind.POSITIONAL)
+    ])).positionalParameters[0]);
+  }
+
+  test_decorate_functionType_returnType() {
+    checkDynamic(
+        decorate(FunctionTypeImpl.synthetic(typeProvider.dynamicType, [], []))
+            .returnType);
+  }
+
+  test_decorate_functionType_star() {
+    expect(
+        decorate(FunctionTypeImpl.synthetic(typeProvider.voidType, [], [],
+                nullabilitySuffix: NullabilitySuffix.star))
+            .node,
+        same(graph.never));
+  }
+
+  test_decorate_interfaceType_simple_star() {
+    checkInt(decorate(InterfaceTypeImpl(typeProvider.intType.element,
+        nullabilitySuffix: NullabilitySuffix.star)));
+  }
+
+  test_decorate_typeParameterType_star() {
+    var element = TypeParameterElementImpl.synthetic('T');
+    checkTypeParameter(
+        decorate(TypeParameterTypeImpl(element,
+            nullabilitySuffix: NullabilitySuffix.star)),
+        element);
+  }
+
+  test_decorate_void() {
+    checkVoid(decorate(typeProvider.voidType));
+  }
+}
diff --git a/pkg/nnbd_migration/test/api_test.dart b/pkg/nnbd_migration/test/api_test.dart
index 44d2eac..4035bae 100644
--- a/pkg/nnbd_migration/test/api_test.dart
+++ b/pkg/nnbd_migration/test/api_test.dart
@@ -959,6 +959,56 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  test_flow_analysis_simple() async {
+    var content = '''
+int f(int x) {
+  if (x == null) {
+    return 0;
+  } else {
+    return x;
+  }
+}
+main() {
+  f(null);
+}
+''';
+    var expected = '''
+int f(int? x) {
+  if (x == null) {
+    return 0;
+  } else {
+    return x;
+  }
+}
+main() {
+  f(null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_function_expression() async {
+    var content = '''
+int f(int i) {
+  var g = (int j) => i;
+  return g(i);
+}
+main() {
+  f(null);
+}
+''';
+    var expected = '''
+int? f(int? i) {
+  var g = (int? j) => i;
+  return g(i);
+}
+main() {
+  f(null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   test_function_expression_invocation() async {
     var content = '''
 abstract class C {
@@ -1332,6 +1382,28 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  test_local_function() async {
+    var content = '''
+int f(int i) {
+  int g(int j) => i;
+  return g(i);
+}
+main() {
+  f(null);
+}
+''';
+    var expected = '''
+int? f(int? i) {
+  int? g(int? j) => i;
+  return g(i);
+}
+main() {
+  f(null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   test_localVariable_type_inferred() async {
     var content = '''
 int f() => null;
@@ -1353,6 +1425,69 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  test_multiDeclaration_innerUsage() async {
+    var content = '''
+void test() {
+  // here non-null is OK.
+  int i1 = 0, i2 = i1.gcd(2);
+  // here non-null is not OK.
+  int i3 = 0, i4 = i3.gcd(2), i5 = null;
+}
+''';
+    var expected = '''
+void test() {
+  // here non-null is OK.
+  int i1 = 0, i2 = i1.gcd(2);
+  // here non-null is not OK.
+  int? i3 = 0, i4 = i3!.gcd(2), i5 = null;
+}
+''';
+
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_multiDeclaration_softEdges() async {
+    var content = '''
+int nullable(int i1, int i2) {
+  int i3 = i1, i4 = i2;
+  return i3;
+}
+int nonNull(int i1, int i2) {
+  int i3 = i1, i4 = i2;
+  return i3;
+}
+int both(int i1, int i2) {
+  int i3 = i1, i4 = i2;
+  return i3;
+}
+void main() {
+  nullable(null, null);
+  nonNull(0, 1);
+  both(0, null);
+}
+''';
+    var expected = '''
+int? nullable(int? i1, int? i2) {
+  int? i3 = i1, i4 = i2;
+  return i3;
+}
+int nonNull(int i1, int i2) {
+  int i3 = i1, i4 = i2;
+  return i3;
+}
+int? both(int i1, int? i2) {
+  int? i3 = i1, i4 = i2;
+  return i3;
+}
+void main() {
+  nullable(null, null);
+  nonNull(0, 1);
+  both(0, null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   test_named_parameter_no_default_unused() async {
     var content = '''
 void f({String s}) {}
@@ -1806,6 +1941,42 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  test_postdominating_usage_after_cfg_altered() async {
+    // By altering the control-flow graph, we can create new postdominators,
+    // which are not recognized as such. This is not a problem as we only do
+    // hard edges on a best-effort basis, and this case would be a lot of
+    // additional complexity.
+    var content = '''
+int f(int a, int b, int c) {
+  if (a != null) {
+    b.toDouble();
+  } else {
+    return null;
+  }
+  c.toDouble;
+}
+
+void main() {
+  f(1, null, null);
+}
+''';
+    var expected = '''
+int f(int a, int? b, int? c) {
+  /* if (a != null) {
+    */ b!.toDouble(); /*
+  } else {
+    return null;
+  } */
+  c!.toDouble;
+}
+
+void main() {
+  f(1, null, null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   test_prefix_minus() async {
     var content = '''
 class C {
@@ -1938,6 +2109,31 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  @failingTest
+  test_removed_if_element_doesnt_introduce_nullability() async {
+    // Failing for two reasons: 1. we don't add ! to recover(), and 2. we get
+    // an unimplemented error.
+    var content = '''
+f(int x) {
+  <int>[if (x == null) recover(), 0];
+}
+int recover() {
+  assert(false);
+  return null;
+}
+''';
+    var expected = '''
+f(int x) {
+  <int>[if (x == null) recover()!, 0];
+}
+int? recover() {
+  assert(false);
+  return null;
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   test_single_file_multiple_changes() async {
     var content = '''
 int f() => null;
diff --git a/pkg/nnbd_migration/test/decorated_type_test.dart b/pkg/nnbd_migration/test/decorated_type_test.dart
index 7e94d86..a0ea3f0 100644
--- a/pkg/nnbd_migration/test/decorated_type_test.dart
+++ b/pkg/nnbd_migration/test/decorated_type_test.dart
@@ -2,14 +2,16 @@
 // 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/element/type.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/testing/test_type_provider.dart';
 import 'package:nnbd_migration/src/decorated_type.dart';
 import 'package:nnbd_migration/src/nullability_node.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'abstract_single_unit.dart';
+import 'migration_visitor_test_base.dart';
 
 main() {
   defineReflectiveSuite(() {
@@ -18,91 +20,320 @@
 }
 
 @reflectiveTest
-class DecoratedTypeTest extends AbstractSingleUnitTest {
-  final _graph = NullabilityGraph();
+class DecoratedTypeTest extends Object
+    with DecoratedTypeTester
+    implements DecoratedTypeTesterBase {
+  final graph = NullabilityGraph();
 
-  NullabilityNode get always => _graph.always;
+  final TypeProvider typeProvider;
 
-  @override
+  factory DecoratedTypeTest() {
+    var typeProvider = TestTypeProvider();
+    return DecoratedTypeTest._(typeProvider);
+  }
+
+  DecoratedTypeTest._(this.typeProvider);
+
+  NullabilityNode get always => graph.always;
+
+  ClassElement get listElement => typeProvider.listType.element;
+
   void setUp() {
     NullabilityNode.clearDebugNames();
-    super.setUp();
   }
 
-  test_toString_bottom() async {
-    var decoratedType = DecoratedType(BottomTypeImpl.instance, _node(1));
-    expect(decoratedType.toString(), 'Never?(type(1))');
+  test_equal_dynamic_and_void() {
+    expect(dynamic_ == dynamic_, isTrue);
+    expect(dynamic_ == void_, isFalse);
+    expect(void_ == dynamic_, isFalse);
+    expect(void_ == void_, isTrue);
   }
 
-  test_toString_interface_type_argument() async {
-    await resolveTestUnit('''List<int> x;''');
-    var type = findElement.topVar('x').type as InterfaceType;
-    var decoratedType = DecoratedType(type, always,
-        typeArguments: [DecoratedType(type.typeArguments[0], _node(1))]);
-    expect(decoratedType.toString(), 'List<int?(type(1))>?');
+  test_equal_functionType_different_nodes() {
+    var returnType = int_();
+    expect(
+        function(returnType, node: newNode()) ==
+            function(returnType, node: newNode()),
+        isFalse);
   }
 
-  test_toString_named_parameter() async {
-    await resolveTestUnit('''dynamic f({int x}) {}''');
-    var type = findElement.function('f').type;
-    var decoratedType = DecoratedType(type, always,
-        namedParameters: {
-          'x': DecoratedType(type.namedParameterTypes['x'], _node(1))
-        },
-        returnType: DecoratedType(type.returnType, always));
-    expect(decoratedType.toString(), 'dynamic Function({x: int?(type(1))})?');
+  test_equal_functionType_named_different_names() {
+    var node = newNode();
+    var argType = int_();
+    expect(
+        function(dynamic_, named: {'x': argType}, node: node) ==
+            function(dynamic_, named: {'y': argType}, node: node),
+        isFalse);
   }
 
-  test_toString_normal_and_named_parameter() async {
-    await resolveTestUnit('''dynamic f(int x, {int y}) {}''');
-    var type = findElement.function('f').type;
-    var decoratedType = DecoratedType(type, always,
-        positionalParameters: [
-          DecoratedType(type.normalParameterTypes[0], _node(1))
-        ],
-        namedParameters: {
-          'y': DecoratedType(type.namedParameterTypes['y'], _node(2))
-        },
-        returnType: DecoratedType(type.returnType, always));
-    expect(decoratedType.toString(),
-        'dynamic Function(int?(type(1)), {y: int?(type(2))})?');
+  test_equal_functionType_named_different_types() {
+    var node = newNode();
+    expect(
+        function(dynamic_, named: {'x': int_()}, node: node) ==
+            function(dynamic_, named: {'x': int_()}, node: node),
+        isFalse);
   }
 
-  test_toString_normal_and_optional_parameter() async {
-    await resolveTestUnit('''dynamic f(int x, [int y]) {}''');
-    var type = findElement.function('f').type;
-    var decoratedType = DecoratedType(type, always,
-        positionalParameters: [
-          DecoratedType(type.normalParameterTypes[0], _node(1)),
-          DecoratedType(type.optionalParameterTypes[0], _node(2))
-        ],
-        returnType: DecoratedType(type.returnType, always));
-    expect(decoratedType.toString(),
-        'dynamic Function(int?(type(1)), [int?(type(2))])?');
+  test_equal_functionType_named_extra() {
+    var node = newNode();
+    var argType = int_();
+    var t1 = function(dynamic_, named: {'x': argType}, node: node);
+    var t2 = function(dynamic_, node: node);
+    expect(t1 == t2, isFalse);
+    expect(t2 == t1, isFalse);
   }
 
-  test_toString_normal_parameter() async {
-    await resolveTestUnit('''dynamic f(int x) {}''');
-    var type = findElement.function('f').type;
-    var decoratedType = DecoratedType(type, always,
-        positionalParameters: [
-          DecoratedType(type.normalParameterTypes[0], _node(1))
-        ],
-        returnType: DecoratedType(type.returnType, always));
-    expect(decoratedType.toString(), 'dynamic Function(int?(type(1)))?');
+  test_equal_functionType_named_same() {
+    var node = newNode();
+    var argType = int_();
+    expect(
+        function(dynamic_, named: {'x': argType}, node: node) ==
+            function(dynamic_, named: {'x': argType}, node: node),
+        isTrue);
   }
 
-  test_toString_optional_parameter() async {
-    await resolveTestUnit('''dynamic f([int x]) {}''');
-    var type = findElement.function('f').type;
-    var decoratedType = DecoratedType(type, always,
-        positionalParameters: [
-          DecoratedType(type.optionalParameterTypes[0], _node(1))
-        ],
-        returnType: DecoratedType(type.returnType, always));
-    expect(decoratedType.toString(), 'dynamic Function([int?(type(1))])?');
+  test_equal_functionType_positional_different() {
+    var node = newNode();
+    expect(
+        function(dynamic_, positional: [int_()], node: node) ==
+            function(dynamic_, positional: [int_()], node: node),
+        isFalse);
   }
 
-  NullabilityNode _node(int offset) =>
-      NullabilityNode.forTypeAnnotation(offset);
+  test_equal_functionType_positional_same() {
+    var node = newNode();
+    var argType = int_();
+    expect(
+        function(dynamic_, positional: [argType], node: node) ==
+            function(dynamic_, positional: [argType], node: node),
+        isTrue);
+  }
+
+  test_equal_functionType_required_different() {
+    var node = newNode();
+    expect(
+        function(dynamic_, required: [int_()], node: node) ==
+            function(dynamic_, required: [int_()], node: node),
+        isFalse);
+  }
+
+  test_equal_functionType_required_same() {
+    var node = newNode();
+    var argType = int_();
+    expect(
+        function(dynamic_, required: [argType], node: node) ==
+            function(dynamic_, required: [argType], node: node),
+        isTrue);
+  }
+
+  test_equal_functionType_required_vs_positional() {
+    var node = newNode();
+    var argType = int_();
+    expect(
+        function(dynamic_, required: [argType], node: node) ==
+            function(dynamic_, positional: [argType], node: node),
+        isFalse);
+  }
+
+  test_equal_functionType_return_different() {
+    var node = newNode();
+    expect(
+        function(int_(), node: node) == function(int_(), node: node), isFalse);
+  }
+
+  test_equal_functionType_return_same() {
+    var node = newNode();
+    var returnType = int_();
+    expect(function(returnType, node: node) == function(returnType, node: node),
+        isTrue);
+  }
+
+  test_equal_functionType_typeFormals_different_bounds() {
+    var n1 = newNode();
+    var n2 = newNode();
+    var t = typeParameter('T', object());
+    var u = typeParameter('U', int_());
+    expect(
+        function(typeParameterType(t, node: n1), typeFormals: [t], node: n2) ==
+            function(typeParameterType(u, node: n1),
+                typeFormals: [u], node: n2),
+        isFalse);
+  }
+
+  test_equal_functionType_typeFormals_equivalent_bounds_after_substitution() {
+    var n1 = newNode();
+    var n2 = newNode();
+    var n3 = newNode();
+    var n4 = newNode();
+    var bound = object();
+    var t = typeParameter('T', bound);
+    var u = typeParameter('U', typeParameterType(t, node: n1));
+    var v = typeParameter('V', bound);
+    var w = typeParameter('W', typeParameterType(v, node: n1));
+    expect(
+        function(void_,
+                typeFormals: [t, u],
+                required: [
+                  typeParameterType(t, node: n2),
+                  typeParameterType(u, node: n3)
+                ],
+                node: n4) ==
+            function(void_,
+                typeFormals: [v, w],
+                required: [
+                  typeParameterType(v, node: n2),
+                  typeParameterType(w, node: n3)
+                ],
+                node: n4),
+        isTrue);
+  }
+
+  test_equal_functionType_typeFormals_same_bounds_named() {
+    var n1 = newNode();
+    var n2 = newNode();
+    var bound = object();
+    var t = typeParameter('T', bound);
+    var u = typeParameter('U', bound);
+    expect(
+        function(void_,
+                typeFormals: [t],
+                named: {'x': typeParameterType(t, node: n1)},
+                node: n2) ==
+            function(void_,
+                typeFormals: [u],
+                named: {'x': typeParameterType(u, node: n1)},
+                node: n2),
+        isTrue);
+  }
+
+  test_equal_functionType_typeFormals_same_bounds_positional() {
+    var n1 = newNode();
+    var n2 = newNode();
+    var bound = object();
+    var t = typeParameter('T', bound);
+    var u = typeParameter('U', bound);
+    expect(
+        function(void_,
+                typeFormals: [t],
+                positional: [typeParameterType(t, node: n1)],
+                node: n2) ==
+            function(void_,
+                typeFormals: [u],
+                positional: [typeParameterType(u, node: n1)],
+                node: n2),
+        isTrue);
+  }
+
+  test_equal_functionType_typeFormals_same_bounds_required() {
+    var n1 = newNode();
+    var n2 = newNode();
+    var bound = object();
+    var t = typeParameter('T', bound);
+    var u = typeParameter('U', bound);
+    expect(
+        function(void_,
+                typeFormals: [t],
+                required: [typeParameterType(t, node: n1)],
+                node: n2) ==
+            function(void_,
+                typeFormals: [u],
+                required: [typeParameterType(u, node: n1)],
+                node: n2),
+        isTrue);
+  }
+
+  test_equal_functionType_typeFormals_same_bounds_return() {
+    var n1 = newNode();
+    var n2 = newNode();
+    var bound = object();
+    var t = typeParameter('T', bound);
+    var u = typeParameter('U', bound);
+    expect(
+        function(typeParameterType(t, node: n1), typeFormals: [t], node: n2) ==
+            function(typeParameterType(u, node: n1),
+                typeFormals: [u], node: n2),
+        isTrue);
+  }
+
+  test_equal_functionType_typeFormals_same_parameters() {
+    var n1 = newNode();
+    var n2 = newNode();
+    var t = typeParameter('T', object());
+    expect(
+        function(typeParameterType(t, node: n1), typeFormals: [t], node: n2) ==
+            function(typeParameterType(t, node: n1),
+                typeFormals: [t], node: n2),
+        isTrue);
+  }
+
+  test_equal_interfaceType_different_args() {
+    var node = newNode();
+    expect(list(int_(), node: node) == list(int_(), node: node), isFalse);
+  }
+
+  test_equal_interfaceType_different_classes() {
+    var node = newNode();
+    expect(int_(node: node) == object(node: node), isFalse);
+  }
+
+  test_equal_interfaceType_different_nodes() {
+    expect(int_() == int_(), isFalse);
+  }
+
+  test_equal_interfaceType_same() {
+    var node = newNode();
+    expect(int_(node: node) == int_(node: node), isTrue);
+  }
+
+  test_equal_interfaceType_same_generic() {
+    var argType = int_();
+    var node = newNode();
+    expect(list(argType, node: node) == list(argType, node: node), isTrue);
+  }
+
+  test_toString_bottom() {
+    var node = newNode();
+    var decoratedType = DecoratedType(BottomTypeImpl.instance, node);
+    expect(decoratedType.toString(), 'Never?($node)');
+  }
+
+  test_toString_interface_type_argument() {
+    var argType = int_();
+    var decoratedType = list(argType, node: always);
+    expect(decoratedType.toString(), 'List<$argType>?');
+  }
+
+  test_toString_named_parameter() {
+    var xType = int_();
+    var decoratedType = function(dynamic_, named: {'x': xType}, node: always);
+    expect(decoratedType.toString(), 'dynamic Function({x: $xType})?');
+  }
+
+  test_toString_normal_and_named_parameter() {
+    var xType = int_();
+    var yType = int_();
+    var decoratedType = function(dynamic_,
+        required: [xType], named: {'y': yType}, node: always);
+    expect(decoratedType.toString(), 'dynamic Function($xType, {y: $yType})?');
+  }
+
+  test_toString_normal_and_optional_parameter() {
+    var xType = int_();
+    var yType = int_();
+    var decoratedType = function(dynamic_,
+        required: [xType], positional: [yType], node: always);
+    expect(decoratedType.toString(), 'dynamic Function($xType, [$yType])?');
+  }
+
+  test_toString_normal_parameter() {
+    var xType = int_();
+    var decoratedType = function(dynamic_, required: [xType], node: always);
+    expect(decoratedType.toString(), 'dynamic Function($xType)?');
+  }
+
+  test_toString_optional_parameter() {
+    var xType = int_();
+    var decoratedType = function(dynamic_, positional: [xType], node: always);
+    expect(decoratedType.toString(), 'dynamic Function([$xType])?');
+  }
 }
diff --git a/pkg/nnbd_migration/test/edge_builder_flow_analysis_test.dart b/pkg/nnbd_migration/test/edge_builder_flow_analysis_test.dart
new file mode 100644
index 0000000..df1b6c6
--- /dev/null
+++ b/pkg/nnbd_migration/test/edge_builder_flow_analysis_test.dart
@@ -0,0 +1,688 @@
+// 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.
+
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'migration_visitor_test_base.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(EdgeBuilderFlowAnalysisTest);
+  });
+}
+
+@reflectiveTest
+class EdgeBuilderFlowAnalysisTest extends EdgeBuilderTestBase {
+  test_assignmentExpression() async {
+    await analyze('''
+void f(int i, int j) {
+  if (i != null) {
+    g(i);
+    i = j;
+    h(i);
+  }
+}
+void g(int k) {}
+void h(int l) {}
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    var kNode = decoratedTypeAnnotation('int k').node;
+    var lNode = decoratedTypeAnnotation('int l').node;
+    // No edge from i to k because i's type is promoted to non-nullable
+    assertNoEdge(iNode, kNode);
+    // But there is an edge from i to l, because it is after the assignment
+    assertEdge(iNode, lNode, hard: false);
+    // And there is an edge from j to i, because a null value of j would lead to
+    // a null value for i.
+    assertEdge(jNode, iNode, hard: false);
+  }
+
+  test_assignmentExpression_lhs_before_rhs() async {
+    await analyze('''
+void f(int i, List<int> l) {
+  if (i != null) {
+    l[i = g(i)] = h(i);
+  }
+}
+int g(int j) => 1;
+int h(int k) => 1;
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    var kNode = decoratedTypeAnnotation('int k').node;
+    var gReturnNode = decoratedTypeAnnotation('int g').node;
+    // No edge from i to j, because i's type is promoted before the call to g.
+    assertNoEdge(iNode, jNode);
+    // But there is an edge from i to k, because the call to h happens after the
+    // assignment.
+    assertEdge(iNode, kNode, hard: false);
+    // And there is an edge from g's return type to i, due to the assignment.
+    assertEdge(gReturnNode, iNode, hard: false);
+  }
+
+  test_assignmentExpression_write_after_rhs() async {
+    await analyze('''
+void f(int i) {
+  if (i != null) {
+    i = g(i);
+    h(i);
+  }
+}
+int g(int j) => 1;
+void h(int k) {}
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    var kNode = decoratedTypeAnnotation('int k').node;
+    var gReturnNode = decoratedTypeAnnotation('int g').node;
+    // No edge from i to j because i's type is promoted before the call to g.
+    assertNoEdge(iNode, jNode);
+    // But there is an edge from i to k, because the call to h happens after the
+    // assignment.
+    assertEdge(iNode, kNode, hard: false);
+    // And there is an edge from g's return type to i, due to the assignment.
+    assertEdge(gReturnNode, iNode, hard: false);
+  }
+
+  test_binaryExpression_ampersandAmpersand_left() async {
+    await analyze('''
+bool f(int i) => i != null && i.isEven;
+bool g(int j) => j.isEven;
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    // No edge from i to `never` because i's type is promoted to non-nullable
+    assertNoEdge(iNode, never);
+    // But there is an edge from j to `never`.
+    assertEdge(jNode, never, hard: true);
+  }
+
+  test_binaryExpression_ampersandAmpersand_right() async {
+    await analyze('''
+void f(bool b, int i, int j) {
+  if (b && i != null) {
+    print(i.isEven);
+    print(j.isEven);
+  }
+}
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    // No edge from i to `never` because i's type is promoted to non-nullable
+    assertNoEdge(iNode, never);
+    // But there is an edge from j to `never`.
+    assertEdge(jNode, never, hard: false);
+  }
+
+  test_binaryExpression_barBar_left() async {
+    await analyze('''
+bool f(int i) => i == null || i.isEven;
+bool g(int j) => j.isEven;
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    // No edge from i to `never` because i's type is promoted to non-nullable
+    assertNoEdge(iNode, never);
+    // But there is an edge from j to `never`.
+    assertEdge(jNode, never, hard: true);
+  }
+
+  test_binaryExpression_barBar_right() async {
+    await analyze('''
+void f(bool b, int i, int j) {
+  if (b || i == null) {} else {
+    print(i.isEven);
+    print(j.isEven);
+  }
+}
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    // No edge from i to `never` because i's type is promoted to non-nullable
+    assertNoEdge(iNode, never);
+    // But there is an edge from j to `never`.
+    assertEdge(jNode, never, hard: false);
+  }
+
+  test_booleanLiteral_false() async {
+    await analyze('''
+void f(int i, int j) {
+  if (i != null || false) {} else return;
+  if (j != null || true) {} else return;
+  i.isEven;
+  j.isEven;
+}
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    // No edge from i to never i is known to be non-nullable at the site of
+    // the call to i.isEven
+    assertNoEdge(iNode, never);
+    // But there is an edge from j to never
+    assertEdge(jNode, never, hard: false);
+  }
+
+  test_booleanLiteral_true() async {
+    await analyze('''
+void f(int i, int j) {
+  if (i == null && true) return;
+  if (j == null && false) return;
+  i.isEven;
+  j.isEven;
+}
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    // No edge from i to never i is known to be non-nullable at the site of
+    // the call to i.isEven
+    assertNoEdge(iNode, never);
+    // But there is an edge from j to never
+    assertEdge(jNode, never, hard: false);
+  }
+
+  test_break_labeled() async {
+    await analyze('''
+void f(int i) {
+  L: while(true) {
+    while (b()) {
+      if (i != null) break L;
+    }
+    g(i);
+  }
+  h(i);
+}
+bool b() => true;
+void g(int j) {}
+void h(int k) {}
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    var kNode = decoratedTypeAnnotation('int k').node;
+    // No edge from i to k because i is promoted at the time of the call to h.
+    assertNoEdge(iNode, kNode);
+    // But there is an edge from i to j, because i is not promoted at the time
+    // of the call to g.
+    assertEdge(iNode, jNode, hard: false);
+  }
+
+  test_break_unlabeled() async {
+    await analyze('''
+void f(int i) {
+  while (true) {
+    if (i != null) break;
+    g(i);
+  }
+  h(i);
+}
+bool b() => true;
+void g(int j) {}
+void h(int k) {}
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    var kNode = decoratedTypeAnnotation('int k').node;
+    // No edge from i to k because i is promoted at the time of the call to h.
+    assertNoEdge(iNode, kNode);
+    // But there is an edge from i to j, because i is not promoted at the time
+    // of the call to g.
+    assertEdge(iNode, jNode, hard: false);
+  }
+
+  test_conditionalExpression() async {
+    await analyze('''
+int f(int i) => i == null ? g(i) : h(i);
+int g(int j) => 1;
+int h(int k) => 1;
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    var kNode = decoratedTypeAnnotation('int k').node;
+    // No edge from i to k because i is known to be non-nullable at the site of
+    // the call to h()
+    assertNoEdge(iNode, kNode);
+    // But there is an edge from i to j
+    // TODO(paulberry): there should be a guard on this edge.
+    assertEdge(iNode, jNode, hard: false);
+  }
+
+  test_conditionalExpression_propagates_promotions() async {
+    await analyze('''
+void f(bool b, int i, int j, int k) {
+  if (b ? (i != null && j != null) : (i != null && k != null)) {
+    i.isEven;
+    j.isEven;
+    k.isEven;
+  }
+}
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    var kNode = decoratedTypeAnnotation('int k').node;
+    // No edge from i to never because i is promoted.
+    assertNoEdge(iNode, never);
+    // But there are edges from j and k to never.
+    assertEdge(jNode, never, hard: false);
+    assertEdge(kNode, never, hard: false);
+  }
+
+  test_constructorDeclaration_assert() async {
+    await analyze('''
+class C {
+  C(int i, int j) : assert(i == null || i.isEven, j.isEven);
+}
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    // No edge from i to `never` because i's type is promoted to non-nullable
+    assertNoEdge(iNode, never);
+    // But there is an edge from j to `never`.
+    assertEdge(jNode, never, hard: true);
+  }
+
+  test_constructorDeclaration_initializer() async {
+    await analyze('''
+class C {
+  bool b1;
+  bool b2;
+  C(int i, int j) : b1 = i == null || i.isEven, b2 = j.isEven;
+}
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    // No edge from i to `never` because i's type is promoted to non-nullable
+    assertNoEdge(iNode, never);
+    // But there is an edge from j to `never`.
+    assertEdge(jNode, never, hard: true);
+  }
+
+  test_constructorDeclaration_redirection() async {
+    await analyze('''
+class C {
+  C(bool b1, bool b2);
+  C.redirect(int i, int j) : this(i == null || i.isEven, j.isEven);
+}
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    // No edge from i to `never` because i's type is promoted to non-nullable
+    assertNoEdge(iNode, never);
+    // But there is an edge from j to `never`.
+    assertEdge(jNode, never, hard: true);
+  }
+
+  test_continue_labeled() async {
+    await analyze('''
+void f(int i) {
+  L: do {
+    do {
+      if (i != null) continue L;
+    } while (g(i));
+    break;
+  } while (h(i));
+}
+bool g(int j) => true;
+bool h(int k) => true;
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    var kNode = decoratedTypeAnnotation('int k').node;
+    // No edge from i to k because i is promoted at the time of the call to h.
+    assertNoEdge(iNode, kNode);
+    // But there is an edge from i to j, because i is not promoted at the time
+    // of the call to g.
+    assertEdge(iNode, jNode, hard: false);
+  }
+
+  test_continue_unlabeled() async {
+    await analyze('''
+void f(int i) {
+  do {
+    if (i != null) continue;
+    h(i);
+    break;
+  } while (g(i));
+}
+bool g(int j) => true;
+void h(int k) {}
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    var kNode = decoratedTypeAnnotation('int k').node;
+    // No edge from i to j because i is promoted at the time of the call to g.
+    assertNoEdge(iNode, jNode);
+    // But there is an edge from i to j, because i is not promoted at the time
+    // of the call to h.
+    assertEdge(iNode, kNode, hard: false);
+  }
+
+  test_do_break_target() async {
+    await analyze('''
+void f(int i) {
+  L: do {
+    do {
+      if (i != null) break L;
+      if (b()) break;
+    } while (true);
+    g(i);
+  } while (true);
+  h(i);
+}
+bool b() => true;
+void g(int j) {}
+void h(int k) {}
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    var kNode = decoratedTypeAnnotation('int k').node;
+    // No edge from i to k because i is promoted at the time of the call to h.
+    assertNoEdge(iNode, kNode);
+    // But there is an edge from i to j, because i is not promoted at the time
+    // of the call to g.
+    assertEdge(iNode, jNode, hard: false);
+  }
+
+  test_do_cancels_promotions_for_assignments_in_body() async {
+    await analyze('''
+void f(int i, int j) {
+  if (i == null) return;
+  if (j == null) return;
+  do {
+    i.isEven;
+    j.isEven;
+    j = null;
+  } while (true);
+}
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    // No edge from i to never because is is promoted.
+    assertNoEdge(iNode, never);
+    // But there is an edge from j to never because its promotion was cancelled.
+    assertEdge(jNode, never, hard: false);
+  }
+
+  test_do_cancels_promotions_for_assignments_in_condition() async {
+    await analyze('''
+void f(int i, int j) {
+  if (i == null) return;
+  if (j == null) return;
+  do {} while (i.isEven && j.isEven && g(j = null));
+}
+bool g(int k) => true;
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    // No edge from i to never because is is promoted.
+    assertNoEdge(iNode, never);
+    // But there is an edge from j to never because its promotion was cancelled.
+    assertEdge(jNode, never, hard: false);
+  }
+
+  test_do_continue_target() async {
+    await analyze('''
+void f(int i) {
+  L: do {
+    do {
+      if (i != null) continue L;
+      g(i);
+    } while (true);
+  } while (h(i));
+}
+void g(int j) {}
+bool h(int k) => true;
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    var kNode = decoratedTypeAnnotation('int k').node;
+    // No edge from i to k because i is promoted at the time of the call to h.
+    assertNoEdge(iNode, kNode);
+    // But there is an edge from i to j, because i is not promoted at the time
+    // of the call to g.
+    assertEdge(iNode, jNode, hard: false);
+  }
+
+  test_field_initializer() async {
+    await analyze('''
+bool b1 = true;
+bool b2 = true;
+class C {
+  bool b = b1 || b2;
+}
+''');
+    // No assertions; we just want to verify that the presence of `||` inside a
+    // field doesn't cause flow analysis to crash.
+  }
+
+  test_functionDeclaration() async {
+    await analyze('''
+void f(int i, int j) {
+  if (i == null) return;
+  print(i.isEven);
+  print(j.isEven);
+}
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    // No edge from i to `never` because i's type is promoted to non-nullable
+    assertNoEdge(iNode, never);
+    // But there is an edge from j to `never`.
+    assertEdge(jNode, never, hard: false);
+  }
+
+  test_functionDeclaration_expression_body() async {
+    await analyze('''
+bool f(int i) => i == null || i.isEven;
+bool g(int j) => j.isEven;
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    // No edge from i to `never` because i's type is promoted to non-nullable
+    assertNoEdge(iNode, never);
+    // But there is an edge from j to `never`.
+    assertEdge(jNode, never, hard: true);
+  }
+
+  test_functionDeclaration_resets_unconditional_control_flow() async {
+    await analyze('''
+void f(bool b, int i, int j) {
+  assert(i != null);
+  if (b) return;
+  assert(j != null);
+}
+void g(int k) {
+  assert(k != null);
+}
+''');
+    assertEdge(decoratedTypeAnnotation('int i').node, never, hard: true);
+    assertNoEdge(always, decoratedTypeAnnotation('int j').node);
+    assertEdge(decoratedTypeAnnotation('int k').node, never, hard: true);
+  }
+
+  test_functionExpression_parameters() async {
+    await analyze('''
+void f() {
+  var g = (int i, int j) {
+    if (i == null) return;
+    print(i.isEven);
+    print(j.isEven);
+  };
+}
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    // No edge from i to `never` because i's type is promoted to non-nullable
+    assertNoEdge(iNode, never);
+    // But there is an edge from j to `never`.
+    assertEdge(jNode, never, hard: false);
+  }
+
+  test_if() async {
+    await analyze('''
+void f(int i) {
+  if (i == null) {
+    g(i);
+  } else {
+    h(i);
+  }
+}
+void g(int j) {}
+void h(int k) {}
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    var kNode = decoratedTypeAnnotation('int k').node;
+    // No edge from i to k because i is known to be non-nullable at the site of
+    // the call to h()
+    assertNoEdge(iNode, kNode);
+    // But there is an edge from i to j
+    assertEdge(iNode, jNode, hard: false, guards: [iNode]);
+  }
+
+  test_if_without_else() async {
+    await analyze('''
+void f(int i) {
+  if (i == null) {
+    g(i);
+    return;
+  }
+  h(i);
+}
+void g(int j) {}
+void h(int k) {}
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    var kNode = decoratedTypeAnnotation('int k').node;
+    // No edge from i to k because i is known to be non-nullable at the site of
+    // the call to h()
+    assertNoEdge(iNode, kNode);
+    // But there is an edge from i to j
+    assertEdge(iNode, jNode, hard: false, guards: [iNode]);
+  }
+
+  test_local_function_parameters() async {
+    await analyze('''
+void f() {
+  void g(int i, int j) {
+    if (i == null) return;
+    print(i.isEven);
+    print(j.isEven);
+  }
+}
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    // No edge from i to `never` because i's type is promoted to non-nullable
+    assertNoEdge(iNode, never);
+    // But there is an edge from j to `never`.
+    assertEdge(jNode, never, hard: false);
+  }
+
+  test_return() async {
+    await analyze('''
+void f(int i, int j) {
+  if (i == null) return;
+  print(i.isEven);
+  print(j.isEven);
+}
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    // No edge from i to `never` because i's type is promoted to non-nullable
+    assertNoEdge(iNode, never);
+    // But there is an edge from j to `never`.
+    assertEdge(jNode, never, hard: false);
+  }
+
+  test_topLevelVar_initializer() async {
+    await analyze('''
+bool b1 = true;
+bool b2 = true;
+bool b3 = b1 || b2;
+''');
+    // No assertions; we just want to verify that the presence of `||` inside a
+    // top level variable doesn't cause flow analysis to crash.
+  }
+
+  test_while_break_target() async {
+    await analyze('''
+void f(int i) {
+  L: while (true) {
+    while (true) {
+      if (i != null) break L;
+      if (b()) break;
+    }
+    g(i);
+  }
+  h(i);
+}
+bool b() => true;
+void g(int j) {}
+void h(int k) {}
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    var kNode = decoratedTypeAnnotation('int k').node;
+    // No edge from i to k because i is promoted at the time of the call to h.
+    assertNoEdge(iNode, kNode);
+    // But there is an edge from i to j, because i is not promoted at the time
+    // of the call to g.
+    assertEdge(iNode, jNode, hard: false);
+  }
+
+  test_while_cancels_promotions_for_assignments_in_body() async {
+    await analyze('''
+void f(int i, int j) {
+  if (i == null) return;
+  if (j == null) return;
+  while (true) {
+    i.isEven;
+    j.isEven;
+    j = null;
+  }
+}
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    // No edge from i to never because is is promoted.
+    assertNoEdge(iNode, never);
+    // But there is an edge from j to never because its promotion was cancelled.
+    assertEdge(jNode, never, hard: false);
+  }
+
+  test_while_cancels_promotions_for_assignments_in_condition() async {
+    await analyze('''
+void f(int i, int j) {
+  if (i == null) return;
+  if (j == null) return;
+  while (i.isEven && j.isEven && g(j = null)) {}
+}
+bool g(int k) => true;
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    // No edge from i to never because is is promoted.
+    assertNoEdge(iNode, never);
+    // But there is an edge from j to never because its promotion was cancelled.
+    assertEdge(jNode, never, hard: false);
+  }
+
+  test_while_promotes() async {
+    await analyze('''
+void f(int i, int j) {
+  while (i != null) {
+    i.isEven;
+    j.isEven;
+  }
+}
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    // No edge from i to never because is is promoted.
+    assertNoEdge(iNode, never);
+    // But there is an edge from j to never.
+    assertEdge(jNode, never, hard: false);
+  }
+}
diff --git a/pkg/nnbd_migration/test/edge_builder_test.dart b/pkg/nnbd_migration/test/edge_builder_test.dart
index cd1f159..81465ac 100644
--- a/pkg/nnbd_migration/test/edge_builder_test.dart
+++ b/pkg/nnbd_migration/test/edge_builder_test.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:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/element.dart';
@@ -10,7 +9,6 @@
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/testing/test_type_provider.dart';
-import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:nnbd_migration/src/decorated_class_hierarchy.dart';
 import 'package:nnbd_migration/src/decorated_type.dart';
 import 'package:nnbd_migration/src/edge_builder.dart';
@@ -30,21 +28,22 @@
 }
 
 @reflectiveTest
-class AssignmentCheckerTest extends Object with EdgeTester {
+class AssignmentCheckerTest extends Object
+    with EdgeTester, DecoratedTypeTester {
   static const EdgeOrigin origin = const _TestEdgeOrigin();
 
   ClassElement _myListOfListClass;
 
   DecoratedType _myListOfListSupertype;
 
+  @override
   final TypeProvider typeProvider;
 
+  @override
   final NullabilityGraphForTesting graph;
 
   final AssignmentCheckerForTesting checker;
 
-  int offset = 0;
-
   factory AssignmentCheckerTest() {
     var typeProvider = TestTypeProvider();
     var graph = NullabilityGraphForTesting();
@@ -59,53 +58,15 @@
 
   AssignmentCheckerTest._(this.typeProvider, this.graph, this.checker);
 
-  NullabilityNode get always => graph.always;
-
-  DecoratedType get bottom => DecoratedType(typeProvider.bottomType, never);
-
-  DecoratedType get dynamic_ => DecoratedType(typeProvider.dynamicType, always);
-
-  NullabilityNode get never => graph.never;
-
-  DecoratedType get null_ => DecoratedType(typeProvider.nullType, always);
-
-  DecoratedType get void_ => DecoratedType(typeProvider.voidType, always);
-
   void assign(DecoratedType source, DecoratedType destination,
       {bool hard = false}) {
     checker.checkAssignment(origin,
         source: source, destination: destination, hard: hard);
   }
 
-  DecoratedType function(DecoratedType returnType,
-      {List<DecoratedType> required = const [],
-      List<DecoratedType> positional = const [],
-      Map<String, DecoratedType> named = const {}}) {
-    int i = 0;
-    var parameters = required
-        .map((t) => ParameterElementImpl.synthetic(
-            'p${i++}', t.type, ParameterKind.REQUIRED))
-        .toList();
-    parameters.addAll(positional.map((t) => ParameterElementImpl.synthetic(
-        'p${i++}', t.type, ParameterKind.POSITIONAL)));
-    parameters.addAll(named.entries.map((e) => ParameterElementImpl.synthetic(
-        e.key, e.value.type, ParameterKind.NAMED)));
-    return DecoratedType(
-        FunctionTypeImpl.synthetic(returnType.type, const [], parameters),
-        NullabilityNode.forTypeAnnotation(offset++),
-        returnType: returnType,
-        positionalParameters: required.toList()..addAll(positional),
-        namedParameters: named);
-  }
-
-  DecoratedType list(DecoratedType elementType) => DecoratedType(
-      typeProvider.listType.instantiate([elementType.type]),
-      NullabilityNode.forTypeAnnotation(offset++),
-      typeArguments: [elementType]);
-
   DecoratedType myListOfList(DecoratedType elementType) {
     if (_myListOfListClass == null) {
-      var t = TypeParameterElementImpl.synthetic('T')..bound = object().type;
+      var t = typeParameter('T', object());
       _myListOfListSupertype = list(list(typeParameterType(t)));
       _myListOfListClass = ClassElementImpl('MyListOfList', 0)
         ..typeParameters = [t]
@@ -114,13 +75,10 @@
     return DecoratedType(
         InterfaceTypeImpl(_myListOfListClass)
           ..typeArguments = [elementType.type],
-        NullabilityNode.forTypeAnnotation(offset++),
+        newNode(),
         typeArguments: [elementType]);
   }
 
-  DecoratedType object() => DecoratedType(
-      typeProvider.objectType, NullabilityNode.forTypeAnnotation(offset++));
-
   void test_bottom_to_generic() {
     var t = list(object());
     assign(bottom, t);
@@ -136,10 +94,8 @@
 
   void test_complex_to_typeParam() {
     var bound = list(object());
-    var t = TypeParameterElementImpl.synthetic('T')..bound = bound.type;
-    checker.bounds[t] = bound;
     var t1 = list(object());
-    var t2 = typeParameterType(t);
+    var t2 = typeParameterType(typeParameter('T', bound));
     assign(t1, t2, hard: true);
     assertEdge(t1.node, t2.node, hard: true);
     assertNoEdge(t1.node, bound.node);
@@ -318,9 +274,7 @@
 
   void test_typeParam_to_complex() {
     var bound = list(object());
-    var t = TypeParameterElementImpl.synthetic('T')..bound = bound.type;
-    checker.bounds[t] = bound;
-    var t1 = typeParameterType(t);
+    var t1 = typeParameterType(typeParameter('T', bound));
     var t2 = list(object());
     assign(t1, t2, hard: true);
     assertEdge(t1.node, t2.node, hard: true);
@@ -330,40 +284,30 @@
   }
 
   void test_typeParam_to_object() {
-    var bound = object();
-    var t = TypeParameterElementImpl.synthetic('T')..bound = bound.type;
-    checker.bounds[t] = bound;
-    var t1 = typeParameterType(t);
+    var t1 = typeParameterType(typeParameter('T', object()));
     var t2 = object();
     assign(t1, t2);
     assertEdge(t1.node, t2.node, hard: false);
   }
 
   void test_typeParam_to_typeParam() {
-    var t = TypeParameterElementImpl.synthetic('T')..bound = object().type;
+    var t = typeParameter('T', object());
     var t1 = typeParameterType(t);
     var t2 = typeParameterType(t);
     assign(t1, t2);
     assertEdge(t1.node, t2.node, hard: false);
   }
 
-  DecoratedType typeParameterType(TypeParameterElement typeParameter) =>
-      DecoratedType(
-          typeParameter.type, NullabilityNode.forTypeAnnotation(offset++));
+  @override
+  TypeParameterElement typeParameter(String name, DecoratedType bound) {
+    var t = super.typeParameter(name, bound);
+    checker.bounds[t] = bound;
+    return t;
+  }
 }
 
 @reflectiveTest
-class EdgeBuilderTest extends MigrationVisitorTestBase {
-  /// Analyzes the given source code, producing constraint variables and
-  /// constraints for it.
-  @override
-  Future<CompilationUnit> analyze(String code) async {
-    var unit = await super.analyze(code);
-    unit.accept(EdgeBuilder(
-        typeProvider, typeSystem, variables, graph, testSource, null));
-    return unit;
-  }
-
+class EdgeBuilderTest extends EdgeBuilderTestBase {
   void assertGLB(
       NullabilityNode node, NullabilityNode left, NullabilityNode right) {
     expect(node, isNot(TypeMatcher<NullabilityNodeForLUB>()));
@@ -719,6 +663,28 @@
     assertNoUpstreamNullability(decoratedTypeAnnotation('bool f').node);
   }
 
+  test_binaryExpression_equal_null() async {
+    await analyze('''
+void f(int i) {
+  if (i == null) {
+    g(i);
+  } else {
+    h(i);
+  }
+}
+void g(int j) {}
+void h(int k) {}
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    var kNode = decoratedTypeAnnotation('int k').node;
+    // No edge from i to k because i is known to be non-nullable at the site of
+    // the call to h()
+    assertNoEdge(iNode, kNode);
+    // But there is an edge from i to j
+    assertEdge(iNode, jNode, hard: false, guards: [iNode]);
+  }
+
   test_binaryExpression_gt_result_not_null() async {
     await analyze('''
 bool f(int i, int j) => i > j;
@@ -783,6 +749,28 @@
     assertNoUpstreamNullability(decoratedTypeAnnotation('bool f').node);
   }
 
+  test_binaryExpression_notEqual_null() async {
+    await analyze('''
+void f(int i) {
+  if (i != null) {
+    h(i);
+  } else {
+    g(i);
+  }
+}
+void g(int j) {}
+void h(int k) {}
+''');
+    var iNode = decoratedTypeAnnotation('int i').node;
+    var jNode = decoratedTypeAnnotation('int j').node;
+    var kNode = decoratedTypeAnnotation('int k').node;
+    // No edge from i to k because i is known to be non-nullable at the site of
+    // the call to h()
+    assertNoEdge(iNode, kNode);
+    // But there is an edge from i to j
+    assertEdge(iNode, jNode, hard: false, guards: [iNode]);
+  }
+
   test_binaryExpression_percent_result_not_null() async {
     await analyze('''
 int f(int i, int j) => i % j;
@@ -1355,6 +1343,20 @@
     assertNoUpstreamNullability(decoratedTypeAnnotation('double').node);
   }
 
+  test_field_metadata() async {
+    await analyze('''
+class A {
+  const A();
+}
+class C {
+  @A()
+  int f;
+}
+''');
+    // No assertions needed; the AnnotationTracker mixin verifies that the
+    // metadata was visited.
+  }
+
   test_field_type_inferred() async {
     await analyze('''
 int f() => 1;
@@ -1432,6 +1434,17 @@
     // No assertions; just checking that it doesn't crash.
   }
 
+  test_forStatement_empty() async {
+    await analyze('''
+
+void test() {
+  for (; ; ) {
+    return;
+  }
+}
+''');
+  }
+
   test_function_assignment() async {
     await analyze('''
 class C {
@@ -1532,22 +1545,6 @@
     assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
   }
 
-  test_functionDeclaration_resets_unconditional_control_flow() async {
-    await analyze('''
-void f(bool b, int i, int j) {
-  assert(i != null);
-  if (b) return;
-  assert(j != null);
-}
-void g(int k) {
-  assert(k != null);
-}
-''');
-    assertEdge(decoratedTypeAnnotation('int i').node, never, hard: true);
-    assertNoEdge(always, decoratedTypeAnnotation('int j').node);
-    assertEdge(decoratedTypeAnnotation('int k').node, never, hard: true);
-  }
-
   test_functionExpressionInvocation_parameterType() async {
     await analyze('''
 abstract class C {
@@ -1696,6 +1693,76 @@
     assertNoEdge(always, decoratedTypeAnnotation('int i').node);
   }
 
+  test_if_element() async {
+    await analyze('''
+void f(bool b) {
+  int i1 = null;
+  int i2 = null;
+  <int>[if (b) i1 else i2];
+}
+''');
+
+    assertNullCheck(checkExpression('b) i1'),
+        assertEdge(decoratedTypeAnnotation('bool b').node, never, hard: true));
+    assertEdge(decoratedTypeAnnotation('int i1').node,
+        decoratedTypeAnnotation('int>[').node,
+        hard: false);
+    assertEdge(decoratedTypeAnnotation('int i2').node,
+        decoratedTypeAnnotation('int>[').node,
+        hard: false);
+  }
+
+  @failingTest
+  test_if_element_guard_equals_null() async {
+    // failing because of an unimplemented exception in conditional modification
+    await analyze('''
+dynamic f(int i, int j, int k) {
+  <int>[if (i == null) j/*check*/ else k/*check*/];
+}
+''');
+    var nullable_i = decoratedTypeAnnotation('int i').node;
+    var nullable_j = decoratedTypeAnnotation('int j').node;
+    var nullable_k = decoratedTypeAnnotation('int k').node;
+    var nullable_itemType = decoratedTypeAnnotation('int>[').node;
+    assertNullCheck(
+        checkExpression('j/*check*/'),
+        assertEdge(nullable_j, nullable_itemType,
+            guards: [nullable_i], hard: false));
+    assertNullCheck(checkExpression('k/*check*/'),
+        assertEdge(nullable_k, nullable_itemType, hard: false));
+    var discard = statementDiscard('if (i == null)');
+    expect(discard.trueGuard, same(nullable_i));
+    expect(discard.falseGuard, null);
+    expect(discard.pureCondition, true);
+  }
+
+  test_if_element_nested() async {
+    await analyze('''
+void f(bool b1, bool b2) {
+  int i1 = null;
+  int i2 = null;
+  int i3 = null;
+  <int>[if (b1) if (b2) i1 else i2 else i3];
+}
+''');
+
+    assertNullCheck(checkExpression('b1)'),
+        assertEdge(decoratedTypeAnnotation('bool b1').node, never, hard: true));
+    assertNullCheck(
+        checkExpression('b2) i1'),
+        assertEdge(decoratedTypeAnnotation('bool b2').node, never,
+            hard: false));
+    assertEdge(decoratedTypeAnnotation('int i1').node,
+        decoratedTypeAnnotation('int>[').node,
+        hard: false);
+    assertEdge(decoratedTypeAnnotation('int i2').node,
+        decoratedTypeAnnotation('int>[').node,
+        hard: false);
+    assertEdge(decoratedTypeAnnotation('int i3').node,
+        decoratedTypeAnnotation('int>[').node,
+        hard: false);
+  }
+
   test_if_guard_equals_null() async {
     await analyze('''
 int f(int i, int j, int k) {
@@ -2519,9 +2586,8 @@
 }
 ''');
 
-    // TODO(mfairhurst): enable this check
-    //assertNullCheck(checkExpression('b1/*check*/'),
-    //    assertEdge(decoratedTypeAnnotation('bool b1').node, never, hard: true));
+    assertNullCheck(checkExpression('b1/*check*/'),
+        assertEdge(decoratedTypeAnnotation('bool b1').node, never, hard: true));
     assertNullCheck(checkExpression('b2/*check*/'),
         assertEdge(decoratedTypeAnnotation('bool b2').node, never, hard: true));
     assertNullCheck(checkExpression('c.m'),
@@ -2545,9 +2611,8 @@
 }
 ''');
 
-    // TODO(mfairhurst): enable this check
-    //assertNullCheck(checkExpression('b1/*check*/'),
-    //    assertEdge(decoratedTypeAnnotation('bool b1').node, never, hard: true));
+    assertNullCheck(checkExpression('b1/*check*/'),
+        assertEdge(decoratedTypeAnnotation('bool b1').node, never, hard: true));
     assertNullCheck(checkExpression('b2/*check*/'),
         assertEdge(decoratedTypeAnnotation('bool b2').node, never, hard: true));
     assertNullCheck(checkExpression('c.m'),
@@ -2568,9 +2633,8 @@
 }
 ''');
 
-    // TODO(mfairhurst): enable this check
-    //assertNullCheck(checkExpression('b/*check*/'),
-    //    assertEdge(decoratedTypeAnnotation('bool b').node, never, hard: false));
+    assertNullCheck(checkExpression('b/*check*/'),
+        assertEdge(decoratedTypeAnnotation('bool b').node, never, hard: false));
     assertNullCheck(checkExpression('c.m'),
         assertEdge(decoratedTypeAnnotation('C c').node, never, hard: false));
   }
@@ -2591,9 +2655,8 @@
 }
 ''');
 
-    // TODO(mfairhurst): enable this check
-    //assertNullCheck(checkExpression('b/*check*/'),
-    //    assertEdge(decoratedTypeAnnotation('bool b').node, never, hard: true));
+    assertNullCheck(checkExpression('b/*check*/'),
+        assertEdge(decoratedTypeAnnotation('bool b').node, never, hard: true));
     assertNullCheck(checkExpression('c1.m'),
         assertEdge(decoratedTypeAnnotation('C c1').node, never, hard: true));
     assertNullCheck(checkExpression('c2.m'),
@@ -2602,13 +2665,53 @@
         assertEdge(decoratedTypeAnnotation('C c3').node, never, hard: true));
   }
 
+  test_postDominators_forElement() async {
+    await analyze('''
+class C {
+  int m() => 0;
+}
+
+void test(bool _b, C c1, C c2) {
+  <int>[for (bool b1 = _b; b1/*check*/; c2.m()) c1.m()];
+}
+''');
+
+    assertNullCheck(checkExpression('b1/*check*/'),
+        assertEdge(decoratedTypeAnnotation('bool b1').node, never, hard: true));
+    assertNullCheck(checkExpression('c1.m'),
+        assertEdge(decoratedTypeAnnotation('C c1').node, never, hard: false));
+    assertNullCheck(checkExpression('c2.m'),
+        assertEdge(decoratedTypeAnnotation('C c2').node, never, hard: false));
+  }
+
+  test_postDominators_forInElement() async {
+    await analyze('''
+class C {
+  int m() => 0;
+}
+void test(List<C> l, C c1) {
+  <int>[for (C _c in l/*check*/) c1.m()];
+  <int>[for (C c2 in <C>[]) c2.m()];
+}
+''');
+
+    assertNullCheck(
+        checkExpression('l/*check*/'),
+        assertEdge(decoratedTypeAnnotation('List<C> l').node, never,
+            hard: true));
+    assertNullCheck(checkExpression('c1.m'),
+        assertEdge(decoratedTypeAnnotation('C c1').node, never, hard: false));
+    assertNullCheck(checkExpression('c2.m'),
+        assertEdge(decoratedTypeAnnotation('C c2').node, never, hard: false));
+  }
+
   test_postDominators_forInStatement_unconditional() async {
     await analyze('''
 class C {
   void m() {}
 }
 void test(List<C> l, C c1, C c2) {
-  for (C c3 in l) {
+  for (C c3 in l/*check*/) {
     c1.m();
     c3.m();
   }
@@ -2617,9 +2720,10 @@
 }
 ''');
 
-    //TODO(mfairhurst): enable this check
-    //assertNullCheck(checkExpression('l/*check*/'),
-    //    assertEdge(decoratedTypeAnnotation('List<C> l').node, never, hard: true));
+    assertNullCheck(
+        checkExpression('l/*check*/'),
+        assertEdge(decoratedTypeAnnotation('List<C> l').node, never,
+            hard: true));
     assertNullCheck(checkExpression('c1.m'),
         assertEdge(decoratedTypeAnnotation('C c1').node, never, hard: false));
     assertNullCheck(checkExpression('c2.m'),
@@ -2628,6 +2732,33 @@
         assertEdge(decoratedTypeAnnotation('C c3').node, never, hard: false));
   }
 
+  test_postDominators_forStatement_conditional() async {
+    await analyze('''
+
+class C {
+  void m() {}
+}
+void test(bool b1, C c1, C c2, C c3) {
+  for (; b1/*check*/; c2.m()) {
+    C c4 = c1;
+    c4.m();
+    return;
+  }
+
+  c3.m();
+}
+''');
+
+    assertNullCheck(checkExpression('b1/*check*/'),
+        assertEdge(decoratedTypeAnnotation('bool b1').node, never, hard: true));
+    assertNullCheck(checkExpression('c4.m'),
+        assertEdge(decoratedTypeAnnotation('C c4').node, never, hard: true));
+    assertNullCheck(checkExpression('c2.m'),
+        assertEdge(decoratedTypeAnnotation('C c2').node, never, hard: false));
+    assertNullCheck(checkExpression('c3.m'),
+        assertEdge(decoratedTypeAnnotation('C c3').node, never, hard: false));
+  }
+
   test_postDominators_forStatement_unconditional() async {
     await analyze('''
 
@@ -2644,9 +2775,9 @@
 }
 ''');
 
-    //TODO(mfairhurst): enable this check
     assertNullCheck(checkExpression('b1/*check*/'),
         assertEdge(decoratedTypeAnnotation('bool b1').node, never, hard: true));
+    //TODO(mfairhurst): enable this check
     //assertNullCheck(checkExpression('b2/*check*/'),
     //    assertEdge(decoratedTypeAnnotation('bool b2').node, never, hard: true));
     //assertEdge(decoratedTypeAnnotation('b3 =').node, never, hard: false);
@@ -2658,6 +2789,27 @@
         assertEdge(decoratedTypeAnnotation('C c3').node, never, hard: false));
   }
 
+  test_postDominators_ifElement() async {
+    await analyze('''
+class C {
+  int m() => 0;
+}
+void test(bool b, C c1, C c2, C c3) {
+  <int>[if (b) c1.m() else c2.m()];
+  c3.m();
+}
+''');
+
+    assertNullCheck(checkExpression('b)'),
+        assertEdge(decoratedTypeAnnotation('bool b').node, never, hard: true));
+    assertNullCheck(checkExpression('c1.m'),
+        assertEdge(decoratedTypeAnnotation('C c1').node, never, hard: false));
+    assertNullCheck(checkExpression('c2.m'),
+        assertEdge(decoratedTypeAnnotation('C c2').node, never, hard: false));
+    assertNullCheck(checkExpression('c3.m'),
+        assertEdge(decoratedTypeAnnotation('C c3').node, never, hard: true));
+  }
+
   test_postDominators_ifStatement_conditional() async {
     await analyze('''
 class C {
@@ -2757,9 +2909,8 @@
 }
 ''');
 
-    // TODO(mfairhurst): enable this check
-    //assertNullCheck(checkExpression('b1/*check*/'),
-    //    assertEdge(decoratedTypeAnnotation('bool b1').node, never, hard: true));
+    assertNullCheck(checkExpression('b1/*check*/'),
+        assertEdge(decoratedTypeAnnotation('bool b1').node, never, hard: true));
     assertNullCheck(checkExpression('b2/*check*/'),
         assertEdge(decoratedTypeAnnotation('bool b2').node, never, hard: true));
     assertNullCheck(checkExpression('c1.m'),
@@ -2768,6 +2919,21 @@
         assertEdge(decoratedTypeAnnotation('C c2').node, never, hard: false));
   }
 
+  test_postDominators_multiDeclaration() async {
+    // Multi declarations cannot use hard edges as shown below.
+    await analyze('''
+void test() {
+  int i1 = 0, i2 = null;
+  i1.toDouble();
+}
+''');
+
+    // i1.toDouble() cannot be a hard edge or i2 will fail assignment
+    assertEdge(decoratedTypeAnnotation('int i').node, never, hard: false);
+    // i2 gets a soft edge to always due to null assignment
+    assertEdge(always, decoratedTypeAnnotation('int i').node, hard: false);
+  }
+
   test_postDominators_reassign() async {
     await analyze('''
 void test(bool b, int i1, int i2) {
@@ -2811,7 +2977,6 @@
         assertEdge(decoratedTypeAnnotation('C c4').node, never, hard: false));
   }
 
-  @failingTest
   test_postDominators_subFunction() async {
     await analyze('''
 class C {
@@ -2851,9 +3016,7 @@
         assertEdge(decoratedTypeAnnotation('C c').node, never, hard: false));
   }
 
-  @failingTest
   test_postDominators_subFunction_ifStatement_unconditional() async {
-    // Failing because function expressions aren't implemented
     await analyze('''
 class C {
   void m() {}
@@ -2914,9 +3077,8 @@
 }
 ''');
 
-    //TODO(mfairhurst): enable this check
-    //assertNullCheck(checkExpression('b/*check*/'),
-    //    assertEdge(decoratedTypeAnnotation('bool b').node, never, hard: true));
+    assertNullCheck(checkExpression('b/*check*/'),
+        assertEdge(decoratedTypeAnnotation('bool b').node, never, hard: true));
     assertNullCheck(checkExpression('c1.m'),
         assertEdge(decoratedTypeAnnotation('C c1').node, never, hard: false));
     assertNullCheck(checkExpression('c2.m'),
@@ -3576,6 +3738,18 @@
     assertEdge(always, setXType.node, hard: false);
   }
 
+  test_topLevelVar_metadata() async {
+    await analyze('''
+class A {
+  const A();
+}
+@A()
+int v;
+''');
+    // No assertions needed; the AnnotationTracker mixin verifies that the
+    // metadata was visited.
+  }
+
   test_topLevelVar_reference() async {
     await analyze('''
 double pi = 3.1415;
@@ -3626,7 +3800,7 @@
     var pointClass =
         findNode.typeName('Point').name.staticElement as ClassElement;
     var pointBound =
-        variables.decoratedElementType(pointClass.typeParameters[0]);
+        variables.decoratedTypeParameterBound(pointClass.typeParameters[0]);
     expect(pointBound.type.toString(), 'num');
     assertEdge(decoratedTypeAnnotation('int>').node, pointBound.node,
         hard: true);
@@ -3637,7 +3811,8 @@
 void f(List<int> x) {}
 ''');
     var listClass = typeProvider.listType.element;
-    var listBound = variables.decoratedElementType(listClass.typeParameters[0]);
+    var listBound =
+        variables.decoratedTypeParameterBound(listClass.typeParameters[0]);
     expect(listBound.type.toString(), 'dynamic');
     assertEdge(decoratedTypeAnnotation('int>').node, listBound.node,
         hard: true);
diff --git a/pkg/nnbd_migration/test/migration_visitor_test_base.dart b/pkg/nnbd_migration/test/migration_visitor_test_base.dart
index 76bf6a1..bf9d88c 100644
--- a/pkg/nnbd_migration/test/migration_visitor_test_base.dart
+++ b/pkg/nnbd_migration/test/migration_visitor_test_base.dart
@@ -4,11 +4,15 @@
 
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:meta/meta.dart';
 import 'package:nnbd_migration/src/conditional_discard.dart';
 import 'package:nnbd_migration/src/decorated_type.dart';
+import 'package:nnbd_migration/src/edge_builder.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';
@@ -17,6 +21,84 @@
 
 import 'abstract_single_unit.dart';
 
+/// Mixin allowing unit tests to create decorated types easily.
+mixin DecoratedTypeTester implements DecoratedTypeTesterBase {
+  int _offset = 0;
+
+  Map<TypeParameterElement, DecoratedType> _decoratedTypeParameterBounds =
+      Map.identity();
+
+  NullabilityNode get always => graph.always;
+
+  DecoratedType get bottom => DecoratedType(typeProvider.bottomType, never);
+
+  DecoratedType get dynamic_ => DecoratedType(typeProvider.dynamicType, always);
+
+  NullabilityNode get never => graph.never;
+
+  DecoratedType get null_ => DecoratedType(typeProvider.nullType, always);
+
+  DecoratedType get void_ => DecoratedType(typeProvider.voidType, always);
+
+  DecoratedType function(DecoratedType returnType,
+      {List<DecoratedType> required = const [],
+      List<DecoratedType> positional = const [],
+      Map<String, DecoratedType> named = const {},
+      List<TypeParameterElement> typeFormals = const [],
+      NullabilityNode node}) {
+    int i = 0;
+    var parameters = required
+        .map((t) => ParameterElementImpl.synthetic(
+            'p${i++}', t.type, ParameterKind.REQUIRED))
+        .toList();
+    parameters.addAll(positional.map((t) => ParameterElementImpl.synthetic(
+        'p${i++}', t.type, ParameterKind.POSITIONAL)));
+    parameters.addAll(named.entries.map((e) => ParameterElementImpl.synthetic(
+        e.key, e.value.type, ParameterKind.NAMED)));
+    return DecoratedType(
+        FunctionTypeImpl.synthetic(returnType.type, typeFormals, parameters),
+        node ?? newNode(),
+        typeFormalBounds: typeFormals
+            .map((formal) => _decoratedTypeParameterBounds[formal])
+            .toList(),
+        returnType: returnType,
+        positionalParameters: required.toList()..addAll(positional),
+        namedParameters: named);
+  }
+
+  DecoratedType int_({NullabilityNode node}) =>
+      DecoratedType(typeProvider.intType, node ?? newNode());
+
+  DecoratedType list(DecoratedType elementType, {NullabilityNode node}) =>
+      DecoratedType(typeProvider.listType.instantiate([elementType.type]),
+          node ?? newNode(),
+          typeArguments: [elementType]);
+
+  NullabilityNode newNode() => NullabilityNode.forTypeAnnotation(_offset++);
+
+  DecoratedType object({NullabilityNode node}) =>
+      DecoratedType(typeProvider.objectType, node ?? newNode());
+
+  TypeParameterElement typeParameter(String name, DecoratedType bound) {
+    var element = TypeParameterElementImpl.synthetic(name);
+    element.bound = bound.type;
+    _decoratedTypeParameterBounds[element] = bound;
+    return element;
+  }
+
+  DecoratedType typeParameterType(TypeParameterElement typeParameter,
+          {NullabilityNode node}) =>
+      DecoratedType(typeParameter.type, node ?? newNode());
+}
+
+/// Base functionality that must be implemented by classes mixing in
+/// [DecoratedTypeTester].
+abstract class DecoratedTypeTesterBase {
+  NullabilityGraph get graph;
+
+  TypeProvider get typeProvider;
+}
+
 /// Mixin allowing unit tests to check for the presence of graph edges.
 mixin EdgeTester {
   NullabilityGraphForTesting get graph;
@@ -127,6 +209,18 @@
   }
 }
 
+class EdgeBuilderTestBase extends MigrationVisitorTestBase {
+  /// Analyzes the given source code, producing constraint variables and
+  /// constraints for it.
+  @override
+  Future<CompilationUnit> analyze(String code) async {
+    var unit = await super.analyze(code);
+    unit.accept(EdgeBuilder(
+        typeProvider, typeSystem, variables, graph, testSource, null));
+    return unit;
+  }
+}
+
 class MigrationVisitorTestBase extends AbstractSingleUnitTest with EdgeTester {
   final InstrumentedVariables variables;
 
diff --git a/pkg/nnbd_migration/test/node_builder_test.dart b/pkg/nnbd_migration/test/node_builder_test.dart
index 19a2546..d8a78b0 100644
--- a/pkg/nnbd_migration/test/node_builder_test.dart
+++ b/pkg/nnbd_migration/test/node_builder_test.dart
@@ -23,8 +23,9 @@
       variables.decoratedElementType(
           findNode.functionDeclaration(search).declaredElement);
 
-  DecoratedType decoratedTypeParameterBound(String search) => variables
-      .decoratedElementType(findNode.typeParameter(search).declaredElement);
+  DecoratedType decoratedTypeParameterBound(String search) =>
+      variables.decoratedTypeParameterBound(
+          findNode.typeParameter(search).declaredElement);
 
   test_class_alias_synthetic_constructors_no_parameters() async {
     await analyze('''
@@ -571,6 +572,29 @@
     // field.
   }
 
+  test_function_generic_bounded() async {
+    await analyze('''
+T f<T extends Object>(T t) => t;
+''');
+    var decoratedType = decoratedFunctionType('f');
+    var bound = decoratedTypeParameterBound('T extends');
+    expect(decoratedType.typeFormalBounds[0], same(bound));
+    expect(decoratedTypeAnnotation('Object'), same(bound));
+    expect(bound.node, isNot(always));
+    expect(bound.type, typeProvider.objectType);
+  }
+
+  test_function_generic_implicit_bound() async {
+    await analyze('''
+T f<T>(T t) => t;
+''');
+    var decoratedType = decoratedFunctionType('f');
+    var bound = decoratedTypeParameterBound('T>');
+    expect(decoratedType.typeFormalBounds[0], same(bound));
+    assertUnion(always, bound.node);
+    expect(bound.type, same(typeProvider.objectType));
+  }
+
   test_function_metadata() async {
     await analyze('''
 class A {
@@ -584,6 +608,23 @@
     expect(node, TypeMatcher<NullabilityNodeMutable>());
   }
 
+  test_functionExpression() async {
+    await analyze('''
+void f() {
+  var x = (int i) => 1;
+}
+''');
+    var functionExpressionElement =
+        findNode.simpleParameter('int i').declaredElement.enclosingElement;
+    var decoratedType =
+        variables.decoratedElementType(functionExpressionElement);
+    expect(decoratedType.positionalParameters[0],
+        same(decoratedTypeAnnotation('int i')));
+    expect(decoratedType.node, same(never));
+    expect(
+        decoratedType.returnType.node, TypeMatcher<NullabilityNodeMutable>());
+  }
+
   test_functionTypedFormalParameter_namedParameter_typed() async {
     await analyze('''
 void f(void g({int i})) {}
@@ -852,6 +893,19 @@
     expect(decoratedIntType.node, isNot(never));
   }
 
+  test_local_function() async {
+    await analyze('''
+void f() {
+  int g(int i) => 1;
+}
+''');
+    var decoratedType = decoratedFunctionType('g');
+    expect(decoratedType.returnType, same(decoratedTypeAnnotation('int g')));
+    expect(decoratedType.positionalParameters[0],
+        same(decoratedTypeAnnotation('int i')));
+    expect(decoratedType.node, same(never));
+  }
+
   test_localVariable_type_implicit_dynamic() async {
     await analyze('''
 main() {
@@ -886,6 +940,33 @@
     expect(decoratedType.node, same(always));
   }
 
+  test_method_generic_bounded() async {
+    await analyze('''
+class C {
+  T f<T extends Object>(T t) => t;
+}
+''');
+    var decoratedType = decoratedMethodType('f');
+    var bound = decoratedTypeParameterBound('T extends');
+    expect(decoratedType.typeFormalBounds[0], same(bound));
+    expect(decoratedTypeAnnotation('Object'), same(bound));
+    expect(bound.node, isNot(always));
+    expect(bound.type, typeProvider.objectType);
+  }
+
+  test_method_generic_implicit_bound() async {
+    await analyze('''
+class C {
+  T f<T>(T t) => t;
+}
+''');
+    var decoratedType = decoratedMethodType('f');
+    var bound = decoratedTypeParameterBound('T>');
+    expect(decoratedType.typeFormalBounds[0], same(bound));
+    assertUnion(always, bound.node);
+    expect(bound.type, same(typeProvider.objectType));
+  }
+
   test_method_metadata() async {
     await analyze('''
 class A {
diff --git a/pkg/nnbd_migration/test/nullability_node_test.dart b/pkg/nnbd_migration/test/nullability_node_test.dart
index 6c18b23..eac19ce 100644
--- a/pkg/nnbd_migration/test/nullability_node_test.dart
+++ b/pkg/nnbd_migration/test/nullability_node_test.dart
@@ -594,6 +594,12 @@
     expect(edge.isSatisfied, true);
   }
 
+  test_substitution_simplify_null() {
+    var n1 = newNode(1);
+    expect(subst(null, n1), same(n1));
+    expect(subst(n1, null), same(n1));
+  }
+
   test_unconstrainted_node_non_nullable() {
     var n1 = newNode(1);
     propagate();
diff --git a/pkg/nnbd_migration/test/test_all.dart b/pkg/nnbd_migration/test/test_all.dart
index 2272dea..48a36fd 100644
--- a/pkg/nnbd_migration/test/test_all.dart
+++ b/pkg/nnbd_migration/test/test_all.dart
@@ -4,9 +4,13 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import 'already_migrated_code_decorator_test.dart'
+    as already_migrated_code_decorator_test;
 import 'api_test.dart' as api_test;
 import 'decorated_class_hierarchy_test.dart' as decorated_class_hierarchy_test;
 import 'decorated_type_test.dart' as decorated_type_test;
+import 'edge_builder_flow_analysis_test.dart'
+    as edge_builder_flow_analysis_test;
 import 'edge_builder_test.dart' as edge_builder_test;
 import 'node_builder_test.dart' as node_builder_test;
 import 'nullability_node_test.dart' as nullability_node_test;
@@ -14,9 +18,11 @@
 
 main() {
   defineReflectiveSuite(() {
+    already_migrated_code_decorator_test.main();
     api_test.main();
     decorated_class_hierarchy_test.main();
     decorated_type_test.main();
+    edge_builder_flow_analysis_test.main();
     edge_builder_test.main();
     node_builder_test.main();
     nullability_node_test.main();
diff --git a/pkg/nnbd_migration/test/utilities/scoped_set_test.dart b/pkg/nnbd_migration/test/utilities/scoped_set_test.dart
index 47a8661..9facb62 100644
--- a/pkg/nnbd_migration/test/utilities/scoped_set_test.dart
+++ b/pkg/nnbd_migration/test/utilities/scoped_set_test.dart
@@ -131,14 +131,6 @@
     expect(set.isInScope(0), true);
   }
 
-  test_pushScope_addAll() {
-    final set = ScopedSet<int>();
-    set.pushScope();
-    set.addAll([0, 1]);
-    expect(set.isInScope(0), true);
-    expect(set.isInScope(1), true);
-  }
-
   test_pushScope_copyCurrent() {
     final set = ScopedSet<int>();
     set.pushScope();
diff --git a/pkg/status_file/bin/remove_non_essential_entries.dart b/pkg/status_file/bin/remove_non_essential_entries.dart
new file mode 100644
index 0000000..80cd930
--- /dev/null
+++ b/pkg/status_file/bin/remove_non_essential_entries.dart
@@ -0,0 +1,131 @@
+// 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.
+
+// Removes all status file expectations that are not relevant in the
+// new workflow, but preserves entries with comments.
+//
+// For example, using the script on this status file
+//   a: Crash
+//   b: RuntimeError
+//   c: RuntimeError # Comment
+//   d: Pass, RuntimeError
+//   e: Pass, Slow, RuntimeError
+//   f: Pass, Slow, RuntimeError # Another comment
+// will produce the output
+//   c: RuntimeError # Comment
+//   e: Slow
+//   f: Pass, Slow, RuntimeError # Another comment
+//
+// When using the option to keep crashes, there will be an additional line
+//   a: Crash
+
+import 'dart:io';
+
+import 'package:args/args.dart';
+import 'package:status_file/canonical_status_file.dart';
+import 'package:status_file/expectation.dart';
+
+StatusEntry filterExpectations(
+    StatusEntry entry, List<Expectation> expectationsToKeep) {
+  List<Expectation> remaining = entry.expectations
+      .where(
+          (Expectation expectation) => expectationsToKeep.contains(expectation))
+      .toList();
+  return remaining.isEmpty
+      ? null
+      : StatusEntry(entry.path, entry.lineNumber, remaining, entry.comment);
+}
+
+StatusFile removeNonEssentialEntries(
+    StatusFile statusFile, List<Expectation> expectationsToKeep) {
+  List<StatusSection> sections = <StatusSection>[];
+  for (StatusSection section in statusFile.sections) {
+    bool hasStatusEntries = false;
+    List<Entry> entries = <Entry>[];
+    for (Entry entry in section.entries) {
+      if (entry is EmptyEntry) {
+        entries.add(entry);
+      } else if (entry is StatusEntry && entry.comment != null ||
+          entry is CommentEntry) {
+        entries.add(entry);
+        hasStatusEntries = true;
+      } else if (entry is StatusEntry) {
+        StatusEntry newEntry = filterExpectations(entry, expectationsToKeep);
+        if (newEntry != null) {
+          entries.add(newEntry);
+          hasStatusEntries = true;
+        }
+      } else {
+        throw "Unknown entry type ${entry.runtimeType}";
+      }
+    }
+    bool isDefaultSection = section.condition == null;
+    if (hasStatusEntries ||
+        (isDefaultSection && section.sectionHeaderComments.isNotEmpty)) {
+      StatusSection newSection =
+          StatusSection(section.condition, -1, section.sectionHeaderComments);
+      newSection.entries.addAll(entries);
+      sections.add(newSection);
+    }
+  }
+  StatusFile newStatusFile = StatusFile(statusFile.path);
+  newStatusFile.sections.addAll(sections);
+  return newStatusFile;
+}
+
+ArgParser buildParser() {
+  var parser = ArgParser();
+  parser.addFlag("overwrite",
+      abbr: 'w',
+      negatable: false,
+      defaultsTo: false,
+      help: "Overwrite input file with output.");
+  parser.addFlag("keep-crashes",
+      abbr: 'c', negatable: false, defaultsTo: false);
+  parser.addFlag("help",
+      abbr: "h",
+      negatable: false,
+      defaultsTo: false,
+      help: "Show help and commands for this tool.");
+  return parser;
+}
+
+void printHelp(ArgParser parser) {
+  print("Usage: dart pkg/status_file/bin/remove_non_essential_entries.dart"
+      " <path>");
+  print(parser.usage);
+}
+
+main(List<String> arguments) {
+  var parser = buildParser();
+  var results = parser.parse(arguments);
+  if (results["help"] || results.rest.isEmpty) {
+    printHelp(parser);
+    return;
+  }
+
+  final List<Expectation> expectationsToKeep = <Expectation>[
+    Expectation.skip,
+    Expectation.skipByDesign,
+    Expectation.skipSlow,
+    Expectation.slow,
+    Expectation.extraSlow
+  ];
+
+  if (results["keep-crashes"]) {
+    expectationsToKeep.add(Expectation.crash);
+  }
+
+  for (String path in results.rest) {
+    bool writeFile = results["overwrite"];
+    var statusFile = StatusFile.read(path);
+    statusFile = removeNonEssentialEntries(statusFile, expectationsToKeep);
+    if (writeFile) {
+      File(path).writeAsStringSync(statusFile.toString());
+      print("Modified $path.");
+    } else {
+      print(statusFile);
+    }
+  }
+}
diff --git a/pkg/test_runner/lib/src/browser.dart b/pkg/test_runner/lib/src/browser.dart
index 5d7427e..8cc2ac0 100644
--- a/pkg/test_runner/lib/src/browser.dart
+++ b/pkg/test_runner/lib/src/browser.dart
@@ -184,10 +184,6 @@
   waitSeconds: 30,
 };
 
-// Don't try to bring up the debugger on a runtime error.
-window.ddcSettings = {
-  trapRuntimeErrors: false
-};
 </script>
 <script type="text/javascript"
         src="/root_dart/third_party/requirejs/require.js"></script>
diff --git a/pkg/test_runner/lib/src/co19_test_config.dart b/pkg/test_runner/lib/src/co19_test_config.dart
index f2c1fc8..912545a 100644
--- a/pkg/test_runner/lib/src/co19_test_config.dart
+++ b/pkg/test_runner/lib/src/co19_test_config.dart
@@ -11,10 +11,14 @@
 
   Co19TestSuite(TestConfiguration configuration, String selector)
       : super(configuration, selector, Path("tests/$selector/src"), [
+          // These files also need to be listed in the filesets in
+          // test_matrix.json so they will be copied to the bots running the
+          // test shards.
           "tests/$selector/$selector-co19.status",
           "tests/$selector/$selector-analyzer.status",
           "tests/$selector/$selector-runtime.status",
           "tests/$selector/$selector-dart2js.status",
+          "tests/$selector/$selector-dartdevc.status",
           "tests/$selector/$selector-kernel.status"
         ]);
 
diff --git a/pkg/test_runner/tool/update_static_error_tests.dart b/pkg/test_runner/tool/update_static_error_tests.dart
index dcd792d..46061c9 100644
--- a/pkg/test_runner/tool/update_static_error_tests.dart
+++ b/pkg/test_runner/tool/update_static_error_tests.dart
@@ -101,8 +101,17 @@
         parser, "Must provide a file path or glob for which tests to update.");
   }
 
-  var glob = Glob(results.rest.single, recursive: true);
-  for (var entry in glob.listSync(root: "tests")) {
+  var result = results.rest.single;
+  // Allow tests to be specified without the extension for compatibility with
+  // the regular test runner syntax.
+  if (!result.endsWith(".dart")) {
+    result += ".dart";
+  }
+  // Allow tests to be specified either relative to the "tests" directory
+  // or relative to the current directory.
+  var root = result.startsWith("tests") ? "." : "tests";
+  var glob = Glob(result, recursive: true);
+  for (var entry in glob.listSync(root: root)) {
     if (!entry.path.endsWith(".dart")) continue;
 
     if (entry is File) {
diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart
index 1969881..2b0f824 100644
--- a/pkg/vm/bin/kernel_service.dart
+++ b/pkg/vm/bin/kernel_service.dart
@@ -731,7 +731,7 @@
   return fileSystem;
 }
 
-train(String scriptUri, String platformKernelPath) {
+train(String scriptUri, String platformKernelPath, bool bytecode) {
   var tag = kTrainTag;
   var responsePort = new RawReceivePort();
   responsePort.handler = (response) {
@@ -757,7 +757,7 @@
     false /* suppress warnings */,
     false /* enable asserts */,
     null /* experimental_flags */,
-    false /* generate bytecode */,
+    bytecode,
     null /* package_config */,
     null /* multirootFilepaths */,
     null /* multirootScheme */,
@@ -767,9 +767,20 @@
 
 main([args]) {
   if ((args?.length ?? 0) > 1 && args[0] == '--train') {
-    // This entry point is used when creating an app snapshot. The argument
-    // provides a script to compile to warm-up generated code.
-    train(args[1], args.length > 2 ? args[2] : null);
+    // This entry point is used when creating an app snapshot.
+    // It takes the following extra arguments:
+    // 1) Script to compile.
+    // 2) Optional '--bytecode' argument to train bytecode generation.
+    // 3) Optional platform kernel path.
+    int argIndex = 1;
+    final String script = args[argIndex++];
+    bool bytecode = false;
+    if ((argIndex < args.length) && (args[argIndex] == '--bytecode')) {
+      bytecode = true;
+      ++argIndex;
+    }
+    final String platform = (argIndex < args.length) ? args[argIndex] : null;
+    train(script, platform, bytecode);
   } else {
     // Entry point for the Kernel isolate.
     return new RawReceivePort()..handler = _processLoadRequest;
diff --git a/pkg/vm/lib/bytecode/assembler.dart b/pkg/vm/lib/bytecode/assembler.dart
index 1fe11b4..c287838 100644
--- a/pkg/vm/lib/bytecode/assembler.dart
+++ b/pkg/vm/lib/bytecode/assembler.dart
@@ -404,15 +404,15 @@
     _emitInstructionD(Opcode.kNativeCall, rd);
   }
 
+  void emitLoadStatic(int rd) {
+    _emitInstructionD(Opcode.kLoadStatic, rd);
+  }
+
   void emitStoreStaticTOS(int rd) {
     emitSourcePosition();
     _emitInstructionD(Opcode.kStoreStaticTOS, rd);
   }
 
-  void emitPushStatic(int rd) {
-    _emitInstructionD(Opcode.kPushStatic, rd);
-  }
-
   void emitCreateArrayTOS() {
     _emitInstruction0(Opcode.kCreateArrayTOS);
   }
diff --git a/pkg/vm/lib/bytecode/dbc.dart b/pkg/vm/lib/bytecode/dbc.dart
index 8aecbc4..f091eab 100644
--- a/pkg/vm/lib/bytecode/dbc.dart
+++ b/pkg/vm/lib/bytecode/dbc.dart
@@ -10,7 +10,7 @@
 /// Before bumping current bytecode version format, make sure that
 /// all users have switched to a VM which is able to consume new
 /// version of bytecode.
-const int currentBytecodeFormatVersion = 18;
+const int currentBytecodeFormatVersion = 19;
 
 enum Opcode {
   kUnusedOpcode000,
@@ -168,8 +168,8 @@
   kUnused17, // Reserved for PushParamLast1
   kPopLocal,
   kPopLocal_Wide,
-  kUnused18, // Reserved for PopLocal0
-  kUnused19,
+  kLoadStatic,
+  kLoadStatic_Wide,
   kStoreLocal,
   kStoreLocal_Wide,
 
@@ -182,8 +182,8 @@
   kUnused20,
 
   // Static fields.
-  kPushStatic,
-  kPushStatic_Wide,
+  kUnused40,
+  kUnused41,
   kStoreStaticTOS,
   kStoreStaticTOS_Wide,
 
@@ -412,7 +412,7 @@
       Encoding.kD, const [Operand.lit, Operand.none, Operand.none]),
   Opcode.kStoreIndexedTOS: const Format(
       Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
-  Opcode.kPushStatic: const Format(
+  Opcode.kLoadStatic: const Format(
       Encoding.kD, const [Operand.lit, Operand.none, Operand.none]),
   Opcode.kStoreStaticTOS: const Format(
       Encoding.kD, const [Operand.lit, Operand.none, Operand.none]),
@@ -633,7 +633,6 @@
     case Opcode.kPushTrue:
     case Opcode.kPushFalse:
     case Opcode.kPushInt:
-    case Opcode.kPushStatic:
       return true;
     default:
       return false;
diff --git a/pkg/vm/lib/bytecode/gen_bytecode.dart b/pkg/vm/lib/bytecode/gen_bytecode.dart
index fdebdc1..4bc67f7 100644
--- a/pkg/vm/lib/bytecode/gen_bytecode.dart
+++ b/pkg/vm/lib/bytecode/gen_bytecode.dart
@@ -40,6 +40,7 @@
         getDefaultFunctionTypeArguments,
         getInstantiatorTypeArguments,
         getStaticType,
+        getTypeParameterTypes,
         hasFreeTypeParameters,
         hasInstantiatorTypeArguments,
         isAllDynamic,
@@ -255,9 +256,8 @@
     }
     final name = objectTable.getNameHandle(null, library.name ?? '');
     final script = getScript(library.fileUri, true);
-    final extensionUris = getNativeExtensionUris(library)
-        .map((String uri) => objectTable.getNameHandle(null, uri))
-        .toList();
+    final extensionUris =
+        objectTable.getPublicNameHandles(getNativeExtensionUris(library));
     if (extensionUris.isNotEmpty) {
       flags |= LibraryDeclaration.hasExtensionsFlag;
     }
@@ -278,10 +278,7 @@
     if (hasInstantiatorTypeArguments(cls)) {
       flags |= ClassDeclaration.hasTypeArgumentsFlag;
       numTypeArguments = flattenInstantiatorTypeArguments(
-              cls,
-              cls.typeParameters
-                  .map((tp) => new TypeParameterType(tp))
-                  .toList())
+              cls, getTypeParameterTypes(cls.typeParameters))
           .length;
       assert(numTypeArguments > 0);
       if (cls.typeParameters.isNotEmpty) {
@@ -617,9 +614,12 @@
         objectTable.mangleMemberName(member, false, false));
 
     final parameters = <ParameterDeclaration>[];
-    parameters
-        .addAll(function.positionalParameters.map(getParameterDeclaration));
-    parameters.addAll(function.namedParameters.map(getParameterDeclaration));
+    for (var param in function.positionalParameters) {
+      parameters.add(getParameterDeclaration(param));
+    }
+    for (var param in function.namedParameters) {
+      parameters.add(getParameterDeclaration(param));
+    }
 
     return new FunctionDeclaration(
         flags,
@@ -667,10 +667,8 @@
 
   TypeParametersDeclaration getTypeParametersDeclaration(
       List<TypeParameter> typeParams) {
-    return new TypeParametersDeclaration(typeParams
-        .map((tp) => new NameAndType(objectTable.getNameHandle(null, tp.name),
-            objectTable.getHandle(tp.bound)))
-        .toList());
+    return new TypeParametersDeclaration(
+        objectTable.getTypeParameterHandles(typeParams));
   }
 
   ParameterDeclaration getParameterDeclaration(VariableDeclaration variable) {
@@ -694,9 +692,13 @@
       return flags;
     }
 
-    List<int> paramFlags = <int>[];
-    paramFlags.addAll(function.positionalParameters.map(getFlags));
-    paramFlags.addAll(function.namedParameters.map(getFlags));
+    final List<int> paramFlags = <int>[];
+    for (var param in function.positionalParameters) {
+      paramFlags.add(getFlags(param));
+    }
+    for (var param in function.namedParameters) {
+      paramFlags.add(getFlags(param));
+    }
 
     for (int flags in paramFlags) {
       if (flags != 0) {
@@ -1384,11 +1386,9 @@
         }
       }
       if (hasInstantiatorTypeArguments(enclosingClass)) {
-        final typeParameters = (isFactory
-                ? node.function.typeParameters
-                : enclosingClass.typeParameters)
-            .map((p) => new TypeParameterType(p))
-            .toList();
+        final typeParameters = getTypeParameterTypes(isFactory
+            ? node.function.typeParameters
+            : enclosingClass.typeParameters);
         instantiatorTypeArguments =
             flattenInstantiatorTypeArguments(enclosingClass, typeParameters);
       }
@@ -2174,11 +2174,15 @@
         break;
     }
 
-    final List<NameAndType> parameters = function.positionalParameters
-        .followedBy(function.namedParameters)
-        .map((v) => new NameAndType(objectTable.getNameHandle(null, v.name),
-            objectTable.getHandle(v.type)))
-        .toList();
+    final List<NameAndType> parameters = <NameAndType>[];
+    for (var v in function.positionalParameters) {
+      parameters.add(new NameAndType(objectTable.getNameHandle(null, v.name),
+          objectTable.getHandle(v.type)));
+    }
+    for (var v in function.namedParameters) {
+      parameters.add(new NameAndType(objectTable.getNameHandle(null, v.name),
+          objectTable.getHandle(v.type)));
+    }
     if (function.requiredParameterCount != parameters.length) {
       if (function.namedParameters.isNotEmpty) {
         flags |= ClosureDeclaration.hasOptionalNamedParamsFlag;
@@ -2187,10 +2191,8 @@
       }
     }
 
-    final typeParams = function.typeParameters
-        .map((tp) => new NameAndType(objectTable.getNameHandle(null, tp.name),
-            objectTable.getHandle(tp.bound)))
-        .toList();
+    final typeParams =
+        objectTable.getTypeParameterHandles(function.typeParameters);
     if (typeParams.isNotEmpty) {
       flags |= ClosureDeclaration.hasTypeParamsFlag;
     }
@@ -3074,10 +3076,7 @@
       if (target.isConst) {
         _genPushConstExpr(target.initializer);
       } else if (_hasTrivialInitializer(target)) {
-        final fieldIndex = cp.addStaticField(target);
-        asm.emitPushConstant(
-            fieldIndex); // TODO(alexmarkov): do we really need this?
-        asm.emitPushStatic(fieldIndex);
+        asm.emitLoadStatic(cp.addStaticField(target));
       } else {
         _genDirectCall(target, objectTable.getArgDescHandle(0), 0, isGet: true);
       }
diff --git a/pkg/vm/lib/bytecode/generics.dart b/pkg/vm/lib/bytecode/generics.dart
index a109999..c24f494 100644
--- a/pkg/vm/lib/bytecode/generics.dart
+++ b/pkg/vm/lib/bytecode/generics.dart
@@ -20,6 +20,17 @@
   return false;
 }
 
+List<DartType> getTypeParameterTypes(List<TypeParameter> typeParameters) {
+  if (typeParameters.isEmpty) {
+    return const <DartType>[];
+  }
+  final types = new List<DartType>(typeParameters.length);
+  for (int i = 0; i < typeParameters.length; ++i) {
+    types[i] = new TypeParameterType(typeParameters[i]);
+  }
+  return types;
+}
+
 bool _canReuseSuperclassTypeArguments(List<DartType> superTypeArgs,
     List<TypeParameter> typeParameters, int overlap) {
   for (int i = 0; i < overlap; ++i) {
@@ -59,7 +70,9 @@
   final substitution = Substitution.fromPairs(typeParameters, typeArgs);
 
   List<DartType> flatTypeArgs = <DartType>[];
-  flatTypeArgs.addAll(superTypeArgs.map((t) => substitution.substituteType(t)));
+  for (var type in superTypeArgs) {
+    flatTypeArgs.add(substitution.substituteType(type));
+  }
   flatTypeArgs.addAll(typeArgs.getRange(overlap, typeArgs.length));
 
   return flatTypeArgs;
@@ -76,12 +89,24 @@
 }
 
 List<DartType> getDefaultFunctionTypeArguments(FunctionNode function) {
-  List<DartType> defaultTypes = function.typeParameters
-      .map((p) => p.defaultType ?? const DynamicType())
-      .toList();
-  if (isAllDynamic(defaultTypes)) {
+  final typeParameters = function.typeParameters;
+  if (typeParameters.isEmpty) {
     return null;
   }
+  bool dynamicOnly = true;
+  for (var tp in typeParameters) {
+    if (tp.defaultType != null && tp.defaultType != const DynamicType()) {
+      dynamicOnly = false;
+      break;
+    }
+  }
+  if (dynamicOnly) {
+    return null;
+  }
+  List<DartType> defaultTypes = <DartType>[];
+  for (var tp in typeParameters) {
+    defaultTypes.add(tp.defaultType ?? const DynamicType());
+  }
   return defaultTypes;
 }
 
diff --git a/pkg/vm/lib/bytecode/object_table.dart b/pkg/vm/lib/bytecode/object_table.dart
index c13e330..d16c0bd 100644
--- a/pkg/vm/lib/bytecode/object_table.dart
+++ b/pkg/vm/lib/bytecode/object_table.dart
@@ -378,6 +378,8 @@
   set flags(int value) {}
 
   bool get isCacheable => true;
+  bool get shouldBeIncludedIntoIndexTable =>
+      _useCount >= ObjectTable.indexTableUseCountThreshold && isCacheable;
 
   factory ObjectHandle._empty(ObjectKind kind, int flags) {
     switch (kind) {
@@ -1532,6 +1534,12 @@
   @override
   ObjectKind get kind => ObjectKind.kScript;
 
+  // Include scripts into index table if there are more than 1 reference
+  // in order to make sure there are no duplicated script objects within the
+  // same bytecode component.
+  @override
+  bool get shouldBeIncludedIntoIndexTable => _useCount > 1;
+
   @override
   int get flags => _flags;
 
@@ -1625,8 +1633,13 @@
     return handle;
   }
 
-  List<ObjectHandle> getHandles(List<Node> nodes) =>
-      nodes.map((n) => getHandle(n)).toList();
+  List<ObjectHandle> getHandles(List<Node> nodes) {
+    final handles = new List<ObjectHandle>(nodes.length);
+    for (int i = 0; i < nodes.length; ++i) {
+      handles[i] = getHandle(nodes[i]);
+    }
+    return handles;
+  }
 
   String mangleGetterName(String name) => 'get:$name';
 
@@ -1659,6 +1672,17 @@
     return getOrAddObject(new _NameHandle(libraryHandle, name));
   }
 
+  List<_NameHandle> getPublicNameHandles(List<String> names) {
+    if (names.isEmpty) {
+      return const <_NameHandle>[];
+    }
+    final handles = new List<_NameHandle>(names.length);
+    for (int i = 0; i < names.length; ++i) {
+      handles[i] = getNameHandle(null, names[i]);
+    }
+    return handles;
+  }
+
   ObjectHandle getSelectorNameHandle(Name name,
       {bool isGetter: false, bool isSetter: false}) {
     return getNameHandle(
@@ -1696,34 +1720,40 @@
     if (typeArgs == null) {
       return null;
     }
-    final List<_TypeHandle> handles =
-        typeArgs.map((t) => getHandle(t) as _TypeHandle).toList();
+    final handles = new List<_TypeHandle>(typeArgs.length);
+    for (int i = 0; i < typeArgs.length; ++i) {
+      handles[i] = getHandle(typeArgs[i]) as _TypeHandle;
+    }
     return getOrAddObject(new _TypeArgumentsHandle(handles));
   }
 
   ObjectHandle getArgDescHandle(int numArguments,
       [int numTypeArguments = 0, List<String> argNames = const <String>[]]) {
     return getOrAddObject(new _ArgDescHandle(
-        numArguments,
-        numTypeArguments,
-        argNames
-            .map<_NameHandle>((name) => getNameHandle(null, name))
-            .toList()));
+        numArguments, numTypeArguments, getPublicNameHandles(argNames)));
   }
 
   ObjectHandle getArgDescHandleByArguments(Arguments args,
       {bool hasReceiver: false, bool isFactory: false}) {
-    return getArgDescHandle(
-        args.positional.length +
-            args.named.length +
-            (hasReceiver ? 1 : 0) +
-            // VM expects that type arguments vector passed to a factory
-            // constructor is counted in numArguments, and not counted in
-            // numTypeArgs.
-            // TODO(alexmarkov): Clean this up.
-            (isFactory ? 1 : 0),
-        isFactory ? 0 : args.types.length,
-        new List<String>.from(args.named.map((ne) => ne.name)));
+    List<_NameHandle> argNames = const <_NameHandle>[];
+    final namedArguments = args.named;
+    if (namedArguments.isNotEmpty) {
+      argNames = new List<_NameHandle>(namedArguments.length);
+      for (int i = 0; i < namedArguments.length; ++i) {
+        argNames[i] = getNameHandle(null, namedArguments[i].name);
+      }
+    }
+    final int numArguments = args.positional.length +
+        args.named.length +
+        (hasReceiver ? 1 : 0) +
+        // VM expects that type arguments vector passed to a factory
+        // constructor is counted in numArguments, and not counted in
+        // numTypeArgs.
+        // TODO(alexmarkov): Clean this up.
+        (isFactory ? 1 : 0);
+    final int numTypeArguments = isFactory ? 0 : args.types.length;
+    return getOrAddObject(
+        new _ArgDescHandle(numArguments, numTypeArguments, argNames));
   }
 
   ObjectHandle getScriptHandle(Uri uri, SourceFile source) {
@@ -1735,6 +1765,18 @@
     return handle;
   }
 
+  List<NameAndType> getTypeParameterHandles(List<TypeParameter> typeParams) {
+    if (typeParams.isEmpty) {
+      return const <NameAndType>[];
+    }
+    final namesAndBounds = new List<NameAndType>();
+    for (TypeParameter tp in typeParams) {
+      namesAndBounds.add(
+          new NameAndType(getNameHandle(null, tp.name), getHandle(tp.bound)));
+    }
+    return namesAndBounds;
+  }
+
   void declareClosure(
       FunctionNode function, Member enclosingMember, int closureIndex) {
     final handle = getOrAddObject(
@@ -1757,7 +1799,7 @@
     int tableSize = 1; // Reserve invalid entry.
     for (var obj in _objects.reversed) {
       assert(obj._reference == null);
-      if (obj._useCount >= indexTableUseCountThreshold && obj.isCacheable) {
+      if (obj.shouldBeIncludedIntoIndexTable) {
         // This object will be included into index table.
         ++tableSize;
       } else {
@@ -2039,11 +2081,7 @@
     final returnType = objectTable.getHandle(node.returnType);
 
     final result = objectTable.getOrAddObject(new _FunctionTypeHandle(
-        node.typeParameters
-            .map((tp) => new NameAndType(
-                objectTable.getNameHandle(null, tp.name),
-                objectTable.getHandle(tp.bound)))
-            .toList(),
+        objectTable.getTypeParameterHandles(node.typeParameters),
         node.requiredParameterCount,
         positionalParams,
         namedParams,
@@ -2090,8 +2128,7 @@
   ObjectHandle visitListConstant(ListConstant node) =>
       objectTable.getOrAddObject(new _ConstObjectHandle(
           ConstTag.kList,
-          new List<ObjectHandle>.from(
-              node.entries.map((Constant c) => objectTable.getHandle(c))),
+          objectTable.getHandles(node.entries),
           objectTable.getHandle(node.typeArgument)));
 
   @override
diff --git a/pkg/vm/lib/frontend_server.dart b/pkg/vm/lib/frontend_server.dart
index 7535474..ba383ba 100644
--- a/pkg/vm/lib/frontend_server.dart
+++ b/pkg/vm/lib/frontend_server.dart
@@ -25,6 +25,9 @@
 import 'package:path/path.dart' as path;
 import 'package:usage/uuid/uuid.dart';
 
+import 'package:vm/bytecode/gen_bytecode.dart'
+    show generateBytecode, createFreshComponentWithBytecode;
+import 'package:vm/bytecode/options.dart' show BytecodeOptions;
 import 'package:vm/incremental_compiler.dart' show IncrementalCompiler;
 import 'package:vm/kernel_front_end.dart'
     show
@@ -34,6 +37,7 @@
         convertFileOrUriArgumentToUri,
         createFrontEndTarget,
         createFrontEndFileSystem,
+        runWithFrontEndCompilerContext,
         setVMEnvironmentDefines,
         writeDepfile;
 
@@ -116,6 +120,16 @@
   ..addFlag('track-widget-creation',
       help: 'Run a kernel transformer to track creation locations for widgets.',
       defaultsTo: false)
+  ..addFlag('gen-bytecode', help: 'Generate bytecode', defaultsTo: false)
+  ..addMultiOption('bytecode-options',
+      help: 'Specify options for bytecode generation:',
+      valueHelp: 'opt1,opt2,...',
+      allowed: BytecodeOptions.commandLineFlags.keys,
+      allowedHelp: BytecodeOptions.commandLineFlags)
+  ..addFlag('drop-ast',
+      help: 'Include only bytecode into the output file', defaultsTo: false)
+  ..addFlag('enable-asserts',
+      help: 'Whether asserts will be enabled.', defaultsTo: false)
   ..addMultiOption('enable-experiment',
       help: 'Comma separated list of experimental features, eg set-literals.',
       hide: true);
@@ -238,6 +252,7 @@
   bool unsafePackageSerialization;
 
   CompilerOptions _compilerOptions;
+  BytecodeOptions _bytecodeOptions;
   FileSystem _fileSystem;
   Uri _mainSource;
   ArgResults _options;
@@ -323,6 +338,12 @@
       return false;
     }
 
+    compilerOptions.bytecode = options['gen-bytecode'];
+    final BytecodeOptions bytecodeOptions = new BytecodeOptions(
+        enableAsserts: options['enable-asserts'],
+        environmentDefines: environmentDefines)
+      ..parseCommandLineFlags(options['bytecode-options']);
+
     compilerOptions.target = createFrontEndTarget(
       options['target'],
       trackWidgetCreation: options['track-widget-creation'],
@@ -342,13 +363,15 @@
     Component component;
     if (options['incremental']) {
       _compilerOptions = compilerOptions;
+      _bytecodeOptions = bytecodeOptions;
       setVMEnvironmentDefines(environmentDefines, _compilerOptions);
 
       _compilerOptions.omitPlatform = false;
       _generator =
           generator ?? _createGenerator(new Uri.file(_initializeFromDill));
       await invalidateIfInitializingFromDill();
-      component = await _runWithPrintRedirection(() => _generator.compile());
+      component = await _runWithPrintRedirection(() async =>
+          await _generateBytecodeIfNeeded(await _generator.compile()));
     } else {
       if (options['link-platform']) {
         // TODO(aam): Remove linkedDependencies once platform is directly embedded
@@ -362,6 +385,9 @@
           aot: options['aot'],
           useGlobalTypeFlowAnalysis: options['tfa'],
           environmentDefines: environmentDefines,
+          genBytecode: compilerOptions.bytecode,
+          bytecodeOptions: bytecodeOptions,
+          dropAST: options['drop-ast'],
           useProtobufTreeShaker: options['protobuf-tree-shaker']));
     }
     if (component != null) {
@@ -388,6 +414,22 @@
     return errors.isEmpty;
   }
 
+  Future<Component> _generateBytecodeIfNeeded(Component component) async {
+    if (_compilerOptions.bytecode && errors.isEmpty) {
+      await runWithFrontEndCompilerContext(
+          _mainSource, _compilerOptions, component, () {
+        generateBytecode(component,
+            coreTypes: _generator.getCoreTypes(),
+            hierarchy: _generator.getClassHierarchy(),
+            options: _bytecodeOptions);
+        if (_options['drop-ast']) {
+          component = createFreshComponentWithBytecode(component);
+        }
+      });
+    }
+    return component;
+  }
+
   void _outputDependenciesDelta(Component component) async {
     Set<Uri> uris = new Set<Uri>();
     for (Uri uri in component.uriToSource.keys) {
@@ -399,11 +441,20 @@
       if (previouslyReportedDependencies.contains(uri)) {
         continue;
       }
-      _outputStream.writeln('+${await asFileUri(_fileSystem, uri)}');
+      try {
+        _outputStream.writeln('+${await asFileUri(_fileSystem, uri)}');
+      } on FileSystemException {
+        // Ignore errors from invalid import uris.
+      }
     }
     for (Uri uri in previouslyReportedDependencies) {
-      if (!uris.contains(uri)) {
+      if (uris.contains(uri)) {
+        continue;
+      }
+      try {
         _outputStream.writeln('-${await asFileUri(_fileSystem, uri)}');
+      } on FileSystemException {
+        // Ignore errors from invalid import uris.
       }
     }
     previouslyReportedDependencies = uris;
@@ -501,12 +552,12 @@
       _mainSource = _getFileOrUri(entryPoint);
     }
     errors.clear();
-    final Component deltaProgram =
-        await _generator.compile(entryPoint: _mainSource);
+    Component deltaProgram = await _generator.compile(entryPoint: _mainSource);
 
     if (deltaProgram != null && transformer != null) {
       transformer.transform(deltaProgram);
     }
+    deltaProgram = await _generateBytecodeIfNeeded(deltaProgram);
     await writeDillFile(deltaProgram, _kernelBinaryFilename);
     _outputStream.writeln(boundaryKey);
     await _outputDependenciesDelta(deltaProgram);
@@ -528,8 +579,10 @@
     Procedure procedure = await _generator.compileExpression(
         expression, definitions, typeDefinitions, libraryUri, klass, isStatic);
     if (procedure != null) {
+      Component component = createExpressionEvaluationComponent(procedure);
+      component = await _generateBytecodeIfNeeded(component);
       final IOSink sink = new File(_kernelBinaryFilename).openWrite();
-      sink.add(serializeProcedure(procedure));
+      sink.add(serializeComponent(component));
       await sink.close();
       _outputStream
           .writeln('$boundaryKey $_kernelBinaryFilename ${errors.length}');
diff --git a/pkg/vm/lib/transformations/protobuf_aware_treeshaker/transformer.dart b/pkg/vm/lib/transformations/protobuf_aware_treeshaker/transformer.dart
index c8c3e4f..7da3194 100644
--- a/pkg/vm/lib/transformations/protobuf_aware_treeshaker/transformer.dart
+++ b/pkg/vm/lib/transformations/protobuf_aware_treeshaker/transformer.dart
@@ -2,12 +2,9 @@
 // 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/api_prototype/constant_evaluator.dart'
-    as constants;
 import 'package:kernel/kernel.dart';
 import 'package:kernel/target/targets.dart';
 import 'package:kernel/core_types.dart';
-import 'package:kernel/vm/constants_native_effects.dart' as vm_constants;
 import 'package:meta/meta.dart';
 import 'package:vm/transformations/type_flow/transformer.dart' as globalTypeFlow
     show transformComponent;
@@ -25,14 +22,6 @@
   final coreTypes = new CoreTypes(component);
   component.computeCanonicalNames();
 
-  // Evaluate constants to ensure @pragma("vm:entry-point") is seen by the
-  // type-flow analysis.
-  final vmConstants = new vm_constants.VmConstantsBackend(coreTypes);
-  constants.transformComponent(component, vmConstants, environment, null,
-      keepFields: true,
-      evaluateAnnotations: true,
-      desugarSets: !target.supportsSetLiterals);
-
   TransformationInfo info = collectInfo ? TransformationInfo() : null;
 
   _treeshakeProtos(target, component, coreTypes, info);
@@ -42,19 +31,21 @@
 void _treeshakeProtos(Target target, Component component, CoreTypes coreTypes,
     TransformationInfo info) {
   globalTypeFlow.transformComponent(target, coreTypes, component);
+
   final collector = removeUnusedProtoReferences(component, coreTypes, info);
-  if (collector == null) {
-    return;
-  }
-  globalTypeFlow.transformComponent(target, coreTypes, component);
-  if (info != null) {
-    for (Class gmSubclass in collector.gmSubclasses) {
-      if (!gmSubclass.enclosingLibrary.classes.contains(gmSubclass)) {
-        info.removedMessageClasses.add(gmSubclass);
+  if (collector != null) {
+    globalTypeFlow.transformComponent(target, coreTypes, component);
+    if (info != null) {
+      for (Class gmSubclass in collector.gmSubclasses) {
+        if (!gmSubclass.enclosingLibrary.classes.contains(gmSubclass)) {
+          info.removedMessageClasses.add(gmSubclass);
+        }
       }
     }
   }
-  // Remove metadata added by the typeflow analysis.
+
+  // Remove metadata added by the typeflow analysis (even if the code doesn't
+  // use any protos).
   component.metadata.clear();
 }
 
diff --git a/pkg/vm/test/frontend_server_test.dart b/pkg/vm/test/frontend_server_test.dart
index a56d500..ed121c0 100644
--- a/pkg/vm/test/frontend_server_test.dart
+++ b/pkg/vm/test/frontend_server_test.dart
@@ -978,6 +978,22 @@
       expect(await starter(args), 0);
     });
 
+    test('compile with bytecode', () async {
+      var file = new File('${tempDir.path}/foo.dart')..createSync();
+      file.writeAsStringSync("main() {}\n");
+      var dillFile = new File('${tempDir.path}/app.dill');
+      expect(dillFile.existsSync(), equals(false));
+      final List<String> args = <String>[
+        '--sdk-root=${sdkRoot.toFilePath()}',
+        '--incremental',
+        '--platform=${platformKernel.path}',
+        '--output-dill=${dillFile.path}',
+        '--gen-bytecode',
+        file.path,
+      ];
+      expect(await starter(args), 0);
+    });
+
     test('compile "package:"-file', () async {
       Directory lib = new Directory('${tempDir.path}/lib')..createSync();
       new File('${lib.path}/foo.dart')
diff --git a/pkg/vm/testcases/bytecode/bootstrapping.dart.expect b/pkg/vm/testcases/bytecode/bootstrapping.dart.expect
index 1fcf912..15d60a1 100644
--- a/pkg/vm/testcases/bytecode/bootstrapping.dart.expect
+++ b/pkg/vm/testcases/bytecode/bootstrapping.dart.expect
@@ -124,14 +124,12 @@
 Bytecode {
   Entry                2
   CheckStack           0
-  PushConstant         CP#0
-  PushStatic           CP#0
+  LoadStatic           CP#0
   PushConstant         CP#1
   InterfaceCall        CP#2, 2
   AssertBoolean        0
   JumpIfTrue           L1
-  PushConstant         CP#0
-  PushStatic           CP#0
+  LoadStatic           CP#0
   PushConstant         CP#4
   InterfaceCall        CP#2, 2
   AssertBoolean        0
@@ -143,8 +141,7 @@
 L2:
   Push                 r1
   JumpIfTrue           L3
-  PushConstant         CP#0
-  PushStatic           CP#0
+  LoadStatic           CP#0
   PushConstant         CP#5
   InterfaceCall        CP#2, 2
   AssertBoolean        0
@@ -156,15 +153,13 @@
 L4:
   Push                 r0
   JumpIfFalse          L5
-  PushConstant         CP#0
-  PushStatic           CP#0
+  LoadStatic           CP#0
   DirectCall           CP#6, 1
   ReturnTOS
 L5:
   DirectCall           CP#8, 0
   PushNull
-  PushConstant         CP#0
-  PushStatic           CP#0
+  LoadStatic           CP#0
   DirectCall           CP#10, 2
   InterfaceCall        CP#12, 2
   ReturnTOS
@@ -214,12 +209,10 @@
 Bytecode {
   Entry                2
   CheckStack           0
-  PushConstant         CP#0
-  PushStatic           CP#0
+  LoadStatic           CP#0
   EqualsNull
   JumpIfFalse          L1
-  PushConstant         CP#1
-  PushStatic           CP#1
+  LoadStatic           CP#1
   DirectCall           CP#2, 1
   StoreLocal           r1
   Push                 r1
@@ -232,8 +225,7 @@
 L2:
   Push                 r0
   Drop1
-  PushConstant         CP#0
-  PushStatic           CP#0
+  LoadStatic           CP#0
   ReturnTOS
 }
 ConstantPool {
@@ -390,8 +382,7 @@
 Bytecode {
   Entry                2
   CheckStack           0
-  PushConstant         CP#0
-  PushStatic           CP#0
+  LoadStatic           CP#0
   EqualsNull
   JumpIfFalse          L1
   Allocate             CP#1
@@ -403,8 +394,7 @@
   DirectCall           CP#6, 2
   StoreStaticTOS       CP#0
 L1:
-  PushConstant         CP#0
-  PushStatic           CP#0
+  LoadStatic           CP#0
   ReturnTOS
 }
 ConstantPool {
@@ -592,12 +582,10 @@
 Bytecode {
   Entry                1
   CheckStack           0
-  PushConstant         CP#0
-  PushStatic           CP#0
+  LoadStatic           CP#0
   EqualsNull
   JumpIfFalse          L1
-  PushConstant         CP#1
-  PushStatic           CP#1
+  LoadStatic           CP#1
   EqualsNull
   BooleanNegateTOS
   PopLocal             r0
@@ -608,13 +596,11 @@
 L2:
   Push                 r0
   JumpIfFalse          L3
-  PushConstant         CP#1
-  PushStatic           CP#1
+  LoadStatic           CP#1
   DynamicCall          CP#3, 1
   StoreStaticTOS       CP#0
 L3:
-  PushConstant         CP#0
-  PushStatic           CP#0
+  LoadStatic           CP#0
   ReturnTOS
 }
 ConstantPool {
diff --git a/pkg/vm/testcases/bytecode/literals.dart.expect b/pkg/vm/testcases/bytecode/literals.dart.expect
index bbfb3d3..5b63921 100644
--- a/pkg/vm/testcases/bytecode/literals.dart.expect
+++ b/pkg/vm/testcases/bytecode/literals.dart.expect
@@ -390,8 +390,7 @@
 Bytecode {
   Entry                0
   CheckStack           0
-  PushConstant         CP#0
-  PushStatic           CP#0
+  LoadStatic           CP#0
   ReturnTOS
 }
 ConstantPool {
diff --git a/tests/modular/issue37523/def.dart b/pkg/vm/testcases/transformations/protobuf_aware_treeshaker/lib/nop_test.dart
similarity index 63%
copy from tests/modular/issue37523/def.dart
copy to pkg/vm/testcases/transformations/protobuf_aware_treeshaker/lib/nop_test.dart
index 3cda2b0..60997dc 100644
--- a/tests/modular/issue37523/def.dart
+++ b/pkg/vm/testcases/transformations/protobuf_aware_treeshaker/lib/nop_test.dart
@@ -2,14 +2,8 @@
 // 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 B {
-  const B();
+main() {
+  // Ensures the protobuf-aware tree shaker can also transform non-protobuf
+  // using code.
+  print("hello world");
 }
-
-class A {
-  final B b;
-  const A(this.b);
-}
-
-const ab = A(B());
-const b = B();
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 34ce647..dd9ea2c 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -924,7 +924,7 @@
     "..:libdart_nosnapshot_with_precompiler",
     "//third_party/zlib",
   ]
-  if (checkout_llvm) {
+  if (defined(checkout_llvm) && checkout_llvm) {
     deps += [ "//runtime/llvm_codegen/bit:test" ]
   }
   include_dirs = [
diff --git a/runtime/bin/file_macos.cc b/runtime/bin/file_macos.cc
index a80071a..7315cfe 100644
--- a/runtime/bin/file_macos.cc
+++ b/runtime/bin/file_macos.cc
@@ -80,17 +80,41 @@
   ASSERT(handle_->fd() >= 0);
   ASSERT(length > 0);
   int prot = PROT_NONE;
+  int map_flags = MAP_PRIVATE;
   switch (type) {
     case kReadOnly:
       prot = PROT_READ;
       break;
     case kReadExecute:
       prot = PROT_READ | PROT_EXEC;
+      if (IsAtLeastOS10_14()) {
+        map_flags |= (MAP_JIT | MAP_ANONYMOUS);
+      }
       break;
     default:
       return NULL;
   }
-  void* addr = mmap(NULL, length, prot, MAP_PRIVATE, handle_->fd(), position);
+  void* addr = NULL;
+  if ((type == kReadExecute) && IsAtLeastOS10_14()) {
+    addr = mmap(NULL, length, (PROT_READ | PROT_WRITE), map_flags, -1, 0);
+    if (addr == MAP_FAILED) {
+      Syslog::PrintErr("mmap failed %s\n", strerror(errno));
+      return NULL;
+    }
+    SetPosition(position);
+    if (!ReadFully(addr, length)) {
+      Syslog::PrintErr("ReadFully failed\n");
+      munmap(addr, length);
+      return NULL;
+    }
+    if (mprotect(addr, length, prot) != 0) {
+      Syslog::PrintErr("mprotect failed %s\n", strerror(errno));
+      munmap(addr, length);
+      return NULL;
+    }
+  } else {
+    addr = mmap(NULL, length, prot, map_flags, handle_->fd(), position);
+  }
   if (addr == MAP_FAILED) {
     return NULL;
   }
diff --git a/runtime/bin/file_system_watcher_win.cc b/runtime/bin/file_system_watcher_win.cc
index 33654c4..990f905 100644
--- a/runtime/bin/file_system_watcher_win.cc
+++ b/runtime/bin/file_system_watcher_win.cc
@@ -56,10 +56,6 @@
 
   DirectoryWatchHandle* handle =
       new DirectoryWatchHandle(dir, list_events, recursive);
-  // Issue a read directly, to be sure events are tracked from now on. This is
-  // okay, since in Dart, we create the socket and start reading immidiately.
-  handle->EnsureInitialized(EventHandler::delegate());
-  handle->IssueRead();
   return reinterpret_cast<intptr_t>(handle);
 }
 
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 673d993..54d9306 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -878,14 +878,6 @@
   file->Release();
 }
 
-static void LoadBytecode() {
-  if (Dart_IsVMFlagSet("enable_interpreter") ||
-      Dart_IsVMFlagSet("use_bytecode_compiler")) {
-    Dart_Handle result = Dart_ReadAllBytecode();
-    CHECK_RESULT(result);
-  }
-}
-
 bool RunMainIsolate(const char* script_name, CommandLineOptions* dart_options) {
   // Call CreateIsolateGroupAndSetup which creates an isolate and loads up
   // the specified application script.
@@ -951,10 +943,6 @@
                 script_name);
     }
 
-    if (Options::gen_snapshot_kind() == kAppJIT) {
-      LoadBytecode();
-    }
-
     if (Options::load_compilation_trace_filename() != NULL) {
       uint8_t* buffer = NULL;
       intptr_t size = 0;
diff --git a/runtime/bin/process_patch.dart b/runtime/bin/process_patch.dart
index dd38f77..86b6de3 100644
--- a/runtime/bin/process_patch.dart
+++ b/runtime/bin/process_patch.dart
@@ -234,10 +234,10 @@
       throw new ArgumentError("Path is not a String: $path");
     }
 
-    if (Platform.isWindows) {
+    if (Platform.isWindows && path.contains(' ') && !path.contains('"')) {
       // Escape paths that may contain spaces
       // Bug: https://github.com/dart-lang/sdk/issues/37751
-      _path = _windowsArgumentEscape(path);
+      _path = '"$path"';
     } else {
       _path = path;
     }
diff --git a/runtime/bin/run_vm_tests.cc b/runtime/bin/run_vm_tests.cc
index aab804b..b4a5020 100644
--- a/runtime/bin/run_vm_tests.cc
+++ b/runtime/bin/run_vm_tests.cc
@@ -210,6 +210,7 @@
         /*shared_data=*/nullptr, /*shared_instructions=*/nullptr, flags,
         isolate_group_data, /*isolate_data=*/nullptr, error);
     if (*error != nullptr) {
+      OS::PrintErr("Error creating isolate group: %s\n", *error);
       free(*error);
       *error = nullptr;
     }
diff --git a/runtime/bin/socket_patch.dart b/runtime/bin/socket_patch.dart
index 56fbc64..d6149e6 100644
--- a/runtime/bin/socket_patch.dart
+++ b/runtime/bin/socket_patch.dart
@@ -528,7 +528,7 @@
               s.setListening(read: false, write: false);
             });
             connecting.clear();
-          }, error: (e) {
+          }, error: (e, st) {
             timer.cancel();
             socket.close();
             // Keep first error, if present.
@@ -676,7 +676,7 @@
     if (len == 0) return null;
     var result = nativeRead(len);
     if (result is OSError) {
-      reportError(result, "Read failed");
+      reportError(result, StackTrace.current, "Read failed");
       return null;
     }
     if (result != null) {
@@ -699,7 +699,7 @@
     if (isClosing || isClosed) return null;
     var result = nativeRecvFrom();
     if (result is OSError) {
-      reportError(result, "Receive failed");
+      reportError(result, StackTrace.current, "Receive failed");
       return null;
     }
     if (result != null) {
@@ -747,7 +747,8 @@
         nativeWrite(bufferAndStart.buffer, bufferAndStart.start, bytes);
     if (result is OSError) {
       OSError osError = result;
-      scheduleMicrotask(() => reportError(osError, "Write failed"));
+      StackTrace st = StackTrace.current;
+      scheduleMicrotask(() => reportError(osError, st, "Write failed"));
       result = 0;
     }
     // The result may be negative, if we forced a short write for testing
@@ -776,7 +777,8 @@
         bytes, (address as _InternetAddress)._in_addr, port);
     if (result is OSError) {
       OSError osError = result;
-      scheduleMicrotask(() => reportError(osError, "Send failed"));
+      StackTrace st = StackTrace.current;
+      scheduleMicrotask(() => reportError(osError, st, "Send failed"));
       result = 0;
     }
     // TODO(ricow): Remove when we track internal and pipe uses.
@@ -934,7 +936,7 @@
 
         if (i == errorEvent) {
           if (!isClosing) {
-            reportError(nativeGetError(), "");
+            reportError(nativeGetError(), null, "");
           }
         } else if (!isClosed) {
           // If the connection is closed right after it's accepted, there's a
@@ -1092,11 +1094,11 @@
     }
   }
 
-  void reportError(error, String message) {
+  void reportError(error, StackTrace st, String message) {
     var e = createError(error, message, address, localPort);
     // Invoke the error handler if any.
     if (eventHandlers[errorEvent] != null) {
-      eventHandlers[errorEvent](e);
+      eventHandlers[errorEvent](e, st);
     }
     // For all errors we close the socket
     close();
@@ -1242,8 +1244,8 @@
         _controller.add(new _RawSocket(socket));
         if (_controller.isPaused) return;
       }
-    }), error: zone.bindUnaryCallbackGuarded((e) {
-      _controller.addError(e);
+    }), error: zone.bindBinaryCallbackGuarded((e, st) {
+      _controller.addError(e, st);
       _controller.close();
     }), destroyed: () {
       _controller.close();
@@ -1346,8 +1348,8 @@
           _controller.add(RawSocketEvent.closed);
           _controller.close();
         },
-        error: zone.bindUnaryCallbackGuarded((e) {
-          _controller.addError(e);
+        error: zone.bindBinaryCallbackGuarded((e, st) {
+          _controller.addError(e, st);
           _socket.close();
         }));
   }
@@ -1889,8 +1891,8 @@
           _controller.add(RawSocketEvent.closed);
           _controller.close();
         },
-        error: zone.bindUnaryCallbackGuarded((e) {
-          _controller.addError(e);
+        error: zone.bindBinaryCallbackGuarded((e, st) {
+          _controller.addError(e, st);
           _socket.close();
         }));
   }
diff --git a/runtime/docs/aot_binary_size_analysis.md b/runtime/docs/aot_binary_size_analysis.md
new file mode 100644
index 0000000..fafb16a
--- /dev/null
+++ b/runtime/docs/aot_binary_size_analysis.md
@@ -0,0 +1,30 @@
+# AOT code size analysis
+
+The Dart VM's AOT compiler has support for emitting binary size information
+for all the code that gets generated. This information can then be visualized.
+
+## Telling the AOT compiler to generate binary size information
+
+Our AOT compiler accepts an extra `--print-instructions-sizes-to=sizes.json`
+flag. If supplied the AOT compiler will emit binary size information for all
+generated functions to `sizes.json`.
+
+This flag can be passed to `gen_snapshot` directly, or to the various wrapper
+scripts (e.g. `pkg/vm/tool/precompiler2`):
+
+```
+% tools/build.py -mrelease -ax64 runtime_kernel dart_precompiled_runtime
+% pkg/vm/tool/precompiler2 --print-instructions-sizes-to=hello_sizes.json hello.dart hello.dart.aot
+```
+
+## Visualizing the information from the binary size json file
+
+To visualize the information emitted by the AOT compiler one can use our binary
+size analysis tool:
+
+```
+% dart pkg/vm/bin/run_binary_size_analysis.dart hello_sizes.json hello_sizes
+Generated file:///.../sdk/hello_sizes/index.html
+% chrome hello_sizes/index.html
+```
+
diff --git a/runtime/lib/async_patch.dart b/runtime/lib/async_patch.dart
index 8ee544e..c1143fb7 100644
--- a/runtime/lib/async_patch.dart
+++ b/runtime/lib/async_patch.dart
@@ -18,30 +18,24 @@
 _fatal(msg) native "DartAsync_fatal";
 
 class _AsyncAwaitCompleter<T> implements Completer<T> {
-  final _completer = new Completer<T>.sync();
+  final _future = new _Future<T>();
   bool isSync;
 
   _AsyncAwaitCompleter() : isSync = false;
 
   void complete([FutureOr<T> value]) {
-    if (isSync) {
-      _completer.complete(value);
-    } else if (value is Future<T>) {
-      value.then(_completer.complete, onError: _completer.completeError);
+    if (!isSync || value is Future<T>) {
+      _future._asyncComplete(value);
     } else {
-      scheduleMicrotask(() {
-        _completer.complete(value);
-      });
+      _future._completeWithValue(value);
     }
   }
 
   void completeError(e, [st]) {
     if (isSync) {
-      _completer.completeError(e, st);
+      _future._completeError(e, st);
     } else {
-      scheduleMicrotask(() {
-        _completer.completeError(e, st);
-      });
+      _future._asyncCompleteError(e, st);
     }
   }
 
@@ -50,8 +44,8 @@
     isSync = true;
   }
 
-  Future<T> get future => _completer.future;
-  bool get isCompleted => _completer.isCompleted;
+  Future<T> get future => _future;
+  bool get isCompleted => !_future._mayComplete;
 }
 
 // We need to pass the value as first argument and leave the second and third
@@ -107,7 +101,7 @@
   // We can only do this for our internal futures (the default implementation of
   // all futures that are constructed by the `dart:async` library).
   object._awaiter = awaiter;
-  return object._thenNoZoneRegistration(thenCallback, errorCallback);
+  return object._thenAwait(thenCallback, errorCallback);
 }
 
 // Called as part of the 'await for (...)' construct. Registers the
@@ -143,7 +137,7 @@
   bool onListenReceived = false;
   bool isScheduled = false;
   bool isSuspendedAtYield = false;
-  Completer cancellationCompleter = null;
+  _Future cancellationFuture = null;
 
   Stream<T> get stream {
     final Stream<T> local = controller.stream;
@@ -210,10 +204,10 @@
   }
 
   void addError(Object error, StackTrace stackTrace) {
-    if ((cancellationCompleter != null) && !cancellationCompleter.isCompleted) {
+    if ((cancellationFuture != null) && cancellationFuture._mayComplete) {
       // If the stream has been cancelled, complete the cancellation future
       // with the error.
-      cancellationCompleter.completeError(error, stackTrace);
+      cancellationFuture._completeError(error, stackTrace);
       return;
     }
     // If stream is cancelled, tell caller to exit the async generator.
@@ -226,10 +220,10 @@
   }
 
   close() {
-    if ((cancellationCompleter != null) && !cancellationCompleter.isCompleted) {
+    if ((cancellationFuture != null) && cancellationFuture._mayComplete) {
       // If the stream has been cancelled, complete the cancellation future
       // with the error.
-      cancellationCompleter.complete();
+      cancellationFuture._completeWithValue(null);
     }
     controller.close();
   }
@@ -257,8 +251,8 @@
     if (controller.isClosed) {
       return null;
     }
-    if (cancellationCompleter == null) {
-      cancellationCompleter = new Completer();
+    if (cancellationFuture == null) {
+      cancellationFuture = new _Future();
       // Only resume the generator if it is suspended at a yield.
       // Cancellation does not affect an async generator that is
       // suspended at an await.
@@ -266,7 +260,7 @@
         scheduleGenerator();
       }
     }
-    return cancellationCompleter.future;
+    return cancellationFuture;
   }
 }
 
diff --git a/runtime/lib/ffi_dynamic_library.cc b/runtime/lib/ffi_dynamic_library.cc
index 7260b2b..e923b6a 100644
--- a/runtime/lib/ffi_dynamic_library.cc
+++ b/runtime/lib/ffi_dynamic_library.cc
@@ -36,14 +36,20 @@
 #elif defined(HOST_OS_WINDOWS)
   SetLastError(0);  // Clear any errors.
 
-  // Convert to wchar_t string.
-  const int name_len =
-      MultiByteToWideChar(CP_UTF8, 0, library_file, -1, NULL, 0);
-  wchar_t* name = new wchar_t[name_len];
-  MultiByteToWideChar(CP_UTF8, 0, library_file, -1, name, name_len);
+  void* ext;
 
-  void* ext = LoadLibraryW(name);
-  delete[] name;
+  if (library_file == nullptr) {
+    ext = GetModuleHandle(nullptr);
+  } else {
+    // Convert to wchar_t string.
+    const int name_len =
+        MultiByteToWideChar(CP_UTF8, 0, library_file, -1, NULL, 0);
+    wchar_t* name = new wchar_t[name_len];
+    MultiByteToWideChar(CP_UTF8, 0, library_file, -1, name, name_len);
+
+    ext = LoadLibraryW(name);
+    delete[] name;
+  }
 
   if (ext == nullptr) {
     const int error = GetLastError();
@@ -70,6 +76,22 @@
   return DynamicLibrary::New(handle);
 }
 
+DEFINE_NATIVE_ENTRY(Ffi_dl_processLibrary, 0, 0) {
+#if defined(HOST_OS_LINUX) || defined(HOST_OS_MACOS) || defined(HOST_OS_ANDROID)
+  return DynamicLibrary::New(RTLD_DEFAULT);
+#else
+  const Array& args = Array::Handle(Array::New(1));
+  args.SetAt(0,
+             String::Handle(String::New(
+                 "DynamicLibrary.process is not available on this platform.")));
+  Exceptions::ThrowByType(Exceptions::kUnsupported, args);
+#endif
+}
+
+DEFINE_NATIVE_ENTRY(Ffi_dl_executableLibrary, 0, 0) {
+  return DynamicLibrary::New(LoadExtensionLibrary(nullptr));
+}
+
 static void* ResolveSymbol(void* handle, const char* symbol) {
 #if defined(HOST_OS_LINUX) || defined(HOST_OS_MACOS) || defined(HOST_OS_ANDROID)
   dlerror();  // Clear any errors.
diff --git a/runtime/lib/ffi_dynamic_library_patch.dart b/runtime/lib/ffi_dynamic_library_patch.dart
index 16c1f78..32cabc6 100644
--- a/runtime/lib/ffi_dynamic_library_patch.dart
+++ b/runtime/lib/ffi_dynamic_library_patch.dart
@@ -8,6 +8,8 @@
 import 'dart:typed_data' show TypedData;
 
 DynamicLibrary _open(String name) native "Ffi_dl_open";
+DynamicLibrary _processLibrary() native "Ffi_dl_processLibrary";
+DynamicLibrary _executableLibrary() native "Ffi_dl_executableLibrary";
 
 @patch
 @pragma("vm:entry-point")
@@ -18,6 +20,12 @@
   }
 
   @patch
+  factory DynamicLibrary.process() => _processLibrary();
+
+  @patch
+  factory DynamicLibrary.executable() => _executableLibrary();
+
+  @patch
   Pointer<T> lookup<T extends NativeType>(String symbolName)
       native "Ffi_dl_lookup";
 
diff --git a/runtime/lib/ffi_native_type_patch.dart b/runtime/lib/ffi_native_type_patch.dart
index 8378e07..edc43950 100644
--- a/runtime/lib/ffi_native_type_patch.dart
+++ b/runtime/lib/ffi_native_type_patch.dart
@@ -7,9 +7,12 @@
 import "dart:_internal" show patch;
 import 'dart:typed_data' show TypedData;
 
+// NativeType is not private, because it is used in type arguments.
+// NativeType is abstract because it not used with const constructors in
+// annotations directly, so it should never be instantiated at runtime.
 @patch
 @pragma("vm:entry-point")
-class NativeType {}
+abstract class NativeType {}
 
 @patch
 @pragma("vm:entry-point")
diff --git a/runtime/lib/string_patch.dart b/runtime/lib/string_patch.dart
index 6bf950f..c08bd49 100644
--- a/runtime/lib/string_patch.dart
+++ b/runtime/lib/string_patch.dart
@@ -219,6 +219,8 @@
     return createFromCharCodes(charCodeList, 0, length, bits);
   }
 
+  // Inlining is disabled as a workaround to http://dartbug.com/37800.
+  @pragma("vm:never-inline")
   static String _createOneByteString(List<int> charCodes, int start, int len) {
     // It's always faster to do this in Dart than to call into the runtime.
     var s = _OneByteString._allocate(len);
diff --git a/runtime/observatory/lib/elements.dart b/runtime/observatory/lib/elements.dart
index 5a57241..e671967 100644
--- a/runtime/observatory/lib/elements.dart
+++ b/runtime/observatory/lib/elements.dart
@@ -49,8 +49,6 @@
 export 'package:observatory/src/elements/logging.dart';
 export 'package:observatory/src/elements/megamorphiccache_ref.dart';
 export 'package:observatory/src/elements/megamorphiccache_view.dart';
-export 'package:observatory/src/elements/memory/dashboard.dart';
-export 'package:observatory/src/elements/memory/graph.dart';
 export 'package:observatory/src/elements/metric/details.dart';
 export 'package:observatory/src/elements/metric/graph.dart';
 export 'package:observatory/src/elements/metrics.dart';
diff --git a/runtime/observatory/lib/heap_snapshot.dart b/runtime/observatory/lib/heap_snapshot.dart
index 84bc390..331f1c7 100644
--- a/runtime/observatory/lib/heap_snapshot.dart
+++ b/runtime/observatory/lib/heap_snapshot.dart
@@ -5,6 +5,7 @@
 library heap_snapshot;
 
 import 'dart:async';
+import 'dart:typed_data';
 import 'package:observatory/models.dart' as M;
 import 'package:observatory/object_graph.dart';
 import 'package:observatory/service.dart' as S;
diff --git a/runtime/observatory/lib/models.dart b/runtime/observatory/lib/models.dart
index c5a6538..60809ef 100644
--- a/runtime/observatory/lib/models.dart
+++ b/runtime/observatory/lib/models.dart
@@ -5,6 +5,8 @@
 library models;
 
 import 'dart:async';
+import 'dart:typed_data';
+import 'package:observatory/object_graph.dart';
 
 part 'src/models/exceptions.dart';
 
@@ -91,7 +93,6 @@
 part 'src/models/repositories/subtype_test_cache.dart';
 part 'src/models/repositories/target.dart';
 part 'src/models/repositories/timeline.dart';
-part 'src/models/repositories/top_retaining_instances.dart';
 part 'src/models/repositories/type_arguments.dart';
 part 'src/models/repositories/unlinked_call.dart';
 part 'src/models/repositories/vm.dart';
diff --git a/runtime/observatory/lib/object_graph.dart b/runtime/observatory/lib/object_graph.dart
index cb98b6e..88643d7 100644
--- a/runtime/observatory/lib/object_graph.dart
+++ b/runtime/observatory/lib/object_graph.dart
@@ -6,214 +6,93 @@
 
 import 'dart:async';
 import 'dart:collection';
+import 'dart:convert';
 import 'dart:typed_data';
 
 import 'package:logging/logging.dart';
 
-class _JenkinsSmiHash {
-  static int combine(int hash, int value) {
-    hash = 0x1fffffff & (hash + value);
-    hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
-    return hash ^ (hash >> 6);
-  }
-
-  static int finish(int hash) {
-    hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
-    hash = hash ^ (hash >> 11);
-    return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
-  }
-
-  static int hash3(a, b, c) => finish(combine(combine(combine(0, a), b), c));
-}
-
-// Map<[uint32, uint32, uint32], uint32>
-class AddressMapper {
-  final Uint32List _table;
-
-  // * 4 ~/3 for 75% load factor
-  // * 4 for four-tuple entries
-  AddressMapper(int N) : _table = new Uint32List((N * 4 ~/ 3) * 4);
-
-  int _scanFor(int high, int mid, int low) {
-    var hash = _JenkinsSmiHash.hash3(high, mid, low);
-    var start = (hash % _table.length) & ~3;
-    var index = start;
-    do {
-      if (_table[index + 3] == 0) return index;
-      if (_table[index] == high &&
-          _table[index + 1] == mid &&
-          _table[index + 2] == low) return index;
-      index = (index + 4) % _table.length;
-    } while (index != start);
-
-    throw new Exception("Interal error: table full");
-  }
-
-  int get(int high, int mid, int low) {
-    int index = _scanFor(high, mid, low);
-    if (_table[index + 3] == 0) return null;
-    return _table[index + 3];
-  }
-
-  int put(int high, int mid, int low, int id) {
-    if (id == 0) throw new Exception("Internal error: invalid id");
-
-    int index = _scanFor(high, mid, low);
-    if ((_table[index + 3] != 0)) {
-      throw new Exception("Internal error: attempt to overwrite key");
-    }
-    _table[index] = high;
-    _table[index + 1] = mid;
-    _table[index + 2] = low;
-    _table[index + 3] = id;
-    return id;
-  }
-}
-
-// Port of dart::ReadStream from vm/datastream.h.
-//
-// The heap snapshot is a series of variable-length unsigned integers. For
-// each byte in the stream, the high bit marks the last byte of an integer and
-// the low 7 bits are the payload. The payloads are sent in little endian
-// order.
-// The largest values used are 64-bit addresses.
-// We read in 4 payload chunks (28-bits) to stay in Smi range on Javascript.
-// We read them into instance variables ('low', 'mid' and 'high') to avoid
-// allocating a container.
-class ReadStream {
-  int position = 0;
-  int _size = 0;
+class _ReadStream {
   final List<ByteData> _chunks;
+  int _chunkIndex = 0;
+  int _byteIndex = 0;
 
-  ReadStream(this._chunks) {
-    int n = _chunks.length;
-    for (var i = 0; i < n; i++) {
-      var chunk = _chunks[i];
-      if (i + 1 != n) {
-        assert(chunk.lengthInBytes == (1 << 20));
+  _ReadStream(this._chunks);
+
+  int readByte() {
+    while (_byteIndex >= _chunks[_chunkIndex].lengthInBytes) {
+      _chunkIndex++;
+      _byteIndex = 0;
+    }
+    return _chunks[_chunkIndex].getUint8(_byteIndex++);
+  }
+
+  /// Read one ULEB128 number.
+  int readUnsigned() {
+    int result = 0;
+    int shift = 0;
+    for (;;) {
+      int part = readByte();
+      result |= (part & 0x7F) << shift;
+      if ((part & 0x80) == 0) {
+        break;
       }
-      _size += chunk.lengthInBytes;
+      shift += 7;
     }
+    return result;
   }
 
-  int get pendingBytes => _size - position;
-
-  int _getUint8(i) {
-    return _chunks[i >> 20].getUint8(i & 0xFFFFF);
+  /// Read one SLEB128 number.
+  int readSigned() {
+    int result = 0;
+    int shift = 0;
+    for (;;) {
+      int part = readByte();
+      result |= (part & 0x7F) << shift;
+      shift += 7;
+      if ((part & 0x80) == 0) {
+        if ((part & 0x40) != 0) {
+          result |= (-1 << shift);
+        }
+        break;
+      }
+    }
+    return result;
   }
 
-  int low = 0;
-  int mid = 0;
-  int high = 0;
-
-  int get clampedUint32 {
-    if (high != 0 || mid > 0xF) {
-      return 0xFFFFFFFF;
-    } else {
-      // Not shift as JS shifts are signed 32-bit.
-      return mid * 0x10000000 + low;
+  double readFloat64() {
+    var bytes = new Uint8List(8);
+    for (var i = 0; i < 8; i++) {
+      bytes[i] = readByte();
     }
+    return new Float64List.view(bytes.buffer)[0];
   }
 
-  int get highUint32 {
-    return high * (1 << 24) + (mid >> 4);
+  String readUtf8() {
+    int len = readUnsigned();
+    var bytes = new Uint8List(len);
+    for (var i = 0; i < len; i++) {
+      bytes[i] = readByte();
+    }
+    return new Utf8Codec(allowMalformed: true).decode(bytes);
   }
 
-  int get lowUint32 {
-    return (mid & 0xF) * (1 << 28) + low;
+  String readLatin1() {
+    int len = readUnsigned();
+    var codeUnits = new Uint8List(len);
+    for (var i = 0; i < len; i++) {
+      codeUnits[i] = readByte();
+    }
+    return new String.fromCharCodes(codeUnits);
   }
 
-  bool get isZero {
-    return (high == 0) && (mid == 0) && (low == 0);
+  String readUtf16() {
+    int len = readUnsigned();
+    var codeUnits = new Uint16List(len);
+    for (var i = 0; i < len; i++) {
+      codeUnits[i] = readByte() | (readByte() << 8);
+    }
+    return new String.fromCharCodes(codeUnits);
   }
-
-  void readUnsigned() {
-    low = 0;
-    mid = 0;
-    high = 0;
-
-    // Low 28 bits.
-    var digit = _getUint8(position++);
-    if (digit > maxUnsignedDataPerByte) {
-      low |= (digit & byteMask << 0);
-      return;
-    }
-    low |= (digit << 0);
-
-    digit = _getUint8(position++);
-    if (digit > maxUnsignedDataPerByte) {
-      low |= ((digit & byteMask) << 7);
-      return;
-    }
-    low |= (digit << 7);
-
-    digit = _getUint8(position++);
-    if (digit > maxUnsignedDataPerByte) {
-      low |= ((digit & byteMask) << 14);
-      return;
-    }
-    low |= (digit << 14);
-
-    digit = _getUint8(position++);
-    if (digit > maxUnsignedDataPerByte) {
-      low |= ((digit & byteMask) << 21);
-      return;
-    }
-    low |= (digit << 21);
-
-    // Mid 28 bits.
-    digit = _getUint8(position++);
-    if (digit > maxUnsignedDataPerByte) {
-      mid |= (digit & byteMask << 0);
-      return;
-    }
-    mid |= (digit << 0);
-
-    digit = _getUint8(position++);
-    if (digit > maxUnsignedDataPerByte) {
-      mid |= ((digit & byteMask) << 7);
-      return;
-    }
-    mid |= (digit << 7);
-
-    digit = _getUint8(position++);
-    if (digit > maxUnsignedDataPerByte) {
-      mid |= ((digit & byteMask) << 14);
-      return;
-    }
-    mid |= (digit << 14);
-
-    digit = _getUint8(position++);
-    if (digit > maxUnsignedDataPerByte) {
-      mid |= ((digit & byteMask) << 21);
-      return;
-    }
-    mid |= (digit << 21);
-
-    // High 28 bits.
-    digit = _getUint8(position++);
-    if (digit > maxUnsignedDataPerByte) {
-      high |= (digit & byteMask << 0);
-      return;
-    }
-    high |= (digit << 0);
-
-    digit = _getUint8(position++);
-    if (digit > maxUnsignedDataPerByte) {
-      high |= ((digit & byteMask) << 7);
-      return;
-    }
-    high |= (digit << 7);
-    throw new Exception("Format error: snapshot field exceeds 64 bits");
-  }
-
-  void skipUnsigned() {
-    while (_getUint8(position++) <= maxUnsignedDataPerByte);
-  }
-
-  static const int dataBitsPerByte = 7;
-  static const int byteMask = (1 << dataBitsPerByte) - 1;
-  static const int maxUnsignedDataPerByte = byteMask;
 }
 
 // Node indices for the root and sentinel nodes. Note that using 0 as the
@@ -222,73 +101,90 @@
 const ROOT = 1;
 const SENTINEL = 0;
 
-class ObjectVertex {
+abstract class SnapshotObject {
+  String get label;
+  String get description;
+  SnapshotClass get klass;
+  int get shallowSize;
+  int get externalSize;
+  int get retainedSize;
+  Iterable<SnapshotObject> get successors;
+  Iterable<SnapshotObject> get predecessors;
+  SnapshotObject get parent;
+  Iterable<SnapshotObject> get children;
+  List<SnapshotObject> get objects;
+}
+
+class _SnapshotObject implements SnapshotObject {
   final int _id;
-  final ObjectGraph _graph;
+  final _SnapshotGraph _graph;
+  final String label;
 
-  ObjectVertex._(this._id, this._graph);
+  _SnapshotObject._(this._id, this._graph, this.label);
 
-  bool get isRoot => ROOT == _id;
-  bool get isStack => vmCid == _graph._kStackCid;
+  bool operator ==(other) {
+    if (other is _SnapshotObject) {
+      return _id == other._id && _graph == other._graph;
+    }
+    return false;
+  }
 
-  bool operator ==(other) => _id == other._id && _graph == other._graph;
   int get hashCode => _id;
 
-  int get retainedSize => _graph._retainedSizes[_id];
-  ObjectVertex get dominator => new ObjectVertex._(_graph._doms[_id], _graph);
-
   int get shallowSize => _graph._shallowSizes[_id];
   int get externalSize => _graph._externalSizes[_id];
-  int get vmCid => _graph._cids[_id];
+  int get retainedSize => _graph._retainedSizes[_id];
 
-  get successors => new _SuccessorsIterable(_graph, _id);
+  String get description => _graph._describeObject(_id);
+  SnapshotClass get klass => _graph._classes[_graph._cids[_id]];
 
-  String get address {
-    // Note that everywhere else in this file, "address" really means an address
-    // scaled down by kObjectAlignment. They were scaled down so they would fit
-    // into Smis on the client.
+  Iterable<SnapshotObject> get successors =>
+      new _SuccessorsIterable(_graph, _id);
 
-    var high32 = _graph._addressesHigh[_id];
-    var low32 = _graph._addressesLow[_id];
-
-    // Complicated way to do (high:low * _kObjectAlignment).toHexString()
-    // without intermediate values exceeding int32.
-
-    var strAddr = "";
-    var carry = 0;
-    combine4(nibble) {
-      nibble = nibble * _graph._kObjectAlignment + carry;
-      carry = nibble >> 4;
-      nibble = nibble & 0xF;
-      strAddr = nibble.toRadixString(16) + strAddr;
-    }
-
-    combine32(thirtyTwoBits) {
-      for (int shift = 0; shift < 32; shift += 4) {
-        combine4((thirtyTwoBits >> shift) & 0xF);
+  Iterable<SnapshotObject> get predecessors {
+    var result = new List<SnapshotObject>();
+    var firstSuccs = _graph._firstSuccs;
+    var succs = _graph._succs;
+    var id = _id;
+    var N = _graph._N;
+    for (var predId = 1; predId <= N; predId++) {
+      var base = firstSuccs[predId];
+      var limit = firstSuccs[predId + 1];
+      for (var i = base; i < limit; i++) {
+        if (succs[i] == id) {
+          var cid = _graph._cids[predId];
+          var name = _graph._edgeName(cid, i - base);
+          result.add(new _SnapshotObject._(predId, _graph, name));
+        }
       }
     }
-
-    combine32(low32);
-    combine32(high32);
-    return strAddr;
+    return result;
   }
 
-  List<ObjectVertex> dominatorTreeChildren() {
+  SnapshotObject get parent {
+    if (_id == ROOT) {
+      return this;
+    }
+    return new _SnapshotObject._(_graph._doms[_id], _graph, "");
+  }
+
+  Iterable<SnapshotObject> get children {
     var N = _graph._N;
     var doms = _graph._doms;
 
     var parentId = _id;
-    var domChildren = <ObjectVertex>[];
+    var domChildren = <SnapshotObject>[];
 
     for (var childId = ROOT; childId <= N; childId++) {
       if (doms[childId] == parentId) {
-        domChildren.add(new ObjectVertex._(childId, _graph));
+        domChildren.add(new _SnapshotObject._(childId, _graph, ""));
       }
     }
 
     return domChildren;
   }
+
+  List<SnapshotObject> get objects => <SnapshotObject>[this];
 }
 
 // A node in the dominator tree where siblings with the same class are merged.
@@ -299,17 +195,16 @@
 // different class.
 class MergedObjectVertex {
   final int _id;
-  final ObjectGraph _graph;
+  final _SnapshotGraph _graph;
 
   MergedObjectVertex._(this._id, this._graph);
 
   bool get isRoot => ROOT == _id;
-  bool get isStack => vmCid == _graph._kStackCid;
 
   bool operator ==(other) => _id == other._id && _graph == other._graph;
   int get hashCode => _id;
 
-  int get vmCid => _graph._cids[_id];
+  SnapshotClass get klass => _graph._classes[_graph._cids[_id]];
 
   int get shallowSize {
     var cids = _graph._cids;
@@ -355,6 +250,17 @@
     return count;
   }
 
+  List<SnapshotObject> get objects {
+    var result = <SnapshotObject>[];
+    var cids = _graph._cids;
+    var sibling = _id;
+    while (sibling != SENTINEL && cids[sibling] == cids[_id]) {
+      result.add(new _SnapshotObject._(sibling, _graph, ""));
+      sibling = _graph._mergedDomNext[sibling];
+    }
+    return result;
+  }
+
   List<MergedObjectVertex> dominatorTreeChildren() {
     var next = _graph._mergedDomNext;
     var cids = _graph._cids;
@@ -376,163 +282,239 @@
   }
 }
 
-class _SuccessorsIterable extends IterableBase<ObjectVertex> {
-  final ObjectGraph _graph;
+class _SuccessorsIterable extends IterableBase<SnapshotObject> {
+  final _SnapshotGraph _graph;
   final int _id;
 
   _SuccessorsIterable(this._graph, this._id);
 
-  Iterator<ObjectVertex> get iterator => new _SuccessorsIterator(_graph, _id);
+  Iterator<SnapshotObject> get iterator => new _SuccessorsIterator(_graph, _id);
 }
 
-class _SuccessorsIterator implements Iterator<ObjectVertex> {
-  final ObjectGraph _graph;
+class _SuccessorsIterator implements Iterator<SnapshotObject> {
+  final _SnapshotGraph _graph;
+  int _cid;
+  int _startSuccIndex;
   int _nextSuccIndex;
   int _limitSuccIndex;
 
-  ObjectVertex current;
+  SnapshotObject current;
 
   _SuccessorsIterator(this._graph, int id) {
-    _nextSuccIndex = _graph._firstSuccs[id];
+    _cid = _graph._cids[id];
+    _startSuccIndex = _graph._firstSuccs[id];
+    _nextSuccIndex = _startSuccIndex;
     _limitSuccIndex = _graph._firstSuccs[id + 1];
   }
 
   bool moveNext() {
     if (_nextSuccIndex < _limitSuccIndex) {
+      var index = _nextSuccIndex - _startSuccIndex;
       var succId = _graph._succs[_nextSuccIndex++];
-      current = new ObjectVertex._(succId, _graph);
+      var name = _graph._edgeName(_cid, index);
+      current = new _SnapshotObject._(succId, _graph, name);
       return true;
     }
     return false;
   }
 }
 
-class _VerticesIterable extends IterableBase<ObjectVertex> {
-  final ObjectGraph _graph;
+class _VerticesIterable extends IterableBase<SnapshotObject> {
+  final _SnapshotGraph _graph;
 
   _VerticesIterable(this._graph);
 
-  Iterator<ObjectVertex> get iterator => new _VerticesIterator(_graph);
+  Iterator<SnapshotObject> get iterator => new _VerticesIterator(_graph);
 }
 
-class _VerticesIterator implements Iterator<ObjectVertex> {
-  final ObjectGraph _graph;
+class _VerticesIterator implements Iterator<SnapshotObject> {
+  final _SnapshotGraph _graph;
 
   int _nextId = 0;
-  ObjectVertex current;
+  SnapshotObject current;
 
   _VerticesIterator(this._graph);
 
   bool moveNext() {
     if (_nextId == _graph._N) return false;
-    current = new ObjectVertex._(_nextId++, _graph);
+    current = new _SnapshotObject._(_nextId++, _graph, "");
     return true;
   }
 }
 
-class ObjectGraph {
-  ObjectGraph(List<ByteData> chunks, int nodeCount)
-      : this._chunks = chunks,
-        this._N = nodeCount;
+abstract class SnapshotClass {
+  String get name;
+  int get externalSize;
+  int get shallowSize;
+  int get ownedSize;
+  int get instanceCount;
+}
 
-  int get internalSize => _internalSize;
-  int get externalSize => _externalSize;
-  int get vertexCount => _N;
-  int get edgeCount => _E;
+class _SnapshotClass implements SnapshotClass {
+  final String name;
+  final String libName;
+  final String libUri;
+  final Map<int, String> fields = new Map<int, String>();
 
-  ObjectVertex get root => new ObjectVertex._(ROOT, this);
+  int totalExternalSize = 0;
+  int totalShallowSize = 0;
+  int totalInstanceCount = 0;
+
+  int ownedSize = 0;
+
+  int liveExternalSize = 0;
+  int liveShallowSize = 0;
+  int liveInstanceCount = 0;
+
+  int get shallowSize => liveShallowSize;
+  int get externalSize => liveExternalSize;
+  int get instanceCount => liveInstanceCount;
+
+  _SnapshotClass(this.name, this.libName, this.libUri);
+}
+
+abstract class SnapshotGraph {
+  int get shallowSize;
+  int get externalSize;
+  int get size;
+  int get capacity;
+
+  SnapshotObject get root;
+  MergedObjectVertex get mergedRoot;
+  Iterable<SnapshotClass> get classes;
+  Iterable<SnapshotObject> get objects;
+
+  factory SnapshotGraph(List<ByteData> chunks) => new _SnapshotGraph(chunks);
+  Stream<String> process();
+}
+
+const kNoData = 0;
+const kNullData = 1;
+const kBoolData = 2;
+const kIntData = 3;
+const kDoubleData = 4;
+const kLatin1Data = 5;
+const kUtf16Data = 6;
+const kLengthData = 7;
+const kNameData = 8;
+
+const kSentinelName = "<omitted-object>";
+const kRootName = "Root";
+const kUnknownFieldName = "<unknown>";
+
+class _SnapshotGraph implements SnapshotGraph {
+  _SnapshotGraph(List<ByteData> chunks) : this._chunks = chunks;
+
+  int get size => _liveShallowSize + _liveExternalSize;
+  int get shallowSize => _liveShallowSize;
+  int get externalSize => _liveExternalSize;
+  int get capacity => _capacity;
+
+  SnapshotObject get root => new _SnapshotObject._(ROOT, this, "Root");
   MergedObjectVertex get mergedRoot => new MergedObjectVertex._(ROOT, this);
-  Iterable<ObjectVertex> get vertices => new _VerticesIterable(this);
+  Iterable<SnapshotObject> get objects => new _VerticesIterable(this);
 
-  int get numCids => _numCids;
-  int getOwnedByCid(int cid) => _ownedSizesByCid[cid];
-
-  Iterable<ObjectVertex> getMostRetained({int classId, int limit}) {
-    if (limit != null && limit < 20) {
-      SplayTreeSet<int> workingSet = new SplayTreeSet<int>((int e1, int e2) {
-        int result = _retainedSizes[e2] - _retainedSizes[e1];
-        if (result != 0) return result;
-        return e2 - e1;
-      });
-
-      for (int i = ROOT + 1; i < _N; i++) {
-        if (classId != null && _cids[i] != classId) continue;
-        workingSet.add(i);
-        if (workingSet.length > limit) {
-          int smallest = workingSet.last;
-          workingSet.remove(smallest);
-        }
-      }
-
-      List<ObjectVertex> result = new List<ObjectVertex>();
-      for (int id in workingSet) {
-        result.add(new ObjectVertex._(id, this));
-      }
-      return result;
+  String _describeObject(int oid) {
+    if (oid == SENTINEL) {
+      return kSentinelName;
+    }
+    if (oid == ROOT) {
+      return kRootName;
+    }
+    var cls = _className(oid);
+    var data = _nonReferenceData[oid];
+    if (data == null) {
+      return cls;
     } else {
-      List<ObjectVertex> _mostRetained =
-          new List<ObjectVertex>.from(vertices.where((u) => !u.isRoot));
-      _mostRetained.sort((u, v) => v.retainedSize - u.retainedSize);
-
-      Iterable<ObjectVertex> result = _mostRetained;
-      if (classId != null) {
-        result = result.where((u) => u.vmCid == classId);
-      }
-      if (limit != null) {
-        result = result.take(limit);
-      }
-      return result;
+      return "$cls($data)";
     }
   }
 
-  Stream<List> process() {
-    final controller = new StreamController<List>.broadcast();
+  String _className(int oid) {
+    var cid = _cids[oid];
+    var cls = _classes[cid];
+    if (cls == null) {
+      return "Class$cid";
+    }
+    return cls.name;
+  }
+
+  String _edgeName(int cid, int index) {
+    var c = _classes[cid];
+    if (c == null) {
+      return kUnknownFieldName;
+    }
+    var n = c.fields[index];
+    if (n == null) {
+      return kUnknownFieldName;
+    }
+    return n;
+  }
+
+  List<SnapshotClass> get classes {
+    var result = new List<SnapshotClass>();
+    for (var c in _classes) {
+      if (c != null) {
+        result.add(c);
+      }
+    }
+    return result;
+  }
+
+  Stream<String> process() {
+    final controller = new StreamController<String>.broadcast();
     (() async {
       // We build futures here instead of marking the steps as async to avoid the
       // heavy lifting being inside a transformed method.
-
-      controller.add(["Remapping $_N objects...", 0.0]);
-      await new Future(() => _remapNodes());
-
-      controller.add(["Remapping $_E references...", 10.0]);
-      await new Future(() => _remapEdges());
-
-      _addrToId = null;
+      var stream = new _ReadStream(_chunks);
       _chunks = null;
 
-      controller.add(["Finding depth-first order...", 20.0]);
+      controller.add("Loading classes...");
+      await new Future(() => _readClasses(stream));
+
+      controller.add("Loading objects...");
+      await new Future(() => _readObjects(stream));
+
+      controller.add("Loading external properties...");
+      await new Future(() => _readExternalProperties(stream));
+      stream = null;
+
+      controller.add("Compute class table...");
+      await new Future(() => _computeClassTable());
+
+      controller.add("Finding depth-first order...");
       await new Future(() => _dfs());
 
-      controller.add(["Finding predecessors...", 30.0]);
+      controller.add("Finding predecessors...");
       await new Future(() => _buildPredecessors());
 
-      controller.add(["Finding dominators...", 40.0]);
+      controller.add("Finding dominators...");
       await new Future(() => _buildDominators());
 
       _semi = null;
       _parent = null;
 
-      controller.add(["Finding in-degree(1) groups...", 50.0]);
+      controller.add("Finding in-degree(1) groups...");
       await new Future(() => _buildOwnedSizes());
 
       _firstPreds = null;
       _preds = null;
 
-      controller.add(["Finding retained sizes...", 60.0]);
+      controller.add("Finding retained sizes...");
       await new Future(() => _calculateRetainedSizes());
 
       _vertex = null;
 
-      controller.add(["Linking dominator tree children...", 70.0]);
+      controller.add("Linking dominator tree children...");
       await new Future(() => _linkDominatorChildren());
 
-      controller.add(["Sorting dominator tree children...", 80.0]);
+      controller.add("Sorting dominator tree children...");
       await new Future(() => _sortDominatorChildren());
 
-      controller.add(["Merging dominator tree siblings...", 90.0]);
+      controller.add("Merging dominator tree siblings...");
       await new Future(() => _mergeDominatorSiblings());
 
-      controller.add(["Processed", 100.0]);
+      controller.add("Loaded");
       controller.close();
     }());
     return controller.stream;
@@ -540,28 +522,31 @@
 
   List<ByteData> _chunks;
 
-  int _kObjectAlignment;
   int _kStackCid;
   int _kFieldCid;
   int _numCids;
   int _N; // Objects in the snapshot.
   int _Nconnected; // Objects reachable from root.
   int _E; // References in the snapshot.
-  int _internalSize;
-  int _externalSize;
+
+  int _capacity;
+  int _liveShallowSize;
+  int _liveExternalSize;
+  int _totalShallowSize;
+  int _totalExternalSize;
+
+  List<_SnapshotClass> _classes;
 
   // Indexed by node id, with id 0 representing invalid/uninitialized.
   // From snapshot.
+  List _nonReferenceData;
   Uint16List _cids;
   Uint32List _shallowSizes;
   Uint32List _externalSizes;
   Uint32List _firstSuccs;
   Uint32List _succs;
-  Uint32List _addressesLow; // No Uint64List in Javascript.
-  Uint32List _addressesHigh;
 
   // Intermediates.
-  AddressMapper _addrToId;
   Uint32List _vertex;
   Uint32List _parent;
   Uint32List _semi;
@@ -573,121 +558,169 @@
   Uint32List _retainedSizes;
   Uint32List _mergedDomHead;
   Uint32List _mergedDomNext;
-  Uint32List _ownedSizesByCid;
 
-  void _remapNodes() {
-    var N = _N;
-    var E = 0;
-    var addrToId = new AddressMapper(N);
+  void _readClasses(_ReadStream stream) {
+    for (var i = 0; i < 8; i++) {
+      stream.readByte(); // Magic value.
+    }
+    stream.readUnsigned(); // Flags
+    stream.readUtf8(); // Name
 
-    var addressesHigh = new Uint32List(N + 1);
-    var addressesLow = new Uint32List(N + 1);
-    var shallowSizes = new Uint32List(N + 1);
-    var externalSizes = new Uint32List(N + 1);
-    var cids = new Uint16List(N + 1);
+    _totalShallowSize = stream.readUnsigned();
+    _capacity = stream.readUnsigned();
+    _totalExternalSize = stream.readUnsigned();
 
-    var stream = new ReadStream(_chunks);
-    stream.readUnsigned();
-    _kObjectAlignment = stream.clampedUint32;
-    stream.readUnsigned();
-    _kStackCid = stream.clampedUint32;
-    stream.readUnsigned();
-    _kFieldCid = stream.clampedUint32;
-    stream.readUnsigned();
-    _numCids = stream.clampedUint32;
+    var K = stream.readUnsigned();
+    var classes = new List<_SnapshotClass>(K + 1);
+    classes[0] = new _SnapshotClass("Root", "", "");
 
-    var id = ROOT;
-    while (id <= N) {
-      stream.readUnsigned(); // addr
-      addrToId.put(stream.high, stream.mid, stream.low, id);
-      addressesHigh[id] = stream.highUint32;
-      addressesLow[id] = stream.lowUint32;
-      stream.readUnsigned(); // shallowSize
-      shallowSizes[id] = stream.clampedUint32;
-      stream.readUnsigned(); // cid
-      cids[id] = stream.clampedUint32;
-
-      stream.readUnsigned();
-      while (!stream.isZero) {
-        E++;
-        stream.readUnsigned();
+    for (var cid = 1; cid <= K; cid++) {
+      int flags = stream.readUnsigned();
+      String name = stream.readUtf8();
+      String libName = stream.readUtf8();
+      String libUri = stream.readUtf8();
+      String reserved = stream.readUtf8();
+      var cls = new _SnapshotClass(name, libName, libUri);
+      int edgeCount = stream.readUnsigned();
+      for (int i = 0; i < edgeCount; i++) {
+        int flags = stream.readUnsigned();
+        int index = stream.readUnsigned();
+        String fieldName = stream.readUtf8();
+        String reserved = stream.readUtf8();
+        cls.fields[index] = fieldName;
       }
-      id++;
+      classes[cid] = cls;
     }
 
-    assert(ROOT == addrToId.get(0, 0, 0));
-
-    stream.readUnsigned();
-    assert(stream.isZero);
-
-    stream.readUnsigned(); // addr
-    while (!stream.isZero) {
-      var nodeId = addrToId.get(stream.high, stream.mid, stream.low);
-      stream.readUnsigned(); // externalSize
-      // The handle's object might be in the VM isolate or an immediate object,
-      // in which case the object isn't included in the snapshot.
-      if (nodeId != null) {
-        externalSizes[nodeId] += stream.clampedUint32;
-      }
-
-      stream.readUnsigned(); // addr
-    }
-
-    _E = E;
-    _addrToId = addrToId;
-    _addressesLow = addressesLow;
-    _addressesHigh = addressesHigh;
-    _shallowSizes = shallowSizes;
-    _externalSizes = externalSizes;
-    _cids = cids;
+    _numCids = K;
+    _classes = classes;
   }
 
-  void _remapEdges() {
-    var N = _N;
-    var E = _E;
-    var addrToId = _addrToId;
+  void _readObjects(_ReadStream stream) {
+    var E = stream.readUnsigned();
+    var N = stream.readUnsigned();
 
+    _N = N;
+    _E = E;
+
+    var shallowSizes = new Uint32List(N + 1);
+    var cids = new Uint16List(N + 1);
+    var nonReferenceData = new List(N + 1);
     var firstSuccs = new Uint32List(N + 2);
     var succs = new Uint32List(E);
+    var eid = 0;
+    for (var oid = 1; oid <= N; oid++) {
+      var cid = stream.readUnsigned();
+      cids[oid] = cid;
 
-    var stream = new ReadStream(_chunks);
-    stream.skipUnsigned(); // kObjectAlignment
-    stream.skipUnsigned(); // kStackCid
-    stream.skipUnsigned(); // kFieldCid
-    stream.skipUnsigned(); // numCids
+      var shallowSize = stream.readUnsigned();
+      shallowSizes[oid] = shallowSize;
 
-    var id = 1, edge = 0;
-    while (id <= N) {
-      stream.skipUnsigned(); // addr
-      stream.skipUnsigned(); // shallowSize
-      stream.skipUnsigned(); // cid
-
-      firstSuccs[id] = edge;
-
-      stream.readUnsigned();
-      while (!stream.isZero) {
-        var childId = addrToId.get(stream.high, stream.mid, stream.low);
-        if (childId != null) {
-          succs[edge] = childId;
-          edge++;
-        } else {
-          throw new Exception(
-              "Heap snapshot contains an edge but lacks its target node");
-        }
-        stream.readUnsigned();
+      var nonReferenceDataTag = stream.readUnsigned();
+      switch (nonReferenceDataTag) {
+        case kNoData:
+          break;
+        case kNullData:
+          nonReferenceData[oid] = "null";
+          break;
+        case kBoolData:
+          nonReferenceData[oid] = stream.readByte() != 0;
+          break;
+        case kIntData:
+          nonReferenceData[oid] = stream.readSigned();
+          break;
+        case kDoubleData:
+          nonReferenceData[oid] = stream.readFloat64();
+          break;
+        case kLatin1Data:
+          var len = stream.readUnsigned();
+          var str = stream.readLatin1();
+          if (str.length < len) {
+            nonReferenceData[oid] = '$str...';
+          } else {
+            nonReferenceData[oid] = str;
+          }
+          break;
+        case kUtf16Data:
+          int len = stream.readUnsigned();
+          var str = stream.readUtf16();
+          if (str.length < len) {
+            nonReferenceData[oid] = '$str...';
+          } else {
+            nonReferenceData[oid] = str;
+          }
+          break;
+        case kLengthData:
+          nonReferenceData[oid] = stream.readUnsigned(); // Length
+          break;
+        case kNameData:
+          nonReferenceData[oid] = stream.readUtf8(); // Name
+          break;
+        default:
+          throw "Unknown tag $nonReferenceDataTag";
       }
-      id++;
+
+      firstSuccs[oid] = eid;
+      var referenceCount = stream.readUnsigned();
+      while (referenceCount > 0) {
+        var childOid = stream.readUnsigned();
+        succs[eid] = childOid;
+        eid++;
+        referenceCount--;
+      }
     }
-    firstSuccs[id] = edge; // Extra entry for cheap boundary detection.
+    firstSuccs[N + 1] = eid;
 
-    assert(id == N + 1);
-    assert(edge == E);
-
-    _E = edge;
+    assert(eid <= E);
+    _E = eid;
+    _shallowSizes = shallowSizes;
+    _cids = cids;
+    _nonReferenceData = nonReferenceData;
     _firstSuccs = firstSuccs;
     _succs = succs;
   }
 
+  void _readExternalProperties(_ReadStream stream) {
+    var N = _N;
+    var externalPropertyCount = stream.readUnsigned();
+
+    var externalSizes = new Uint32List(N + 1);
+    for (var i = 0; i < externalPropertyCount; i++) {
+      var oid = stream.readUnsigned();
+      var externalSize = stream.readUnsigned();
+      var name = stream.readUtf8();
+      externalSizes[oid] += externalSize;
+    }
+
+    _externalSizes = externalSizes;
+  }
+
+  void _computeClassTable() {
+    var N = _N;
+    var classes = _classes;
+    var cids = _cids;
+    var shallowSizes = _shallowSizes;
+    var externalSizes = _externalSizes;
+    var totalShallowSize = 0;
+    var totalExternalSize = 0;
+
+    for (var oid = 1; oid <= N; oid++) {
+      var shallowSize = shallowSizes[oid];
+      totalShallowSize += shallowSize;
+
+      var externalSize = externalSizes[oid];
+      totalExternalSize += externalSize;
+
+      var cls = classes[cids[oid]];
+      cls.totalShallowSize += shallowSize;
+      cls.totalExternalSize += externalSize;
+      cls.totalInstanceCount++;
+    }
+
+    _totalShallowSize = totalShallowSize;
+    _totalExternalSize = totalExternalSize;
+  }
+
   void _dfs() {
     var N = _N;
     var firstSuccs = _firstSuccs;
@@ -723,7 +756,9 @@
         edgePos++;
         stackCurrentEdgePos[stackTop] = edgePos;
 
-        if (semi[childId] == 0) {
+        if (childId == SENTINEL) {
+          // Omitted target.
+        } else if (semi[childId] == 0) {
           parent[childId] = v;
 
           // Push child.
@@ -739,7 +774,8 @@
 
     if (dfsNumber != N) {
       // This may happen in filtered snapshots.
-      Logger.root.warning('Heap snapshot contains unreachable nodes.');
+      Logger.root.warning(
+          'Heap snapshot contains ${N - dfsNumber} unreachable nodes.');
     }
 
     assert(() {
@@ -892,14 +928,13 @@
 
     // TODO(rmacnak): Maybe keep the per-objects sizes to be able to provide
     // examples of large owners for each class.
-    var ownedSizesByCid = new Uint32List(_numCids);
+    var classes = _classes;
     for (var i = 1; i <= Nconnected; i++) {
       var v = vertex[i];
       var cid = cids[v];
-      ownedSizesByCid[cid] += ownedSizes[v];
+      var cls = classes[cid];
+      cls.ownedSize += ownedSizes[v];
     }
-
-    _ownedSizesByCid = ownedSizesByCid;
   }
 
   static int _eval(int v, Uint32List ancestor, Uint32List semi,
@@ -1057,8 +1092,10 @@
     var N = _N;
     var Nconnected = _Nconnected;
 
-    var internalSize = 0;
-    var externalSize = 0;
+    var liveShallowSize = 0;
+    var liveExternalSize = 0;
+    var classes = _classes;
+    var cids = _cids;
     var shallowSizes = _shallowSizes;
     var externalSizes = _externalSizes;
     var vertex = _vertex;
@@ -1067,8 +1104,15 @@
     // Sum internal and external sizes.
     for (var i = 1; i <= Nconnected; i++) {
       var v = vertex[i];
-      internalSize += shallowSizes[v];
-      externalSize += externalSizes[v];
+      var shallowSize = shallowSizes[v];
+      var externalSize = externalSizes[v];
+      liveShallowSize += shallowSize;
+      liveExternalSize += externalSize;
+
+      var cls = classes[cids[v]];
+      cls.liveShallowSize += shallowSize;
+      cls.liveExternalSize += externalSize;
+      cls.liveInstanceCount++;
     }
 
     // Start with retained size as shallow size + external size.
@@ -1086,11 +1130,19 @@
     }
 
     // Root retains everything.
-    assert(retainedSizes[ROOT] == (internalSize + externalSize));
+    assert(retainedSizes[ROOT] == (liveShallowSize + liveExternalSize));
 
     _retainedSizes = retainedSizes;
-    _internalSize = internalSize;
-    _externalSize = externalSize;
+    _liveShallowSize = liveShallowSize;
+    _liveExternalSize = liveExternalSize;
+
+    Logger.root
+        .info("internal-garbage: ${_totalShallowSize - _liveShallowSize}");
+    Logger.root
+        .info("external-garbage: ${_totalExternalSize - _liveExternalSize}");
+    Logger.root.info("fragmentation: ${_capacity - _totalShallowSize}");
+    assert(_liveShallowSize <= _totalShallowSize);
+    assert(_totalShallowSize <= _capacity);
   }
 
   // Build linked lists of the children for each node in the dominator tree.
diff --git a/runtime/observatory/lib/repositories.dart b/runtime/observatory/lib/repositories.dart
index e349ff2..51ea321 100644
--- a/runtime/observatory/lib/repositories.dart
+++ b/runtime/observatory/lib/repositories.dart
@@ -50,7 +50,6 @@
 part 'src/repositories/subtype_test_cache.dart';
 part 'src/repositories/target.dart';
 part 'src/repositories/timeline.dart';
-part 'src/repositories/top_retaining_instances.dart';
 part 'src/repositories/type_arguments.dart';
 part 'src/repositories/unlinked_call.dart';
 part 'src/repositories/vm.dart';
diff --git a/runtime/observatory/lib/service_common.dart b/runtime/observatory/lib/service_common.dart
index c2166c1..4e47b95 100644
--- a/runtime/observatory/lib/service_common.dart
+++ b/runtime/observatory/lib/service_common.dart
@@ -199,18 +199,15 @@
 
   void _onBinaryMessage(dynamic data) {
     _webSocket.nonStringToByteData(data).then((ByteData bytes) {
-      // See format spec. in VMs Service::SendEvent.
-      int offset = 0;
-      // Dart2JS workaround (no getUint64). Limit to 4 GB metadata.
-      assert(bytes.getUint32(offset, Endian.big) == 0);
-      int metaSize = bytes.getUint32(offset + 4, Endian.big);
-      offset += 8;
-      var meta = _utf8Decoder.convert(new Uint8List.view(
-          bytes.buffer, bytes.offsetInBytes + offset, metaSize));
-      offset += metaSize;
-      var data = new ByteData.view(bytes.buffer, bytes.offsetInBytes + offset,
-          bytes.lengthInBytes - offset);
-      var map = _parseJSON(meta);
+      var metadataOffset = 4;
+      var dataOffset = bytes.getUint32(0, Endian.little);
+      var metadataLength = dataOffset - metadataOffset;
+      var dataLength = bytes.lengthInBytes - dataOffset;
+      var metadata = _utf8Decoder.convert(new Uint8List.view(
+          bytes.buffer, bytes.offsetInBytes + metadataOffset, metadataLength));
+      var data = new ByteData.view(
+          bytes.buffer, bytes.offsetInBytes + dataOffset, dataLength);
+      var map = _parseJSON(metadata);
       if (map == null || map['method'] != 'streamNotify') {
         return;
       }
diff --git a/runtime/observatory/lib/src/app/application.dart b/runtime/observatory/lib/src/app/application.dart
index 9b7f90c..42ffe2e 100644
--- a/runtime/observatory/lib/src/app/application.dart
+++ b/runtime/observatory/lib/src/app/application.dart
@@ -173,7 +173,6 @@
     _pageRegistry.add(new PortsPage(this));
     _pageRegistry.add(new LoggingPage(this));
     _pageRegistry.add(new TimelinePage(this));
-    _pageRegistry.add(new MemoryDashboardPage(this));
     _pageRegistry.add(new TimelineDashboardPage(this));
     // Note that ErrorPage must be the last entry in the list as it is
     // the catch all.
diff --git a/runtime/observatory/lib/src/app/page.dart b/runtime/observatory/lib/src/app/page.dart
index c03847f..bcc224a 100644
--- a/runtime/observatory/lib/src/app/page.dart
+++ b/runtime/observatory/lib/src/app/page.dart
@@ -32,7 +32,6 @@
     new StronglyReachableInstancesRepository();
 final _subtypeTestCacheRepository = new SubtypeTestCacheRepository();
 final _timelineRepository = new TimelineRepository();
-final _topRetainingInstancesRepository = new TopRetainingInstancesRepository();
 final _typeArgumentsRepository = new TypeArgumentsRepository();
 final _unlinkedCallRepository = new UnlinkedCallRepository();
 final _vmrepository = new VMRepository();
@@ -266,7 +265,6 @@
                 _objectRepository,
                 _evalRepository,
                 _stronglyReachangleInstancesRepository,
-                _topRetainingInstancesRepository,
                 _classSampleProfileRepository,
                 queue: app.queue)
             .element
@@ -719,60 +717,6 @@
   }
 }
 
-class MemoryDashboardPage extends MatchingPage {
-  MemoryDashboardPage(app) : super('memory-dashboard', app);
-
-  final DivElement container = new DivElement();
-
-  void _visit(Uri uri) {
-    super._visit(uri);
-    if (app.vm == null) {
-      Logger.root.severe('MemoryDashboard has no VM');
-      // Reroute to vm-connect.
-      app.locationManager.go(Uris.vmConnect());
-      return;
-    }
-    final editor = getEditor(uri);
-    app.vm.reload().then((serviceObject) async {
-      VM vm = serviceObject;
-      // Preload all isolates to avoid sorting problems.
-      await Future.wait(vm.isolates.map((i) => i.load()));
-      container.children = <Element>[
-        new MemoryDashboardElement(
-                vm,
-                _vmrepository,
-                new IsolateRepository(vm),
-                editor,
-                _allocationProfileRepository,
-                _heapSnapshotRepository,
-                _objectRepository,
-                app.events,
-                app.notifications,
-                queue: app.queue)
-            .element
-      ];
-    }).catchError((e, stack) {
-      Logger.root.severe('MemoryDashboard visit error: $e');
-      // Reroute to vm-connect.
-      app.locationManager.go(Uris.vmConnect());
-    });
-  }
-
-  void onInstall() {
-    if (element == null) {
-      element = container;
-    }
-    app.startGCEventListener();
-  }
-
-  @override
-  void onUninstall() {
-    super.onUninstall();
-    app.stopGCEventListener();
-    container.children = const [];
-  }
-}
-
 class PortsPage extends MatchingPage {
   PortsPage(app) : super('ports', app);
 
diff --git a/runtime/observatory/lib/src/elements/class_instances.dart b/runtime/observatory/lib/src/elements/class_instances.dart
index 0ddb4e0..792f8e9 100644
--- a/runtime/observatory/lib/src/elements/class_instances.dart
+++ b/runtime/observatory/lib/src/elements/class_instances.dart
@@ -12,7 +12,6 @@
 import 'package:observatory/src/elements/retaining_path.dart';
 import 'package:observatory/src/elements/sentinel_value.dart';
 import 'package:observatory/src/elements/strongly_reachable_instances.dart';
-import 'package:observatory/src/elements/top_retaining_instances.dart';
 import 'package:observatory/utils.dart';
 
 class ClassInstancesElement extends CustomElement implements Renderable {
@@ -21,7 +20,6 @@
     ClassRefElement.tag,
     InboundReferencesElement.tag,
     RetainingPathElement.tag,
-    TopRetainingInstancesElement.tag
   ]);
 
   RenderingScheduler<ClassInstancesElement> _r;
@@ -33,7 +31,6 @@
   M.RetainedSizeRepository _retainedSizes;
   M.ReachableSizeRepository _reachableSizes;
   M.StronglyReachableInstancesRepository _stronglyReachableInstances;
-  M.TopRetainingInstancesRepository _topRetainingInstances;
   M.ObjectRepository _objects;
   M.Guarded<M.Instance> _retainedSize = null;
   bool _loadingRetainedBytes = false;
@@ -49,7 +46,6 @@
       M.RetainedSizeRepository retainedSizes,
       M.ReachableSizeRepository reachableSizes,
       M.StronglyReachableInstancesRepository stronglyReachableInstances,
-      M.TopRetainingInstancesRepository topRetainingInstances,
       M.ObjectRepository objects,
       {RenderingQueue queue}) {
     assert(isolate != null);
@@ -57,7 +53,6 @@
     assert(retainedSizes != null);
     assert(reachableSizes != null);
     assert(stronglyReachableInstances != null);
-    assert(topRetainingInstances != null);
     assert(objects != null);
     ClassInstancesElement e = new ClassInstancesElement.created();
     e._r = new RenderingScheduler<ClassInstancesElement>(e, queue: queue);
@@ -66,7 +61,6 @@
     e._retainedSizes = retainedSizes;
     e._reachableSizes = reachableSizes;
     e._stronglyReachableInstances = stronglyReachableInstances;
-    e._topRetainingInstances = topRetainingInstances;
     e._objects = objects;
     return e;
   }
@@ -87,17 +81,12 @@
   }
 
   StronglyReachableInstancesElement _strong;
-  TopRetainingInstancesElement _topRetainig;
 
   void render() {
     _strong = _strong ??
         new StronglyReachableInstancesElement(
             _isolate, _cls, _stronglyReachableInstances, _objects,
             queue: _r.queue);
-    _topRetainig = _topRetainig ??
-        new TopRetainingInstancesElement(
-            _isolate, _cls, _topRetainingInstances, _objects,
-            queue: _r.queue);
     final instanceCount =
         _cls.newSpace.current.instances + _cls.oldSpace.current.instances;
     final size = Utils.formatSize(
@@ -150,16 +139,6 @@
                 ..classes = ['memberValue']
                 ..children = _createRetainedSizeValue()
             ],
-          new DivElement()
-            ..classes = ['memberItem']
-            ..children = <Element>[
-              new DivElement()
-                ..classes = ['memberName']
-                ..text = 'toplist by retained memory ',
-              new DivElement()
-                ..classes = ['memberValue']
-                ..children = <Element>[_topRetainig.element]
-            ]
         ]
     ];
   }
diff --git a/runtime/observatory/lib/src/elements/class_view.dart b/runtime/observatory/lib/src/elements/class_view.dart
index fc8254e..4ca3b75 100644
--- a/runtime/observatory/lib/src/elements/class_view.dart
+++ b/runtime/observatory/lib/src/elements/class_view.dart
@@ -71,7 +71,6 @@
   M.InboundReferencesRepository _references;
   M.RetainingPathRepository _retainingPaths;
   M.StronglyReachableInstancesRepository _stronglyReachableInstances;
-  M.TopRetainingInstancesRepository _topRetainedInstances;
   M.FieldRepository _fields;
   M.ScriptRepository _scripts;
   M.ObjectRepository _objects;
@@ -100,7 +99,6 @@
       M.ObjectRepository objects,
       M.EvalRepository eval,
       M.StronglyReachableInstancesRepository stronglyReachable,
-      M.TopRetainingInstancesRepository topRetained,
       M.ClassSampleProfileRepository profiles,
       {RenderingQueue queue}) {
     assert(vm != null);
@@ -118,7 +116,6 @@
     assert(objects != null);
     assert(eval != null);
     assert(stronglyReachable != null);
-    assert(topRetained != null);
     assert(profiles != null);
     ClassViewElement e = new ClassViewElement.created();
     e._r = new RenderingScheduler<ClassViewElement>(e, queue: queue);
@@ -137,7 +134,6 @@
     e._objects = objects;
     e._eval = eval;
     e._stronglyReachableInstances = stronglyReachable;
-    e._topRetainedInstances = topRetained;
     e._profiles = profiles;
     return e;
   }
@@ -168,14 +164,8 @@
             _references, _retainingPaths, _objects,
             queue: _r.queue);
     _classInstances = _classInstances ??
-        new ClassInstancesElement(
-            _isolate,
-            _cls,
-            _retainedSizes,
-            _reachableSizes,
-            _stronglyReachableInstances,
-            _topRetainedInstances,
-            _objects,
+        new ClassInstancesElement(_isolate, _cls, _retainedSizes,
+            _reachableSizes, _stronglyReachableInstances, _objects,
             queue: _r.queue);
     var header = '';
     if (_cls.isAbstract) {
diff --git a/runtime/observatory/lib/src/elements/css/shared.css b/runtime/observatory/lib/src/elements/css/shared.css
index 218cc7f..f573064 100644
--- a/runtime/observatory/lib/src/elements/css/shared.css
+++ b/runtime/observatory/lib/src/elements/css/shared.css
@@ -1321,20 +1321,38 @@
   height: 30px;
   padding-left: 5%;
   padding-right: 5%;
+
+  display: flex;
+  flex-direction: row;
 }
 .heap-snapshot .tree-item > .size,
 .heap-snapshot .tree-item > .percentage {
-  display: inline-block;
   text-align: right;
-  width: 4em;
   margin-left: 0.25em;
   margin-right: 0.25em;
+  flex-basis: 5em;
+  flex-grow: 0;
+  flex-shrink: 0;
 }
-
+.heap-snapshot .tree-item > .edge {
+  margin-left: 0.25em;
+  margin-right: 0.25em;
+  flex-basis: 0;
+  flex-grow: 1;
+  flex-shrink: 1;
+}
 .heap-snapshot .tree-item > .name {
-  display: inline;
   margin-left: 0.5em;
   margin-right: 0.5em;
+  flex-basis: 0;
+  flex-grow: 4;
+  flex-shrink: 4;
+}
+.heap-snapshot .tree-item > .link {
+  margin-left: 0.25em;
+  margin-right: 0.25em;
+  flex-grow: 0;
+  flex-shrink: 0;
 }
 
 
@@ -2720,7 +2738,7 @@
 
 .virtual-collection .header.attached > div,
 .virtual-collection .buffer > div {
-  display: inline-block;
+/*  display: inline-block;*/
 }
 
 .virtual-collection .buffer > div {
@@ -2819,3 +2837,14 @@
 .vm-connect ul {
   list-style-type: none;
 }
+
+.treemapTile {
+  position: absolute;
+  box-sizing: border-box;
+  border: solid 1px;
+  font-size: 10px;
+  text-align: center;
+  overflow: hidden;
+  white-space: nowrap;
+  cursor: default;
+}
diff --git a/runtime/observatory/lib/src/elements/debugger.dart b/runtime/observatory/lib/src/elements/debugger.dart
index 6355605..a7ccbbc 100644
--- a/runtime/observatory/lib/src/elements/debugger.dart
+++ b/runtime/observatory/lib/src/elements/debugger.dart
@@ -1793,7 +1793,7 @@
         break;
 
       case S.ServiceEvent.kIsolateRunnable:
-      case S.ServiceEvent.kGraph:
+      case S.ServiceEvent.kHeapSnapshot:
       case S.ServiceEvent.kGC:
       case S.ServiceEvent.kInspect:
         // Ignore.
diff --git a/runtime/observatory/lib/src/elements/heap_map.dart b/runtime/observatory/lib/src/elements/heap_map.dart
index 51373bfc..f658591 100644
--- a/runtime/observatory/lib/src/elements/heap_map.dart
+++ b/runtime/observatory/lib/src/elements/heap_map.dart
@@ -95,8 +95,7 @@
       _canvas = new CanvasElement()
         ..width = 1
         ..height = 1
-        ..onMouseMove.listen(_handleMouseMove)
-        ..onMouseDown.listen(_handleClick);
+        ..onMouseMove.listen(_handleMouseMove);
     }
 
     // Set hover text to describe the object under the cursor.
@@ -222,16 +221,6 @@
     _r.dirty();
   }
 
-  void _handleClick(MouseEvent event) {
-    final isolate = _isolate as S.Isolate;
-    final address = _objectAt(event.offset).address.toRadixString(16);
-    isolate.getObjectByAddress(address).then((result) {
-      if (result.type != 'Sentinel') {
-        new AnchorElement(href: Uris.inspect(_isolate, object: result)).click();
-      }
-    });
-  }
-
   void _updateFragmentationData() {
     if (_fragmentation == null || _canvas == null) {
       return;
diff --git a/runtime/observatory/lib/src/elements/heap_snapshot.dart b/runtime/observatory/lib/src/elements/heap_snapshot.dart
index 2b32375..ee4664f 100644
--- a/runtime/observatory/lib/src/elements/heap_snapshot.dart
+++ b/runtime/observatory/lib/src/elements/heap_snapshot.dart
@@ -9,9 +9,13 @@
 import 'dart:async';
 import 'dart:html';
 import 'dart:math' as Math;
+import 'dart:typed_data';
 import 'package:observatory/models.dart' as M;
+import 'package:observatory/heap_snapshot.dart' as S;
+import 'package:observatory/object_graph.dart';
 import 'package:observatory/src/elements/class_ref.dart';
 import 'package:observatory/src/elements/containers/virtual_tree.dart';
+import 'package:observatory/src/elements/curly_block.dart';
 import 'package:observatory/src/elements/helpers/any_ref.dart';
 import 'package:observatory/src/elements/helpers/nav_bar.dart';
 import 'package:observatory/src/elements/helpers/nav_menu.dart';
@@ -27,9 +31,13 @@
 
 enum HeapSnapshotTreeMode {
   dominatorTree,
+  dominatorTreeMap,
   mergedDominatorTree,
+  mergedDominatorTreeMap,
   ownershipTable,
-  groupByClass
+  successors,
+  predecessors,
+  classes,
 }
 
 class HeapSnapshotElement extends CustomElement implements Renderable {
@@ -57,14 +65,16 @@
   M.HeapSnapshot _snapshot;
   Stream<M.HeapSnapshotLoadingProgressEvent> _progressStream;
   M.HeapSnapshotLoadingProgress _progress;
-  M.HeapSnapshotRoots _roots = M.HeapSnapshotRoots.user;
-  HeapSnapshotTreeMode _mode = HeapSnapshotTreeMode.dominatorTree;
+  HeapSnapshotTreeMode _mode = HeapSnapshotTreeMode.mergedDominatorTreeMap;
 
   M.IsolateRef get isolate => _isolate;
   M.NotificationRepository get notifications => _notifications;
   M.HeapSnapshotRepository get profiles => _snapshots;
   M.VMRef get vm => _vm;
 
+  List<SnapshotObject> selection;
+  M.HeapSnapshotMergedDominatorNode mergedSelection;
+
   factory HeapSnapshotElement(
       M.VM vm,
       M.IsolateRef isolate,
@@ -119,6 +129,18 @@
                 _refresh();
               }))
             .element,
+        (new NavRefreshElement(label: 'save', queue: _r.queue)
+              ..disabled = M.isHeapSnapshotProgressRunning(_progress?.status)
+              ..onRefresh.listen((e) {
+                _save();
+              }))
+            .element,
+        (new NavRefreshElement(label: 'load', queue: _r.queue)
+              ..disabled = M.isHeapSnapshotProgressRunning(_progress?.status)
+              ..onRefresh.listen((e) {
+                _load();
+              }))
+            .element,
         new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
     ];
@@ -146,7 +168,7 @@
 
   Future _refresh() async {
     _progress = null;
-    _progressStream = _snapshots.get(isolate, roots: _roots, gc: true);
+    _progressStream = _snapshots.get(isolate);
     _r.dirty();
     _progressStream.listen((e) {
       _progress = e.progress;
@@ -161,6 +183,38 @@
     }
   }
 
+  _save() async {
+    var blob = new Blob(_snapshot.chunks, 'application/octet-stream');
+    var blobUrl = Url.createObjectUrl(blob);
+    var link = new AnchorElement();
+    link.href = blobUrl;
+    var now = new DateTime.now();
+    link.download = 'dart-heap-${now.year}-${now.month}-${now.day}.bin';
+    link.click();
+  }
+
+  _load() async {
+    var input = new InputElement();
+    input.type = 'file';
+    input.multiple = false;
+    input.onChange.listen((event) {
+      var file = input.files[0];
+      var reader = new FileReader();
+      reader.onLoad.listen((event) async {
+        Uint8List blob = reader.result;
+        var chunks = [new ByteData.view(blob.buffer)];
+        var snapshot = new S.HeapSnapshot();
+        await snapshot.loadProgress(null, chunks).last;
+        _snapshot = snapshot;
+        selection = null;
+        mergedSelection = null;
+        _r.dirty();
+      });
+      reader.readAsArrayBuffer(file);
+    });
+    input.click();
+  }
+
   static List<Element> _createStatusMessage(String message,
       {String description: '', double progress: 0.0}) {
     return [
@@ -201,36 +255,6 @@
                 ..children = <Element>[
                   new DivElement()
                     ..classes = ['memberName']
-                    ..text = 'Refreshed ',
-                  new DivElement()
-                    ..classes = ['memberName']
-                    ..text = Utils.formatDateTime(_snapshot.timestamp)
-                ],
-              new DivElement()
-                ..classes = ['memberItem']
-                ..children = <Element>[
-                  new DivElement()
-                    ..classes = ['memberName']
-                    ..text = 'Objects ',
-                  new DivElement()
-                    ..classes = ['memberName']
-                    ..text = '${_snapshot.objects}'
-                ],
-              new DivElement()
-                ..classes = ['memberItem']
-                ..children = <Element>[
-                  new DivElement()
-                    ..classes = ['memberName']
-                    ..text = 'References ',
-                  new DivElement()
-                    ..classes = ['memberName']
-                    ..text = '${_snapshot.references}'
-                ],
-              new DivElement()
-                ..classes = ['memberItem']
-                ..children = <Element>[
-                  new DivElement()
-                    ..classes = ['memberName']
                     ..text = 'Size ',
                   new DivElement()
                     ..classes = ['memberName']
@@ -241,17 +265,7 @@
                 ..children = <Element>[
                   new DivElement()
                     ..classes = ['memberName']
-                    ..text = 'Roots ',
-                  new DivElement()
-                    ..classes = ['memberName']
-                    ..children = _createRootsSelect()
-                ],
-              new DivElement()
-                ..classes = ['memberItem']
-                ..children = <Element>[
-                  new DivElement()
-                    ..classes = ['memberName']
-                    ..text = 'Analysis ',
+                    ..text = 'View ',
                   new DivElement()
                     ..classes = ['memberName']
                     ..children = _createModeSelect()
@@ -261,11 +275,15 @@
     ];
     switch (_mode) {
       case HeapSnapshotTreeMode.dominatorTree:
+        if (selection == null) {
+          selection = _snapshot.root.objects;
+        }
         _tree = new VirtualTreeElement(
             _createDominator, _updateDominator, _getChildrenDominator,
-            items: _getChildrenDominator(_snapshot.dominatorTree),
-            queue: _r.queue);
-        _tree.expand(_snapshot.dominatorTree);
+            items: selection, queue: _r.queue);
+        if (selection.length == 1) {
+          _tree.expand(selection.first);
+        }
         final text = 'In a heap dominator tree, an object X is a parent of '
             'object Y if every path from the root to Y goes through '
             'X. This allows you to find "choke points" that are '
@@ -279,6 +297,35 @@
           _tree.element
         ]);
         break;
+      case HeapSnapshotTreeMode.dominatorTreeMap:
+        var content = new DivElement();
+        content.style.border = '1px solid black';
+        content.style.width = '100%';
+        content.style.height = '100%';
+        content.text = 'Performing layout...';
+        Timer.run(() {
+          // Generate the treemap after the content div has been added to the
+          // document so that we can ask the browser how much space is
+          // available for treemap layout.
+          if (selection == null) {
+            selection = _snapshot.root.objects;
+          }
+          _showTreemap(selection.first, content);
+        });
+
+        final text =
+            'Double-click a tile to zoom in. Double-click the outermost tile to zoom out. Right-click a tile to inspect its object.';
+        report.addAll([
+          new DivElement()
+            ..classes = ['content-centered-big', 'explanation']
+            ..text = text,
+          new DivElement()
+            ..classes = ['content-centered-big']
+            ..style.width = '100%'
+            ..style.height = '100%'
+            ..children = [content]
+        ]);
+        break;
       case HeapSnapshotTreeMode.mergedDominatorTree:
         _tree = new VirtualTreeElement(_createMergedDominator,
             _updateMergedDominator, _getChildrenMergedDominator,
@@ -294,13 +341,42 @@
           _tree.element
         ]);
         break;
+      case HeapSnapshotTreeMode.mergedDominatorTreeMap:
+        var content = new DivElement();
+        content.style.border = '1px solid black';
+        content.style.width = '100%';
+        content.style.height = '100%';
+        content.text = 'Performing layout...';
+        Timer.run(() {
+          // Generate the treemap after the content div has been added to the
+          // document so that we can ask the browser how much space is
+          // available for treemap layout.
+          if (mergedSelection == null) {
+            mergedSelection = _snapshot.mergedDominatorTree;
+          }
+          _showTreemap(mergedSelection, content);
+        });
+
+        final text =
+            'Double-click a tile to zoom in. Double-click the outermost tile to zoom out. Right-click a tile to inspect its objects.';
+        report.addAll([
+          new DivElement()
+            ..classes = ['content-centered-big', 'explanation']
+            ..text = text,
+          new DivElement()
+            ..classes = ['content-centered-big']
+            ..style.width = '100%'
+            ..style.height = '100%'
+            ..children = [content]
+        ]);
+        break;
       case HeapSnapshotTreeMode.ownershipTable:
-        final items = _snapshot.ownershipClasses.toList();
-        items.sort((a, b) => b.size - a.size);
+        final items = _snapshot.classes.where((c) => c.ownedSize > 0).toList();
+        items.sort((a, b) => b.ownedSize - a.ownedSize);
         _tree = new VirtualTreeElement(_createOwnershipClass,
             _updateOwnershipClass, _getChildrenOwnershipClass,
             items: items, queue: _r.queue);
-        _tree.expand(_snapshot.dominatorTree);
+        _tree.expand(_snapshot.root);
         final text = 'An object X is said to "own" object Y if X is the only '
             'object that references Y, or X owns the only object that '
             'references Y. In particular, objects "own" the space of any '
@@ -312,15 +388,51 @@
           _tree.element
         ]);
         break;
-      case HeapSnapshotTreeMode.groupByClass:
-        final items = _snapshot.classReferences.toList();
+      case HeapSnapshotTreeMode.successors:
+        if (selection == null) {
+          selection = _snapshot.root.objects;
+        }
+        _tree = new VirtualTreeElement(
+            _createSuccessor, _updateSuccessor, _getChildrenSuccessor,
+            items: selection, queue: _r.queue);
+        if (selection.length == 1) {
+          _tree.expand(selection.first);
+        }
+        final text = '';
+        report.addAll([
+          new DivElement()
+            ..classes = ['content-centered-big', 'explanation']
+            ..text = text,
+          _tree.element
+        ]);
+        break;
+      case HeapSnapshotTreeMode.predecessors:
+        if (selection == null) {
+          selection = _snapshot.root.objects;
+        }
+        _tree = new VirtualTreeElement(
+            _createPredecessor, _updatePredecessor, _getChildrenPredecessor,
+            items: selection, queue: _r.queue);
+        if (selection.length == 1) {
+          _tree.expand(selection.first);
+        }
+        final text = '';
+        report.addAll([
+          new DivElement()
+            ..classes = ['content-centered-big', 'explanation']
+            ..text = text,
+          _tree.element
+        ]);
+        break;
+      case HeapSnapshotTreeMode.classes:
+        final items = _snapshot.classes.toList();
         items.sort((a, b) => b.shallowSize - a.shallowSize);
         _tree = new VirtualTreeElement(
-            _createGroup, _updateGroup, _getChildrenGroup,
+            _createClass, _updateClass, _getChildrenClass,
             items: items, queue: _r.queue);
-        _tree.expand(_snapshot.dominatorTree);
         report.add(_tree.element);
         break;
+
       default:
         break;
     }
@@ -332,16 +444,79 @@
       ..classes = ['tree-item']
       ..children = <Element>[
         new SpanElement()
+          ..classes = ['percentage']
+          ..title = 'percentage of heap being retained',
+        new SpanElement()
           ..classes = ['size']
           ..title = 'retained size',
         new SpanElement()..classes = ['lines'],
         new ButtonElement()
           ..classes = ['expander']
           ..onClick.listen((_) => toggle(autoToggleSingleChildNodes: true)),
+        new SpanElement()..classes = ['name'],
+        new AnchorElement()
+          ..classes = ['link']
+          ..text = "[inspect]",
+        new AnchorElement()
+          ..classes = ['link']
+          ..text = "[incoming]",
+        new AnchorElement()
+          ..classes = ['link']
+          ..text = "[dominator-map]",
+      ];
+  }
+
+  static HtmlElement _createSuccessor(toggle) {
+    return new DivElement()
+      ..classes = ['tree-item']
+      ..children = <Element>[
+        new SpanElement()..classes = ['lines'],
+        new ButtonElement()
+          ..classes = ['expander']
+          ..onClick.listen((_) => toggle(autoToggleSingleChildNodes: true)),
         new SpanElement()
-          ..classes = ['percentage']
-          ..title = 'percentage of heap being retained',
-        new SpanElement()..classes = ['name']
+          ..classes = ['size']
+          ..title = 'retained size',
+        new SpanElement()
+          ..classes = ['edge']
+          ..title = 'name of outgoing field',
+        new SpanElement()..classes = ['name'],
+        new AnchorElement()
+          ..classes = ['link']
+          ..text = "[incoming]",
+        new AnchorElement()
+          ..classes = ['link']
+          ..text = "[dominator-tree]",
+        new AnchorElement()
+          ..classes = ['link']
+          ..text = "[dominator-map]",
+      ];
+  }
+
+  static HtmlElement _createPredecessor(toggle) {
+    return new DivElement()
+      ..classes = ['tree-item']
+      ..children = <Element>[
+        new SpanElement()..classes = ['lines'],
+        new ButtonElement()
+          ..classes = ['expander']
+          ..onClick.listen((_) => toggle(autoToggleSingleChildNodes: true)),
+        new SpanElement()
+          ..classes = ['size']
+          ..title = 'retained size',
+        new SpanElement()
+          ..classes = ['edge']
+          ..title = 'name of incoming field',
+        new SpanElement()..classes = ['name'],
+        new SpanElement()
+          ..classes = ['link']
+          ..text = "[inspect]",
+        new AnchorElement()
+          ..classes = ['link']
+          ..text = "[dominator-tree]",
+        new AnchorElement()
+          ..classes = ['link']
+          ..text = "[dominator-map]",
       ];
   }
 
@@ -350,33 +525,15 @@
       ..classes = ['tree-item']
       ..children = <Element>[
         new SpanElement()
+          ..classes = ['percentage']
+          ..title = 'percentage of heap being retained',
+        new SpanElement()
           ..classes = ['size']
           ..title = 'retained size',
         new SpanElement()..classes = ['lines'],
         new ButtonElement()
           ..classes = ['expander']
           ..onClick.listen((_) => toggle(autoToggleSingleChildNodes: true)),
-        new SpanElement()
-          ..classes = ['percentage']
-          ..title = 'percentage of heap being retained',
-        new SpanElement()..classes = ['name']
-      ];
-  }
-
-  static HtmlElement _createGroup(toggle) {
-    return new DivElement()
-      ..classes = ['tree-item']
-      ..children = <Element>[
-        new SpanElement()
-          ..classes = ['size']
-          ..title = 'shallow size',
-        new SpanElement()..classes = ['lines'],
-        new ButtonElement()
-          ..classes = ['expander']
-          ..onClick.listen((_) => toggle(autoToggleSingleChildNodes: true)),
-        new SpanElement()
-          ..classes = ['count']
-          ..title = 'shallow size',
         new SpanElement()..classes = ['name']
       ];
   }
@@ -386,11 +543,32 @@
       ..classes = ['tree-item']
       ..children = <Element>[
         new SpanElement()
+          ..classes = ['percentage']
+          ..title = 'percentage of heap owned',
+        new SpanElement()
           ..classes = ['size']
           ..title = 'owned size',
+        new SpanElement()..classes = ['name']
+      ];
+  }
+
+  static HtmlElement _createClass(toggle) {
+    return new DivElement()
+      ..classes = ['tree-item']
+      ..children = <Element>[
+        new SpanElement()..classes = ['lines'],
+        new ButtonElement()
+          ..classes = ['expander']
+          ..onClick.listen((_) => toggle(autoToggleSingleChildNodes: true)),
         new SpanElement()
           ..classes = ['percentage']
           ..title = 'percentage of heap owned',
+        new SpanElement()
+          ..classes = ['size']
+          ..title = 'shallow size',
+        new SpanElement()
+          ..classes = ['size']
+          ..title = 'instance count',
         new SpanElement()..classes = ['name']
       ];
   }
@@ -399,7 +577,7 @@
   static const int kMinRetainedSize = 4096;
 
   static Iterable _getChildrenDominator(nodeDynamic) {
-    M.HeapSnapshotDominatorNode node = nodeDynamic;
+    SnapshotObject node = nodeDynamic;
     final list = node.children.toList();
     list.sort((a, b) => b.retainedSize - a.retainedSize);
     return list
@@ -407,6 +585,18 @@
         .take(kMaxChildren);
   }
 
+  static Iterable _getChildrenSuccessor(nodeDynamic) {
+    SnapshotObject node = nodeDynamic;
+    final list = node.successors.toList();
+    return list;
+  }
+
+  static Iterable _getChildrenPredecessor(nodeDynamic) {
+    SnapshotObject node = nodeDynamic;
+    final list = node.predecessors.toList();
+    return list;
+  }
+
   static Iterable _getChildrenMergedDominator(nodeDynamic) {
     M.HeapSnapshotMergedDominatorNode node = nodeDynamic;
     final list = node.children.toList();
@@ -416,152 +606,324 @@
         .take(kMaxChildren);
   }
 
-  static Iterable _getChildrenGroup(item) {
-    if (item is M.HeapSnapshotClassReferences) {
-      if (item.inbounds.isNotEmpty || item.outbounds.isNotEmpty) {
-        return [item.inbounds, item.outbounds];
-      }
-    } else if (item is Iterable) {
-      return item.toList()..sort((a, b) => b.shallowSize - a.shallowSize);
-    }
-    return const [];
-  }
-
   static Iterable _getChildrenOwnershipClass(item) {
     return const [];
   }
 
+  static Iterable _getChildrenClass(item) {
+    return const [];
+  }
+
   void _updateDominator(HtmlElement element, nodeDynamic, int depth) {
-    M.HeapSnapshotDominatorNode node = nodeDynamic;
-    element.children[0].text = Utils.formatSize(node.retainedSize);
-    _updateLines(element.children[1].children, depth);
-    if (_getChildrenDominator(node).isNotEmpty) {
-      element.children[2].text = _tree.isExpanded(node) ? '▼' : '►';
-    } else {
-      element.children[2].text = '';
-    }
-    element.children[3].text =
+    SnapshotObject node = nodeDynamic;
+    element.children[0].text =
         Utils.formatPercentNormalized(node.retainedSize * 1.0 / _snapshot.size);
-    final wrapper = new SpanElement()
-      ..classes = ['name']
-      ..text = 'Loading...';
-    element.children[4] = wrapper;
-    if (node.isStack) {
-      wrapper
-        ..text = ''
-        ..children = <Element>[
-          new AnchorElement(href: Uris.debugger(isolate))..text = 'stack frames'
-        ];
+    element.children[1].text = Utils.formatSize(node.retainedSize);
+    _updateLines(element.children[2].children, depth);
+    if (_getChildrenDominator(node).isNotEmpty) {
+      element.children[3].text = _tree.isExpanded(node) ? '▼' : '►';
     } else {
-      node.object.then((object) {
-        wrapper
-          ..text = ''
-          ..children = <Element>[
-            anyRef(_isolate, object, _objects,
-                queue: _r.queue, expandable: false)
-          ];
-      });
+      element.children[3].text = '';
     }
+    element.children[4].text = node.description;
+    element.children[5].onClick.listen((_) {
+      selection = node.objects;
+      _mode = HeapSnapshotTreeMode.successors;
+      _r.dirty();
+    });
+    element.children[6].onClick.listen((_) {
+      selection = node.objects;
+      _mode = HeapSnapshotTreeMode.predecessors;
+      _r.dirty();
+    });
+    element.children[7].onClick.listen((_) {
+      selection = node.objects;
+      _mode = HeapSnapshotTreeMode.dominatorTreeMap;
+      _r.dirty();
+    });
+  }
+
+  void _updateSuccessor(HtmlElement element, nodeDynamic, int depth) {
+    SnapshotObject node = nodeDynamic;
+    _updateLines(element.children[0].children, depth);
+    if (_getChildrenSuccessor(node).isNotEmpty) {
+      element.children[1].text = _tree.isExpanded(node) ? '▼' : '►';
+    } else {
+      element.children[1].text = '';
+    }
+    element.children[2].text = Utils.formatSize(node.retainedSize);
+    element.children[3].text = node.label;
+    element.children[4].text = node.description;
+    element.children[5].onClick.listen((_) {
+      selection = node.objects;
+      _mode = HeapSnapshotTreeMode.predecessors;
+      _r.dirty();
+    });
+    element.children[6].onClick.listen((_) {
+      selection = node.objects;
+      _mode = HeapSnapshotTreeMode.dominatorTree;
+      _r.dirty();
+    });
+    element.children[7].onClick.listen((_) {
+      selection = node.objects;
+      _mode = HeapSnapshotTreeMode.dominatorTreeMap;
+      _r.dirty();
+    });
+  }
+
+  void _updatePredecessor(HtmlElement element, nodeDynamic, int depth) {
+    SnapshotObject node = nodeDynamic;
+    _updateLines(element.children[0].children, depth);
+    if (_getChildrenSuccessor(node).isNotEmpty) {
+      element.children[1].text = _tree.isExpanded(node) ? '▼' : '►';
+    } else {
+      element.children[1].text = '';
+    }
+    element.children[2].text = Utils.formatSize(node.retainedSize);
+    element.children[3].text = node.label;
+    element.children[4].text = node.description;
+    element.children[5].onClick.listen((_) {
+      selection = node.objects;
+      _mode = HeapSnapshotTreeMode.successors;
+      _r.dirty();
+    });
+    element.children[6].onClick.listen((_) {
+      selection = node.objects;
+      _mode = HeapSnapshotTreeMode.dominatorTree;
+      _r.dirty();
+    });
+    element.children[7].onClick.listen((_) {
+      selection = node.objects;
+      _mode = HeapSnapshotTreeMode.dominatorTreeMap;
+      _r.dirty();
+    });
   }
 
   void _updateMergedDominator(HtmlElement element, nodeDynamic, int depth) {
     M.HeapSnapshotMergedDominatorNode node = nodeDynamic;
-    element.children[0].text = Utils.formatSize(node.retainedSize);
-    _updateLines(element.children[1].children, depth);
-    if (_getChildrenMergedDominator(node).isNotEmpty) {
-      element.children[2].text = _tree.isExpanded(node) ? '▼' : '►';
-    } else {
-      element.children[2].text = '';
-    }
-    element.children[3].text =
+    element.children[0].text =
         Utils.formatPercentNormalized(node.retainedSize * 1.0 / _snapshot.size);
-    final wrapper = new SpanElement()
-      ..classes = ['name']
-      ..text = 'Loading...';
-    element.children[4] = wrapper;
-    if (node.isStack) {
-      wrapper
-        ..text = ''
-        ..children = <Element>[
-          new AnchorElement(href: Uris.debugger(isolate))..text = 'stack frames'
-        ];
+    element.children[1].text = Utils.formatSize(node.retainedSize);
+    _updateLines(element.children[2].children, depth);
+    if (_getChildrenMergedDominator(node).isNotEmpty) {
+      element.children[3].text = _tree.isExpanded(node) ? '▼' : '►';
     } else {
-      node.klass.then((klass) {
-        wrapper
-          ..text = ''
-          ..children = <Element>[
-            new SpanElement()..text = '${node.instanceCount} instances of ',
-            anyRef(_isolate, klass, _objects,
-                queue: _r.queue, expandable: false)
-          ];
-      });
+      element.children[3].text = '';
     }
+    element.children[4]
+      ..text = '${node.instanceCount} instances of ${node.klass.name}';
   }
 
-  void _updateGroup(HtmlElement element, item, int depth) {
+  void _updateOwnershipClass(HtmlElement element, nodeDynamic, int depth) {
+    SnapshotClass node = nodeDynamic;
     _updateLines(element.children[1].children, depth);
-    if (item is M.HeapSnapshotClassReferences) {
-      element.children[0].text = Utils.formatSize(item.shallowSize);
-      element.children[2].text = _tree.isExpanded(item) ? '▼' : '►';
-      element.children[3].text = '${item.instances} instances of ';
-      element.children[4] =
-          (new ClassRefElement(_isolate, item.clazz, queue: _r.queue)
-                ..classes = ['name'])
-              .element;
-    } else if (item is Iterable) {
-      element.children[0].text = '';
-      if (item.isNotEmpty) {
-        element.children[2].text = _tree.isExpanded(item) ? '▼' : '►';
-      } else {
-        element.children[2].text = '';
-      }
-      element.children[3].text = '';
-      int references = 0;
-      for (var referenceGroup in item) {
-        references += referenceGroup.count;
-      }
-      if (item is Iterable<M.HeapSnapshotClassInbound>) {
-        element.children[4] = new SpanElement()
-          ..classes = ['name']
-          ..text = '$references incoming references';
-      } else {
-        element.children[4] = new SpanElement()
-          ..classes = ['name']
-          ..text = '$references outgoing references';
-      }
-    } else {
-      element.children[0].text = '';
-      element.children[2].text = '';
-      element.children[3].text = '';
-      element.children[4] = new SpanElement()..classes = ['name'];
-      if (item is M.HeapSnapshotClassInbound) {
-        element.children[3].text =
-            '${item.count} references from instances of ';
-        element.children[4].children = <Element>[
-          new ClassRefElement(_isolate, item.source, queue: _r.queue).element
-        ];
-      } else if (item is M.HeapSnapshotClassOutbound) {
-        element.children[3]..text = '${item.count} references to instances of ';
-        element.children[4].children = <Element>[
-          new ClassRefElement(_isolate, item.target, queue: _r.queue).element
-        ];
-      }
-    }
+    element.children[0].text =
+        Utils.formatPercentNormalized(node.ownedSize * 1.0 / _snapshot.size);
+    element.children[1].text = Utils.formatSize(node.ownedSize);
+    element.children[2].text = node.name;
   }
 
-  void _updateOwnershipClass(HtmlElement element, item, int depth) {
+  void _updateClass(HtmlElement element, nodeDynamic, int depth) {
+    SnapshotClass node = nodeDynamic;
     _updateLines(element.children[1].children, depth);
-    element.children[0].text = Utils.formatSize(item.size);
-    element.children[1].text =
-        Utils.formatPercentNormalized(item.size * 1.0 / _snapshot.size);
-    element.children[2] = new SpanElement()
-      ..classes = ['name']
-      ..children = <Element>[
-        new SpanElement()..text = ' instances of ',
-        (new ClassRefElement(_isolate, item.clazz, queue: _r.queue)
-              ..classes = ['name'])
-            .element
-      ];
+    element.children[2].text =
+        Utils.formatPercentNormalized(node.shallowSize * 1.0 / _snapshot.size);
+    element.children[3].text =
+        Utils.formatSize(node.shallowSize + node.externalSize);
+    element.children[4].text = node.instanceCount.toString();
+    element.children[5].text = node.name;
+  }
+
+  String color(String string) {
+    int hue = string.hashCode % 360;
+    return "hsl($hue,60%,60%)";
+  }
+
+  String prettySize(num size) {
+    if (size < 1024) return size.toStringAsFixed(0) + "B";
+    size /= 1024;
+    if (size < 1024) return size.toStringAsFixed(1) + "KiB";
+    size /= 1024;
+    if (size < 1024) return size.toStringAsFixed(1) + "MiB";
+    size /= 1024;
+    return size.toStringAsFixed(1) + "GiB";
+  }
+
+  /* SnapshotObject | M.MergedDominatorNode */
+  void _showTreemap(dynamic node, DivElement content) {
+    final w = content.offsetWidth.toDouble();
+    final h = content.offsetHeight.toDouble();
+    final topTile = _createTreemapTile(node, w, h, 0, content);
+    topTile.style.width = "${w}px";
+    topTile.style.height = "${h}px";
+    topTile.style.border = "none";
+    content.children = [topTile];
+  }
+
+  Element _createTreemapTile(dynamic node, double width, double height,
+      int depth, DivElement content) {
+    final div = new DivElement();
+    div.className = "treemapTile";
+    div.style.backgroundColor = color(node.klass.name);
+    div.onDoubleClick.listen((event) {
+      event.stopPropagation();
+      if (depth == 0) {
+        // Zoom out.
+        if (node is SnapshotObject) {
+          selection = node.parent.objects;
+        } else {
+          mergedSelection = node.parent;
+        }
+      } else {
+        // Zoom in.
+        if (node is SnapshotObject) {
+          selection = node.objects;
+        } else {
+          mergedSelection = node;
+        }
+      }
+      _r.dirty();
+    });
+    div.onContextMenu.listen((event) {
+      event.stopPropagation();
+      if (node is SnapshotObject) {
+        selection = node.objects;
+        _mode = HeapSnapshotTreeMode.successors;
+      } else {
+        selection = node.objects;
+        _mode = HeapSnapshotTreeMode.successors;
+      }
+      _r.dirty();
+    });
+
+    double left = 0.0;
+    double top = 0.0;
+
+    const kPadding = 5;
+    const kBorder = 1;
+    left += kPadding - kBorder;
+    top += kPadding - kBorder;
+    width -= 2 * kPadding;
+    height -= 2 * kPadding;
+
+    final label = "${node.description} [${prettySize(node.retainedSize)}]";
+    div.title = label; // I.e., tooltip.
+
+    if (width < 10 || height < 10) {
+      // Too small: don't render label or children.
+      return div;
+    }
+
+    div.append(new SpanElement()..text = label);
+    const kLabelHeight = 9.0;
+    top += kLabelHeight;
+    height -= kLabelHeight;
+
+    if (depth > 2) {
+      // Too deep: don't render children.
+      return div;
+    }
+    if (width < 4 || height < 4) {
+      // Too small: don't render children.
+      return div;
+    }
+
+    final children = new List<dynamic>();
+    for (var c in node.children) {
+      // Size 0 children seem to confuse the layout algorithm (accumulating
+      // rounding errors?).
+      if (c.retainedSize > 0) {
+        children.add(c);
+      }
+    }
+    children.sort((a, b) => b.retainedSize - a.retainedSize);
+
+    final double scale = width * height / node.retainedSize;
+
+    // Bruls M., Huizing K., van Wijk J.J. (2000) Squarified Treemaps. In: de
+    // Leeuw W.C., van Liere R. (eds) Data Visualization 2000. Eurographics.
+    // Springer, Vienna.
+    for (int rowStart = 0; // Index of first child in the next row.
+        rowStart < children.length;) {
+      // Prefer wider rectangles, the better to fit text labels.
+      const double GOLDEN_RATIO = 1.61803398875;
+      final bool verticalSplit = (width / height) > GOLDEN_RATIO;
+
+      double space;
+      if (verticalSplit) {
+        space = height;
+      } else {
+        space = width;
+      }
+
+      double rowMin = children[rowStart].retainedSize * scale;
+      double rowMax = rowMin;
+      double rowSum = 0.0;
+      double lastRatio = 0.0;
+
+      int rowEnd; // One after index of last child in the next row.
+      for (rowEnd = rowStart; rowEnd < children.length; rowEnd++) {
+        double size = children[rowEnd].retainedSize * scale;
+        if (size < rowMin) rowMin = size;
+        if (size > rowMax) rowMax = size;
+        rowSum += size;
+
+        double ratio = Math.max((space * space * rowMax) / (rowSum * rowSum),
+            (rowSum * rowSum) / (space * space * rowMin));
+        if ((lastRatio != 0) && (ratio > lastRatio)) {
+          // Adding the next child makes the aspect ratios worse: remove it and
+          // add the row.
+          rowSum -= size;
+          break;
+        }
+        lastRatio = ratio;
+      }
+
+      double rowLeft = left;
+      double rowTop = top;
+      double rowSpace = rowSum / space;
+
+      for (var i = rowStart; i < rowEnd; i++) {
+        var child = children[i];
+        double size = child.retainedSize * scale;
+
+        double childWidth;
+        double childHeight;
+        if (verticalSplit) {
+          childWidth = rowSpace;
+          childHeight = size / childWidth;
+        } else {
+          childHeight = rowSpace;
+          childWidth = size / childHeight;
+        }
+
+        var childDiv = _createTreemapTile(
+            child, childWidth, childHeight, depth + 1, content);
+        childDiv.style.left = "${rowLeft}px";
+        childDiv.style.top = "${rowTop}px";
+        // Oversize the final div by kBorder to make the borders overlap.
+        childDiv.style.width = "${childWidth + kBorder}px";
+        childDiv.style.height = "${childHeight + kBorder}px";
+        div.append(childDiv);
+
+        if (verticalSplit)
+          rowTop += childHeight;
+        else
+          rowLeft += childWidth;
+      }
+
+      if (verticalSplit) {
+        left += rowSpace;
+        width -= rowSpace;
+      } else {
+        top += rowSpace;
+        height -= rowSpace;
+      }
+
+      rowStart = rowEnd;
+    }
+
+    return div;
   }
 
   static _updateLines(List<Element> lines, int n) {
@@ -574,46 +936,26 @@
     }
   }
 
-  static String rootsToString(M.HeapSnapshotRoots roots) {
-    switch (roots) {
-      case M.HeapSnapshotRoots.user:
-        return 'User';
-      case M.HeapSnapshotRoots.vm:
-        return 'VM';
-    }
-    throw new Exception('Unknown HeapSnapshotRoots');
-  }
-
-  List<Element> _createRootsSelect() {
-    var s;
-    return [
-      s = new SelectElement()
-        ..classes = ['roots-select']
-        ..value = rootsToString(_roots)
-        ..children = M.HeapSnapshotRoots.values.map((roots) {
-          return new OptionElement(
-              value: rootsToString(roots), selected: _roots == roots)
-            ..text = rootsToString(roots);
-        }).toList(growable: false)
-        ..onChange.listen((_) {
-          _roots = M.HeapSnapshotRoots.values[s.selectedIndex];
-          _refresh();
-        })
-    ];
-  }
-
   static String modeToString(HeapSnapshotTreeMode mode) {
     switch (mode) {
       case HeapSnapshotTreeMode.dominatorTree:
-        return 'Dominator tree';
+        return 'Dominators (tree)';
+      case HeapSnapshotTreeMode.dominatorTreeMap:
+        return 'Dominators (treemap)';
       case HeapSnapshotTreeMode.mergedDominatorTree:
-        return 'Dominator tree (merged siblings by class)';
+        return 'Dominators (tree, siblings merged by class)';
+      case HeapSnapshotTreeMode.mergedDominatorTreeMap:
+        return 'Dominators (treemap, siblings merged by class)';
       case HeapSnapshotTreeMode.ownershipTable:
-        return 'Ownership table';
-      case HeapSnapshotTreeMode.groupByClass:
-        return 'Group by class';
+        return 'Ownership';
+      case HeapSnapshotTreeMode.successors:
+        return 'Successors / outgoing references';
+      case HeapSnapshotTreeMode.predecessors:
+        return 'Predecessors / incoming references';
+      case HeapSnapshotTreeMode.classes:
+        return 'Classes';
     }
-    throw new Exception('Unknown HeapSnapshotTreeMode');
+    throw new Exception('Unknown HeapSnapshotTreeMode: $mode');
   }
 
   List<Element> _createModeSelect() {
diff --git a/runtime/observatory/lib/src/elements/memory/allocations.dart b/runtime/observatory/lib/src/elements/memory/allocations.dart
deleted file mode 100644
index 11ff282..0000000
--- a/runtime/observatory/lib/src/elements/memory/allocations.dart
+++ /dev/null
@@ -1,276 +0,0 @@
-// Copyright (c) 2017, 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.
-
-/// This Element is part of MemoryDashboardElement.
-///
-/// The Element is stripped down version of AllocationProfileElement where
-/// concepts like old and new space has been hidden away.
-///
-/// For each class in the system it is shown the Total number of instances
-/// alive, the Total memory used by these instances, the number of instances
-/// created since the last reset, the memory used by these instances.
-
-import 'dart:async';
-import 'dart:html';
-import 'package:observatory/models.dart' as M;
-import 'package:observatory/src/elements/class_ref.dart';
-import 'package:observatory/src/elements/containers/virtual_collection.dart';
-import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
-import 'package:observatory/src/elements/helpers/tag.dart';
-import 'package:observatory/utils.dart';
-
-enum _SortingField {
-  accumulatedSize,
-  accumulatedInstances,
-  currentSize,
-  currentInstances,
-  className,
-}
-
-enum _SortingDirection { ascending, descending }
-
-class MemoryAllocationsElement extends CustomElement implements Renderable {
-  static const tag = const Tag<MemoryAllocationsElement>('memory-allocations',
-      dependencies: const [ClassRefElement.tag, VirtualCollectionElement.tag]);
-
-  RenderingScheduler<MemoryAllocationsElement> _r;
-
-  Stream<RenderedEvent<MemoryAllocationsElement>> get onRendered =>
-      _r.onRendered;
-
-  M.IsolateRef _isolate;
-  M.AllocationProfileRepository _repository;
-  M.AllocationProfile _profile;
-  M.EditorRepository _editor;
-  _SortingField _sortingField = _SortingField.accumulatedInstances;
-  _SortingDirection _sortingDirection = _SortingDirection.descending;
-
-  M.IsolateRef get isolate => _isolate;
-
-  factory MemoryAllocationsElement(M.IsolateRef isolate,
-      M.EditorRepository editor, M.AllocationProfileRepository repository,
-      {RenderingQueue queue}) {
-    assert(isolate != null);
-    assert(editor != null);
-    assert(repository != null);
-    MemoryAllocationsElement e = new MemoryAllocationsElement.created();
-    e._r = new RenderingScheduler<MemoryAllocationsElement>(e, queue: queue);
-    e._isolate = isolate;
-    e._editor = editor;
-    e._repository = repository;
-    return e;
-  }
-
-  MemoryAllocationsElement.created() : super.created(tag);
-
-  @override
-  attached() {
-    super.attached();
-    _r.enable();
-    _refresh();
-  }
-
-  @override
-  detached() {
-    super.detached();
-    _r.disable(notify: true);
-    children = <Element>[];
-  }
-
-  Future reload({bool gc = false, bool reset = false}) async {
-    return _refresh(gc: gc, reset: reset);
-  }
-
-  void render() {
-    if (_profile == null) {
-      children = <Element>[
-        new DivElement()
-          ..classes = ['content-centered-big']
-          ..children = <Element>[new HeadingElement.h2()..text = 'Loading...']
-      ];
-    } else {
-      children = <Element>[
-        new VirtualCollectionElement(
-                _createCollectionLine, _updateCollectionLine,
-                createHeader: _createCollectionHeader,
-                search: _search,
-                items: _profile.members
-                    .where((member) =>
-                        member.newSpace.accumulated.instances != 0 ||
-                        member.newSpace.current.instances != 0 ||
-                        member.oldSpace.accumulated.instances != 0 ||
-                        member.oldSpace.current.instances != 0)
-                    .toList()
-                      ..sort(_createSorter()),
-                queue: _r.queue)
-            .element
-      ];
-    }
-  }
-
-  _createSorter() {
-    var getter;
-    switch (_sortingField) {
-      case _SortingField.accumulatedSize:
-        getter = _getAccumulatedSize;
-        break;
-      case _SortingField.accumulatedInstances:
-        getter = _getAccumulatedInstances;
-        break;
-      case _SortingField.currentSize:
-        getter = _getCurrentSize;
-        break;
-      case _SortingField.currentInstances:
-        getter = _getCurrentInstances;
-        break;
-      case _SortingField.className:
-        getter = (M.ClassHeapStats s) => s.clazz.name;
-        break;
-    }
-    switch (_sortingDirection) {
-      case _SortingDirection.ascending:
-        int sort(M.ClassHeapStats a, M.ClassHeapStats b) {
-          return getter(a).compareTo(getter(b));
-        }
-        return sort;
-      case _SortingDirection.descending:
-        int sort(M.ClassHeapStats a, M.ClassHeapStats b) {
-          return getter(b).compareTo(getter(a));
-        }
-        return sort;
-    }
-  }
-
-  static HtmlElement _createCollectionLine() => new DivElement()
-    ..classes = ['collection-item']
-    ..children = <Element>[
-      new SpanElement()
-        ..classes = ['bytes']
-        ..text = '0B',
-      new SpanElement()
-        ..classes = ['instances']
-        ..text = '0',
-      new SpanElement()
-        ..classes = ['bytes']
-        ..text = '0B',
-      new SpanElement()
-        ..classes = ['instances']
-        ..text = '0',
-      new SpanElement()..classes = ['name']
-    ];
-
-  List<HtmlElement> _createCollectionHeader() {
-    final resetAccumulators = new ButtonElement();
-    return [
-      new DivElement()
-        ..classes = ['collection-item']
-        ..children = <Element>[
-          new SpanElement()
-            ..classes = ['group']
-            ..nodes = [
-              new Text('Since Last '),
-              resetAccumulators
-                ..text = 'Reset'
-                ..title = 'Reset'
-                ..onClick.listen((_) async {
-                  resetAccumulators.disabled = true;
-                  await _refresh(reset: true);
-                  resetAccumulators.disabled = false;
-                })
-            ],
-          new SpanElement()
-            ..classes = ['group']
-            ..text = 'Current'
-        ],
-      new DivElement()
-        ..classes = ['collection-item']
-        ..children = <Element>[
-          _createHeaderButton(const ['bytes'], 'Size',
-              _SortingField.accumulatedSize, _SortingDirection.descending),
-          _createHeaderButton(const ['instances'], 'Instances',
-              _SortingField.accumulatedInstances, _SortingDirection.descending),
-          _createHeaderButton(const ['bytes'], 'Size',
-              _SortingField.currentSize, _SortingDirection.descending),
-          _createHeaderButton(const ['instances'], 'Instances',
-              _SortingField.currentInstances, _SortingDirection.descending),
-          _createHeaderButton(const ['name'], 'Class', _SortingField.className,
-              _SortingDirection.ascending)
-        ],
-    ];
-  }
-
-  ButtonElement _createHeaderButton(List<String> classes, String text,
-          _SortingField field, _SortingDirection direction) =>
-      new ButtonElement()
-        ..classes = classes
-        ..text = _sortingField != field
-            ? text
-            : _sortingDirection == _SortingDirection.ascending
-                ? '$text▼'
-                : '$text▲'
-        ..onClick.listen((_) => _setSorting(field, direction));
-
-  void _setSorting(_SortingField field, _SortingDirection defaultDirection) {
-    if (_sortingField == field) {
-      switch (_sortingDirection) {
-        case _SortingDirection.descending:
-          _sortingDirection = _SortingDirection.ascending;
-          break;
-        case _SortingDirection.ascending:
-          _sortingDirection = _SortingDirection.descending;
-          break;
-      }
-    } else {
-      _sortingDirection = defaultDirection;
-      _sortingField = field;
-    }
-    _r.dirty();
-  }
-
-  void _updateCollectionLine(Element e, itemDynamic, index) {
-    M.ClassHeapStats item = itemDynamic;
-    e.children[0].text = Utils.formatSize(_getAccumulatedSize(item));
-    e.children[1].text = '${_getAccumulatedInstances(item)}';
-    e.children[2].text = Utils.formatSize(_getCurrentSize(item));
-    e.children[3].text = '${_getCurrentInstances(item)}';
-    if (item.clazz == null) {
-      e.children[4] = new SpanElement()
-        ..text = item.displayName
-        ..classes = ['name'];
-      return;
-    }
-    e.children[4] = (new ClassRefElement(_isolate, item.clazz, queue: _r.queue)
-          ..classes = ['name'])
-        .element;
-    Element.clickEvent.forTarget(e.children[4], useCapture: true).listen((e) {
-      if (_editor.isAvailable) {
-        e.preventDefault();
-        _editor.openClass(isolate, item.clazz);
-      }
-    });
-  }
-
-  bool _search(Pattern pattern, itemDynamic) {
-    M.ClassHeapStats item = itemDynamic;
-    final String value = item.clazz?.name ?? item.displayName;
-    return value.contains(pattern);
-  }
-
-  Future _refresh({bool gc: false, bool reset: false}) async {
-    _profile = null;
-    _r.dirty();
-    _profile =
-        await _repository.get(_isolate, gc: gc, reset: reset, combine: true);
-    _r.dirty();
-  }
-
-  static int _getAccumulatedSize(M.ClassHeapStats s) =>
-      s.newSpace.accumulated.bytes + s.oldSpace.accumulated.bytes;
-  static int _getAccumulatedInstances(M.ClassHeapStats s) =>
-      s.newSpace.accumulated.instances + s.oldSpace.accumulated.instances;
-  static int _getCurrentSize(M.ClassHeapStats s) =>
-      s.newSpace.current.bytes + s.oldSpace.current.bytes;
-  static int _getCurrentInstances(M.ClassHeapStats s) =>
-      s.newSpace.current.instances + s.oldSpace.current.instances;
-}
diff --git a/runtime/observatory/lib/src/elements/memory/dashboard.dart b/runtime/observatory/lib/src/elements/memory/dashboard.dart
deleted file mode 100644
index c0af46d..0000000
--- a/runtime/observatory/lib/src/elements/memory/dashboard.dart
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright (c) 2017, 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.
-
-/// This page is not directly reachable from the main Observatory ui.
-/// It is mainly mented to be used from editors as an integrated tool.
-///
-/// This page mainly targeting developers and not VM experts, so concepts like
-/// old and new heap are abstracted away.
-///
-/// The page comprises an overall memory usage of the VM from where it is
-/// possible to select an isolate to deeply analyze.
-/// See MemoryGraphElement
-///
-/// Once an isolate is selected it is possible to information specific to it.
-/// See MemoryProfileElement
-///
-/// The logic in this Element is mainly mented to orchestrate the two
-/// sub-components by means of positioning and message passing.
-
-import 'dart:async';
-import 'dart:html';
-import 'package:observatory/models.dart' as M;
-import 'package:observatory/src/elements/helpers/nav_bar.dart';
-import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
-import 'package:observatory/src/elements/helpers/tag.dart';
-import 'package:observatory/src/elements/nav/notify.dart';
-import 'package:observatory/src/elements/memory/graph.dart';
-import 'package:observatory/src/elements/memory/profile.dart';
-
-class MemoryDashboardElement extends CustomElement implements Renderable {
-  static const tag = const Tag<MemoryDashboardElement>('memory-dashboard',
-      dependencies: const [
-        NavNotifyElement.tag,
-        MemoryGraphElement.tag,
-        MemoryProfileElement.tag,
-      ]);
-
-  RenderingScheduler<MemoryDashboardElement> _r;
-
-  Stream<RenderedEvent<MemoryDashboardElement>> get onRendered => _r.onRendered;
-
-  M.VMRef _vm;
-  M.VMRepository _vms;
-  M.IsolateRepository _isolates;
-  M.EditorRepository _editor;
-  M.AllocationProfileRepository _allocations;
-  M.HeapSnapshotRepository _snapshots;
-  M.ObjectRepository _objects;
-  M.EventRepository _events;
-  M.NotificationRepository _notifications;
-
-  M.VMRef get vm => _vm;
-  M.NotificationRepository get notifications => _notifications;
-
-  factory MemoryDashboardElement(
-      M.VMRef vm,
-      M.VMRepository vms,
-      M.IsolateRepository isolates,
-      M.EditorRepository editor,
-      M.AllocationProfileRepository allocations,
-      M.HeapSnapshotRepository snapshots,
-      M.ObjectRepository objects,
-      M.EventRepository events,
-      M.NotificationRepository notifications,
-      {RenderingQueue queue}) {
-    assert(vm != null);
-    assert(vms != null);
-    assert(isolates != null);
-    assert(editor != null);
-    assert(allocations != null);
-    assert(events != null);
-    assert(notifications != null);
-    MemoryDashboardElement e = new MemoryDashboardElement.created();
-    e._r = new RenderingScheduler<MemoryDashboardElement>(e, queue: queue);
-    e._vm = vm;
-    e._vms = vms;
-    e._isolates = isolates;
-    e._editor = editor;
-    e._allocations = allocations;
-    e._snapshots = snapshots;
-    e._objects = objects;
-    e._events = events;
-    e._notifications = notifications;
-    return e;
-  }
-
-  MemoryDashboardElement.created() : super.created(tag);
-
-  @override
-  attached() {
-    super.attached();
-    _r.enable();
-  }
-
-  @override
-  detached() {
-    super.detached();
-    _r.disable(notify: true);
-    children = <Element>[];
-  }
-
-  M.IsolateRef _isolate;
-
-  MemoryGraphElement _graph;
-
-  void render() {
-    if (_graph == null) {
-      _graph =
-          new MemoryGraphElement(vm, _vms, _isolates, _events, queue: _r.queue)
-            ..onIsolateSelected.listen(_onIsolateSelected);
-    }
-    children = <Element>[
-      navBar(<Element>[
-        new NavNotifyElement(_notifications, queue: _r.queue).element
-      ]),
-      new DivElement()
-        ..classes = ['content-centered-big']
-        ..children = <Element>[
-          new HeadingElement.h2()..text = 'Memory Dashboard',
-          new HRElement(),
-          _graph.element,
-          new HRElement(),
-        ],
-    ];
-    if (_isolate == null) {
-      children.add(new DivElement()
-        ..classes = ['content-centered-big']
-        ..children = <Element>[
-          new HeadingElement.h1()..text = "No isolate selected"
-        ]);
-    } else {
-      children.add(new MemoryProfileElement(
-              _isolate, _editor, _allocations, _snapshots, _objects)
-          .element);
-    }
-  }
-
-  void _onIsolateSelected(IsolateSelectedEvent e) {
-    _isolate = _r.checkAndReact(_isolate, e.isolate);
-  }
-}
diff --git a/runtime/observatory/lib/src/elements/memory/graph.dart b/runtime/observatory/lib/src/elements/memory/graph.dart
deleted file mode 100644
index 5f0fd9d..0000000
--- a/runtime/observatory/lib/src/elements/memory/graph.dart
+++ /dev/null
@@ -1,462 +0,0 @@
-// Copyright (c) 2017, 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.
-
-/// This Element is part of MemoryDashboardElement.
-///
-/// The Element periodically interrogates the VM to log the memory usage of each
-/// Isolate and of the Native Memory.
-///
-/// For each isolate it is shown the Used and Free heap (new and old are merged
-/// together)
-///
-/// When a GC event is received an extra point is introduced in the graph to
-/// make the representation as precise as possible.
-///
-/// When an Isolate is selected the event is bubbled up to the parent.
-
-import 'dart:async';
-import 'dart:html';
-import 'package:observatory/models.dart' as M;
-import 'package:charted/charted.dart';
-import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
-import 'package:observatory/src/elements/helpers/tag.dart';
-import 'package:observatory/utils.dart';
-
-class IsolateSelectedEvent {
-  final M.Isolate isolate;
-
-  const IsolateSelectedEvent([this.isolate]);
-}
-
-class MemoryGraphElement extends CustomElement implements Renderable {
-  static const tag = const Tag<MemoryGraphElement>('memory-graph');
-
-  RenderingScheduler<MemoryGraphElement> _r;
-
-  final StreamController<IsolateSelectedEvent> _onIsolateSelected =
-      new StreamController<IsolateSelectedEvent>();
-
-  Stream<RenderedEvent<MemoryGraphElement>> get onRendered => _r.onRendered;
-  Stream<IsolateSelectedEvent> get onIsolateSelected =>
-      _onIsolateSelected.stream;
-
-  M.VMRef _vm;
-  M.VMRepository _vms;
-  M.IsolateRepository _isolates;
-  M.EventRepository _events;
-  StreamSubscription _onGCSubscription;
-  StreamSubscription _onResizeSubscription;
-  StreamSubscription _onConnectionClosedSubscription;
-  Timer _onTimer;
-
-  M.VMRef get vm => _vm;
-
-  factory MemoryGraphElement(M.VMRef vm, M.VMRepository vms,
-      M.IsolateRepository isolates, M.EventRepository events,
-      {RenderingQueue queue}) {
-    assert(vm != null);
-    assert(vms != null);
-    assert(isolates != null);
-    assert(events != null);
-    MemoryGraphElement e = new MemoryGraphElement.created();
-    e._r = new RenderingScheduler<MemoryGraphElement>(e, queue: queue);
-    e._vm = vm;
-    e._vms = vms;
-    e._isolates = isolates;
-    e._events = events;
-    return e;
-  }
-
-  MemoryGraphElement.created() : super.created(tag) {
-    final now = new DateTime.now();
-    var sample = now.subtract(_window);
-    while (sample.isBefore(now)) {
-      _ts.add(sample);
-      _vmSamples.add(<int>[0, 0]);
-      _isolateUsedSamples.add([]);
-      _isolateFreeSamples.add([]);
-      sample = sample.add(_period);
-    }
-    _ts.add(now);
-    _vmSamples.add(<int>[0, 0]);
-    _isolateUsedSamples.add([]);
-    _isolateFreeSamples.add([]);
-  }
-
-  static const Duration _period = const Duration(seconds: 2);
-  static const Duration _window = const Duration(minutes: 2);
-
-  @override
-  attached() {
-    super.attached();
-    _r.enable();
-    _onGCSubscription =
-        _events.onGCEvent.listen((e) => _refresh(gcIsolate: e.isolate));
-    _onConnectionClosedSubscription =
-        _events.onConnectionClosed.listen((_) => _onTimer.cancel());
-    _onResizeSubscription = window.onResize.listen((_) => _r.dirty());
-    _onTimer = new Timer.periodic(_period, (_) => _refresh());
-    _refresh();
-  }
-
-  @override
-  detached() {
-    super.detached();
-    _r.disable(notify: true);
-    children = <Element>[];
-    _onGCSubscription.cancel();
-    _onConnectionClosedSubscription.cancel();
-    _onResizeSubscription.cancel();
-    _onTimer.cancel();
-  }
-
-  final List<DateTime> _ts = <DateTime>[];
-  final List<List<int>> _vmSamples = <List<int>>[];
-  final List<M.IsolateRef> _seenIsolates = <M.IsolateRef>[];
-  final List<List<int>> _isolateUsedSamples = <List<int>>[];
-  final List<List<int>> _isolateFreeSamples = <List<int>>[];
-  final Map<String, int> _isolateIndex = <String, int>{};
-  final Map<String, String> _isolateName = <String, String>{};
-
-  var _selected;
-  var _previewed;
-  var _hovered;
-
-  void render() {
-    if (_previewed != null || _hovered != null) return;
-
-    // cache data of hoverboards
-    final ts = new List<DateTime>.from(_ts);
-    final vmSamples = new List<List<int>>.from(_vmSamples);
-    final isolateFreeSamples = new List<List<int>>.from(_isolateFreeSamples);
-    final isolateUsedSamples = new List<List<int>>.from(_isolateUsedSamples);
-
-    final now = _ts.last;
-    final nativeComponents = 1;
-    final legend = new DivElement();
-    final host = new DivElement();
-    final theme = new MemoryChartTheme(1);
-    children = <Element>[theme.style, legend, host];
-    final rect = host.getBoundingClientRect();
-
-    final series =
-        new List<int>.generate(_isolateIndex.length * 2 + 1, (i) => i + 1);
-    // The stacked line chart sorts from top to bottom
-    final columns = [
-      new ChartColumnSpec(
-          formatter: _formatTimeAxis, type: ChartColumnSpec.TYPE_NUMBER),
-      new ChartColumnSpec(label: 'Native', formatter: Utils.formatSize)
-    ]..addAll(_isolateName.keys.expand((id) => [
-          new ChartColumnSpec(formatter: Utils.formatSize),
-          new ChartColumnSpec(label: _label(id), formatter: Utils.formatSize)
-        ]));
-    // The stacked line chart sorts from top to bottom
-    final rows = new List.generate(_ts.length, (sampleIndex) {
-      final free = isolateFreeSamples[sampleIndex];
-      final used = isolateUsedSamples[sampleIndex];
-      final isolates = _isolateIndex.keys.expand((key) {
-        final isolateIndex = _isolateIndex[key];
-        return <int>[free[isolateIndex], used[isolateIndex]];
-      });
-      return [
-        ts[sampleIndex].difference(now).inMicroseconds,
-        vmSamples[sampleIndex][1] ?? 1000000
-      ]..addAll(isolates);
-    });
-
-    final scale = new LinearScale()..domain = [(-_window).inMicroseconds, 0];
-    final axisConfig = new ChartAxisConfig()..scale = scale;
-    final sMemory =
-        new ChartSeries('Memory', series, new StackedLineChartRenderer());
-    final config = new ChartConfig([sMemory], [0])
-      ..legend = new ChartLegend(legend)
-      ..registerDimensionAxis(0, axisConfig);
-    config.minimumSize = new Rect(rect.width, rect.height);
-    final data = new ChartData(columns, rows);
-    final state = new ChartState(isMultiSelect: true)
-      ..changes.listen(_handleEvent);
-    final area = new CartesianArea(host, data, config, state: state)
-      ..theme = theme;
-    area.addChartBehavior(new Hovercard(builder: (int column, int row) {
-      if (column == 1) {
-        final data = vmSamples[row];
-        return _formatNativeOvercard(data[0], data[1]);
-      }
-      final isolate = _seenIsolates[column - 2];
-      final index = _isolateIndex[isolate.id];
-      final free = isolateFreeSamples[row][index];
-      final used = isolateUsedSamples[row][index];
-      return _formatIsolateOvercard(isolate.name, free, used);
-    }));
-    area.draw();
-
-    if (_selected != null) {
-      state.select(_selected);
-      if (_selected > 1) {
-        state.select(_selected + 1);
-      }
-    }
-  }
-
-  String _formatTimeAxis(dynamic ms) =>
-      Utils.formatDuration(new Duration(microseconds: ms.toInt()),
-          precision: DurationComponent.Seconds);
-
-  bool _running = false;
-
-  Future _refresh({M.IsolateRef gcIsolate}) async {
-    if (_running) return;
-    _running = true;
-    final now = new DateTime.now();
-    final start = now.subtract(_window);
-    final vm = await _vms.get(_vm);
-    // The Service classes order isolates from the older to the newer
-    final isolates =
-        (await Future.wait(vm.isolates.map(_isolates.get))).reversed.toList();
-    while (_ts.first.isBefore(start)) {
-      _ts.removeAt(0);
-      _vmSamples.removeAt(0);
-      _isolateUsedSamples.removeAt(0);
-      _isolateFreeSamples.removeAt(0);
-    }
-
-    if (_ts.first.isAfter(start)) {
-      _ts.insert(0, start);
-      _vmSamples.insert(0, _vmSamples.first);
-      _isolateUsedSamples.insert(0, _isolateUsedSamples.first);
-      _isolateFreeSamples.insert(0, _isolateFreeSamples.first);
-    }
-
-    if (_isolateIndex.length == 0) {
-      _selected = isolates.length * 2;
-      _onIsolateSelected.add(new IsolateSelectedEvent(isolates.last));
-    }
-
-    isolates
-        .where((isolate) => !_isolateIndex.containsKey(isolate.id))
-        .forEach((isolate) {
-      _isolateIndex[isolate.id] = _isolateIndex.length;
-      _seenIsolates.addAll([isolate, isolate]);
-    });
-
-    if (_isolateIndex.length != _isolateName.length) {
-      final extra =
-          new List.filled(_isolateIndex.length - _isolateName.length, 0);
-      _isolateUsedSamples.forEach((sample) => sample.addAll(extra));
-      _isolateFreeSamples.forEach((sample) => sample.addAll(extra));
-    }
-
-    final length = _isolateIndex.length;
-
-    if (gcIsolate != null) {
-      // After GC we add an extra point to show the drop in a clear way
-      final List<int> isolateUsedSample = new List<int>.filled(length, 0);
-      final List<int> isolateFreeSample = new List<int>.filled(length, 0);
-      isolates.forEach((M.Isolate isolate) {
-        _isolateName[isolate.id] = isolate.name;
-        final index = _isolateIndex[isolate.id];
-        if (isolate.id == gcIsolate) {
-          isolateUsedSample[index] =
-              _isolateUsedSamples.last[index] + _isolateFreeSamples.last[index];
-          isolateFreeSample[index] = 0;
-        } else {
-          isolateUsedSample[index] = _used(isolate);
-          isolateFreeSample[index] = _free(isolate);
-        }
-      });
-      _isolateUsedSamples.add(isolateUsedSample);
-      _isolateFreeSamples.add(isolateFreeSample);
-
-      _vmSamples.add(<int>[vm.currentRSS, vm.heapAllocatedMemoryUsage]);
-
-      _ts.add(now);
-    }
-    final List<int> isolateUsedSample = new List<int>.filled(length, 0);
-    final List<int> isolateFreeSample = new List<int>.filled(length, 0);
-    isolates.forEach((M.Isolate isolate) {
-      _isolateName[isolate.id] = isolate.name;
-      final index = _isolateIndex[isolate.id];
-      isolateUsedSample[index] = _used(isolate);
-      isolateFreeSample[index] = _free(isolate);
-    });
-    _isolateUsedSamples.add(isolateUsedSample);
-    _isolateFreeSamples.add(isolateFreeSample);
-
-    _vmSamples.add(<int>[vm.currentRSS, vm.heapAllocatedMemoryUsage]);
-
-    _ts.add(now);
-    _r.dirty();
-    _running = false;
-  }
-
-  void _handleEvent(records) => records.forEach((record) {
-        if (record is ChartSelectionChangeRecord) {
-          var selected = record.add;
-          if (selected == null) {
-            if (selected != _selected) {
-              _onIsolateSelected.add(const IsolateSelectedEvent());
-              _r.dirty();
-            }
-          } else {
-            if (selected == 1) {
-              if (selected != _selected) {
-                _onIsolateSelected.add(const IsolateSelectedEvent());
-                _r.dirty();
-              }
-            } else {
-              selected -= selected % 2;
-              if (selected != _selected) {
-                _onIsolateSelected
-                    .add(new IsolateSelectedEvent(_seenIsolates[selected - 2]));
-                _r.dirty();
-              }
-            }
-          }
-          _selected = selected;
-          _previewed = null;
-          _hovered = null;
-        } else if (record is ChartPreviewChangeRecord) {
-          _previewed = record.previewed;
-        } else if (record is ChartHoverChangeRecord) {
-          _hovered = record.hovered;
-        }
-      });
-
-  int _used(M.Isolate i) => i.newSpace.used + i.oldSpace.used;
-  int _capacity(M.Isolate i) => i.newSpace.capacity + i.oldSpace.capacity;
-  int _free(M.Isolate i) => _capacity(i) - _used(i);
-
-  String _label(String isolateId) {
-    final index = _isolateIndex[isolateId];
-    final name = _isolateName[isolateId];
-    final free = _isolateFreeSamples.last[index];
-    final used = _isolateUsedSamples.last[index];
-    final usedStr = Utils.formatSize(used);
-    final capacity = free + used;
-    final capacityStr = Utils.formatSize(capacity);
-    return '${name} ($usedStr / $capacityStr)';
-  }
-
-  static HtmlElement _formatNativeOvercard(int currentRSS, int heap) =>
-      new DivElement()
-        ..children = <Element>[
-          new DivElement()
-            ..classes = ['hovercard-title']
-            ..text = 'Native',
-          new DivElement()
-            ..classes = ['hovercard-measure', 'hovercard-multi']
-            ..children = <Element>[
-              new DivElement()
-                ..classes = ['hovercard-measure-label']
-                ..text = 'Total Memory Usage',
-              new DivElement()
-                ..classes = ['hovercard-measure-value']
-                ..text = currentRSS != null
-                    ? Utils.formatSize(currentRSS)
-                    : "unavailable",
-            ],
-          new DivElement()
-            ..classes = ['hovercard-measure', 'hovercard-multi']
-            ..children = <Element>[
-              new DivElement()
-                ..classes = ['hovercard-measure-label']
-                ..text = 'Native Heap',
-              new DivElement()
-                ..classes = ['hovercard-measure-value']
-                ..text = heap != null ? Utils.formatSize(heap) : "unavailable",
-            ]
-        ];
-
-  static HtmlElement _formatIsolateOvercard(String name, int free, int used) {
-    final capacity = free + used;
-    return new DivElement()
-      ..children = <Element>[
-        new DivElement()
-          ..classes = ['hovercard-title']
-          ..text = name,
-        new DivElement()
-          ..classes = ['hovercard-measure', 'hovercard-multi']
-          ..children = <Element>[
-            new DivElement()
-              ..classes = ['hovercard-measure-label']
-              ..text = 'Heap Capacity',
-            new DivElement()
-              ..classes = ['hovercard-measure-value']
-              ..text = Utils.formatSize(capacity),
-          ],
-        new DivElement()
-          ..classes = ['hovercard-measure', 'hovercard-multi']
-          ..children = <Element>[
-            new DivElement()
-              ..classes = ['hovercard-measure-label']
-              ..text = 'Free Heap',
-            new DivElement()
-              ..classes = ['hovercard-measure-value']
-              ..text = Utils.formatSize(free),
-          ],
-        new DivElement()
-          ..classes = ['hovercard-measure', 'hovercard-multi']
-          ..children = <Element>[
-            new DivElement()
-              ..classes = ['hovercard-measure-label']
-              ..text = 'Used Heap',
-            new DivElement()
-              ..classes = ['hovercard-measure-value']
-              ..text = Utils.formatSize(used),
-          ]
-      ];
-  }
-}
-
-class MemoryChartTheme extends QuantumChartTheme {
-  final int _offset;
-
-  MemoryChartTheme(int offset) : _offset = offset {
-    assert(offset != null);
-    assert(offset >= 0);
-  }
-
-  @override
-  String getColorForKey(key, [int state = 0]) {
-    key -= 1;
-    if (key > _offset) {
-      key = _offset + (key - _offset) ~/ 2;
-    }
-    key += 1;
-    return super.getColorForKey(key, state);
-  }
-
-  @override
-  String getFilterForState(int state) => state & ChartState.COL_PREVIEW != 0 ||
-          state & ChartState.VAL_HOVERED != 0 ||
-          state & ChartState.COL_SELECTED != 0 ||
-          state & ChartState.VAL_HIGHLIGHTED != 0
-      ? 'url(#drop-shadow)'
-      : '';
-
-  @override
-  String get filters =>
-      '<defs>' +
-      super.filters +
-      '''
-<filter id="stroke-grid" primitiveUnits="userSpaceOnUse">
-    <feFlood in="SourceGraphic" x="0" y="0" width="4" height="4"
-      flood-color="black" flood-opacity="0.2" result='Black'/>
-    <feFlood in="SourceGraphic" x="1" y="1" width="3" height="3"
-      flood-color="black" flood-opacity="0.8" result='White'/>
-    <feComposite in="Black" in2="White" operator="xor" x="0" y="0" width="4" height="4"/>
-    <feTile x="0" y="0" width="100%" height="100%" />
-    <feComposite in2="SourceAlpha" result="Pattern" operator="in" x="0" y="0" width="100%" height="100%"/>
-    <feComposite in="SourceGraphic" in2="Pattern" operator="atop" x="0" y="0" width="100%" height="100%"/>
-</filter>
-  </defs>
-''';
-
-  StyleElement get style => new StyleElement()
-    ..text = '''
-memory-graph svg .stacked-line-rdr-line:nth-child(2n+${_offset + 1})
-  path:nth-child(1) {
-  filter: url(#stroke-grid);
-}''';
-}
diff --git a/runtime/observatory/lib/src/elements/memory/profile.dart b/runtime/observatory/lib/src/elements/memory/profile.dart
deleted file mode 100644
index 7d86456..0000000
--- a/runtime/observatory/lib/src/elements/memory/profile.dart
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright (c) 2017, 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.
-
-/// This Element is part of MemoryDashboardElement.
-///
-/// The Element is stripped down version of AllocationProfileElement where
-/// concepts like old and new space has been hidden away.
-///
-/// For each class in the system it is shown the Total number of instances
-/// alive, the Total memory used by these instances, the number of instances
-/// created since the last reset, the memory used by these instances.
-///
-/// When a GC event is received the profile is reloaded.
-
-import 'dart:async';
-import 'dart:html';
-import 'package:observatory/models.dart' as M;
-import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
-import 'package:observatory/src/elements/helpers/tag.dart';
-import 'package:observatory/src/elements/memory/allocations.dart';
-import 'package:observatory/src/elements/memory/snapshot.dart';
-
-enum _Analysis { allocations, dominatorTree }
-
-class MemoryProfileElement extends CustomElement implements Renderable {
-  static const tag = const Tag<MemoryProfileElement>('memory-profile',
-      dependencies: const [
-        MemoryAllocationsElement.tag,
-        MemorySnapshotElement.tag
-      ]);
-
-  RenderingScheduler<MemoryProfileElement> _r;
-
-  Stream<RenderedEvent<MemoryProfileElement>> get onRendered => _r.onRendered;
-
-  M.IsolateRef _isolate;
-  M.AllocationProfileRepository _allocations;
-  M.EditorRepository _editor;
-  M.HeapSnapshotRepository _snapshots;
-  M.ObjectRepository _objects;
-
-  _Analysis _analysis = _Analysis.allocations;
-
-  M.IsolateRef get isolate => _isolate;
-
-  factory MemoryProfileElement(
-      M.IsolateRef isolate,
-      M.EditorRepository editor,
-      M.AllocationProfileRepository allocations,
-      M.HeapSnapshotRepository snapshots,
-      M.ObjectRepository objects,
-      {RenderingQueue queue}) {
-    assert(isolate != null);
-    assert(editor != null);
-    assert(allocations != null);
-    assert(snapshots != null);
-    assert(objects != null);
-    MemoryProfileElement e = new MemoryProfileElement.created();
-    e._r = new RenderingScheduler<MemoryProfileElement>(e, queue: queue);
-    e._isolate = isolate;
-    e._editor = editor;
-    e._allocations = allocations;
-    e._snapshots = snapshots;
-    e._objects = objects;
-    return e;
-  }
-
-  MemoryProfileElement.created() : super.created(tag);
-
-  @override
-  attached() {
-    super.attached();
-    _r.enable();
-  }
-
-  @override
-  detached() {
-    super.detached();
-    _r.disable(notify: true);
-    children = <Element>[];
-  }
-
-  void render() {
-    HtmlElement current;
-    var reload;
-    switch (_analysis) {
-      case _Analysis.allocations:
-        final MemoryAllocationsElement allocations =
-            new MemoryAllocationsElement(_isolate, _editor, _allocations);
-        current = allocations.element;
-        reload = ({bool gc: false}) => allocations.reload(gc: gc);
-        break;
-      case _Analysis.dominatorTree:
-        final MemorySnapshotElement snapshot =
-            new MemorySnapshotElement(_isolate, _editor, _snapshots, _objects);
-        current = snapshot.element;
-        reload = ({bool gc: false}) => snapshot.reload(gc: gc);
-        break;
-    }
-
-    assert(current != null);
-
-    final ButtonElement bReload = new ButtonElement();
-    final ButtonElement bGC = new ButtonElement();
-    children = <Element>[
-      new DivElement()
-        ..classes = ['content-centered-big']
-        ..children = <Element>[
-          new HeadingElement.h1()
-            ..nodes = [
-              new Text(_isolate.name),
-              bReload
-                ..classes = ['header_button']
-                ..text = ' ↺ Refresh'
-                ..title = 'Refresh'
-                ..onClick.listen((e) async {
-                  bReload.disabled = true;
-                  bGC.disabled = true;
-                  await reload();
-                  bReload.disabled = false;
-                  bGC.disabled = false;
-                }),
-              bGC
-                ..classes = ['header_button']
-                ..text = ' ♺ Collect Garbage'
-                ..title = 'Collect Garbage'
-                ..onClick.listen((e) async {
-                  bGC.disabled = true;
-                  bReload.disabled = true;
-                  await reload(gc: true);
-                  bGC.disabled = false;
-                  bReload.disabled = false;
-                }),
-              new SpanElement()
-                ..classes = ['tab_buttons']
-                ..children = <Element>[
-                  new ButtonElement()
-                    ..text = 'Allocations'
-                    ..disabled = _analysis == _Analysis.allocations
-                    ..onClick.listen((_) {
-                      _analysis = _Analysis.allocations;
-                      _r.dirty();
-                    }),
-                  new ButtonElement()
-                    ..text = 'Dominator Tree'
-                    ..disabled = _analysis == _Analysis.dominatorTree
-                    ..onClick.listen((_) {
-                      _analysis = _Analysis.dominatorTree;
-                      _r.dirty();
-                    }),
-                ]
-            ],
-        ],
-      current
-    ];
-  }
-}
diff --git a/runtime/observatory/lib/src/elements/memory/snapshot.dart b/runtime/observatory/lib/src/elements/memory/snapshot.dart
deleted file mode 100644
index b518e96..0000000
--- a/runtime/observatory/lib/src/elements/memory/snapshot.dart
+++ /dev/null
@@ -1,268 +0,0 @@
-// Copyright (c) 2017, 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:html';
-import 'dart:math' as Math;
-import 'package:observatory/models.dart' as M;
-import 'package:observatory/src/elements/class_ref.dart';
-import 'package:observatory/src/elements/containers/virtual_tree.dart';
-import 'package:observatory/src/elements/helpers/any_ref.dart';
-import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
-import 'package:observatory/src/elements/helpers/tag.dart';
-import 'package:observatory/src/elements/helpers/uris.dart';
-import 'package:observatory/utils.dart';
-
-class MemorySnapshotElement extends CustomElement implements Renderable {
-  static const tag =
-      const Tag<MemorySnapshotElement>('memory-snapshot', dependencies: const [
-    ClassRefElement.tag,
-    VirtualTreeElement.tag,
-  ]);
-
-  RenderingScheduler<MemorySnapshotElement> _r;
-
-  Stream<RenderedEvent<MemorySnapshotElement>> get onRendered => _r.onRendered;
-
-  M.IsolateRef _isolate;
-  M.EditorRepository _editor;
-  M.HeapSnapshotRepository _snapshots;
-  M.ObjectRepository _objects;
-  M.HeapSnapshot _snapshot;
-  Stream<M.HeapSnapshotLoadingProgressEvent> _progressStream;
-  M.HeapSnapshotLoadingProgress _progress;
-
-  M.IsolateRef get isolate => _isolate;
-
-  factory MemorySnapshotElement(M.IsolateRef isolate, M.EditorRepository editor,
-      M.HeapSnapshotRepository snapshots, M.ObjectRepository objects,
-      {RenderingQueue queue}) {
-    assert(isolate != null);
-    assert(editor != null);
-    assert(snapshots != null);
-    assert(objects != null);
-    MemorySnapshotElement e = new MemorySnapshotElement.created();
-    e._r = new RenderingScheduler<MemorySnapshotElement>(e, queue: queue);
-    e._isolate = isolate;
-    e._editor = editor;
-    e._snapshots = snapshots;
-    e._objects = objects;
-    return e;
-  }
-
-  MemorySnapshotElement.created() : super.created(tag);
-
-  @override
-  attached() {
-    super.attached();
-    _r.enable();
-    _refresh();
-  }
-
-  @override
-  detached() {
-    super.detached();
-    _r.disable(notify: true);
-    children = <Element>[];
-  }
-
-  void render() {
-    if (_progress == null) {
-      children = const [];
-      return;
-    }
-    List<Element> content;
-    switch (_progress.status) {
-      case M.HeapSnapshotLoadingStatus.fetching:
-        content = _createStatusMessage('Fetching snapshot from VM...',
-            description: _progress.stepDescription,
-            progress: _progress.progress);
-        break;
-      case M.HeapSnapshotLoadingStatus.loading:
-        content = _createStatusMessage('Loading snapshot...',
-            description: _progress.stepDescription,
-            progress: _progress.progress);
-        break;
-      case M.HeapSnapshotLoadingStatus.loaded:
-        content = _createReport();
-        break;
-    }
-    children = content;
-  }
-
-  Future reload({bool gc: false}) => _refresh(gc: gc);
-
-  Future _refresh({bool gc: false}) async {
-    _progress = null;
-    _progressStream =
-        _snapshots.get(isolate, roots: M.HeapSnapshotRoots.user, gc: gc);
-    _r.dirty();
-    _progressStream.listen((e) {
-      _progress = e.progress;
-      _r.dirty();
-    });
-    _progress = (await _progressStream.first).progress;
-    _r.dirty();
-    if (M.isHeapSnapshotProgressRunning(_progress.status)) {
-      _progress = (await _progressStream.last).progress;
-      _snapshot = _progress.snapshot;
-      _r.dirty();
-    }
-  }
-
-  static List<Element> _createStatusMessage(String message,
-      {String description: '', double progress: 0.0}) {
-    return [
-      new DivElement()
-        ..classes = ['content-centered-big']
-        ..children = <Element>[
-          new DivElement()
-            ..classes = ['statusBox', 'shadow', 'center']
-            ..children = <Element>[
-              new DivElement()
-                ..classes = ['statusMessage']
-                ..text = message,
-              new DivElement()
-                ..classes = ['statusDescription']
-                ..text = description,
-              new DivElement()
-                ..style.background = '#0489c3'
-                ..style.width = '$progress%'
-                ..style.height = '15px'
-                ..style.borderRadius = '4px'
-            ]
-        ]
-    ];
-  }
-
-  VirtualTreeElement _tree;
-
-  List<Element> _createReport() {
-    final List roots = _getChildrenDominator(_snapshot.dominatorTree).toList();
-    _tree = new VirtualTreeElement(
-        _createDominator, _updateDominator, _getChildrenDominator,
-        items: roots, queue: _r.queue);
-    if (roots.length == 1) {
-      _tree.expand(roots.first, autoExpandSingleChildNodes: true);
-    }
-    final text = 'In a heap dominator tree, an object X is a parent of '
-        'object Y if every path from the root to Y goes through '
-        'X. This allows you to find "choke points" that are '
-        'holding onto a lot of memory. If an object becomes '
-        'garbage, all its children in the dominator tree become '
-        'garbage as well. '
-        'The retained size of an object is the sum of the '
-        'retained sizes of its children in the dominator tree '
-        'plus its own shallow size, and is the amount of memory '
-        'that would be freed if the object became garbage.';
-    return <HtmlElement>[
-      new DivElement()
-        ..classes = ['content-centered-big', 'explanation']
-        ..text = text
-        ..title = text,
-      _tree.element
-    ];
-  }
-
-  static HtmlElement _createDominator(toggle) {
-    return new DivElement()
-      ..classes = ['tree-item']
-      ..children = <Element>[
-        new SpanElement()
-          ..classes = ['size']
-          ..title = 'retained size',
-        new SpanElement()..classes = ['lines'],
-        new ButtonElement()
-          ..classes = ['expander']
-          ..onClick.listen((_) => toggle(autoToggleSingleChildNodes: true)),
-        new SpanElement()
-          ..classes = ['percentage']
-          ..title = 'percentage of heap being retained',
-        new SpanElement()..classes = ['name']
-      ];
-  }
-
-  static const int kMaxChildren = 100;
-  static const int kMinRetainedSize = 4096;
-
-  static Iterable _getChildrenDominator(nodeDynamic) {
-    M.HeapSnapshotDominatorNode node = nodeDynamic;
-    final list = node.children.toList();
-    list.sort((a, b) => b.retainedSize - a.retainedSize);
-    return list
-        .where((child) => child.retainedSize >= kMinRetainedSize)
-        .take(kMaxChildren);
-  }
-
-  void _updateDominator(HtmlElement element, nodeDynamic, int depth) {
-    M.HeapSnapshotDominatorNode node = nodeDynamic;
-    element.children[0].text = Utils.formatSize(node.retainedSize);
-    _updateLines(element.children[1].children, depth);
-    if (_getChildrenDominator(node).isNotEmpty) {
-      element.children[2].text = _tree.isExpanded(node) ? '▼' : '►';
-    } else {
-      element.children[2].text = '';
-    }
-    element.children[3].text =
-        Utils.formatPercentNormalized(node.retainedSize * 1.0 / _snapshot.size);
-    final wrapper = new SpanElement()
-      ..classes = ['name']
-      ..text = 'Loading...';
-    element.children[4] = wrapper;
-    if (node.isStack) {
-      wrapper
-        ..text = ''
-        ..children = <Element>[
-          new AnchorElement(href: Uris.debugger(isolate))..text = 'stack frames'
-        ];
-    } else {
-      node.object.then((object) {
-        wrapper
-          ..text = ''
-          ..children = <Element>[
-            anyRef(_isolate, object, _objects,
-                queue: _r.queue, expandable: false)
-          ];
-      });
-    }
-    Element.clickEvent
-        .forTarget(element.children[4], useCapture: true)
-        .listen((e) {
-      if (_editor.isAvailable) {
-        e.preventDefault();
-        _sendNodeToEditor(node);
-      }
-    });
-  }
-
-  Future _sendNodeToEditor(M.HeapSnapshotDominatorNode node) async {
-    final object = await node.object;
-    if (node.isStack) {
-      // TODO (https://github.com/flutter/flutter-intellij/issues/1290)
-      // open debugger
-      return new Future.value();
-    }
-    _editor.openObject(_isolate, object);
-  }
-
-  static _updateLines(List<Element> lines, int n) {
-    n = Math.max(0, n);
-    while (lines.length > n) {
-      lines.removeLast();
-    }
-    while (lines.length < n) {
-      lines.add(new SpanElement());
-    }
-  }
-
-  static String rootsToString(M.HeapSnapshotRoots roots) {
-    switch (roots) {
-      case M.HeapSnapshotRoots.user:
-        return 'User';
-      case M.HeapSnapshotRoots.vm:
-        return 'VM';
-    }
-    throw new Exception('Unknown HeapSnapshotRoots');
-  }
-}
diff --git a/runtime/observatory/lib/src/elements/top_retaining_instances.dart b/runtime/observatory/lib/src/elements/top_retaining_instances.dart
deleted file mode 100644
index 31a84a5..0000000
--- a/runtime/observatory/lib/src/elements/top_retaining_instances.dart
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (c) 2016, 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:html';
-import 'dart:async';
-import 'package:observatory/models.dart' as M;
-import 'package:observatory/src/elements/curly_block.dart';
-import 'package:observatory/src/elements/instance_ref.dart';
-import 'package:observatory/src/elements/helpers/any_ref.dart';
-import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
-import 'package:observatory/src/elements/helpers/tag.dart';
-import 'package:observatory/utils.dart';
-
-class TopRetainingInstancesElement extends CustomElement implements Renderable {
-  static const tag = const Tag<TopRetainingInstancesElement>(
-      'top-retainig-instances',
-      dependencies: const [CurlyBlockElement.tag, InstanceRefElement.tag]);
-
-  RenderingScheduler<TopRetainingInstancesElement> _r;
-
-  Stream<RenderedEvent<TopRetainingInstancesElement>> get onRendered =>
-      _r.onRendered;
-
-  M.IsolateRef _isolate;
-  M.ClassRef _cls;
-  M.TopRetainingInstancesRepository _topRetainingInstances;
-  M.ObjectRepository _objects;
-  Iterable<M.RetainingObject> _topRetaining;
-  bool _expanded = false;
-
-  M.IsolateRef get isolate => _isolate;
-  M.ClassRef get cls => _cls;
-
-  factory TopRetainingInstancesElement(
-      M.IsolateRef isolate,
-      M.ClassRef cls,
-      M.TopRetainingInstancesRepository topRetainingInstances,
-      M.ObjectRepository objects,
-      {RenderingQueue queue}) {
-    assert(isolate != null);
-    assert(cls != null);
-    assert(topRetainingInstances != null);
-    assert(objects != null);
-    TopRetainingInstancesElement e = new TopRetainingInstancesElement.created();
-    e._r =
-        new RenderingScheduler<TopRetainingInstancesElement>(e, queue: queue);
-    e._isolate = isolate;
-    e._cls = cls;
-    e._topRetainingInstances = topRetainingInstances;
-    e._objects = objects;
-    return e;
-  }
-
-  TopRetainingInstancesElement.created() : super.created(tag);
-
-  @override
-  void attached() {
-    super.attached();
-    _r.enable();
-  }
-
-  @override
-  void detached() {
-    super.detached();
-    children = <Element>[];
-    _r.disable(notify: true);
-  }
-
-  void render() {
-    children = <Element>[
-      (new CurlyBlockElement(expanded: _expanded, queue: _r.queue)
-            ..content = <Element>[
-              new DivElement()
-                ..classes = ['memberList']
-                ..children = _createContent()
-            ]
-            ..onToggle.listen((e) async {
-              _expanded = e.control.expanded;
-              if (_expanded) {
-                e.control.disabled = true;
-                await _refresh();
-                e.control.disabled = false;
-              }
-            }))
-          .element
-    ];
-  }
-
-  Future _refresh() async {
-    _topRetaining = null;
-    _topRetaining = await _topRetainingInstances.get(_isolate, _cls);
-    _r.dirty();
-  }
-
-  List<Element> _createContent() {
-    if (_topRetaining == null) {
-      return [new SpanElement()..text = 'Loading...'];
-    }
-    return _topRetaining
-        .map<Element>((r) => new DivElement()
-          ..classes = ['memberItem']
-          ..children = <Element>[
-            new DivElement()
-              ..classes = ['memberName']
-              ..text = '${Utils.formatSize(r.retainedSize)} ',
-            new DivElement()
-              ..classes = ['memberValue']
-              ..children = <Element>[
-                anyRef(_isolate, r.object, _objects, queue: _r.queue)
-              ]
-          ])
-        .toList();
-  }
-}
diff --git a/runtime/observatory/lib/src/heap_snapshot/heap_snapshot.dart b/runtime/observatory/lib/src/heap_snapshot/heap_snapshot.dart
index 130d56c..c238385 100644
--- a/runtime/observatory/lib/src/heap_snapshot/heap_snapshot.dart
+++ b/runtime/observatory/lib/src/heap_snapshot/heap_snapshot.dart
@@ -4,171 +4,38 @@
 
 part of heap_snapshot;
 
+// TODO(observatory): The two levels of interface (SnapshotGraph + HeapSnapshot)
+// probably aren't providing any value after the removal of class-based
+// reference merging that only happen in the second layer. Consider flattening.
+
 class HeapSnapshot implements M.HeapSnapshot {
-  ObjectGraph graph;
+  SnapshotGraph graph;
   DateTime timestamp;
-  int get objects => graph.vertexCount;
-  int get references => graph.edgeCount;
-  int get size => graph.internalSize + graph.externalSize;
-  HeapSnapshotDominatorNode dominatorTree;
+  int get size => graph.shallowSize + graph.externalSize;
   HeapSnapshotMergedDominatorNode mergedDominatorTree;
-  List<MergedVertex> classReferences;
-  List<HeapSnapshotOwnershipClass> ownershipClasses;
+  List<SnapshotClass> classes;
+  SnapshotObject get root => graph.root;
+  List<ByteData> chunks;
 
-  static Future sleep([Duration duration = const Duration(microseconds: 0)]) {
-    final Completer completer = new Completer();
-    new Timer(duration, () => completer.complete());
-    return completer.future;
-  }
-
-  Stream<List> loadProgress(S.Isolate isolate, S.RawHeapSnapshot raw) {
-    final progress = new StreamController<List>.broadcast();
-    progress.add(['', 0.0]);
-    graph = new ObjectGraph(raw.chunks, raw.count);
-    var signal = (String description, double p) {
-      progress.add([description, p]);
-      return sleep();
-    };
+  Stream<String> loadProgress(S.Isolate isolate, List<ByteData> chunks) {
+    final progress = new StreamController<String>.broadcast();
+    progress.add('Loading...');
+    this.chunks = chunks;
+    graph = new SnapshotGraph(chunks);
     (() async {
       timestamp = new DateTime.now();
       final stream = graph.process();
       stream.listen((status) {
-        status[1] /= 2.0;
         progress.add(status);
       });
       await stream.last;
-      dominatorTree = new HeapSnapshotDominatorNode(isolate, graph.root);
       mergedDominatorTree =
-          new HeapSnapshotMergedDominatorNode(isolate, graph.mergedRoot);
-      classReferences = await buildMergedVertices(isolate, graph, signal);
-      ownershipClasses = buildOwnershipClasses(isolate, graph);
+          new HeapSnapshotMergedDominatorNode(isolate, graph.mergedRoot, null);
+      classes = graph.classes.toList();
       progress.close();
     }());
     return progress.stream;
   }
-
-  Future<List<MergedVertex>> buildMergedVertices(
-      S.Isolate isolate, ObjectGraph graph, signal) async {
-    final cidToMergedVertex = <int, MergedVertex>{};
-
-    int count = 0;
-    final Stopwatch watch = new Stopwatch();
-    watch.start();
-    var needToUpdate = () {
-      count++;
-      if (((count % 256) == 0) && (watch.elapsedMilliseconds > 16)) {
-        watch.reset();
-        return true;
-      }
-      return false;
-    };
-    final length = graph.vertices.length;
-    for (final vertex in graph.vertices) {
-      if (vertex.vmCid == 0) {
-        continue;
-      }
-      if (needToUpdate()) {
-        await signal('', count * 50.0 / length + 50);
-      }
-      final cid = vertex.vmCid;
-      MergedVertex source = cidToMergedVertex[cid];
-      if (source == null) {
-        cidToMergedVertex[cid] = source = new MergedVertex(isolate, cid);
-      }
-
-      source.instances++;
-      source.shallowSize += vertex.shallowSize ?? 0;
-
-      for (final vertex2 in vertex.successors) {
-        if (vertex2.vmCid == 0) {
-          continue;
-        }
-        final cid2 = vertex2.vmCid;
-        MergedEdge edge = source.outgoingEdges[cid2];
-        if (edge == null) {
-          MergedVertex target = cidToMergedVertex[cid2];
-          if (target == null) {
-            cidToMergedVertex[cid2] = target = new MergedVertex(isolate, cid2);
-          }
-          edge = new MergedEdge(source, target);
-          source.outgoingEdges[cid2] = edge;
-          target.incomingEdges.add(edge);
-        }
-        edge.count++;
-        // An over-estimate if there are multiple references to the same object.
-        edge.shallowSize += vertex2.shallowSize ?? 0;
-      }
-    }
-    return cidToMergedVertex.values.toList();
-  }
-
-  buildOwnershipClasses(S.Isolate isolate, ObjectGraph graph) {
-    var numCids = graph.numCids;
-    var classes = new List<HeapSnapshotOwnershipClass>();
-    for (var cid = 0; cid < numCids; cid++) {
-      var size = graph.getOwnedByCid(cid);
-      if (size != 0) {
-        classes.add(new HeapSnapshotOwnershipClass(cid, isolate, size));
-      }
-    }
-    return classes;
-  }
-
-  List<Future<S.ServiceObject>> getMostRetained(S.Isolate isolate,
-      {int classId, int limit}) {
-    List<Future<S.ServiceObject>> result = <Future<S.ServiceObject>>[];
-    for (ObjectVertex v
-        in graph.getMostRetained(classId: classId, limit: limit)) {
-      result.add(
-          isolate.getObjectByAddress(v.address).then((S.ServiceObject obj) {
-        if (obj is S.HeapObject) {
-          obj.retainedSize = v.retainedSize;
-        } else {
-          print("${obj.runtimeType} should be a HeapObject");
-        }
-        return obj;
-      }));
-    }
-    return result;
-  }
-}
-
-class HeapSnapshotDominatorNode implements M.HeapSnapshotDominatorNode {
-  final ObjectVertex v;
-  final S.Isolate isolate;
-  S.ServiceObject _preloaded;
-
-  bool get isStack => v.isStack;
-
-  Future<S.ServiceObject> get object {
-    if (_preloaded != null) {
-      return new Future.value(_preloaded);
-    } else {
-      return isolate.getObjectByAddress(v.address).then((S.ServiceObject obj) {
-        return _preloaded = obj;
-      });
-    }
-  }
-
-  Iterable<HeapSnapshotDominatorNode> _children;
-  Iterable<HeapSnapshotDominatorNode> get children {
-    if (_children != null) {
-      return _children;
-    } else {
-      return _children =
-          new List.unmodifiable(v.dominatorTreeChildren().map((v) {
-        return new HeapSnapshotDominatorNode(isolate, v);
-      }));
-    }
-  }
-
-  int get retainedSize => v.retainedSize;
-  int get shallowSize => v.shallowSize;
-  int get externalSize => v.externalSize;
-
-  HeapSnapshotDominatorNode(S.Isolate isolate, ObjectVertex vertex)
-      : isolate = isolate,
-        v = vertex;
 }
 
 class HeapSnapshotMergedDominatorNode
@@ -176,11 +43,10 @@
   final MergedObjectVertex v;
   final S.Isolate isolate;
 
-  bool get isStack => v.isStack;
+  SnapshotClass get klass => v.klass;
 
-  Future<S.HeapObject> get klass {
-    return new Future.value(isolate.getClassByCid(v.vmCid));
-  }
+  final _parent;
+  HeapSnapshotMergedDominatorNode get parent => _parent ?? this;
 
   Iterable<HeapSnapshotMergedDominatorNode> _children;
   Iterable<HeapSnapshotMergedDominatorNode> get children {
@@ -189,104 +55,22 @@
     } else {
       return _children =
           new List.unmodifiable(v.dominatorTreeChildren().map((v) {
-        return new HeapSnapshotMergedDominatorNode(isolate, v);
+        return new HeapSnapshotMergedDominatorNode(isolate, v, this);
       }));
     }
   }
 
+  List<SnapshotObject> get objects => v.objects;
+
   int get instanceCount => v.instanceCount;
   int get retainedSize => v.retainedSize;
   int get shallowSize => v.shallowSize;
   int get externalSize => v.externalSize;
 
-  HeapSnapshotMergedDominatorNode(S.Isolate isolate, MergedObjectVertex vertex)
+  String get description => "$instanceCount instances of ${klass.name}";
+
+  HeapSnapshotMergedDominatorNode(
+      S.Isolate isolate, MergedObjectVertex vertex, this._parent)
       : isolate = isolate,
         v = vertex;
 }
-
-class MergedEdge {
-  final MergedVertex sourceVertex;
-  final MergedVertex targetVertex;
-  int count = 0;
-  int shallowSize = 0;
-  int retainedSize = 0;
-
-  MergedEdge(this.sourceVertex, this.targetVertex);
-}
-
-class MergedVertex implements M.HeapSnapshotClassReferences {
-  final int cid;
-  final S.Isolate isolate;
-  S.Class get clazz => isolate.getClassByCid(cid);
-  int instances = 0;
-  int shallowSize = 0;
-  int retainedSize = 0;
-
-  List<MergedEdge> incomingEdges = new List<MergedEdge>();
-  Map<int, MergedEdge> outgoingEdges = new Map<int, MergedEdge>();
-
-  Iterable<HeapSnapshotClassInbound> _inbounds;
-  Iterable<HeapSnapshotClassInbound> get inbounds {
-    if (_inbounds != null) {
-      return _inbounds;
-    } else {
-      // It is important to keep the template.
-      // https://github.com/dart-lang/sdk/issues/27144
-      return _inbounds = new List<HeapSnapshotClassInbound>.unmodifiable(
-          incomingEdges.map((edge) {
-        return new HeapSnapshotClassInbound(this, edge);
-      }));
-    }
-  }
-
-  Iterable<HeapSnapshotClassOutbound> _outbounds;
-  Iterable<HeapSnapshotClassOutbound> get outbounds {
-    if (_outbounds != null) {
-      return _outbounds;
-    } else {
-      // It is important to keep the template.
-      // https://github.com/dart-lang/sdk/issues/27144
-      return _outbounds = new List<HeapSnapshotClassOutbound>.unmodifiable(
-          outgoingEdges.values.map((edge) {
-        return new HeapSnapshotClassOutbound(this, edge);
-      }));
-    }
-  }
-
-  MergedVertex(this.isolate, this.cid);
-}
-
-class HeapSnapshotClassInbound implements M.HeapSnapshotClassInbound {
-  final MergedVertex vertex;
-  final MergedEdge edge;
-  S.Class get source => edge.sourceVertex != vertex
-      ? edge.sourceVertex.clazz
-      : edge.targetVertex.clazz;
-  int get count => edge.count;
-  int get shallowSize => edge.shallowSize;
-  int get retainedSize => edge.retainedSize;
-
-  HeapSnapshotClassInbound(this.vertex, this.edge);
-}
-
-class HeapSnapshotClassOutbound implements M.HeapSnapshotClassOutbound {
-  final MergedVertex vertex;
-  final MergedEdge edge;
-  S.Class get target => edge.sourceVertex != vertex
-      ? edge.sourceVertex.clazz
-      : edge.targetVertex.clazz;
-  int get count => edge.count;
-  int get shallowSize => edge.shallowSize;
-  int get retainedSize => edge.retainedSize;
-
-  HeapSnapshotClassOutbound(this.vertex, this.edge);
-}
-
-class HeapSnapshotOwnershipClass implements M.HeapSnapshotOwnershipClass {
-  final int cid;
-  final S.Isolate isolate;
-  S.Class get clazz => isolate.getClassByCid(cid);
-  final int size;
-
-  HeapSnapshotOwnershipClass(this.cid, this.isolate, this.size);
-}
diff --git a/runtime/observatory/lib/src/models/objects/class.dart b/runtime/observatory/lib/src/models/objects/class.dart
index 9d1a7d1..47a1a34 100644
--- a/runtime/observatory/lib/src/models/objects/class.dart
+++ b/runtime/observatory/lib/src/models/objects/class.dart
@@ -71,5 +71,3 @@
   int get count;
   Iterable<ObjectRef> get instances;
 }
-
-abstract class TopRetainedInstances {}
diff --git a/runtime/observatory/lib/src/models/objects/heap_snapshot.dart b/runtime/observatory/lib/src/models/objects/heap_snapshot.dart
index 9250370..f6630c0 100644
--- a/runtime/observatory/lib/src/models/objects/heap_snapshot.dart
+++ b/runtime/observatory/lib/src/models/objects/heap_snapshot.dart
@@ -4,60 +4,19 @@
 
 part of models;
 
-enum HeapSnapshotRoots { user, vm }
-
 abstract class HeapSnapshot {
   DateTime get timestamp;
-  int get objects;
-  int get references;
   int get size;
-  HeapSnapshotDominatorNode get dominatorTree;
+  SnapshotObject get root;
   HeapSnapshotMergedDominatorNode get mergedDominatorTree;
-  Iterable<HeapSnapshotClassReferences> get classReferences;
-  Iterable<HeapSnapshotOwnershipClass> get ownershipClasses;
-}
-
-abstract class HeapSnapshotDominatorNode {
-  int get shallowSize;
-  int get retainedSize;
-  bool get isStack;
-  Future<ObjectRef> get object;
-  Iterable<HeapSnapshotDominatorNode> get children;
+  Iterable<SnapshotClass> get classes;
+  List<ByteData> get chunks;
 }
 
 abstract class HeapSnapshotMergedDominatorNode {
   int get instanceCount;
   int get shallowSize;
   int get retainedSize;
-  bool get isStack;
-  Future<ObjectRef> get klass;
+  SnapshotClass get klass;
   Iterable<HeapSnapshotMergedDominatorNode> get children;
 }
-
-abstract class HeapSnapshotClassReferences {
-  ClassRef get clazz;
-  int get instances;
-  int get shallowSize;
-  int get retainedSize;
-  Iterable<HeapSnapshotClassInbound> get inbounds;
-  Iterable<HeapSnapshotClassOutbound> get outbounds;
-}
-
-abstract class HeapSnapshotClassInbound {
-  ClassRef get source;
-  int get count;
-  int get shallowSize;
-  int get retainedSize;
-}
-
-abstract class HeapSnapshotClassOutbound {
-  ClassRef get target;
-  int get count;
-  int get shallowSize;
-  int get retainedSize;
-}
-
-abstract class HeapSnapshotOwnershipClass {
-  ClassRef get clazz;
-  int get size;
-}
diff --git a/runtime/observatory/lib/src/models/repositories/heap_snapshot.dart b/runtime/observatory/lib/src/models/repositories/heap_snapshot.dart
index 9274da6..41fde0e 100644
--- a/runtime/observatory/lib/src/models/repositories/heap_snapshot.dart
+++ b/runtime/observatory/lib/src/models/repositories/heap_snapshot.dart
@@ -30,6 +30,5 @@
 }
 
 abstract class HeapSnapshotRepository {
-  Stream<HeapSnapshotLoadingProgressEvent> get(IsolateRef isolate,
-      {HeapSnapshotRoots roots: HeapSnapshotRoots.vm, bool gc: false});
+  Stream<HeapSnapshotLoadingProgressEvent> get(IsolateRef isolate);
 }
diff --git a/runtime/observatory/lib/src/models/repositories/top_retaining_instances.dart b/runtime/observatory/lib/src/models/repositories/top_retaining_instances.dart
deleted file mode 100644
index 576f662..0000000
--- a/runtime/observatory/lib/src/models/repositories/top_retaining_instances.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (c) 2016, 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
-
-part of models;
-
-abstract class TopRetainingInstancesRepository {
-  Future<Iterable<RetainingObject>> get(IsolateRef isolate, ClassRef cls);
-}
diff --git a/runtime/observatory/lib/src/repositories/heap_snapshot.dart b/runtime/observatory/lib/src/repositories/heap_snapshot.dart
index 198af19..9a1093a 100644
--- a/runtime/observatory/lib/src/repositories/heap_snapshot.dart
+++ b/runtime/observatory/lib/src/repositories/heap_snapshot.dart
@@ -16,8 +16,6 @@
   Stream<HeapSnapshotLoadingProgressEvent> get onProgress => _onProgress.stream;
 
   final S.Isolate isolate;
-  final M.HeapSnapshotRoots roots;
-  final bool gc;
 
   M.HeapSnapshotLoadingStatus _status = M.HeapSnapshotLoadingStatus.fetching;
   String _stepDescription = '';
@@ -33,7 +31,7 @@
   Duration get loadingTime => _loadingTime.elapsed;
   HeapSnapshot get snapshot => _snapshot;
 
-  HeapSnapshotLoadingProgress(this.isolate, this.roots, this.gc) {
+  HeapSnapshotLoadingProgress(this.isolate) {
     _run();
   }
 
@@ -43,15 +41,12 @@
       _status = M.HeapSnapshotLoadingStatus.fetching;
       _triggerOnProgress();
 
-      await isolate.getClassRefs();
-
-      final stream = isolate.fetchHeapSnapshot(roots, gc);
+      final stream = isolate.fetchHeapSnapshot();
 
       stream.listen((status) {
-        if (status is List) {
-          _progress = status[0] * 100.0 / status[1];
-          _stepDescription = 'Receiving snapshot chunk ${status[0] + 1}'
-              ' of ${status[1]}...';
+        if (status is List && status[0] is double) {
+          _progress = 0.5;
+          _stepDescription = 'Receiving snapshot chunk ${status[0] + 1}...';
           _triggerOnProgress();
         }
       });
@@ -66,10 +61,10 @@
 
       HeapSnapshot snapshot = new HeapSnapshot();
 
-      Stream<List> progress = snapshot.loadProgress(isolate, response);
+      Stream<String> progress = snapshot.loadProgress(isolate, response);
       progress.listen((value) {
-        _stepDescription = value[0];
-        _progress = value[1];
+        _stepDescription = value;
+        _progress = 0.5;
         _triggerOnProgress();
       });
 
@@ -101,11 +96,9 @@
 }
 
 class HeapSnapshotRepository implements M.HeapSnapshotRepository {
-  Stream<HeapSnapshotLoadingProgressEvent> get(M.IsolateRef i,
-      {M.HeapSnapshotRoots roots: M.HeapSnapshotRoots.vm, bool gc: false}) {
+  Stream<HeapSnapshotLoadingProgressEvent> get(M.IsolateRef i) {
     S.Isolate isolate = i as S.Isolate;
     assert(isolate != null);
-    assert(gc != null);
-    return new HeapSnapshotLoadingProgress(isolate, roots, gc).onProgress;
+    return new HeapSnapshotLoadingProgress(isolate).onProgress;
   }
 }
diff --git a/runtime/observatory/lib/src/repositories/top_retaining_instances.dart b/runtime/observatory/lib/src/repositories/top_retaining_instances.dart
deleted file mode 100644
index 400ac14..0000000
--- a/runtime/observatory/lib/src/repositories/top_retaining_instances.dart
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2016, 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
-
-part of repositories;
-
-class TopRetainingInstancesRepository
-    implements M.TopRetainingInstancesRepository {
-  Future<Iterable<M.RetainingObject>> get(M.IsolateRef i, M.ClassRef c) async {
-    S.Isolate isolate = i as S.Isolate;
-    S.Class cls = c as S.Class;
-    assert(isolate != null);
-    assert(cls != null);
-    final raw =
-        await isolate.fetchHeapSnapshot(M.HeapSnapshotRoots.vm, true).last;
-    final snapshot = new HeapSnapshot();
-    await snapshot.loadProgress(isolate, raw).last;
-    return (await Future.wait(
-            snapshot.getMostRetained(isolate, classId: cls.vmCid, limit: 10)))
-        .map((object) => new S.RetainingObject(object));
-  }
-}
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index a4a29aa..866aed5 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -878,7 +878,7 @@
         await listenEventStream(kVMStream, _dispatchEventToIsolate);
         await listenEventStream(kIsolateStream, _dispatchEventToIsolate);
         await listenEventStream(kDebugStream, _dispatchEventToIsolate);
-        await listenEventStream(_kGraphStream, _dispatchEventToIsolate);
+        await listenEventStream(kHeapSnapshotStream, _dispatchEventToIsolate);
         await listenEventStream(kServiceStream, _updateService);
       } on NetworkRpcException catch (_) {
         // ignore network errors here.
@@ -928,7 +928,7 @@
   static const kGCStream = 'GC';
   static const kStdoutStream = 'Stdout';
   static const kStderrStream = 'Stderr';
-  static const _kGraphStream = '_Graph';
+  static const kHeapSnapshotStream = 'HeapSnapshot';
   static const kServiceStream = 'Service';
 
   /// Returns a single-subscription Stream object for a VM event stream.
@@ -1219,12 +1219,6 @@
   }
 }
 
-class RawHeapSnapshot {
-  final chunks;
-  final count;
-  RawHeapSnapshot(this.chunks, this.count);
-}
-
 /// State for a running isolate.
 class Isolate extends ServiceObjectOwner implements M.Isolate {
   static const kLoggingStream = 'Logging';
@@ -1355,20 +1349,6 @@
     return invokeRpc('_getPersistentHandles', {});
   }
 
-  Future<List<Class>> getClassRefs() async {
-    ServiceMap classList = await invokeRpc('getClassList', {});
-    assert(classList.type == 'ClassList');
-    var classRefs = <Class>[];
-    for (var cls in classList['classes']) {
-      // Skip over non-class classes.
-      if (cls is Class) {
-        _classesByCid[cls.vmCid] = cls;
-        classRefs.add(cls);
-      }
-    }
-    return classRefs;
-  }
-
   /// Given the class list, loads each class.
   Future<List<Class>> _loadClasses(ServiceMap classList) {
     assert(classList.type == 'ClassList');
@@ -1376,7 +1356,6 @@
     for (var cls in classList['classes']) {
       // Skip over non-class classes.
       if (cls is Class) {
-        _classesByCid[cls.vmCid] = cls;
         futureClasses.add(cls.load().then<Class>((_) => cls));
       }
     }
@@ -1401,8 +1380,6 @@
     return new Future.value(objectClass);
   }
 
-  Class getClassByCid(int cid) => _classesByCid[cid];
-
   ServiceObject getFromMap(Map map) {
     if (map == null) {
       return null;
@@ -1467,7 +1444,6 @@
 
   Class objectClass;
   final rootClasses = <Class>[];
-  Map<int, Class> _classesByCid = new Map<int, Class>();
 
   Library rootLibrary;
   List<Library> libraries = <Library>[];
@@ -1508,43 +1484,30 @@
     }
 
     // Occasionally these actually arrive out of order.
-    var chunkIndex = event.chunkIndex;
-    var chunkCount = event.chunkCount;
     if (_chunksInProgress == null) {
-      _chunksInProgress = new List(chunkCount);
+      _chunksInProgress = new List();
     }
-    _chunksInProgress[chunkIndex] = event.data;
-    _snapshotFetch.add([chunkIndex, chunkCount]);
 
-    for (var i = 0; i < chunkCount; i++) {
-      if (_chunksInProgress[i] == null) return;
+    _chunksInProgress.add(event.data);
+    _snapshotFetch.add([_chunksInProgress.length, _chunksInProgress.length]);
+    if (!event.lastChunk) {
+      return;
     }
 
     var loadedChunks = _chunksInProgress;
     _chunksInProgress = null;
 
     if (_snapshotFetch != null) {
-      _snapshotFetch.add(new RawHeapSnapshot(loadedChunks, event.nodeCount));
+      _snapshotFetch.add(loadedChunks);
       _snapshotFetch.close();
     }
   }
 
-  static String _rootsToString(M.HeapSnapshotRoots roots) {
-    switch (roots) {
-      case M.HeapSnapshotRoots.user:
-        return "User";
-      case M.HeapSnapshotRoots.vm:
-        return "VM";
-    }
-    return null;
-  }
-
-  Stream fetchHeapSnapshot(M.HeapSnapshotRoots roots, bool collectGarbage) {
+  Stream fetchHeapSnapshot() {
     if (_snapshotFetch == null || _snapshotFetch.isClosed) {
       _snapshotFetch = new StreamController.broadcast();
-      // isolate.vm.streamListen('_Graph');
-      isolate.invokeRpcNoUpgrade('_requestHeapSnapshot',
-          {'roots': _rootsToString(roots), 'collectGarbage': collectGarbage});
+      // isolate.vm.streamListen('HeapSnapshot');
+      isolate.invokeRpcNoUpgrade('requestHeapSnapshot', {});
     }
     return _snapshotFetch.stream;
   }
@@ -1719,7 +1682,7 @@
         _updateRunState();
         break;
 
-      case ServiceEvent.kGraph:
+      case ServiceEvent.kHeapSnapshot:
         _loadHeapSnapshot(event);
         break;
 
@@ -1915,15 +1878,6 @@
     return invokeRpc('getInstances', params);
   }
 
-  Future<ServiceObject /*HeapObject*/ > getObjectByAddress(String address,
-      [bool ref = true]) {
-    Map params = {
-      'address': address,
-      'ref': ref,
-    };
-    return invokeRpc('_getObjectByAddress', params);
-  }
-
   final Map<String, ServiceMetric> dartMetrics = <String, ServiceMetric>{};
 
   final Map<String, ServiceMetric> nativeMetrics = <String, ServiceMetric>{};
@@ -2108,7 +2062,7 @@
   static const kBreakpointAdded = 'BreakpointAdded';
   static const kBreakpointResolved = 'BreakpointResolved';
   static const kBreakpointRemoved = 'BreakpointRemoved';
-  static const kGraph = '_Graph';
+  static const kHeapSnapshot = 'HeapSnapshot';
   static const kGC = 'GC';
   static const kInspect = 'Inspect';
   static const kDebuggerSettingsUpdate = '_DebuggerSettingsUpdate';
@@ -2154,7 +2108,7 @@
   String service;
   String alias;
 
-  int chunkIndex, chunkCount, nodeCount;
+  bool lastChunk;
 
   bool get isPauseEvent {
     return (kind == kPauseStart ||
@@ -2203,15 +2157,7 @@
     if (map['_data'] != null) {
       data = map['_data'];
     }
-    if (map['chunkIndex'] != null) {
-      chunkIndex = map['chunkIndex'];
-    }
-    if (map['chunkCount'] != null) {
-      chunkCount = map['chunkCount'];
-    }
-    if (map['nodeCount'] != null) {
-      nodeCount = map['nodeCount'];
-    }
+    lastChunk = map['last'] ?? false;
     if (map['count'] != null) {
       count = map['count'];
     }
@@ -2495,7 +2441,6 @@
   SourceLocation location;
 
   DartError error;
-  int vmCid;
 
   final Allocations newSpace = new Allocations();
   final Allocations oldSpace = new Allocations();
@@ -2529,7 +2474,6 @@
     }
     var idPrefix = "classes/";
     assert(id.startsWith(idPrefix));
-    vmCid = int.parse(id.substring(idPrefix.length));
 
     if (mapIsRef) {
       return;
diff --git a/runtime/observatory/observatory_sources.gni b/runtime/observatory/observatory_sources.gni
index 01dfff3..c69b433 100644
--- a/runtime/observatory/observatory_sources.gni
+++ b/runtime/observatory/observatory_sources.gni
@@ -93,11 +93,6 @@
   "lib/src/elements/logging_list.dart",
   "lib/src/elements/megamorphiccache_ref.dart",
   "lib/src/elements/megamorphiccache_view.dart",
-  "lib/src/elements/memory/allocations.dart",
-  "lib/src/elements/memory/dashboard.dart",
-  "lib/src/elements/memory/graph.dart",
-  "lib/src/elements/memory/profile.dart",
-  "lib/src/elements/memory/snapshot.dart",
   "lib/src/elements/metric/details.dart",
   "lib/src/elements/metric/graph.dart",
   "lib/src/elements/metrics.dart",
@@ -139,7 +134,6 @@
   "lib/src/elements/subtypetestcache_view.dart",
   "lib/src/elements/timeline/dashboard.dart",
   "lib/src/elements/timeline_page.dart",
-  "lib/src/elements/top_retaining_instances.dart",
   "lib/src/elements/type_arguments_ref.dart",
   "lib/src/elements/unknown_ref.dart",
   "lib/src/elements/unlinkedcall_ref.dart",
@@ -232,7 +226,6 @@
   "lib/src/models/repositories/subtype_test_cache.dart",
   "lib/src/models/repositories/target.dart",
   "lib/src/models/repositories/timeline.dart",
-  "lib/src/models/repositories/top_retaining_instances.dart",
   "lib/src/models/repositories/type_arguments.dart",
   "lib/src/models/repositories/unlinked_call.dart",
   "lib/src/models/repositories/vm.dart",
@@ -271,7 +264,6 @@
   "lib/src/repositories/subtype_test_cache.dart",
   "lib/src/repositories/target.dart",
   "lib/src/repositories/timeline.dart",
-  "lib/src/repositories/top_retaining_instances.dart",
   "lib/src/repositories/type_arguments.dart",
   "lib/src/repositories/unlinked_call.dart",
   "lib/src/repositories/vm.dart",
diff --git a/runtime/observatory/tests/service/address_mapper_test.dart b/runtime/observatory/tests/service/address_mapper_test.dart
deleted file mode 100644
index 2116d93..0000000
--- a/runtime/observatory/tests/service/address_mapper_test.dart
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2015, 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:observatory/object_graph.dart';
-import 'package:unittest/unittest.dart';
-
-dynamic confuse() {
-  if (true) {
-    return "5";
-  }
-  return 5;
-}
-
-main() {
-  var map = new AddressMapper(42);
-
-  expect(map.get(1, 2, 3), isNull);
-  expect(map.put(1, 2, 3, 4), equals(4));
-  expect(map.get(1, 2, 3), equals(4));
-
-  expect(map.get(2, 3, 1), isNull);
-  expect(map.get(3, 1, 2), isNull);
-
-  bool exceptionThrown = false;
-  try {
-    expect(exceptionThrown, isFalse);
-    map.put(1, 2, 3, 44);
-    expect(true, isFalse);
-  } catch (e) {
-    exceptionThrown = true;
-  }
-  expect(exceptionThrown, isTrue);
-
-  exceptionThrown = false;
-  try {
-    expect(exceptionThrown, isFalse);
-    map.put(5, 6, 7, 0);
-    expect(true, isFalse);
-  } catch (e) {
-    exceptionThrown = true;
-  }
-  expect(exceptionThrown, isTrue);
-
-  exceptionThrown = false;
-  try {
-    expect(exceptionThrown, isFalse);
-    map.put(confuse(), 6, 7, 0);
-    expect(true, isFalse);
-  } catch (e) {
-    exceptionThrown = true;
-  }
-  expect(exceptionThrown, isTrue);
-}
diff --git a/runtime/observatory/tests/service/dominator_tree_user_test.dart b/runtime/observatory/tests/service/dominator_tree_user_test.dart
deleted file mode 100644
index d2053d2..0000000
--- a/runtime/observatory/tests/service/dominator_tree_user_test.dart
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright (c) 2015, 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.
-// VMOptions=
-// VMOptions=--use_compactor
-// VMOptions=--use_compactor --force_evacuation
-
-import 'package:observatory/heap_snapshot.dart';
-import 'package:observatory/models.dart' as M;
-import 'package:observatory/service_io.dart';
-import 'package:unittest/unittest.dart';
-import 'test_helper.dart';
-
-// small example from [Lenguaer & Tarjan 1979]
-class R {
-  var x;
-  var y;
-  var z;
-}
-
-class A {
-  var x;
-}
-
-class B {
-  var x;
-  var y;
-  var z;
-}
-
-class C {
-  var x;
-  var y;
-}
-
-class D {
-  var x;
-}
-
-class E {
-  var x;
-}
-
-class F {
-  var x;
-}
-
-class G {
-  var x;
-  var y;
-}
-
-class H {
-  var x;
-  var y;
-}
-
-class I {
-  var x;
-}
-
-class J {
-  var x;
-}
-
-class K {
-  var x;
-  var y;
-}
-
-class L {
-  var x;
-}
-
-var r;
-
-buildGraph() {
-  r = new R();
-  var a = new A();
-  var b = new B();
-  var c = new C();
-  var d = new D();
-  var e = new E();
-  var f = new F();
-  var g = new G();
-  var h = new H();
-  var i = new I();
-  var j = new J();
-  var k = new K();
-  var l = new L();
-
-  r.x = a;
-  r.y = b;
-  r.z = c;
-  a.x = d;
-  b.x = a;
-  b.y = d;
-  b.z = e;
-  c.x = f;
-  c.y = g;
-  d.x = l;
-  e.x = h;
-  f.x = i;
-  g.x = i;
-  g.y = j;
-  h.x = e;
-  h.y = k;
-  i.x = k;
-  j.x = i;
-  k.x = i;
-  k.y = r;
-  l.x = h;
-}
-
-var tests = <IsolateTest>[
-  (Isolate isolate) async {
-    final Library rootLib = await isolate.rootLibrary.load();
-    final raw =
-        await isolate.fetchHeapSnapshot(M.HeapSnapshotRoots.user, false).last;
-    final snapshot = new HeapSnapshot();
-    await snapshot.loadProgress(isolate, raw).last;
-
-    node(String className) {
-      var cls = rootLib.classes.singleWhere((cls) => cls.name == className);
-      return snapshot.graph.vertices.singleWhere((v) => v.vmCid == cls.vmCid);
-    }
-
-    expect(node('I').dominator, equals(node('R')));
-    expect(node('K').dominator, equals(node('R')));
-    expect(node('C').dominator, equals(node('R')));
-    expect(node('H').dominator, equals(node('R')));
-    expect(node('E').dominator, equals(node('R')));
-    expect(node('A').dominator, equals(node('R')));
-    expect(node('D').dominator, equals(node('R')));
-    expect(node('B').dominator, equals(node('R')));
-
-    expect(node('F').dominator, equals(node('C')));
-    expect(node('G').dominator, equals(node('C')));
-    expect(node('J').dominator, equals(node('G')));
-    expect(node('L').dominator, equals(node('D')));
-
-    expect(node('R'), isNotNull); // The field.
-  },
-];
-
-main(args) => runIsolateTests(args, tests, testeeBefore: buildGraph);
diff --git a/runtime/observatory/tests/service/dominator_tree_vm_test.dart b/runtime/observatory/tests/service/dominator_tree_vm_test.dart
index 6199bf5..4953b0e 100644
--- a/runtime/observatory/tests/service/dominator_tree_vm_test.dart
+++ b/runtime/observatory/tests/service/dominator_tree_vm_test.dart
@@ -114,30 +114,28 @@
 
 var tests = <IsolateTest>[
   (Isolate isolate) async {
-    final Library rootLib = await isolate.rootLibrary.load();
-    final raw =
-        await isolate.fetchHeapSnapshot(M.HeapSnapshotRoots.vm, false).last;
+    final raw = await isolate.fetchHeapSnapshot().last;
     final snapshot = new HeapSnapshot();
     await snapshot.loadProgress(isolate, raw).last;
 
     node(String className) {
-      var cls = rootLib.classes.singleWhere((cls) => cls.name == className);
-      return snapshot.graph.vertices.singleWhere((v) => v.vmCid == cls.vmCid);
+      return snapshot.graph.objects
+          .singleWhere((v) => v.klass.name == className);
     }
 
-    expect(node('I').dominator, equals(node('R')));
-    expect(node('K').dominator, equals(node('R')));
-    expect(node('C').dominator, equals(node('R')));
-    expect(node('H').dominator, equals(node('R')));
-    expect(node('E').dominator, equals(node('R')));
-    expect(node('A').dominator, equals(node('R')));
-    expect(node('D').dominator, equals(node('R')));
-    expect(node('B').dominator, equals(node('R')));
+    expect(node('I').parent, equals(node('R')));
+    expect(node('K').parent, equals(node('R')));
+    expect(node('C').parent, equals(node('R')));
+    expect(node('H').parent, equals(node('R')));
+    expect(node('E').parent, equals(node('R')));
+    expect(node('A').parent, equals(node('R')));
+    expect(node('D').parent, equals(node('R')));
+    expect(node('B').parent, equals(node('R')));
 
-    expect(node('F').dominator, equals(node('C')));
-    expect(node('G').dominator, equals(node('C')));
-    expect(node('J').dominator, equals(node('G')));
-    expect(node('L').dominator, equals(node('D')));
+    expect(node('F').parent, equals(node('C')));
+    expect(node('G').parent, equals(node('C')));
+    expect(node('J').parent, equals(node('G')));
+    expect(node('L').parent, equals(node('D')));
 
     expect(node('R'), isNotNull); // The field.
   },
diff --git a/runtime/observatory/tests/service/get_version_rpc_test.dart b/runtime/observatory/tests/service/get_version_rpc_test.dart
index dde16e8..0a1fa50 100644
--- a/runtime/observatory/tests/service/get_version_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_version_rpc_test.dart
@@ -12,7 +12,7 @@
     var result = await vm.invokeRpcNoUpgrade('getVersion', {});
     expect(result['type'], equals('Version'));
     expect(result['major'], equals(3));
-    expect(result['minor'], equals(25));
+    expect(result['minor'], equals(26));
     expect(result['_privateMajor'], equals(0));
     expect(result['_privateMinor'], equals(0));
   },
diff --git a/runtime/observatory/tests/service/object_graph_stack_reference_test.dart b/runtime/observatory/tests/service/object_graph_stack_reference_test.dart
deleted file mode 100644
index c5e3167..0000000
--- a/runtime/observatory/tests/service/object_graph_stack_reference_test.dart
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2016, 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:developer';
-
-import 'test_helper.dart';
-import 'service_test_common.dart';
-
-import 'package:observatory/heap_snapshot.dart';
-import 'package:observatory/models.dart' as M;
-import 'package:observatory/object_graph.dart';
-import 'package:observatory/service_io.dart';
-import 'package:unittest/unittest.dart';
-
-int arrayLength = 1024 * 1024;
-int minArraySize = arrayLength * 4;
-
-void script() {
-  var stackSlot = new List(arrayLength);
-  debugger();
-  print(stackSlot); // Prevent optimizing away the stack slot.
-}
-
-Future checkForStackReferent(Isolate isolate) async {
-  Library corelib =
-      isolate.libraries.singleWhere((lib) => lib.uri == 'dart:core');
-  await corelib.load();
-  Class _List =
-      corelib.classes.singleWhere((cls) => cls.vmName.startsWith('_List'));
-  int kArrayCid = _List.vmCid;
-
-  RawHeapSnapshot raw =
-      await isolate.fetchHeapSnapshot(M.HeapSnapshotRoots.user, false).last;
-  HeapSnapshot snapshot = new HeapSnapshot();
-  await snapshot.loadProgress(isolate, raw).last;
-  ObjectGraph graph = snapshot.graph;
-
-  var root = graph.root;
-  var stack =
-      graph.root.dominatorTreeChildren().singleWhere((child) => child.isStack);
-  expect(stack.retainedSize, greaterThanOrEqualTo(minArraySize));
-
-  bool foundBigArray = false;
-  for (var stackReferent in stack.dominatorTreeChildren()) {
-    if (stackReferent.vmCid == kArrayCid &&
-        stackReferent.shallowSize >= minArraySize) {
-      foundBigArray = true;
-    }
-  }
-}
-
-var tests = <IsolateTest>[
-  hasStoppedAtBreakpoint,
-  checkForStackReferent,
-  resumeIsolate,
-];
-
-main(args) => runIsolateTests(args, tests, testeeConcurrent: script);
diff --git a/runtime/observatory/tests/service/object_graph_user_test.dart b/runtime/observatory/tests/service/object_graph_user_test.dart
deleted file mode 100644
index 6c251b0..0000000
--- a/runtime/observatory/tests/service/object_graph_user_test.dart
+++ /dev/null
@@ -1,97 +0,0 @@
-// 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.
-
-import 'package:observatory/heap_snapshot.dart';
-import 'package:observatory/models.dart' as M;
-import 'package:observatory/object_graph.dart';
-import 'package:observatory/service_io.dart';
-import 'package:unittest/unittest.dart';
-import 'test_helper.dart';
-
-class Foo {
-  dynamic left;
-  dynamic right;
-}
-
-Foo r;
-
-List lst;
-
-void script() {
-  // Create 3 instances of Foo, with out-degrees
-  // 0 (for b), 1 (for a), and 2 (for staticFoo).
-  r = new Foo();
-  var a = new Foo();
-  var b = new Foo();
-  r.left = a;
-  r.right = b;
-  a.left = b;
-
-  lst = new List(2);
-  lst[0] = lst; // Self-loop.
-  // Larger than any other fixed-size list in a fresh heap.
-  lst[1] = new List(123456);
-}
-
-int fooId;
-
-var tests = <IsolateTest>[
-  (Isolate isolate) async {
-    Library lib = await isolate.rootLibrary.load();
-    expect(lib.classes.length, equals(1));
-    Class fooClass = lib.classes.first;
-    fooId = fooClass.vmCid;
-
-    RawHeapSnapshot raw =
-        await isolate.fetchHeapSnapshot(M.HeapSnapshotRoots.user, false).last;
-    HeapSnapshot snapshot = new HeapSnapshot();
-    await snapshot.loadProgress(isolate, raw).last;
-    ObjectGraph graph = snapshot.graph;
-
-    expect(fooId, isNotNull);
-    Iterable<ObjectVertex> foos =
-        graph.vertices.where((ObjectVertex obj) => obj.vmCid == fooId);
-    expect(foos.length, equals(3));
-    expect(foos.where((obj) => obj.successors.length == 0).length, equals(1));
-    expect(foos.where((obj) => obj.successors.length == 1).length, equals(1));
-    expect(foos.where((obj) => obj.successors.length == 2).length, equals(1));
-
-    ObjectVertex bVertex =
-        foos.where((ObjectVertex obj) => obj.successors.length == 0).first;
-    ObjectVertex aVertex =
-        foos.where((ObjectVertex obj) => obj.successors.length == 1).first;
-    ObjectVertex rVertex =
-        foos.where((ObjectVertex obj) => obj.successors.length == 2).first;
-
-    // TODO(koda): Check actual byte sizes.
-
-    expect(aVertex.retainedSize, equals(aVertex.shallowSize));
-    expect(bVertex.retainedSize, equals(bVertex.shallowSize));
-    expect(
-        rVertex.retainedSize,
-        equals(
-            aVertex.shallowSize + bVertex.shallowSize + rVertex.shallowSize));
-
-    Library corelib =
-        isolate.libraries.singleWhere((lib) => lib.uri == 'dart:core');
-    await corelib.load();
-    Class _List =
-        corelib.classes.singleWhere((cls) => cls.vmName.startsWith('_List'));
-    int kArrayCid = _List.vmCid;
-    // startsWith to ignore the private mangling
-    List<ObjectVertex> lists = new List.from(
-        graph.vertices.where((ObjectVertex obj) => obj.vmCid == kArrayCid));
-    expect(lists.length >= 2, isTrue);
-    // Order by decreasing retained size.
-    lists.sort((u, v) => v.retainedSize - u.retainedSize);
-    ObjectVertex first = lists[0];
-    ObjectVertex second = lists[1];
-    // Check that the short list retains more than the long list inside.
-    expect(first.successors.length, equals(2 + second.successors.length));
-    // ... and specifically, that it retains exactly itself + the long one.
-    expect(first.retainedSize, equals(first.shallowSize + second.shallowSize));
-  },
-];
-
-main(args) => runIsolateTests(args, tests, testeeBefore: script);
diff --git a/runtime/observatory/tests/service/object_graph_vm_test.dart b/runtime/observatory/tests/service/object_graph_vm_test.dart
index 299e113..dd4b936 100644
--- a/runtime/observatory/tests/service/object_graph_vm_test.dart
+++ b/runtime/observatory/tests/service/object_graph_vm_test.dart
@@ -34,35 +34,32 @@
   lst[1] = new List(1234569);
 }
 
-int fooId;
-
 var tests = <IsolateTest>[
   (Isolate isolate) async {
-    Library lib = await isolate.rootLibrary.load();
-    expect(lib.classes.length, equals(1));
-    Class fooClass = lib.classes.first;
-    fooId = fooClass.vmCid;
-
-    RawHeapSnapshot raw =
-        await isolate.fetchHeapSnapshot(M.HeapSnapshotRoots.vm, false).last;
+    var raw = await isolate.fetchHeapSnapshot().last;
     HeapSnapshot snapshot = new HeapSnapshot();
     await snapshot.loadProgress(isolate, raw).last;
-    ObjectGraph graph = snapshot.graph;
+    var graph = snapshot.graph;
 
-    expect(fooId, isNotNull);
-    Iterable<ObjectVertex> foos =
-        graph.vertices.where((ObjectVertex obj) => obj.vmCid == fooId);
+    Iterable<SnapshotObject> foos =
+        graph.objects.where((SnapshotObject obj) => obj.klass.name == "Foo");
     expect(foos.length, equals(3));
-    expect(foos.where((obj) => obj.successors.length == 0).length, equals(1));
-    expect(foos.where((obj) => obj.successors.length == 1).length, equals(1));
-    expect(foos.where((obj) => obj.successors.length == 2).length, equals(1));
 
-    ObjectVertex bVertex =
-        foos.where((ObjectVertex obj) => obj.successors.length == 0).first;
-    ObjectVertex aVertex =
-        foos.where((ObjectVertex obj) => obj.successors.length == 1).first;
-    ObjectVertex rVertex =
-        foos.where((ObjectVertex obj) => obj.successors.length == 2).first;
+    SnapshotObject bVertex = foos.singleWhere((SnapshotObject obj) {
+      List<SnapshotObject> successors = obj.successors.toList();
+      return successors[0].klass.name == "Null" &&
+          successors[1].klass.name == "Null";
+    });
+    SnapshotObject aVertex = foos.singleWhere((SnapshotObject obj) {
+      List<SnapshotObject> successors = obj.successors.toList();
+      return successors[0].klass.name == "Foo" &&
+          successors[1].klass.name == "Null";
+    });
+    SnapshotObject rVertex = foos.singleWhere((SnapshotObject obj) {
+      List<SnapshotObject> successors = obj.successors.toList();
+      return successors[0].klass.name == "Foo" &&
+          successors[1].klass.name == "Foo";
+    });
 
     // TODO(koda): Check actual byte sizes.
 
@@ -73,23 +70,17 @@
         equals(
             aVertex.shallowSize + bVertex.shallowSize + rVertex.shallowSize));
 
-    Library corelib =
-        isolate.libraries.singleWhere((lib) => lib.uri == 'dart:core');
-    await corelib.load();
-    Class _List =
-        corelib.classes.singleWhere((cls) => cls.vmName.startsWith('_List'));
-    int kArrayCid = _List.vmCid;
-    // startsWith to ignore the private mangling
-    List<ObjectVertex> lists = new List.from(
-        graph.vertices.where((ObjectVertex obj) => obj.vmCid == kArrayCid));
+    List<SnapshotObject> lists = new List.from(
+        graph.objects.where((SnapshotObject obj) => obj.klass.name == '_List'));
     expect(lists.length >= 2, isTrue);
     // Order by decreasing retained size.
     lists.sort((u, v) => v.retainedSize - u.retainedSize);
-    ObjectVertex first = lists[0];
-    ObjectVertex second = lists[1];
+    SnapshotObject first = lists[0];
+    expect(first.successors.length, greaterThanOrEqualTo(2));
+    SnapshotObject second = lists[1];
+    expect(second.successors.length, greaterThanOrEqualTo(1234569));
     // Check that the short list retains more than the long list inside.
-    expect(first.successors.length, equals(2 + second.successors.length));
-    // ... and specifically, that it retains exactly itself + the long one.
+    // and specifically, that it retains exactly itself + the long one.
     expect(first.retainedSize, equals(first.shallowSize + second.shallowSize));
   },
 ];
diff --git a/runtime/observatory/tests/service/read_stream_test.dart b/runtime/observatory/tests/service/read_stream_test.dart
deleted file mode 100644
index 5af654e..0000000
--- a/runtime/observatory/tests/service/read_stream_test.dart
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2015, 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:observatory/object_graph.dart';
-import 'package:unittest/unittest.dart';
-import 'dart:typed_data';
-
-testRoundTrip(final int n) {
-  var bytes = [];
-  var remaining = n;
-  while (remaining > 127) {
-    bytes.add(remaining & 127);
-    remaining = remaining >> 7;
-  }
-  bytes.add(remaining + 128);
-
-  print("Encoded $n as $bytes");
-
-  var typedBytes = new ByteData.view(new Uint8List.fromList(bytes).buffer);
-  var stream = new ReadStream([typedBytes]);
-  stream.readUnsigned();
-
-  expect(stream.isZero, equals(n == 0));
-
-  expect(stream.low, equals((n >> 0) & 0xFFFFFFF));
-  expect(stream.mid, equals((n >> 28) & 0xFFFFFFF));
-  expect(stream.high, equals((n >> 56) & 0xFFFFFFF));
-
-  const kMaxUint32 = (1 << 32) - 1;
-  if (n > kMaxUint32) {
-    expect(stream.clampedUint32, equals(kMaxUint32));
-  } else {
-    expect(stream.clampedUint32, equals(n));
-  }
-
-  expect(stream.position, equals(bytes.length));
-}
-
-main() {
-  const kMaxUint64 = (1 << 64) - 1;
-
-  var n = 3;
-  while (n < kMaxUint64) {
-    testRoundTrip(n);
-    n <<= 1;
-  }
-
-  n = 5;
-  while (n < kMaxUint64) {
-    testRoundTrip(n);
-    n <<= 1;
-  }
-}
diff --git a/runtime/observatory/web/third_party/trace_viewer_full.html b/runtime/observatory/web/third_party/trace_viewer_full.html
index 7c0f430..d8ff5f7 100644
--- a/runtime/observatory/web/third_party/trace_viewer_full.html
+++ b/runtime/observatory/web/third_party/trace_viewer_full.html
@@ -13,7 +13,7 @@
       font-family: sans-serif;
       -webkit-justify-content: center;
       background: rgba(0, 0, 0, 0.8);
-      display: -webkit-flex;
+      display: flex;
       height: 100%;
       left: 0;
       position: fixed;
@@ -25,32 +25,31 @@
     }
     overlay-vertical-centering-container {
       -webkit-justify-content: center;
-      -webkit-flex-direction: column;
-      display: -webkit-flex;
+      flex-direction: column;
+      display: flex;
     }
     overlay-frame {
       z-index: 1100;
       background: rgb(255, 255, 255);
       border: 1px solid #ccc;
       margin: 75px;
-      display: -webkit-flex;
-      -webkit-flex-direction: column;
+      display: flex;
+      flex-direction: column;
       min-height: 0;
     }
     title-bar {
       -webkit-align-items: center;
-      -webkit-flex-direction: row;
+      flex-direction: row;
       border-bottom: 1px solid #ccc;
       background-color: #ddd;
-      display: -webkit-flex;
+      display: flex;
       padding: 5px;
-      -webkit-flex: 0 0 auto;
+      flex: 0 0 auto;
     }
     title {
       display: inline;
       font-weight: bold;
-      -webkit-box-flex: 1;
-      -webkit-flex: 1 1 auto;
+      flex: 1 1 auto;
     }
     close-button {
       -webkit-align-self: flex-end;
@@ -68,9 +67,9 @@
       cursor: pointer;
     }
     overlay-content {
-      display: -webkit-flex;
-      -webkit-flex: 1 1 auto;
-      -webkit-flex-direction: column;
+      display: flex;
+      flex: 1 1 auto;
+      flex-direction: column;
       overflow-y: auto;
       padding: 10px;
       min-width: 300px;
@@ -79,9 +78,9 @@
     button-bar {
       -webkit-align-items: baseline;
       border-top: 1px solid #ccc;
-      display: -webkit-flex;
-      -webkit-flex: 0 0 auto;
-      -webkit-flex-direction: row-reverse;
+      display: flex;
+      flex: 0 0 auto;
+      flex-direction: row-reverse;
       padding: 4px;
     }
   </style>
@@ -100,26 +99,23 @@
       </overlay-frame>
     </overlay-vertical-centering-container>
   </overlay-mask>
-</template><style>
-* /deep/ .labeled-checkbox {
-  display: flex;
-  white-space: nowrap;
-}
-</style><polymer-element is="a" name="tr-ui-a-analysis-link" on-click="{{onClicked_}}" on-mouseenter="{{onMouseEnter_}}" on-mouseleave="{{onMouseLeave_}}">
+</template><dom-module id="tr-ui-a-analysis-link">
   <template>
     <style>
     :host {
       display: inline;
-      color: -webkit-link;
       cursor: pointer;
+      cursor: pointer;
+      white-space: nowrap;
+    }
+    a {
       text-decoration: underline;
-      cursor: pointer;
     }
     </style>
-    <content></content>
+    <a href="{{href}}" on-click="onClicked_" on-mouseenter="onMouseEnter_" on-mouseleave="onMouseLeave_"><slot></slot></a>
+
   </template>
-  
-</polymer-element><polymer-element name="tr-ui-b-table">
+</dom-module><dom-module id="tr-ui-b-table">
   <template>
     <style>
       :host {
@@ -128,8 +124,6 @@
       }
 
       table {
-        font-size: 12px;
-
         flex: 1 1 auto;
         align-self: stretch;
         border-collapse: separate;
@@ -140,13 +134,17 @@
 
       tr > td {
         padding: 2px 4px 2px 4px;
-        vertical-align: text-top;
+        vertical-align: top;
       }
 
-      tr:focus,
-      td:focus {
-        outline: 1px dotted rgba(0,0,0,0.1);
-        outline-offset: 0;
+      table > tbody:focus {
+        outline: none;
+      }
+      table > tbody:focus[selection-mode="row"] > tr[selected],
+      table > tbody:focus[selection-mode="cell"] > tr > td[selected],
+      table > tbody:focus > tr.empty-row > td {
+        outline: 1px dotted #666666;
+        outline-offset: -1px;
       }
 
       button.toggle-button {
@@ -215,6 +213,10 @@
         background-color: rgb(171, 217, 202);  /* semi-light turquoise */
       }
 
+      table > colgroup > col[selected] {
+        background-color: #e6e6e6;  /* grey */
+      }
+
       table > tbody > tr.empty-row > td {
         color: #666;
         font-style: italic;
@@ -229,20 +231,25 @@
         border-top: 1px solid #ffffff;
       }
 
-      expand-button {
-        -webkit-user-select: none;
-        display: inline-block;
-        cursor: pointer;
-        font-size: 9px;
-        min-width: 8px;
-        max-width: 8px;
+      :host([zebra]) table tbody tr:nth-child(even) {
+        background-color: #f4f4f4;
       }
 
-      .button-expanded {
+      expand-button {
+        -webkit-user-select: none;
+        cursor: pointer;
+        margin-right: 3px;
+        font-size: smaller;
+        height: 1rem;
+      }
+
+      expand-button.button-expanded {
         transform: rotate(90deg);
       }
     </style>
     <table>
+      <colgroup id="cols">
+      </colgroup>
       <thead id="head">
       </thead>
       <tbody id="body">
@@ -251,8 +258,7 @@
       </tfoot>
     </table>
   </template>
-  
-</polymer-element><polymer-element name="tr-ui-b-table-header-cell" on-tap="onTap_">
+</dom-module><dom-module id="tr-ui-b-table-header-cell">
   <template>
   <style>
     :host {
@@ -264,56 +270,165 @@
       flex: 0 1 auto;
     }
 
-    side-element {
+    #side {
       -webkit-user-select: none;
-      flex: 1 0 auto;
-      padding-left: 4px;
+      flex: 0 0 auto;
+      padding-left: 2px;
+      padding-right: 2px;
       vertical-align: top;
       font-size: 15px;
       font-family: sans-serif;
-      display: inline;
       line-height: 85%;
+      margin-left: 5px;
+    }
+
+    #side.disabled {
+      color: rgb(140, 140, 140);
+    }
+
+    #title:empty, #side:empty {
+      display: none;
     }
   </style>
 
-    <span id="title"></span><side-element id="side"></side-element>
+    <span id="title"></span>
+    <span id="side"></span>
   </template>
-
-  
-</polymer-element><polymer-element name="tr-v-ui-scalar-span">
+</dom-module><dom-module id="tr-v-ui-scalar-context-controller">
+  <template></template>
+</dom-module><dom-module id="tr-v-ui-scalar-span">
   <template>
     <style>
     :host {
-      display: block;
+      display: flex;
+      flex-direction: row;
+      justify-content: flex-end;
       position: relative;
+      /* Limit the sparkline's negative z-index to the span only. */
+      isolation: isolate;
     }
-    #content.right-align {
-      text-align: right;
-      position: relative;
-      display: block;
+
+    :host(.left-align) {
+      justify-content: flex-start;
     }
+
+    :host(.inline) {
+      display: inline-flex;
+    }
+
     #sparkline {
       width: 0%;
       position: absolute;
       bottom: 0;
-      right: 0;
       display: none;
       height: 100%;
       background-color: hsla(216, 100%, 94.5%, .75);
-      border-left: 1px solid hsl(216, 100%, 89%);
+      border-color: hsl(216, 100%, 89%);
       box-sizing: border-box;
+      z-index: -1;
     }
-    #warning {
+    #sparkline.positive {
+      border-right-style: solid;
+      /* The border width must be kept in sync with buildSparklineStyle_(). */
+      border-right-width: 1px;
+    }
+    #sparkline:not(.positive) {
+      border-left-style: solid;
+      /* The border width must be kept in sync with buildSparklineStyle_(). */
+      border-left-width: 1px;
+    }
+    #sparkline.better {
+      background-color: hsla(115, 100%, 93%, .75);
+      border-color: hsl(118, 60%, 80%);
+    }
+    #sparkline.worse {
+      background-color: hsla(0, 100%, 88%, .75);
+      border-color: hsl(0, 100%, 80%);
+    }
+
+    #content {
+      white-space: nowrap;
+    }
+    #content, #significance, #warning {
+      flex-grow: 0;
+    }
+    #content.better {
+      color: green;
+    }
+    #content.worse {
+      color: red;
+    }
+
+    #significance svg {
       margin-left: 4px;
-      font-size: 66%;
+      display: none;
+      height: 1em;
+      vertical-align: text-top;
+      stroke-width: 4;
+      fill: rgba(0, 0, 0, 0);
+    }
+    #significance #insignificant {
+      stroke: black;
+    }
+    #significance #significantly_better {
+      stroke: green;
+    }
+    #significance #significantly_worse {
+      stroke: red;
+    }
+
+    #warning {
+      display: none;
+      margin-left: 4px;
+      height: 1em;
+      vertical-align: text-top;
+      stroke-width: 0;
+    }
+    #warning path {
+      fill: rgb(255, 185, 185);
+    }
+    #warning rect {
+      fill: red;
     }
     </style>
+
     <span id="sparkline"></span>
+
     <span id="content"></span>
-    <span id="warning" style="display:none">⚠</span>
+
+    <span id="significance">
+      
+      <svg id="insignificant" viewBox="0 0 128 128">
+        <circle cx="64" cy="64" r="60"></circle>
+        <circle cx="44" cy="44" r="4"></circle>
+        <circle cx="84" cy="44" r="4"></circle>
+        <line x1="36" x2="92" y1="80" y2="80"></line>
+      </svg>
+
+      
+      <svg id="significantly_better" viewBox="0 0 128 128">
+        <circle cx="64" cy="64" r="60"></circle>
+        <circle cx="44" cy="44" r="4"></circle>
+        <circle cx="84" cy="44" r="4"></circle>
+        <path d="M 28 64 Q 64 128 100 64"></path>
+      </svg>
+
+      
+      <svg id="significantly_worse" viewBox="0 0 128 128">
+        <circle cx="64" cy="64" r="60"></circle>
+        <circle cx="44" cy="44" r="4"></circle>
+        <circle cx="84" cy="44" r="4"></circle>
+        <path d="M 36 96 Q 64 48 92 96"></path>
+      </svg>
+    </span>
+
+    <svg id="warning" viewBox="0 0 128 128">
+      <path d="M 64 0 L 128 128 L 0 128 L 64 0"></path>
+      <rect height="84" width="8" x="60" y="0"></rect>
+      <rect height="24" width="8" x="60" y="100"></rect>
+    </svg>
   </template>
-  
-</polymer-element><polymer-element is="HTMLUnknownElement" name="tr-ui-a-generic-object-view">
+</dom-module><dom-module id="tr-ui-a-generic-object-view">
   <template>
     <style>
     :host {
@@ -324,9 +439,7 @@
     <div id="content">
     </div>
   </template>
-
-  
-</polymer-element><polymer-element is="HTMLUnknownElement" name="tr-ui-a-generic-object-view-with-label">
+</dom-module><dom-module id="tr-ui-a-generic-object-view-with-label">
   <template>
     <style>
     :host {
@@ -334,9 +447,7 @@
     }
     </style>
   </template>
-
-  
-</polymer-element><polymer-element name="tr-ui-b-drag-handle">
+</dom-module><dom-module id="tr-ui-b-drag-handle">
   <template>
     <style>
     :host {
@@ -356,7 +467,6 @@
       flex: 0 0 auto;
       height: 7px;
       position: relative;
-      z-index: 10;
     }
 
     :host(.vertical-drag-handle) {
@@ -370,14 +480,15 @@
       flex: 0 0 auto;
       position: relative;
       width: 7px;
-      z-index: 10;
     }
     </style>
+    <div></div>
   </template>
-  
-</polymer-element><polymer-element name="tv-ui-b-hotkey-controller">
-  
-</polymer-element><polymer-element is="HTMLDivElement" name="tr-ui-b-info-bar">
+</dom-module><dom-module id="tv-ui-b-hotkey-controller">
+  <template>
+    <div></div>
+  </template>
+</dom-module><dom-module id="tr-ui-b-info-bar">
   <template>
     <style>
     :host {
@@ -393,8 +504,8 @@
       padding: 0 3px 0 3px;
     }
 
-    :host(.info-bar-hidden) {
-      display: none;
+    :host([hidden]) {
+      display: none !important;
     }
 
     #message { flex: 1 1 auto; }
@@ -403,11 +514,7 @@
     <span id="message"></span>
     <span id="buttons"></span>
   </template>
-
-  
-</polymer-element><style>
-* /deep/ .x-list-view{-webkit-user-select:none;display:block}* /deep/ .x-list-view:focus{outline:none}* /deep/ .x-list-view *{-webkit-user-select:none}* /deep/ .x-list-view>.list-item{padding:2px 4px 2px 4px}* /deep/ .x-list-view:focus>.list-item[selected]{background-color:rgb(171,217,202);outline:1px dotted rgba(0,0,0,0.1);outline-offset:0}* /deep/ .x-list-view>.list-item[selected]{background-color:rgb(103,199,165)}
-</style><polymer-element name="tr-ui-b-mouse-mode-icon">
+</dom-module><dom-module id="tr-ui-b-mouse-mode-icon">
   <template>
     <style>
     :host {
@@ -421,8 +528,7 @@
     }
     </style>
   </template>
-  
-</polymer-element><polymer-element name="tr-ui-b-mouse-mode-selector">
+</dom-module><dom-module id="tr-ui-b-mouse-mode-selector">
   <template>
     <style>
     :host {
@@ -469,7 +575,7 @@
     <div class="buttons">
     </div>
   </template>
-</polymer-element><polymer-element name="tr-ui-e-chrome-cc-display-item-list-item">
+</dom-module><dom-module id="tr-ui-e-chrome-cc-display-item-list-item">
   <template>
     <style>
       :host {
@@ -512,110 +618,28 @@
     </style>
     <div class="header">
       {{name}}
-      <template if="{{richDetails &amp;&amp; richDetails.skp64}}">
-        <a class="extra" download="drawing.skp" href="data:application/octet-stream;base64,{{richDetails.skp64}}" on-click="{{stopPropagation}}">SKP</a>
+      <template if="{{_computeIfSKP(richDetails)}}" is="dom-if">
+        <a class="extra" download="drawing.skp" href$="{{_computeHref(richDetails)}}" on-click="{{stopPropagation}}">SKP</a>
       </template>
     </div>
     <div class="details">
-      <template if="{{rawDetails}}">
+      <template if="{{rawDetails}}" is="dom-if">
         <div class="raw-details">{{rawDetails}}</div>
       </template>
-      <template bind="{{richDetails}}" if="{{richDetails}}">
+      <template if="{{richDetails}}" is="dom-if">
         <dl>
-          <template bind="{{cullRect}}" if="{{cullRect}}">
-            <dt>Cull rect</dt>
-            <dd>{{x}},{{y}} {{width}}×{{height}}</dd>
-          </template>
-          <template bind="{{visualRect}}" if="{{visualRect}}">
+          <template if="{{richDetails.visualRect}}" is="dom-if">
             <dt>Visual rect</dt>
-            <dd>{{x}},{{y}} {{width}}×{{height}}</dd>
+            <dd>{{richDetails.visualRect.x}},{{richDetails.visualRect.y}}
+                {{richDetails.visualRect.width}}×{{richDetails.visualRect.height}}
+            </dd>
           </template>
         </dl>
       </template>
     </div>
   </template>
-  
-</polymer-element><style>
-* * /deep/ tr-ui-e-chrome-cc-picture-ops-list-view{-webkit-flex-direction:column;border-top:1px solid grey;display:-webkit-flex}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view{-webkit-flex:1 1 auto;overflow:auto}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item{border-bottom:1px solid #555;font-size:small;font-weight:bold;padding-bottom:5px;padding-left:5px}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item:hover{background-color:#f0f0f0;cursor:pointer}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item>*{color:#777;font-size:x-small;font-weight:normal;margin-left:1em;max-width:300px}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item>.elementInfo{color:purple;font-size:small;font-weight:bold}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item>.time{color:rgb(136,0,0)}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view .x-list-view:focus>.list-item[beforeSelection]{background-color:rgb(171,217,202);outline:1px dotted rgba(0,0,0,0.1);outline-offset:0}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view .x-list-view>.list-item[beforeSelection]{background-color:rgb(103,199,165)}
-</style><template id="tr-ui-e-chrome-cc-display-item-debugger-template">
-  <style>
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger {
-    -webkit-flex: 1 1 auto;
-    display: -webkit-flex;
-  }
 
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel {
-    -webkit-flex-direction: column;
-    display: -webkit-flex;
-    min-width: 300px;
-    overflow-y: auto;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
-        display-item-info {
-    -webkit-flex: 1 1 auto;
-    padding-top: 2px;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
-        display-item-info .title {
-    font-weight: bold;
-    margin-left: 5px;
-    margin-right: 5px;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
-        display-item-info .export {
-    margin: 5px;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > tr-ui-b-drag-handle {
-    -webkit-flex: 0 0 auto;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel {
-    -webkit-flex: 1 1 auto;
-    display: -webkit-flex;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
-      display-item-info > header {
-    border-bottom: 1px solid #555;
-  }
-
-  /*************************************************/
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel >
-      tr-ui-e-chrome-cc-picture-ops-list-view.hasPictureOps {
-    display: block;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel >
-        tr-ui-b-drag-handle.hasPictureOps {
-    display: block;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel >
-        tr-ui-e-chrome-cc-picture-ops-list-view {
-    display: none;
-    overflow-y: auto;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel >
-        tr-ui-b-drag-handle {
-    display: none;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-display-item-debugger raster-area {
-    -webkit-flex: 1 1 auto;
-    background-color: #ddd;
-    min-height: 200px;
-    min-width: 200px;
-    overflow-y: auto;
-    padding-left: 5px;
-  }
-  </style>
-
+</dom-module><template id="tr-ui-e-chrome-cc-display-item-debugger-template">
   <left-panel>
     <display-item-info>
       <header>
@@ -633,173 +657,46 @@
     </display-item-info>
   </left-panel>
   <right-panel>
-    <raster-area><canvas></canvas></raster-area>
+    <raster-area>
+      <canvas-scroller>
+        <canvas></canvas>
+      </canvas-scroller>
+    </raster-area>
   </right-panel>
-</template><style>
-* /deep/ .tr-ui-e-chrome-cc-display-item-list-view{-webkit-flex:1 1 auto!important;display:-webkit-flex}
-</style><style>
-* /deep/ tr-ui-e-chrome-cc-layer-picker{-webkit-flex-direction:column;display:-webkit-flex}* /deep/ tr-ui-e-chrome-cc-layer-picker>top-controls{-webkit-flex:0 0 auto;background-image:-webkit-gradient(linear,0 0,100% 0,from(#E5E5E5),to(#D1D1D1));border-bottom:1px solid #8e8e8e;border-top:1px solid white;display:inline;font-size:14px;padding-left:2px}* /deep/ tr-ui-e-chrome-cc-layer-picker>top-controls input[type='checkbox']{vertical-align:-2px}* /deep/ tr-ui-e-chrome-cc-layer-picker>.x-list-view{-webkit-flex:1 1 auto;font-family:monospace;overflow:auto}* /deep/ tr-ui-e-chrome-cc-layer-picker>tr-ui-a-generic-object-view{-webkit-flex:0 0 auto;height:200px;overflow:auto}* /deep/ tr-ui-e-chrome-cc-layer-picker>tr-ui-a-generic-object-view *{-webkit-user-select:text!important;cursor:text}
-</style><style>
-* /deep/ quad-stack-view {
-  display: block;
-  float: left;
-  height: 100%;
-  overflow: hidden;
-  position: relative; /* For the absolute positioned mouse-mode-selector */
-  width: 100%;
-}
-
-* /deep/ quad-stack-view > #header {
-  position: absolute;
-  font-size: 70%;
-  top: 10px;
-  left: 10px;
-  width: 800px;
-}
-* /deep/ quad-stack-view > #stacking-distance-slider {
-  position: absolute;
-  font-size: 70%;
-  top: 10px;
-  right: 10px;
-}
-
-* /deep/ quad-stack-view > #chrome-left {
-  content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMcAAABICAYAAABC4+HLAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAB3RJTUUH3QcNFyMmV/Pm9QAAIABJREFUeNrtvXmwXdd13vlbe9/7BgzEQAIcQAIEQYKjSAokLVlOW5Fk2nLKmqx0J2Wp0k652h13uiy5XYqdwU7sSnckpZ1yV3U75apU4kos27Elu9NlyRXZjiiRomSTIiWZs0hwHsABJIY33rPX6j/W2ueed3DvAyDKKoGFW0UCeO/ec/fZZ+29v7XWt74lAIuLi7tXV1f/raq+zcy2AogIZsbpvrqfMzNE5IS/1/fVn5sZKaUTrtX9/v7nT+fn9e/1e052X/3r1THWa3R/37+miKCq7c+mjW/a+F/P57vj6/45bayn+wzXs4n+794Q9nP8+PHdS0tL31LVmfpGVQU4YSInGUb/YfZvpn+zp/LQu4Y27X31d933nurkq+qaa08yotO55npG0v2O+r1/XZ9fb2FMWoD9Oe5+pju//e+fdP3u83+j2I+89NJLn11dXf1bdSCTJnnSSpz2+/VWZ/8m+w+g/zD616yT2P9733BOZ5f4dhbCevPQHet63zVtV3y9n1/v/k9nZ562SNY7Gd5o9iPPP//8qxVKrQdL+hOy3qqdNEnTjv1JA+vuRpMGvd7kn8oCqded9B2THuJ6u/Kk7+vuiNOgQH8OX+/np813/376O/CkU2EavDwVWPiGsp9nn33WJt3ItF2ne2xOe2jTHuTJMOS0He1UcG33791JmWQYkzB6dyfp7tynsktPG8/Jdv2TGcLpfH7Sc5m0EKZBsPV+tp4PMe39bwj7efrpp229G5u2O3WPplN1cE/XQZsENybtnNN2pv4x3N1Fpu2S/SO6j6fXgz6n4gRPGmMfR7/ez/cXd/1798Tsfr4PMU52Oq4Hp95I9jPor7ZJ+G7STlEnvN7gesfXpB2tH5lZzynrO07Txtb92aQTY9rv+3i1v4jqv5umOSEq0r9O3/iqEUx6MPXnqjpxrk73812oMQmP968zyUj68zPp+U1bxG80+5GnnnrKpkVxTiWUuN4q7+96/YFXp6pvANN8hD7MmRbF6O7200KR9ed9CDbpSF4v6jIJtnQjQdPGOylK9p34/HowaFL0Z73IUNex7Z5Gk3bkN6L9yBNPPGHdY3fayu3uSP0dqH62uyP0w4XrDWo957gPEfqf78e4p4U8+0Y86R6711pvAUyL3vTvd9ou238Q/Xn4dj4/Cd6d7BlMC532534S9OnO8xvVfuTxxx+39RJlk/DtpAGc6k6hquScp+7EkyIn0+LV60Ufpu2q05zN/sOYFIfvP8CT5VEmGWN/h5w0zm/38+sl7/r3drLntt58rzdXbyT7kccee8z6O2b3JnLO6zpjk47nkyVg1pu07muas9b3CaZh4f5uPMn4Sikn7Jj9RTEJMnQfVHdck4x3Wt5i0qL6dj8/6WQ5GcSYBiEn+STrhT/fqPYzmJYxrRcopax5eH18Oi38WI2ulLImYTPNMavv716z/93rRXUmOZXVgZ5kePX7+hPeN5xJTmx3MdXf9zHyM888w8LCwgn30IUQ0xzWSYvhVD4/LarTzpWBpOl+zqRQ9lqjE2DCtbH2x9MW3XA45JxzzmHnzp0njYp9r9jPoH75Gkekc8SZ2ZpjrH/Ez8wMSSmHMY4YjZp2MDnniVGT/sPvRhxmZ2fJOWHmxj0ajU7AtvV6k4727gSklMg5M4jdq6iyuro69bv799fNptYF0X3vJKjz8MMPMz+/gWuvuYatW7eScgIEwTADEwEUAZDkBgtuYONlCCJgAuZ/N5QkCcP8avFzUH8fsZgNEoJJLAakc+2TjENi90RQjGSCJm1/hwlmgmRFFIwEYoiNxyPxvYZ07gVKUzh8+DD333cfRZXLLrvsBLxfjbl76pyO/ZRS1thq325O137k4YcftvUSOf1Ufdco/uwLX+LOv7ibZ194EYBdF+zkB956C+98+99ARE64ue6XqyqDwaDdGZqm4Qtf/DK3f+UveO7QS2uu944f/IH2WpNwdp2U/oT8+W23c8dX7+K5GN9FF+zkb7zlZt71jh9cswNPw8uTsPU0h19VeeSRR7j55lvYumUzK6MCpqTs9p2AAiRLmChWBBIIiqZEMkVUMAQTJZtQSCCKkDE0/h+7twkKpCSYxrhVMTGyCYogohRLCGvHoYD0xyGKScIUpC5AVSQl/0ACaxeCkJJhakDCTJEEiKAmDMx8XSdAY6lZQjHmZoa89NLL3Pv1r3PVVVeesDH3T+FTtZ/uguhu8v3o36naj4ggjzzyiPXhwtRjOf6+tLjEP//4r3HOuRfw5psPsOeSXQA8+dQz3Pu1ezl2+BC//I9+jvn5uXWjDfW1uLjIr37y19m8/fzJ13vlBf75L/48c3Oza3aWadSP5eUVfuUT/2bd6/3yL/xvbNgwv2Y3qbtOF0J2MfN6ka7nnnuOvZfuZcfO8xitKnloFBXEBHGLc4MTQwVEDeIkyAqa/Pdh9z5vaqgkUuz8akYGVATEHOYYiCSUQtJqkCDJsJJIvXFYNRIzLGWQQqqLEiOhqKS6gnzhqJ9cJplsiiXBSnfBJF957TEoJBKYYskwFUSgWCKnBkmZp59+mpdfepmdO3eu2USn+V/r2c/JWAX9CN/J7KdNiD744IO2nqM0Cff+01/9P7js6gP8d29/C5detJNtmzYC8OrxBZ547kVu/+JfcPDBe/iXv/xPkCnkvHalm/HPTvV6v/SP25vs3mB3fKurI37pX36cfdesf73HHriH//2X/3Fr/NOSTZMyzn0n0sx47LHH+JEf+REWFhd8pzcliRtyBVbFYlcTN0bfpoWEYiaxENTtjOQwByOZ7+r+b/zacY5YICvH/iDmBurjmzQOKMlIWkPThpohkuN0iwWI+YrNGkdeQswwcbhlWEAzw8wXazZDJfsYMP84ghXzxSHip5rB/IY5/sv/+0dc96Y3rdmA2uz0YDA1EHIqDNv1KDAVvk2yn64vOujHlqdlJ+vv/+wLX2JuywVcfOkeXj2ywGtHn0C1Hov+uUsu3cNzzz/Hf7vtdm5959snRknq6wtfvOOUr/fnX7yDH37n29fccBdG5Zy57fYvs2HrqV7vdm59x9vXJeqtx6WqD+T555/nyiv3s7y8TMLhSgLMElkURx+KENi+7uzi0EgtIUCi+OmSwIpjmYTSAIN6uiSDkkAKQgp/IgON+yaGnxIBz/rjcPckj30LU5I5rCsJsiYsafgjCbXEUIwiiqq4e1J9FjVfNCioYMlPC/eJIFuisTiN0oBkhllBcmJlaYnL9+/n0KFD7Nixg5xza6hPP/00S0tLzM7Mho/lfpGicW/hyyCQAv75Nuw+UOwi/o7WmXLfClhYOMaWLVvZtWtXG7TpRibrMx/0V1j34XcdT4DBYMA933yQnRdeymhUOHZsCZFEqrurORRZHRV2XrCLr33jft596zsZjUbtiuzGqQeDAXd//T52Xrj3lK53zzce4G/d+k6WlpfXOF5jSAhf+8YD7DjF8d3zjQf50VvfRdM0LYzqv/pHcH9napqGF154gb/59rdz7PhxTPCdNSliisYuK5rjIRsWPyeJQyGhWhyNCEn9sbrPIGRJmBRfeCb+kEXQwDZG49AFIYmh4kvmhHGYISTEGl9YBimPoZypvx8VJA3R5IurMcdrSTrjLuGjGJCNpJnGlCwWp6CRMLIoMCBhFJPYIAxNxjVXX83v//7vs337dnLONE1DzpmXX36Zt73tB1g8fhwzh3OIObyrp60IWp9XNlBfRtkCPqWIM9T5x+GhDIQN8/O88srLfPWrX+WWW245IeLVPvvubt49biZRMTDj6MISGzdt9i81YTjIzM/OMjc7w3AwANwp27hpM0cWln0iOt9RowruSAlHFpZP43pLJxAB68lnZuSUOXJa41tCIuQ7jYBWf9fnP5kZo9GIlZUVLrzwQpaXVzxihGHJEE1ucdlIkgOwKMncj5Ds0SjfZd2R9re7AeWkGOFUhuOrrd+jFDPMEkJ1XGPhxdY+cRzZARPJfR9Jiqm/P2wONKHJwJRs6jt0Su5nWHJfQj2IYBQIp14xBkI47OE/BVyUFI6/KCk5zJOSGY1W2bFjB03TrOGtzQyHNKNRnTGQghWjWInxGI0phvtyNOZg0GAU86hmlMYw9c9qMYyCjgpHjx9ndmYD3//Wt3LPPfdM9FtUlYGqUko5IbzVdUi7WHw4M8vc3CxzczNsmnejq6HSphSWVlYBWF2ZY2Z2tt2tuwuw/ruUwszs6V2vuxi6TlYd48zM6V+vC8/qYqgnZT861Y+dP/bYo/zoj/4Yo3o8u1PgoVRJiPqJBRkRo6C+oxchSaGIxC5uJHEfwDdqN3xTg+wRKXd2EyRIBppjy/fLY02CWCzTxuHX91MAEfdPNJESqBopFcwyJurAqg3jWpx6DqkExVIiNwIDQa1BAWRAQiE5XExJ/URCyQgFIZlB9rk8cOAAt912G/v3728jiMOZGVQDEShoSUhuEM2U5CecFHWIGbAzlwZJghRDs0AJ2FVdu2wUMxI+XyqFpjF27drF0aNH2bRpU7txt455fcjVuCrE6Ds6DkdW2bF9C1lg49wsG+ZmOWfjHNu3bGL7lk1s2TjPpvlZNszOkMTYsW0LWvSEHbhraDu2nfr1ztu6haa3uLqn0qhpOO+0rncOTWcy+vmMesLVxVgXdimFpmligWbmZgZtLN8vFmFZbbBGHfdSwo9whxot8ZAdMydzTG9aUDGKGlZ8QaiGU6wGVtDSUChIY6j6gqOBTHPScZj5qVHUoAg0DaYlIIWhlj2qFUhBDUwLNH4tMCgKZqRSGMwO+PM//VOGgznPe2jDYGbIvfd8g5mZAapCMcEEv6cK8RpFLLFp06Z2Lqvt7dmzh4cfeRBTQ1E04GXBEG187pLSqNKYbyBm0IQda6MoDUbB1DwQUvyE1tJgKFqM1dJw6Z5Lefzxx1vb7B4EqbtSJjmmXYjVNIXrr7mCI68dZmaQmJ8dsu2cTezYtpkd2zaz9ZyNzM8OmRlkjr52mBuu2c/qaHRCZGcMSxpuuGb/qV/v2isYxfW6GdFqtE3TcMNpjq8mGbs+xyRSX520GhMvpfDC889z7XXXsdKsYMV8t7fA3ChYJmWgGKkIlh3SWeQEwJDkp0UJKKIioGNXW9R3PnKKEK+E32BYDlxvUMTQzEnHIREQSCQaMSRn9+dlvKOmMUr3aFRKcco43JIUicWU+G+3fYHf/c+/x6c+9R+ZGQ6ZmZ3jtz/1Kf7PX/vX3HPvvTHaQsYgKUnFo9C5oBirKytcdeVVvPjii+1zEBGOHTvGxk0bfXGabyxGQ1GHmaYB4YqRLDYIIXyw4vDQ/HoJQ61BTHyPKeZ3aMbxhQXm5+dPSDCaGamPt7pQZRJL8qYbrmP56KscPnwYEZgZJAbZ/5sZZMA4fPgVlo++yoEbrqXCtq4Bdv2bm9/8JpaPvXZq17v+2hNgTXcxN03DzQeuP+Xx3XLg+hNoGN1Togsxu4umnijPv/AC+6/YTxlZZIo1YJIf5yLmBpeFMhCwEg67J8QkVacyRe66eLg1aRtcUVFSgmzFsx3uWSKSkWIUibiSpcD1648DMU/ggTvP6r5PskhrmEMfRFEJKBcZfJPkjq4nQTA13vk338mHfuJDfOXOr/J7v/t7/M7v/A53fvlOfuqnfoqbbjhA8di1/2nZr5kU0YQlhz7XvukannrqqTW2snXrVpYXFrBmBH5+OBnA/CRxP0NJVjySZoo2DrLcbhu0eDTORONnxde3FUQLqoVmtMreS/fwzDPPnOBe5J/+6Z/+F/1dvZ9V7BqHiHDDtVdy51f/ktVRw9ZzNpMkMRo1HD16jAce/hbPPv0k/+N//941Wcr1CoNuvO4q7vjKetd7gr/3t98zkXJ8QpTJjBuuu5IvTxnf/Q9/i+effpIPf/DHJiqO9EPX/Yhd9UuWl5fZMD/ProsupJhDBEniOzaCWMakuNMsjp0znhzTSv0wRbL4yYCQyWgliJhTMzKZRty3cNhDJNgMY0ACz66H333ScRSHVSnCrZbdfzFpc4okFLHsvkEkBE0E6YSPfXxQrHDF/suZnZ3jttu+wHPPPcv73vdefuiHfpiVZrlNbLYJy4Hfm9uSn4jaFF47coScUuvnbd26lccOPsa27eehxXd/JO7LQAZgJRZ84+epZM8JeYwtIaKIRZpGxXNFLTvMIuye2LRxE48++ig7d+5c48/KPffcY5O4+11nvOsj1N/Pz2/ggYe/xaNPPUcTGHc4GLBvz0Vcc8U+VlZXpkrgTCrPrNf71pPPnnC9a6+8gqWlxTUOUx1T/VmfGbphw0buf+gRHn3yudavaMe3/3JWVpZPYOXW+6vX7CYcu9GUpmm47777+OAHP+h4NxYlSdr8gOGOY45TwCpIsRQwxkjqxi7iECCJY3MBj91L8viXKSlFrN7iG6SyrOp1OaVxEAlB1EPFyTzSVCkjmgSp2XGNPALBO2kMy0JW8YhW8VNpODvLp//g03zjG/diCDfeeAN/+8c/yOrqClgOLpZgA8NGKU6vOI0QhMzK8iL/9fOf58orr2QwGJBz5v777+etb/l+jh096rAzCNApbhMqRItTRVKHGBmcF6CYkSUjWlr+pNNrIodiwlNPP8WuXbvWJKoHXew+GAwYjUYnxPS78d9q3EtLi+zfdym3HLiBuVlP1qyurPLakSMsryxPrNfuhnL7hLKFhePs33cpN9/4Jubm58BgeWWFI0eOsLBwfM3i7BrytLrlhYXjXL1/H993043MzsyAwMrKKseOHWNxcWEq6a3PzO0nSFWV0WjE7OwsMzOzLC8teagTQ5w8FVljZ8B6bD/Ig2YkUaz4I1Tx06Sh+E4cxuIZcHdAU8Ak0+T2ihtWzYSj1NThScfhYM4dbne6fVcV8bCx5zpicanvvO2qix+bepSrFMgizM7O8h8/9Z/46p1f4f0f+HEA/ugP/5CVpRU+/KEPsTxa8XAxhpRUM6C+IFViDgqbNp3Tnso153HhhRfyyuGXyGmGOjtJxfliqYbFPX+hpiQKWIoNB1CFQYrTsqGIRLTKT+xk0ChA4Yr9+3ng/vvZu3dvaw+D7mmxsrLCYDBY44TWf3eNsJsPeeWVV9aVdekvvm7Uql88tLq6yksvvzy1sH+aSkh9NU3T+k0iwuLiIouLi+0J2K8zmERP7+Z2qvPdz3EcOnSI6667jtXVZTQZ0pgf81KZrNWgAuNWrlJSSolEWPL9WqWGOt2eJSlaguJhvusnEc/yV0ygRkkpiH+QRSnCScfhnCl1smM44BVIdVnBnnFOEfpMiBVUnMxYeWFZ3FP6/z77x9x5x528//0f4F3vfAdigpbCZ/7wM1yyezdveetbnL8lCbNC5cAUJ7d4SFoSS6Nlrrnmap555ll27tzJcDjk3HPP5eDBg1x2+RU0qytgQol5dNaDopactoLFCVyQLKhCSua+hQTzWD33YwKpcUaA/8ztbBRRs/bk6OPsLkTRoHj3C/Yn1Rv0/ZJJBSarq6troEr3c/XPmvnuQ7FJmfu+sMAkI+/WpPQTndMURGqCr8/6rD8/dOgQ73nPezh27HhEYzzk6Md6pX8bFbAIhonDJKhoxWLXTwFp1NdPY8EgFzT8Dv+AOwbOrjWPgKXKbfLo1CmNo15HPHFmUhgTVQh+lOOWLM641aCFWEtbj+cgyo/+yLvZtnUb3//Wt7G6OkIwfviHb2Xnzgu48c3Xs7K86idNzTGUoLlLxUdOiMwI1159NX/5l3exbdu29jkuLi4yPzvL8dUVSoNDtDjJLKBRI0YmkqXOcEQSFI2cShKkLowSSUlLkU+CZMbi4iLnbt/O8vIyMzMzbkt33nmnTaqK6lZx1aOuX7vcx+yTanq7MKpbfNR1quvu3F8wfQp5d7ev4+v6Al3o0/eX1hMHm1aLPEl8YWFhgZWVZd7+gz/IatOEPzDwya8bdXLoQwnqglR6OBFNcqhDOLbq22dEIiM513iUR8woyZ32XJ3sFDukuPtSKhnxFMbRJgZjx0ymIIM2CWkBO6xS4FNk7cVQC1jia6UNh1rOfgKotgnLFGOWDkFRTZyuUmodSaX1BNoYCF+548vMDGeYn59nZmYGVeXwK4fZef4FqFkEH2owISElnil+X77Ak/PQLBYzYNKQbNDys2rEziJQkFDO2bKVu+6+i71797q9dxNp/d247yfUnMC00Gw3kdNNltXPTitb7VZ91YRQn6zY/96+L1TDq30nvY6l+2fNldSxdU/Mfji3C+1WVlZ45JFHeOtb3sZodTWIbL4raTAKa8UFxTlOTlfxZJRU34DkcXuLRG6p4VdAszu+QZZTBSkOY6zu/MUJWaYRTTuNcfhxlaIOQ+Ik8ARhqZBNPOyMJFLkFDTGX0wpJUCYiI+ztaHY7ASsGRuemS+iZCCqEbiKMKv6ovRxKbccuIWDBw+2lBIR4YVDLzAzHJLQCF1bhzZSPKnZEjiDvqLmi5sCyfMeJpU640466uPT5Pe4PFohDTLD4dARQ3e3rYbdzRB3F0mfqj0pD9CFL12sXiM+1ZDrd9WfdSejv+C6pMWukXezmv3/uhCpe63uoqvjrYuq6WHOetp1v3N+fp65+TnMMpTShjOt3QE9ROvYPI5/83oKlRL1FIrzNSRyAJXFamBNLexzjJ78mqq+YFJxACZ4dvB0xqFBFycpUMhmlBw0k6CxWnJDdlqKnwR+gezcrmD+WkR+tN1/jUJARRM/tSg+1mSU8K80KCGkgiEeoFAfkqkyt2kD8/PzLVlVVbn22mu57YtfYLUUNm7cgBYfmgUb2BduHJfFKBRnAqRIXBZnKIuCNMWTirFo0eKUEwEdGcuLy2MbuP32260LfU6m0zRNm3Q9XdZazDIajRgOh+2C6Auk9X2e9dQpJtU+96HSYDA4IYk5TVh4Te1w+Br9U+PFF1/kyquuYu/eS50KkiQoHtLmCHJEhGosnRrPD6IgOaIl5rAJ8YSYJoWSUSnk5Bwqq5gjJUyLR4tybhm8vkA4rXFIMmiEkqSlswseyclSTxL3XzyRCGLF5QaiZLZSw2t+JuHObaJuAuo8KLF6i/V/Dgu1pk+C1hEOcRLP8D/1zFM89NBDnH/++QyHQy91Hgx44IEHKKUwPz9PaZq4txpVq5WINZIXLoJGwZa4RyZtrNzvQVGSed3LzOwsKQm7du0aEw+7jmyfaDiJRtENuU2Td+z/vMvd6i6++u8uhOpHlyoEqousr3LXvYd+sq7eU9c3miSjWRdJ9WO6i7DuYIcOHeLHP/B+ji0skSWyA6kWKKU2x13LUn3HcuydUoSjgk6NJqwUkNziYMtK1hTwSONKvggk+WJJgbFNGswyScopj6MN+yZjkEAbQwYNlMwwfKKSPN8S9u9JNcmIRj1HkByliEfGRoKm5KzxONMkxpCjTEDw7L1FWUESpWgIX2SLkoKoGMzC/iuu4Mtf/jI7duxobWJ5eZnLLrusjXh2Swb69tO3iYpQuqWw1fftRkyHw+GaIM2gL0ZQv7juntN0nLoZ9a5D3GXdttTfyHr2F0QdcH8xdk+P6kt0F0w3RNyv0OtH37rXn8TA7YsorK6unlBPXEphYWGByy+7jMWlZa+YK8kd5sDqKejfRkNmgBaPubvwgNKUQYxRIZnvxil2VC3+WREnFOILysSDrKoCNAgShU/J687l9MeRygCNYqriTA7PyquzcX0z953fiIRMtnEJbQ7elnrQQHMhaaIBp8cHLPOKkUqV0VYvQsy8ZiVqQ8Tpu2OonmBlZYX9+/dz5MgRtmzZsqaMtm8bw+FwzabaZ23X1+zs7Bok008kT5JYSl0j74ZtR6PRGojV3fFreLOLxfs+S5f+XXfe6mtMKputi6DrVPfpIX1fon5n15/o+g2T9GHrOJaXl9fkbUoprTJJHWddwE3T8MQTT/COH3oXpSmRqnP6tyexvKRUUMQG7luY1GgqiSF5UDynkSzwdZSamkQxj4dXsyWyQE7uvFrUwWrKEIVPOqgV36c/Do3TS6VGsiLWr2PlkAxYKo5zaiYcozHncGlAGEsgJUUdObhn4ZAmp2Acx2JHpBO50tZvMrE2ny1RHKXA277/bRw8eHCNXX237Sd1C4e6cKceMd2sdI3ydJ31SYXsdYDd1djdyfuwqgt3BoPBCSJjNRFZrzccDtes+vWUUvqJwvr+4XC4Jsxcd4+6+6SUGI1GHD16lAcffJD/4e/8HZaPL3nVWXCSPLTpLB1LbqopZGsQT4aliB5pyaTAtwWQQfAhtJCDqaqRlCtBabBhwnKJIiOLTDfQSOQrTn8czsNIHhUL6J0HOGwzJxUWEZJKsDIEy4ZJ9ipDrUojGg67JwuCKxwejuc1LIfJB8YXEY9WRZGXImQN1i+GpuSnWTGWV5b48Ic/zNfvvZejR4+uQTffLfuR27/0pdhCiAL6MUmM4J7Uyq5WmiU0kmqEo2oj1Z9JyLVU3GqRFfU5Cp+ge52uDx+7UJ3kVgFJWPO++pska+Vqqq+FdcbT+S4i4tJqRdXQUCSU3JeTljM1HA64+qorWS4N2VJ8jQYBLpMoQUWHAUKDix9U+ptj/cBI4nymAEvxQBwe+XXjHlJBtdIQ05hwh6JZSPo6xtFm68f3i4IFnZycQhBhnJF3H1yD4hIlsCpjxq6M6+NpqTIhAySKFKfiD5K11A93xI0qFlRTqV42HLkhEyQJDz74wASxD9pn1SGutQteqM+acRBhLBI2wZ7Hw2+t6/lDh2woQhG8drkaazUUBI00ewpqDClR1EXGqiZRq2IR0jE5HM+avZWITzsTMqInEb2oC0BDoCxJ8IoiopCCy+OsS6c1iPiR7xFFI6dQvqhiCjHlLfwQN6Lx/Xssp5iQrBpK5JJbdqrXSYiF1kegDM8ZBDkvplIl5igHLSMoH9XZFIOSa2WdeXVbZGpdWMfxuVRHH39fLFvPVai87nH4JsDaZ6WG5SBFVl6X1PmHsV5QhEQcCZcsAAAWiUlEQVTN/3S+VfIipBosE0FLzWRnf1Z4Vtp9J/WAXcpRvBVUrprIi/vGxpG2yOWf5FkJRdx+Bh6DeN32nCRKFyV2No1Yd12ViguMpZRiB/AEVor4u0VM2+LYN/Hj2LO6cXhGFVjoVDjetnqsBMUnDuVURS1IpOw7TqP12K8Lw5Nm7vA5dUDVs8MSnl8hwpKhzKfqIgWu3RScHgtjSw4l6s6SgtWKuhqHU9OkzbYWMyx1ggPm7FZJyZ1UBIsyToschguG+HcXxZN+kdmuQVdNJRJw1jlVtS2W+k6MQ8W8bDcMMhWjSfgmY8Vza6o+P8Hd0wjFWlQG1mNc8OfqGWev2WgipKzqBuf+T4kyFB9f0TzOktdEqLoWlpl4HQaN86LsVJ+VeaTvO2jPg6B6erRDIIdR13oD/02s+uQTSJvrdfwpUTBjA2sTR9IINlCkyWiuzM/sD0DMSS0mTkqzhKbiANpo2aClEXLc2LhYP7Kfgb/rSSvWtMk2y7G7hbSHVUigtcjIKMUX60iEQQOWa/DU0BIs2ahRdqLOd2aOihZee+UwRYsbQ3a2qmbIxb1hC1U3oQ1ZjRm7GnkFEXKLIYmEn4zRRYp6kXofFYIEydHLB4OK0RmHf5eChOYVY2q81edWhdrCc3B4GBC3as3Fs0rFoaDXllQYowEVfcMiiJh10Yt2TqzkTGE/GeS7OkeDFD5CSfFnOFxSAjRKwKIUxklGvC4TGRSk8aIXk8bLO1NyxuQgao6roYaRWlSEWZhiIlFaAw+tpMANKeHx8Ip5Ww5NPDj1YnpPPDmFuoqMWRz1VfAMgvgnhpVwxIrn5Er2IqEkvjMnySjFT6SUnX/0HZij44tHWVkdccnu3Zx9fe+/Btr4DuvUBW1hjiTfL1IpNAKDyNiqFefN+Kbv8Wp1LaVKoSdi89Iq7/lRlc0jKJqsfW9JNi7cJ3mMPRwlrUzTtoYldokorjZxcKniO4e6DIWvfMVLSXODufU7wcE8yVZq2FDHO3xj1SeSVr0jWUE1ofL65shILC6tsG/fZW3M/ezre/uVkBJVZo5HCacxyDruuJkTzqzSHrK4WFqFKWLkyOWk6kTWLHllZhYP3UXZekRliFj4uHorBSFMzOPdFllaB8w4F0Y8sqJVXdzEaxnCaTXxMkpxBVn/uqSh9FcimuEOutQQRUrOdkU8vBo+kNcCvP45SiI0zejswjiTFodLODaUCJ21YbzgpKSICnn9rbSliCYRprOE5OTOoLg2kJHIUQYq2aMKOVVpRtpoeKoymVLpy0FbSA66UjinxRLJ7RfLGUWcyyMOzCLC6pg4uUaTmKDZa4fropFU2miNk3BaXgdSwqlLige1amVdcvr2654j9zfOvs4gWEVxVW2rNc2iHg7P7qiJiDujppTqtBSw1CDmcXRWidqA8LOtuAYTTlOQKOUZkwIrv8ZFugbqWqzSOulxZBQNOU+HLSkcNi3GAEHzyIPDGkxRF0cKCqpiKaT7i7rwWBX6ipNINbtoQHJGJjmFbEsVFNOWkWq8zjkadRzDs68zBVa5wQ2DgpAkObOsRFSiCsdJxdgZyKHm4OFbBhG4SZW373FzHUR7lKBGWIT2UieLOtTIaUQtmvsblT7txDUlkzRXIqUnk5LnHyQWBknIqDvFklxVQ2sCLBYdCcmGWnJJTvFQoRYhDYKBKhGxyQRPKLVhz29njlxMwDVaObs2zjBYFUmdxqzF3yI1l5DaTKSiaEkgrhhHEmaGmc2bNjM7mHF4o5HOi2qvXEJu3/DC/uAQEU53FokkWxDGUtVX9TLHpDkUx+tWPBYTm8kDl6jJngjy/GotAfUQclRTen11VMah47BdUUgpBJ6DFaCUEAwzJGVmN8yxYdM8m+Y3QM7Vg4kkkTE7nJ06R5VHZHEAnV0bZxysiqysefioiDCIWmQstbyYZMllKkMndX5mA//3b/w//MnnPsett97K//qz/wuriwbZd+IaXUo11m8pdFIjc12MJJGbiOIUzFzvtR1P01bOEUS9lDOPPPQQr7z6Kju2n8cVV1zuSStxaUxyiCfXa5iHgEuQ5VxCMORhUE/IVapQUGFTSqwsL/E7v/uf+eY3v86RI0eYGQ65/PLLee973su1N1xPWVnh2OICn/+jz/P+D3wgAgedOTJXRS8mDCIjXSkjZ19nCqyKrKMUT+J5mt4CK9MamAZRKhnMzczyG//2N3jowQe56aab+PrX7yUxJCWLCJLDnMoZwlwNIqc4naQySR1Mlcp5CQl8SSn8F2lT+W5YnpRqSmHvnktJOfHoY4+ShkFYyzkSSNYqjbcyXuKEEq1Z+6iuz4RAcpw6szNz/Pmf/lf+3k/+JN969GG2bd/Gvn37uPiSSzh+fIGPf/IT/Itf+iWOHDvGRz/yc+Q8OHGOYuJUPNTbWGkTY2dfZ9DiKADFG5aIppYe4KJi2qrsIQ2iwuzcLP/+t/4D9993H9u2bUO1cPPNN6Ml5F5qWNZLgl260Wruo6qMp7arllrxgFHtHyFgxeVUUggwN5W8KL7INm3eiKJs2LQRBQ5+63FyErSx4PxUiFfpGR4CdqFwRTUFT6j4Yo6SycEg8cd//F/49Gf+kBuuvx5B2LZ1G9deey2X7N5N0YZ9+/axuLTEz/7sz7Jnz+4WgnbnyKNmrhiokS23s7DqzINViaalbZQcNGXR0AbKThxIgllhbm6WT/32b3P3XXezY8cOzIwtW7byD3/mH7K4shzdiYxG8IRfKzwfLMiiYeAaxfnFI0ollMilbY4HRaNqLXnmXDJWCkVgzyWX8sSTjzOcmWPzhs0cOX6EJ558kt2790TysJCCJtBUVTypQoBGyRp98ELmrHgTl8OHD/MHf/Bp9u3bx2g04qMf/Qh7du9meWWZLENKafh3/+Hf8/xzz3HFFVcE6zeoJDFHLvDhVBlVF1FGcoSlzxrcmeVz2ABSoYTSRAlYoCl7D4eggc8Mh3zmM3/A7bffwfnnnw/Azp07+djHPkajDefMDUNhI1rwBllNVVlcWvRdNFid3quCwP7aGo5ZioYr3gekcnA8cqWklMMHSly+7woee+IgOQ3YumULh189zLPPPsPFF+9qWxRr66iH6oc60SxriBCrO82ShJQGfPozf8TevXs5duwYv/iLv8imTedw7PhxhEQjixxfXOa+b/4V5+04b1xGGwVHqXK7teZSSnTZqnUTejaSe+YtDu82mkU6HYEyYh5gFVNSHvC5P/kTPv/5P+Oiiy5sDeOhhx7i3e9+d0igyLgntYybtm/cuJFf/79+nXM2nxPKEwnJ2tJKUu0BIerZZIWmKdx11x1ITuOWXLjgGSHfLyS2bN3Cls3nUFTZunUbrx0+zPPPvsCFF1zoY8rR6kqcqGgaogiR6fYwrUfWBnOzPPLwg2zffi6X7buM7du2szJaDSq28OLLr/LRj3yEiy++mKNHj3p8S4RmtQkWLeHZV3GxqvAXGFNbZvnZ15myOEwsIq+1j0EmpdKqSKDG7Pw8n/7MZ9izZ8+a6r9zzz2X8847b90vKKXhi1/8Eu99z4+5+28lEhgS7EpXscgpuzyKKK+8dIiLd+9hkMQ1YtMIs2FIygS1pOo6hR9hZLZu386hFw6x6+JdjJrGe3lHEZEnxx37ayTzarPHJmU2JGNpyWVZLrrgQlaa1SBOehRr1wUX8NnPfg60RPbeN4Dl0QrLxxfbXuKo530oNm4qGYIHdhZXnWGLwxVhnJEq4lDDosREjZShrK5y1VVXsbS0dNpfsLo6YveuXWhxDySJdy8ySSRV1LIr1WlpT565jZs5fuwIaWbW9Y0sk5JGHsPFYES974KKMDDH+0X9NGmaEs0nvejHlFbqsu19h4euNdiBRYW5uVnX2F1aIqsXz2jxSpOl0SrLr7ziaRJlXAVnRm6VA6tgW/FkYuuE51pOefZ1Ri0OCrkMKGmsnySB2ZNAo0JZXuEjH/kon/zkJ9bUY59//vlcffVV3tpM2sLTtrZPzNiydQs33ngTy6tLkSj0uolkng/IOHFPa2mjGlu3biJnf2+tx0gdSYFg/XPs+AJZ1DsUkVhZXuDSSy9DKYg5M9ijYt4FqaiQcnFNpWxYyd5ZVYSiDeeffz5NU7j77rv50E98iIWlBVqhm5JdtsYysxtmKKPG+wCKK3VX9JSTM38tNFqrOksKn+fs68x5ydPPPF116sPochSF+C5emyFIRGQ+8YmPt7W8zz77HH//7/8kb37zAe+akw1TbwxZBbUV7yCkVW81HOycDG0kmh5KW8stVVM1VUHxCO9aFMvgnKnXXn2Nlw4dYtu554IVFldX2Lt7D6Vx/ydngvIuURIqQYyM8leSJzsju52ScMcdt/OlL93O4uIiBw68mb/7d3+C5ZXlqGly3+uVl17iV37lV7nxxhv4n/7B/8xoZTWKZizyi937SO6UR4vjFw49z00HbjprdWdKnsOakFUxjQ6exYnehdDmHtdooIWPfexjlJDc2bXrIn7zN3+Tv/rmN5zuPYrrFHXcrRaG6Ht+MYNSEFXKyHMSpp4LMNShkXmyT83afm+VKFi1/I6+eoRnn3uGrdu3oRiLSyvsufgSmlGlo9decNCkWn9hjKJGo4QAcqNOFUmmFFPe8a53ISJs3ryZ2277Iv/q4/+Kl156iY0bNoHC5z77x/yjX/gFzr/gfP7irr9kNg+pnQHaA7VoKwEKhjVB3bez2fEz7uR48qknLJNbdQ9LtaC4qkDUckZvmSXJM9Sf/OQnWxmUgwcP8lu/9VssLi4g5CASWtCVkq+TWmgURfFAiHpVXaZg9YpHtCza9bbyjeIwaSYP+NrXv8auCy6ClFg8vsieS/d4F9bIp2RxkWLNtLXX0Zpi3M8uKPBaO8DEybi0uMSv/ZtfY252luXlZR5//HEWFhYYDAZccsklbN++nYWFBd73vvdx0803U7Q5YY6INsaVGZ+Sy8+8+PwhDhw4cNbqzqSTo2BRqFOiFtuL8FMIFFA0+jQ03p8tZX7+536e5RWP7uw4b4d/Pqjpg2gmoqqIGk2IhlkqFINGjSZOBFXvEJpKQa2BQqhIBPtcFGu8GaIUb86+aX4TBeP48aPs3rMbbUY0USCF+omgRKticzHjohpL1JeHJqUpTl+36HmtpmyY38A/+6f/hAsvuojRaMT+/fu5+aabuf6GG5ifn2eQB/zMz/wDvu+W76OUZuIcWaijazFUCqWRXlHX2dcZcXI88eTjZpJoJYTa5iJjwYFKwo7MhwscZKGMCnd/7S7edMONbJyb94hTkii2DwVwAaxBZNCWt0rkARSviZBilARZw1hTLcgfh4UsKvEkpPEXFo6zcdNm12K1VjmrrfKr2lOefmg1WECdS+b6JjZuqFgpLHhgYn7DPMeOH+eRRx7m6NGjzM7NcsnFl7D3sr0cO7rg2XCxqXOU1JuqJFwsLQ0yh154nptuOutznDmL44knDPHqORt4Ew/VHPUXIeyg4pSLUK3TkHMPcaiqTeFwJVH14d2g1ZyqHmL1Xq0aelUaurBZooVCrdgLmJNrfTmtTlGKL9boA6HiDUwkh8SPiod9XUCD1EQ31VSbqsQCiSYsYhJtvdplBGY0SRhaFc2JTqbqQoGCYqc4RzUhmtOAF188C6vOLFhFzYr7jq5BIdeooZBUQg3PXD+1lOiyGBhe3dFurGqQatvpE6JKLjXeQ6HVEKoOdpwQxXMY3qXHG40UDGk80lTEe+URkvtaqScWPSrCnyBgVJXsMUtobtqGj973O8iUNCGr0zj3KciNqr7gBhqkkLZ3hYXBW0uzP5U5MhOn47SaT2dfZ8zi0Ej21cahRLzes9niESh1yEEJdZCIHCW1tr2UiF+H6Nmg0RWxrbQTV6zTKmxEkPQ6X1xlHNUKAwnZzuR1TqUEEz3V0m9DdeCD01Atz3jVYTSalOLYvwRd3YoLOlSVESxakdnIGzhqRJWiM5IFrUXR1z1HVb3x7OsMSgIGEhmTG6L/AsGXkoznMGosn+QVdC01PYWyRwqZ+mjxS9u1xHddBMvFdYdLaRuyCDky8jXWFO1QrLiUTklRo+Rqikkt1MktZEejM1UIK9RbkFQV1r1iRC17UZVEaxcpURUYcEqhiPsz0nj0rKr6IfK650gH5ezaONNODqnE1xAIIKIsVVXDosmIR1b94edsnUIoGxtRLm1OoVXwVWtVDnNTF03VeM1eUpqsbdjYRKKvsg0zDmUkKSKlI1Zcuw+NW+VWX8ePIRdSbheLjFwNBD8NBiWa1BOOe/gG5rMShUoBM78Dc+Slv+msxZ1RPkfoQbmYQY3qgI4E1QYzx+Zq3uAU9SyzVawfjd2LetMUxXtEW/SK8B50OT4T6iMaHY5QShVIEPH6h+TizVWlRIMoWFTRIjTi/kkJyCYWbFtTirijXlXNVUucHrX/t2vrWiNOlykuueNhZ1opTO/zEi20NNqhvc450qawYX4Df3XffWsoOGdf38PRqscOPmYpFG1ShlSyc5kyUQvurXSlNBGFicBU1F20WlPquk2VLlLFvzUUsVPrRIdvUCKqU6nudY83acNg1tK9MySvIHRIpeTk6iWErGfkMaM/orcPQ1rdbvdtShrXkVeyjCilqrkXVzqR6NtXhcorn+t1z1HxnNIrr77KyspS9LUIXtkayFUZPbV1g7WdWaPXfCsKYViwVySawXTeYIzJjq3av7Tq7bWPNxEKr+OQWrIs2p6I1umjN+011oSvrSfCyOrvpBaGhSp7R4e3+px0tXbbga+9le/WHMljjx70pHg4qSqCyMhLSU1c87XqzVpoCIbUjSuXgKYQcDbI4vKZskauvmrcgmhGJSRzglflSt/RtsBcMsc0t4TDksbibN4ZKSrwxJCiHnatRVFt96DIrkdttySX1K+ZE4v0dTXmFCdUFonmMcEOiJyMiLbq79+xOZJOo4ToAe6+j7WLX6r5mDe7SUGt8QaQHgk0Fd94skb9irR+XKp6KTIOr0t0lR1InKhrxkGba5LiRNRstZeGz1OTooePpjVtjMfPKuar6kNXKqq6ovugfVZEi4BoU2AaWsUhB0vQ1uJ5EJWX3605annVIkKREp1Ds3cBjRZZIeCHiIuU1V3FzBscinn72kQJ/K2RSIwFIJVHFUVNRNutCN820SvDdbAij5E1yIdGrhQMIWTjSyvCTU7MRqjUhZ4tdi6NZF9oZsVNSLZxf47sLYNTZMyl+hrRMyKpRueMyHN8p+coKqBU1GnuGCWVttNq7R8jql6LbnGaRu9AojamCm1HcUtUZDZutBqSQeoVj2hBtbgGcJETx4GXAljxZ+bs6WjtXIxRSLYq6gvDAqKGwkpSIoEM0gQnwSo1SZgp3tO8RBsJgnemMVduG+NnpbUeJ/Fdn6OBVme0hmKJTp9tljlk4iWq8qLfRirxuTJuQqPRJqgemVrPqugYlELbqf62WHSASuIdf1o2cNDMq9+SQqbexp2anKBo0fsiGMSR3EvW0ERfDRkYTSPef1oEHakLrJVEoYE09Aw+CVd/tKCwZ3IqSBn4Qygh+fnXNEeSBt8T4zj7rMZzNPjKV75KbbLT9idogVhIeNZjrdvaqsrsmESuo9Mjq6NCMq61DvwvXdzr35GihUBtKmNRm60hNh05OMfHMZQkqdN2rYtvg9LRJiSqhm0kO10BoZUBSiYtDBtLhNSuFFVwOnlo+K9xjhLfG+M4+6zGc/T/A8/G/snZpSWJAAAAAElFTkSuQmCC);
-  display: none;
-}
-
-* /deep/ quad-stack-view > #chrome-mid {
-  content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAABICAYAAADRa1RpAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAB3RJTUUH3QcNFycE5v9iFQAAAQtJREFUOMvtkjGSWzEMQx/0eYrM3v8k3vgqycalSwlI8Ufyl3OBFMtGIgUCIEd6PB6RBEASqvfONSrJXrDNbNkQ8ywA2y/SmayW+ZIESTsiyQsxo40xmMS2aUmYbheHpCVd0+UqJGGMsey3mUyldoUvlY3D9rIN0K7Wbe/WbZ+y1yWtaVtrp3VJzAEX6ZVjc2p7b2mtnYhNdl6m05rwtfV/ltx7XypJTpXeO7Y5juOlchzHaWxyrJmuhLapqgIJONv05+srThBgiQpBTSRwGOr3rwccgWHUhJ7P5/YNlbd/2XiL78L/WajP240AQUihfnx84EDJjCHKHjTAbkimQDgBjAJ1/3kHAgEk/gL71AHEWVXPGQAAAABJRU5ErkJggg==);
-  display: none;
-}
-
-* /deep/ quad-stack-view > #chrome-right {
-  content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAABICAYAAACaw4eEAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAB3RJTUUH3QcNFyghKmOqnQAADE1JREFUaN6dmsuyZsdRhb/M2uf07bREYDykPeIleAMibNx92i9BgEPBgyB5xlvgtgI8VDNBI41xhGkpQowERgqw3H0ue1cuBlm1T/3Vu4XNiWj9l12XrMyVK1fWL/v6668lCXdHEt/1Z2YnnyUhCTPbX8dn45pmRkR81z7/XUr59Pz8/K8ePnz47/bVV19pnDhu0t+Pmx0Z+Pv8zWv1/eZnZ2dntw8ePPizZXw4bj5/P3vq6G/eePZiX9fd9/Xng6/reg78/dInzxPG9+/auH83GjEbPUahj6m1Hoa6v1/X9c+XPrlP7INqrfuru7+10WzUkUHvOtTojPF1mPdHSzdqPPXo5vm046bdq0fhGr+bvXZk6OgAM2OZBx7hZD7hnCzbtp149Wid0YOjx+eE6t8tMzb659Ebkg5PPY8ZvXpEQWNCzck2M4H3BWeM1Fr31/6+GziPmTefM3tcYzQoIt4a3+cso2EzhsYTzAAdw9M9M3rviPv683dl/Oi9pdZKKeVk4piVRyDu1NI3mCtARFBKeWeGbtt2yHV9HXdnGUMyGjSfZq4K42ajYbPXx836XjO+jsj3rawcFx5dPgK8bzJ6eGbzI8yO3j4yaMToiWF98fl0c4bNSXBEJ/Ozd1HSEY8BLGOIxlONeCqlnHyWtGNoxteRMX38uP44fkyyPnfpp58zqy/s7jsGj0rOEcvPVaMD/sj4I/zWWllmMB/VviOwHumv+dkRGc9EOtOUu6fHZteOGBtDN/+NeJwPNRsxl54RU3PIO4x827a3wNwfdr45kib92WhAf9+fHem1I7FZa31rr+WIr45kzrjZsixvZWHHYcfqXFHGctM9ta7ridcigmVZWNf1DvyllN2wkatmHIxCby7kYzbPOD2qFCN39efrut55rE8YM3I+8VENHPFVa2VZlkOSdXe2bTuhmHdl+W5ox8T8YCbD/l2t9YQqRiNGjx8l1JEamVXKri56doyTuzfGhWd+OyLJjsNRlo+eHaX63Iy8ldnjQn3hbmA/yagGusfG7JwrxZytcxMyjpnH77VyPEEP65iVs5tntp4ldp8zlrG+x8z2Y9L1f91Jy+zeccGZn0Zv9nFHTH500BGbM6HOojMiWEZQf1cN7Aut68qyLCdeGFN+xuRYJ7tXu5fetU9EZCiPOp8xm8bTzLqpe2jkoDnzxjCOa8/VZByzzG7t8gQ4eT+GdO4Be0kZDTgq5kea/0g0RgS+rushNkbg93o6aqeejUeNR/fcUWmaqWLbtn39MdGWGcRHUrcb17E1jhszq3tvxNCsJuaE6VGZMbeMKTrL6LGelVL2k41jx6zuRbknSS9BI7WMdDRTxLi3z+VkDl3/7vb29oS3xhoZESdZOm4whrW/7/NHT83UtNze3u6c1I06Ozs7wdjc7PaQzsV8JNSOp7k97IDvtDPDYTdsvts6Pz8/MXCsm2PD2g/Tm+Vx0bHZHTNvjMyRyh2pajk/P0cIZEAHLLgXQLg5ckDCAFsKCwtIeHHAQGAmSnEkMAyZMBkin4lc3jBEM4a7MZgo7mBGhLD/+M1/qiCqDJflIjICYbknjlEtQEl81cBDYIaUi3aDwoEQ7mABuFMjcHOMQHLMRLSDhhlFQk4+k9IhLggZBREeVLN+NNwNCAhRwjGMimGyPJlA3owyIwiKEltWjTBHNchIGpLleIS5ITNKQHVDYRiBGUQI/83X/0XUyorhm2EKAsvT1IqFgwusgglCWARV3SuGmdNchwgiRHWQagcHIqCNJ7whJ6AI20AeUJ3A0ilP/vQJ33zzDdvNDbWkO91oAwphrah7wVGG1cHMqSHkggiwDJthmAcgjIIVg5rfWc1h2AZ7AgBLpMElMpQCUyOSX/3rr/j+9/+EGoEQTgKxKnDADRROmCiWySJBeILbMCxENVhwBISCnldm4EBEeiQRk1AJs/Y5ER2q7BX03v17SQnumDeXRqXgDaSA1cSdIExQDM+UgtoArTyMIjABJUPt4S2hRHEIgbdstV5LI4OusDvDMgMNqw3sHqi0HPcMotyRNqp5ArnmRrkLuBm4kHmjDAeEDMICk2PFMwomqjI2xYSHsJIUUnxoeBO7rdQUJ2qeJk8SLfdLGtgWCouEVzFUG7NXMAXVG1YqyDdMhSDgFuTpabUEiUguUw3AiAafbhoR4EtmpJknKArgytMaBHBmIozEIQ41M1dK7ySGEvxQ8NoI1w2WFh0XlsUaFYilJ5zhpuGKwBxXeygIqxlrE6Ih1wKPgi8L799/QGcJo4M5o9oYDfcKUZJmEFdX12zrikh2xwwrQA2KOeqETRlCGaKaUFXLpjQwy5Elu4dzflb4uw8/5MXP/wEsE6ORVX8hbVRzTVcN4ic/ec4HH3zA7XaTC1sQtZUXAm98Z7I7uvjii8+5ePw4pUiwu7TXuogM3cX7j/jhX/yIJz948gf/NPjll1/yy1/+E//z299RCGrL+AxI8krQfhk5Ab+6LmrGyDA1dvfkqOvXNzy7fMonn7w8umjafabmsDuowPPnz3nz5joLiN9VCwIqJDGHweixV59/weNHF4itZSMJbGq61kg3h3N2fs7D9x7jIdTwIzw3tCxrZo560U5U8frNFdu6URWJS8RmRukto3smv07uxwJrMa9uLDJCG1ZKI87AWJBvhEOsG9WEhSVcWBtu1A615da2kboiPaRW4hSRcBGEClhg0cTDycWdJR1XgUdkrN2hRqslGapydo+fffgRL37+Ir1opzrrJHZDAiB49vySv/3gp9zcRiqLCpsrjSLrnpQ27KH8/ItXPHz4PtRbRMoTajrBw6Hk4o8vLvjhj/6SH/w/wf/xx//I629/u9fPjkxLIZfVwmLwWBhQqUqgU1NZlCrkQVRwGW9urrl89pRPXr78gw27vHzO9dVVI2cIOYVIGHkrYXVDUQaPvXrFo4tHbFV7dnkjzGT+5BjXwnK/cPHovcRLI9hME3ZeM2+HtRwQAVdXb1ivr6ldzfYC3sSnPFAUZHW+HE7WtqamZL07avrcnYgKKtR6m/VKQTR9n0JQjZj7KqD2LCLY2h4quqsKNUWA5BQPatjAY1hTpuAO2iqlGLV1EQJ8C87vnfOzjz7ixS8+5vf93y+sFeZnl5f89K//htttw1bAW5d05rAK90awjOD//BUPHtynblmInXStyUHJR3jw3sV7/PjpU548eXJArvZ/gv/Fx7/g9bfftug4NfVKa7byd8pN9ZT5I9rFSM/wSPFXrOn5Tby5vubp0x/z8uU/t1Jx5/H9v3b3/q4YGJfPLrl+c0Pde8lgEWxN0znG1jG6e+zfXnHvwQNETdmMINqlSEeZJ1Dvn93j4uJiL+6jv8TQO9L6lya9f/fta26228wodVwZboFU2gLbqbqglZLarzTbdpvBEhWxNJI1bq5uuV6/SRCHt35AyAwPo5aKZzlIHRb5SqTR1nRSnitQtC4phNlyqvlTppRUlmZEQJizhCErbYSa57J8SNkLRm3s7RV54AHymjK9cYjUyg+wqV8XRCtfdzea+IZiFIoSsFKBEm1SE26SpXZCeDh7g9P64R4SrU2ZkC1btea5TMDsqCJ5UfUuZwO1BlnZ6tkgrWWWqjOgqhJmsLWa2dowsKZK0nuKlMWokWWBoBIeiJpZF6CqhtnMdHSHW6PdZLfijjISu2HX11dEjURrTza3BtymzaLV5NZwEGQYW4ekaLdCkXSDRCkidr2n/XKGUlOKjxc6oXZN0H4ZefXrVxQ3atTsjD1lkJpIDNEwlSCRZ53rp4zViNiQtqwEStHT1YoUOaclSY1MmmjXCelNz2Q1T5L/7LPPYDEePXqYNa0ENHnd7xeKKUFiAO2HBM97DZMoS1prMmQLrqCE8uZHIgVDNAFpFEW7BnGKWQtnYJ6GOmL54+99D0JEzfT1alRzikHtda+1/4nsxk/VqQZmlXXzJMUiqFu7nrJMe8v2LhteteuAvEcrVqk1m+Owdn9h7ZYSE6WAIrkjPCVIFua8s0jhWHfhZ5YZZ6rZNxoplZp3clg2uUSKAcmwYpgqUs1iFI5Z4rr3mliq3IVqVDbwM9CGkao1rN1IR6F4xepCEFht1wAhIKjRNH0Dv6ym5lHrEQw8JSlUtapghHJ+qiK13OyZ6yyf/sunSYqyVuPavVVq3bvSgrKxcKVGU7/s1U5ovXz1W5v9ftPVet68cbSehRo65ZNfUuB/AWHLchVUWJtFAAAAAElFTkSuQmCC);
-  display: none;
-}
-</style><template id="quad-stack-view-template">
-  <div id="header"></div>
-  <input id="stacking-distance-slider" max="400" min="1" step="1" type="range"/>
-  
-  <canvas id="canvas"></canvas>
-  <img id="chrome-left"/>
-  <img id="chrome-mid"/>
-  <img id="chrome-right"/>
-</template><style>
-* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view {
-  position: relative;
-}
-
-* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view > top-controls {
-  -webkit-flex: 0 0 auto;
-  background-image: -webkit-gradient(linear,
-                                     0 0, 100% 0,
-                                     from(#E5E5E5),
-                                     to(#D1D1D1));
-  border-bottom: 1px solid #8e8e8e;
-  border-top: 1px solid white;
-  display: flex;
-  flex-flow: row wrap;
-  flex-direction: row;
-  font-size:  14px;
-  padding-left: 2px;
-  overflow: hidden;
-}
-
-* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view >
-      top-controls input[type='checkbox'] {
-  vertical-align: -2px;
-}
-
-* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view > .what-rasterized {
-  color: -webkit-link;
-  cursor: pointer;
-  text-decoration: underline;
-  position: absolute;
-  bottom: 10px;
-  left: 10px;
-}
-
-* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view > #input-event {
-  content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMnwAADJ8BPja39wAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAyNSURBVHic7Z1PTCPXHcc/4wWWVbJN2cJSLVqiQJuGpoIGEVWReoBNIlIF5RCRSysOK9EbksUeOHLIIQcULbLEEYk7oqduD6gSRoqUEyK7dCOabOHghCiAE/JntQtesHt4fuM3z2+MZzy2x8ZfaTTjN+Px4/fh9/7Pb6xMJkND4VGk2hloyKkGkJCpASRkagAJmRpAQqYGkJCpASRkaqp2BvzKsizf3w1z38sKc+ZUaQCuAFeB57P7q4AF/Kxsj4GnLrfL+6PDYofQAskCaAJ6gJeB6+QAFOvZpwgwPwOHwCNgN5uu/+H252raJHRALMu6ggDwCtALNAf8E88QUL5AAHqSTVcNUTU4oQBiWVYzMIiA0E3lGhtp4CsEnPtACgFDGqXiYKoKxLKsCPAaMIwojlzV1tZGV1cXHR0ddHR00N7ebh93dHQAcHh4aG/JZNI+3tvb4+jo6LzsPAY+QYA5Ix9KBsoPpmpALMt6BXgTaHe7pre3l5GREUZGRujv7/fdsspkMmxtbRGPx4nH4+zs7BS6/HtgHfgvOW9xeE05bVZxIJZldQNvATf1c5FIhMHBQYaHh7l16xbd3d1lyUMikWBtbY319XU2NzdJp9Omy74B1oAEAoa8yIZTDttVDIhlWZeB94Dfm86Pjo4SjUbLBsFNiUSCWCzG6uqq2yVfAv9CNKHTlNlbKgLEsqxrwF+BX+nnhoaGuHPnDv39/WXPRyFtbW1x9+5dNjY2TKePgBXgOwQUFUyg3lJ2IJZl9QAfAK1qek9PD9PT04yMjJT1970qHo8zPz/P7u6ufuoE+CewQw6Kw2OCsGVZgViW9SdgFNGLBqC1tZWZmRnGx8eJRMI5lJZOp1lZWWFubo7j42P1VAZR4W8gWmJn5KBAAEVYWYBkm7PvIvoWtjo7O1lYWKCvry/w3yyHtre3mZqaYn9/Xz/1EPg3ot+iQslQIpTAgWRh/A0x5GFrYGCAWCxGe7trKzeUSiaTRKNRHjx4oJ/6CvgHoigLDEo5yox30WCMjY2xtLRUczAA2tvbWVpaYmxsTD91E3gbMbTTBFxCFM0WYPntMwXqIdk64x3lM9FolMnJycB+o5paXFwkFovplfcniDrlNLvJXr4vTwnMQ7KtqVE1rZ5gAExOThKNRvXkPyMGQaWXlOQpgQDJ9jM+QGlNjY2N1RUMqcnJSb34shClwnVE8aVCAY9QSi6ysj3wv6N0+gYGBlhaWqKlpaWke4dVqVSK27dv6xX9j8AyYpDyGaL4svsqxdo5CA95DwVGZ2cnsVisbmEAtLS0EIvF6OzsVJNfQIzRlVTJlwQkO1Boj021traysLBQk60pr2pvb2dhYYHWVscAxEuI1pcKJYIHKKV6yFvqh5mZmZrp9AWhvr4+ZmZm9OQ3MAMpSr6BZOcz7CH0np4exsfH/d6uZjU+Pk5Pj6PbdR34LT69xBeQbG/8TTVteno6tGNT5VQkEmF6elpPfh24TK7VFaFIKH4t+BrKTN/Q0FDoRm0rqZGREYaGhtSkXyDqVs9Fl2cg2QUJw2ranTt3vN6m7mSwwR8R68dULzm31eXHQwZRFiSMjo5WfXIpDOrv72d01DFQcQXoQ3hI0V7iB8gr9pcjEdNQwoVVNBrV69EXcanccfEST0Cyi9jsSe/BwcGKz4GHWd3d3QwOOqaAOoDnMFfuRnn1kJfV7wwPD3v8ev1Ls4mF+Ac2FVsW5C8aLxpI9ou/U9Nu3brlOcP1LoNNbuJej+R5ihcPaQJ+Iz/09vY2iiuDuru76e3tVZN+jeiTyFHggsWWFyA9KAufL3K/4zxptrkE3MClYkcDUxQQU3HVAOIug226yHlIXvNXrUe8eEiHPGhra2v0PQqov7+ftrY2NekFzEVWSXWI3Rns6uoq6ZGyepdlWXR1dalJrRTwEFVegFyVB3L5f0Pu0mzUirC1CsPoJcUCuYLyGFkDyPnSbBQhB8VUZNm99nOBZC+8qqZdhBnBUmWw0RXMQHx5iOPpprB5yMbGBp999lm1s+GQwUZXKFBUSRULxOEhYQNy//59Hj58WO1sOOQCpGAfBOoESBhVwENMm61in/cOXRt3f3+f09NTAH766SdaWlrY29sDoLm5mevXr1cze25y9QypYoH8rH44PDwsIU/B6KOPPrLzcXBwQCQS4dNPPwXgxo0bfPzxx9XMnslGJ7h7hkX2GZOaBRKLxezjxcVFLl++zMTERBVz5JTBRseGy3zXIaEDEna5eAgENIX7WP2QTCaL/NrFlcFG0kMKLvIttsh6ilg83ATh85D3338/dGNrmo3SiAXYuvLgeImX9Rj4peHHqq5r165VOwt50mx0gjkqhJT92cvgol2P7O3thSa+VBiVyWTsJnhWsv4wBrZR5QWIjfzo6IitrS0vebxQ2tra0oPdPCbfQ4ze4gXII/VDPB73k9cLIYNtDnACUJ9td8gLkF2UiqkBxF2abc6AJOboD3lQzgWi1BWnCCgA7OzskEgk/Oa5bpVIJPTwT9+RCymoe4jvIkt+8Qs1cW1tzVem61kGm8jiKk1+gIE8eV25+Ihc3CjW19c9fr3+pdkkgwCiwsiL+oDyUKhXIE8QISUA2NzcbBRbihKJBJubm2rSD4h4KLLuOMMQRUiVn9XvdrGVTqcdg3wXXbFYTI9Op3qHuqlQHCoKSNadJNH7KGNbq6urjT4Jou+hRaVLIUoTE4zA6hD5Q5+oCXfv3vVxm/qSwQY7iG6C9BAZByWv6auOevgBIr3ke5mwsbFxofsl8XhcDw34BPgaYXg1KI0p6JlDRQPRiq0zRGQ1W/Pz827RPeta6XSa+fl5Pfl/5LxC3QrCAP9P4WYQcW2/kQm7u7usrKz4vF3tamVlRY/P+CPwLTlvcANiDN/kCYjiJXLv6AXNzc2xvb3t5ZY1re3tbebm5vRk2Vc7JReExgTDqFI8JIMIMvylTDw+PmZqaupCzCgmk0mmpqb0IJkHiLpV9Ypn5MA4oJimMDwD0eqSDCLIsD3WvL+/TzQaJZVKeb11zSiVShGNRvXgmE+Az8kVU8+UrSjvgNKCz8jxmaeIIMNyEoYHDx4wOztbwq3DrdnZWT1W1imi5XmCE0YKlyLLbYLPFxDlZhLKd4ggw/aJe/fusbi46Of2odbi4iL37t1TkzLAfxAzqmc4PcPkIQVVqofIfRrREVpXL4jFYnUFRQbB1PQIMZsqYaSUraiWlaqSQvxlV3rIFd2XEIsm/gL8Qb1ubGyMDz/8sGajzKVSKWZnZ3XPANHs/xxh+BSiyDrObifkirCiiisIDogK5TIwjvY6ijoMpHwEbCJAPCMHQIWhxl4sKmxsEEEwwQmlCQHlbeBV9do6CjX+DbBNDobqHSYYRQfCLDnimKEZfJbN0CpiENLOxf7+PhMTEywvL4d6mCWdTrO8vMzExIQOI4Pod31OPowTzHWHpz80kMjWyqpB6SXSU5oRQYbfARwVSA2+ruIU0ZrSK/ATnEBky8oxqlusnQMLNa4VXRa5Sr4JEYdwDPG8tkM18kKXJ+TmgWQ/Q3qDDsNTJa4r6NjvkA/lEsJTnkdEMX3J9N0Qv/LoAFFEyRaTbFFJGPK4ZBhQntdVgDuUZkTr6w2E1zgUspeC/YjoY3yPczgkZdhk568kGFC+F7qAE4qsU2S90owIpfo6ImCkUVV6bd4TxHzGtzgnmNThEN0rHK0pSngFUtleeeQCRa1XmhHN41eBAcRDka6qwIslU4jRhq/Jn8tQh0HUitttWtb3YvRyv4MKck8MyUeCZRGmeosMGPkiIshNpR72yCCW6hwgFiTI1pE0tDS6abDQ87BIMarEW9rAGUFNNot1MHL/HCIs3k1E8K9LAWfpDDEYepDd5Lopdc5b9Qx9r14nx/EgABhQASCQ109RizAdjApH9vhvIOJNvYCIFyJjhhSjNLlm6WMEgCS5tbbqAjbTlKsKwwTCHmCtmfcY2j/khCL3auwPNXyRGqOwifzQRq2IYk7dwDl8cYwwpjoqrRrSDYYKpdCaqpLrC5Oq8S5c+xCzx+hwTJtbEBdT3aMbUBpVXWvrtsnz+op1CNArVFXlbdEu3mICowJS9+cBsR/Exx2IaQG0af1tHggI1itUVft96vahsi/kOabPxQCRe93IaW3TAVQMhFRVgdiZMIORexOgQiDkXv3DdAObPMYIgAqBkAoFECmtJ+4Gp9Ax2rEORe51w+sQ7OOK17FhAqLKBY567AbBTSY4rsfVsktogagqACfvUpd0tz/SkR4GW9QEEFVBhtAI499ec0DqXf8H8f4X10jf2YAAAAAASUVORK5CYII=);
-  display: none;
-}
-</style><template id="tr-ui-e-chrome-cc-layer-tree-quad-stack-view-template">
-  <img id="input-event"/>
-</template><style>
-* /deep/ tr-ui-e-chrome-cc-layer-view{-webkit-flex-direction:column;display:-webkit-flex;left:0;position:relative;top:0}* /deep/ tr-ui-e-chrome-cc-layer-view>tr-ui-e-chrome-cc-layer-tree-quad-stack-view{-webkit-flex:1 1 100%;-webkit-flex-direction:column;min-height:0;display:-webkit-flex;width:100%}* /deep/tr-ui-e-chrome-cc- layer-view>tr-ui-e-chrome-cc-layer-view-analysis{height:150px;overflow-y:auto}* /deep/ tr-ui-e-chrome-cc-layer-view>tr-ui-e-chrome-cc-layer-view-analysis *{-webkit-user-select:text}
-</style><style>
-* /deep/ .tr-ui-e-chrome-cc-lthi-s-view{-webkit-flex:1 1 auto!important;-webkit-flex-direction:row;display:-webkit-flex}* /deep/ .tr-ui-e-chrome-cc-lthi-s-view>tr-ui-e-chrome-cc-layer-picker{-webkit-flex:1 1 auto}* /deep/ .tr-ui-e-chrome-cc-lthi-s-view>tr-ui-b-drag-handle{-webkit-flex:0 0 auto}
-</style><style>
-* /deep/ tr-ui-e-chrome-cc-picture-ops-chart-summary-view{-webkit-flex:0 0 auto;font-size:0;margin:0;min-height:200px;min-width:200px;overflow:hidden;padding:0}* /deep/ tr-ui-e-chrome-cc-picture-ops-chart-summary-view.hidden{display:none}
-</style><style>
-* /deep/ tr-ui-e-chrome-cc-picture-ops-chart-view{display:block;height:180px;margin:0;padding:0;position:relative}* /deep/ tr-ui-e-chrome-cc-picture-ops-chart-view>.use-percentile-scale{left:0;position:absolute;top:0}
-</style><template id="tr-ui-e-chrome-cc-picture-debugger-template">
+</template><template id="quad-stack-view-template">
   <style>
-  * /deep/ tr-ui-e-chrome-cc-picture-debugger {
-    -webkit-flex: 1 1 auto;
-    -webkit-flex-direction: row;
-    display: -webkit-flex;
+  #chrome-left {
+    background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMcAAABICAYAAABC4+HLAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAB3RJTUUH3QcNFyMmV/Pm9QAAIABJREFUeNrtvXmwXdd13vlbe9/7BgzEQAIcQAIEQYKjSAokLVlOW5Fk2nLKmqx0J2Wp0k652h13uiy5XYqdwU7sSnckpZ1yV3U75apU4kos27Elu9NlyRXZjiiRomSTIiWZs0hwHsABJIY33rPX6j/W2ueed3DvAyDKKoGFW0UCeO/ec/fZZ+29v7XWt74lAIuLi7tXV1f/raq+zcy2AogIZsbpvrqfMzNE5IS/1/fVn5sZKaUTrtX9/v7nT+fn9e/1e052X/3r1THWa3R/37+miKCq7c+mjW/a+F/P57vj6/45bayn+wzXs4n+794Q9nP8+PHdS0tL31LVmfpGVQU4YSInGUb/YfZvpn+zp/LQu4Y27X31d933nurkq+qaa08yotO55npG0v2O+r1/XZ9fb2FMWoD9Oe5+pju//e+fdP3u83+j2I+89NJLn11dXf1bdSCTJnnSSpz2+/VWZ/8m+w+g/zD616yT2P9733BOZ5f4dhbCevPQHet63zVtV3y9n1/v/k9nZ562SNY7Gd5o9iPPP//8qxVKrQdL+hOy3qqdNEnTjv1JA+vuRpMGvd7kn8oCqded9B2THuJ6u/Kk7+vuiNOgQH8OX+/np813/376O/CkU2EavDwVWPiGsp9nn33WJt3ItF2ne2xOe2jTHuTJMOS0He1UcG33791JmWQYkzB6dyfp7tynsktPG8/Jdv2TGcLpfH7Sc5m0EKZBsPV+tp4PMe39bwj7efrpp229G5u2O3WPplN1cE/XQZsENybtnNN2pv4x3N1Fpu2S/SO6j6fXgz6n4gRPGmMfR7/ez/cXd/1798Tsfr4PMU52Oq4Hp95I9jPor7ZJ+G7STlEnvN7gesfXpB2tH5lZzynrO07Txtb92aQTY9rv+3i1v4jqv5umOSEq0r9O3/iqEUx6MPXnqjpxrk73812oMQmP968zyUj68zPp+U1bxG80+5GnnnrKpkVxTiWUuN4q7+96/YFXp6pvANN8hD7MmRbF6O7200KR9ed9CDbpSF4v6jIJtnQjQdPGOylK9p34/HowaFL0Z73IUNex7Z5Gk3bkN6L9yBNPPGHdY3fayu3uSP0dqH62uyP0w4XrDWo957gPEfqf78e4p4U8+0Y86R6711pvAUyL3vTvd9ou238Q/Xn4dj4/Cd6d7BlMC532534S9OnO8xvVfuTxxx+39RJlk/DtpAGc6k6hquScp+7EkyIn0+LV60Ufpu2q05zN/sOYFIfvP8CT5VEmGWN/h5w0zm/38+sl7/r3drLntt58rzdXbyT7kccee8z6O2b3JnLO6zpjk47nkyVg1pu07muas9b3CaZh4f5uPMn4Sikn7Jj9RTEJMnQfVHdck4x3Wt5i0qL6dj8/6WQ5GcSYBiEn+STrhT/fqPYzmJYxrRcopax5eH18Oi38WI2ulLImYTPNMavv716z/93rRXUmOZXVgZ5kePX7+hPeN5xJTmx3MdXf9zHyM888w8LCwgn30IUQ0xzWSYvhVD4/LarTzpWBpOl+zqRQ9lqjE2DCtbH2x9MW3XA45JxzzmHnzp0njYp9r9jPoH75Gkekc8SZ2ZpjrH/Ez8wMSSmHMY4YjZp2MDnniVGT/sPvRhxmZ2fJOWHmxj0ajU7AtvV6k4727gSklMg5M4jdq6iyuro69bv799fNptYF0X3vJKjz8MMPMz+/gWuvuYatW7eScgIEwTADEwEUAZDkBgtuYONlCCJgAuZ/N5QkCcP8avFzUH8fsZgNEoJJLAakc+2TjENi90RQjGSCJm1/hwlmgmRFFIwEYoiNxyPxvYZ07gVKUzh8+DD333cfRZXLLrvsBLxfjbl76pyO/ZRS1thq325O137k4YcftvUSOf1Ufdco/uwLX+LOv7ibZ194EYBdF+zkB956C+98+99ARE64ue6XqyqDwaDdGZqm4Qtf/DK3f+UveO7QS2uu944f/IH2WpNwdp2U/oT8+W23c8dX7+K5GN9FF+zkb7zlZt71jh9cswNPw8uTsPU0h19VeeSRR7j55lvYumUzK6MCpqTs9p2AAiRLmChWBBIIiqZEMkVUMAQTJZtQSCCKkDE0/h+7twkKpCSYxrhVMTGyCYogohRLCGvHoYD0xyGKScIUpC5AVSQl/0ACaxeCkJJhakDCTJEEiKAmDMx8XSdAY6lZQjHmZoa89NLL3Pv1r3PVVVeesDH3T+FTtZ/uguhu8v3o36naj4ggjzzyiPXhwtRjOf6+tLjEP//4r3HOuRfw5psPsOeSXQA8+dQz3Pu1ezl2+BC//I9+jvn5uXWjDfW1uLjIr37y19m8/fzJ13vlBf75L/48c3Oza3aWadSP5eUVfuUT/2bd6/3yL/xvbNgwv2Y3qbtOF0J2MfN6ka7nnnuOvZfuZcfO8xitKnloFBXEBHGLc4MTQwVEDeIkyAqa/Pdh9z5vaqgkUuz8akYGVATEHOYYiCSUQtJqkCDJsJJIvXFYNRIzLGWQQqqLEiOhqKS6gnzhqJ9cJplsiiXBSnfBJF957TEoJBKYYskwFUSgWCKnBkmZp59+mpdfepmdO3eu2USn+V/r2c/JWAX9CN/J7KdNiD744IO2nqM0Cff+01/9P7js6gP8d29/C5detJNtmzYC8OrxBZ547kVu/+JfcPDBe/iXv/xPkCnkvHalm/HPTvV6v/SP25vs3mB3fKurI37pX36cfdesf73HHriH//2X/3Fr/NOSTZMyzn0n0sx47LHH+JEf+REWFhd8pzcliRtyBVbFYlcTN0bfpoWEYiaxENTtjOQwByOZ7+r+b/zacY5YICvH/iDmBurjmzQOKMlIWkPThpohkuN0iwWI+YrNGkdeQswwcbhlWEAzw8wXazZDJfsYMP84ghXzxSHip5rB/IY5/sv/+0dc96Y3rdmA2uz0YDA1EHIqDNv1KDAVvk2yn64vOujHlqdlJ+vv/+wLX2JuywVcfOkeXj2ywGtHn0C1Hov+uUsu3cNzzz/Hf7vtdm5959snRknq6wtfvOOUr/fnX7yDH37n29fccBdG5Zy57fYvs2HrqV7vdm59x9vXJeqtx6WqD+T555/nyiv3s7y8TMLhSgLMElkURx+KENi+7uzi0EgtIUCi+OmSwIpjmYTSAIN6uiSDkkAKQgp/IgON+yaGnxIBz/rjcPckj30LU5I5rCsJsiYsafgjCbXEUIwiiqq4e1J9FjVfNCioYMlPC/eJIFuisTiN0oBkhllBcmJlaYnL9+/n0KFD7Nixg5xza6hPP/00S0tLzM7Mho/lfpGicW/hyyCQAv75Nuw+UOwi/o7WmXLfClhYOMaWLVvZtWtXG7TpRibrMx/0V1j34XcdT4DBYMA933yQnRdeymhUOHZsCZFEqrurORRZHRV2XrCLr33jft596zsZjUbtiuzGqQeDAXd//T52Xrj3lK53zzce4G/d+k6WlpfXOF5jSAhf+8YD7DjF8d3zjQf50VvfRdM0LYzqv/pHcH9napqGF154gb/59rdz7PhxTPCdNSliisYuK5rjIRsWPyeJQyGhWhyNCEn9sbrPIGRJmBRfeCb+kEXQwDZG49AFIYmh4kvmhHGYISTEGl9YBimPoZypvx8VJA3R5IurMcdrSTrjLuGjGJCNpJnGlCwWp6CRMLIoMCBhFJPYIAxNxjVXX83v//7vs337dnLONE1DzpmXX36Zt73tB1g8fhwzh3OIObyrp60IWp9XNlBfRtkCPqWIM9T5x+GhDIQN8/O88srLfPWrX+WWW245IeLVPvvubt49biZRMTDj6MISGzdt9i81YTjIzM/OMjc7w3AwANwp27hpM0cWln0iOt9RowruSAlHFpZP43pLJxAB68lnZuSUOXJa41tCIuQ7jYBWf9fnP5kZo9GIlZUVLrzwQpaXVzxihGHJEE1ucdlIkgOwKMncj5Ds0SjfZd2R9re7AeWkGOFUhuOrrd+jFDPMEkJ1XGPhxdY+cRzZARPJfR9Jiqm/P2wONKHJwJRs6jt0Su5nWHJfQj2IYBQIp14xBkI47OE/BVyUFI6/KCk5zJOSGY1W2bFjB03TrOGtzQyHNKNRnTGQghWjWInxGI0phvtyNOZg0GAU86hmlMYw9c9qMYyCjgpHjx9ndmYD3//Wt3LPPfdM9FtUlYGqUko5IbzVdUi7WHw4M8vc3CxzczNsmnejq6HSphSWVlYBWF2ZY2Z2tt2tuwuw/ruUwszs6V2vuxi6TlYd48zM6V+vC8/qYqgnZT861Y+dP/bYo/zoj/4Yo3o8u1PgoVRJiPqJBRkRo6C+oxchSaGIxC5uJHEfwDdqN3xTg+wRKXd2EyRIBppjy/fLY02CWCzTxuHX91MAEfdPNJESqBopFcwyJurAqg3jWpx6DqkExVIiNwIDQa1BAWRAQiE5XExJ/URCyQgFIZlB9rk8cOAAt912G/v3728jiMOZGVQDEShoSUhuEM2U5CecFHWIGbAzlwZJghRDs0AJ2FVdu2wUMxI+XyqFpjF27drF0aNH2bRpU7txt455fcjVuCrE6Ds6DkdW2bF9C1lg49wsG+ZmOWfjHNu3bGL7lk1s2TjPpvlZNszOkMTYsW0LWvSEHbhraDu2nfr1ztu6haa3uLqn0qhpOO+0rncOTWcy+vmMesLVxVgXdimFpmligWbmZgZtLN8vFmFZbbBGHfdSwo9whxot8ZAdMydzTG9aUDGKGlZ8QaiGU6wGVtDSUChIY6j6gqOBTHPScZj5qVHUoAg0DaYlIIWhlj2qFUhBDUwLNH4tMCgKZqRSGMwO+PM//VOGgznPe2jDYGbIvfd8g5mZAapCMcEEv6cK8RpFLLFp06Z2Lqvt7dmzh4cfeRBTQ1E04GXBEG187pLSqNKYbyBm0IQda6MoDUbB1DwQUvyE1tJgKFqM1dJw6Z5Lefzxx1vb7B4EqbtSJjmmXYjVNIXrr7mCI68dZmaQmJ8dsu2cTezYtpkd2zaz9ZyNzM8OmRlkjr52mBuu2c/qaHRCZGcMSxpuuGb/qV/v2isYxfW6GdFqtE3TcMNpjq8mGbs+xyRSX520GhMvpfDC889z7XXXsdKsYMV8t7fA3ChYJmWgGKkIlh3SWeQEwJDkp0UJKKIioGNXW9R3PnKKEK+E32BYDlxvUMTQzEnHIREQSCQaMSRn9+dlvKOmMUr3aFRKcco43JIUicWU+G+3fYHf/c+/x6c+9R+ZGQ6ZmZ3jtz/1Kf7PX/vX3HPvvTHaQsYgKUnFo9C5oBirKytcdeVVvPjii+1zEBGOHTvGxk0bfXGabyxGQ1GHmaYB4YqRLDYIIXyw4vDQ/HoJQ61BTHyPKeZ3aMbxhQXm5+dPSDCaGamPt7pQZRJL8qYbrmP56KscPnwYEZgZJAbZ/5sZZMA4fPgVlo++yoEbrqXCtq4Bdv2bm9/8JpaPvXZq17v+2hNgTXcxN03DzQeuP+Xx3XLg+hNoGN1Togsxu4umnijPv/AC+6/YTxlZZIo1YJIf5yLmBpeFMhCwEg67J8QkVacyRe66eLg1aRtcUVFSgmzFsx3uWSKSkWIUibiSpcD1648DMU/ggTvP6r5PskhrmEMfRFEJKBcZfJPkjq4nQTA13vk338mHfuJDfOXOr/J7v/t7/M7v/A53fvlOfuqnfoqbbjhA8di1/2nZr5kU0YQlhz7XvukannrqqTW2snXrVpYXFrBmBH5+OBnA/CRxP0NJVjySZoo2DrLcbhu0eDTORONnxde3FUQLqoVmtMreS/fwzDPPnOBe5J/+6Z/+F/1dvZ9V7BqHiHDDtVdy51f/ktVRw9ZzNpMkMRo1HD16jAce/hbPPv0k/+N//941Wcr1CoNuvO4q7vjKetd7gr/3t98zkXJ8QpTJjBuuu5IvTxnf/Q9/i+effpIPf/DHJiqO9EPX/Yhd9UuWl5fZMD/ProsupJhDBEniOzaCWMakuNMsjp0znhzTSv0wRbL4yYCQyWgliJhTMzKZRty3cNhDJNgMY0ACz66H333ScRSHVSnCrZbdfzFpc4okFLHsvkEkBE0E6YSPfXxQrHDF/suZnZ3jttu+wHPPPcv73vdefuiHfpiVZrlNbLYJy4Hfm9uSn4jaFF47coScUuvnbd26lccOPsa27eehxXd/JO7LQAZgJRZ84+epZM8JeYwtIaKIRZpGxXNFLTvMIuye2LRxE48++ig7d+5c48/KPffcY5O4+11nvOsj1N/Pz2/ggYe/xaNPPUcTGHc4GLBvz0Vcc8U+VlZXpkrgTCrPrNf71pPPnnC9a6+8gqWlxTUOUx1T/VmfGbphw0buf+gRHn3yudavaMe3/3JWVpZPYOXW+6vX7CYcu9GUpmm47777+OAHP+h4NxYlSdr8gOGOY45TwCpIsRQwxkjqxi7iECCJY3MBj91L8viXKSlFrN7iG6SyrOp1OaVxEAlB1EPFyTzSVCkjmgSp2XGNPALBO2kMy0JW8YhW8VNpODvLp//g03zjG/diCDfeeAN/+8c/yOrqClgOLpZgA8NGKU6vOI0QhMzK8iL/9fOf58orr2QwGJBz5v777+etb/l+jh096rAzCNApbhMqRItTRVKHGBmcF6CYkSUjWlr+pNNrIodiwlNPP8WuXbvWJKoHXew+GAwYjUYnxPS78d9q3EtLi+zfdym3HLiBuVlP1qyurPLakSMsryxPrNfuhnL7hLKFhePs33cpN9/4Jubm58BgeWWFI0eOsLBwfM3i7BrytLrlhYXjXL1/H993043MzsyAwMrKKseOHWNxcWEq6a3PzO0nSFWV0WjE7OwsMzOzLC8teagTQ5w8FVljZ8B6bD/Ig2YkUaz4I1Tx06Sh+E4cxuIZcHdAU8Ak0+T2ihtWzYSj1NThScfhYM4dbne6fVcV8bCx5zpicanvvO2qix+bepSrFMgizM7O8h8/9Z/46p1f4f0f+HEA/ugP/5CVpRU+/KEPsTxa8XAxhpRUM6C+IFViDgqbNp3Tnso153HhhRfyyuGXyGmGOjtJxfliqYbFPX+hpiQKWIoNB1CFQYrTsqGIRLTKT+xk0ChA4Yr9+3ng/vvZu3dvaw+D7mmxsrLCYDBY44TWf3eNsJsPeeWVV9aVdekvvm7Uql88tLq6yksvvzy1sH+aSkh9NU3T+k0iwuLiIouLi+0J2K8zmERP7+Z2qvPdz3EcOnSI6667jtXVZTQZ0pgf81KZrNWgAuNWrlJSSolEWPL9WqWGOt2eJSlaguJhvusnEc/yV0ygRkkpiH+QRSnCScfhnCl1smM44BVIdVnBnnFOEfpMiBVUnMxYeWFZ3FP6/z77x9x5x528//0f4F3vfAdigpbCZ/7wM1yyezdveetbnL8lCbNC5cAUJ7d4SFoSS6Nlrrnmap555ll27tzJcDjk3HPP5eDBg1x2+RU0qytgQol5dNaDopactoLFCVyQLKhCSua+hQTzWD33YwKpcUaA/8ztbBRRs/bk6OPsLkTRoHj3C/Yn1Rv0/ZJJBSarq6troEr3c/XPmvnuQ7FJmfu+sMAkI+/WpPQTndMURGqCr8/6rD8/dOgQ73nPezh27HhEYzzk6Md6pX8bFbAIhonDJKhoxWLXTwFp1NdPY8EgFzT8Dv+AOwbOrjWPgKXKbfLo1CmNo15HPHFmUhgTVQh+lOOWLM641aCFWEtbj+cgyo/+yLvZtnUb3//Wt7G6OkIwfviHb2Xnzgu48c3Xs7K86idNzTGUoLlLxUdOiMwI1159NX/5l3exbdu29jkuLi4yPzvL8dUVSoNDtDjJLKBRI0YmkqXOcEQSFI2cShKkLowSSUlLkU+CZMbi4iLnbt/O8vIyMzMzbkt33nmnTaqK6lZx1aOuX7vcx+yTanq7MKpbfNR1quvu3F8wfQp5d7ev4+v6Al3o0/eX1hMHm1aLPEl8YWFhgZWVZd7+gz/IatOEPzDwya8bdXLoQwnqglR6OBFNcqhDOLbq22dEIiM513iUR8woyZ32XJ3sFDukuPtSKhnxFMbRJgZjx0ymIIM2CWkBO6xS4FNk7cVQC1jia6UNh1rOfgKotgnLFGOWDkFRTZyuUmodSaX1BNoYCF+548vMDGeYn59nZmYGVeXwK4fZef4FqFkEH2owISElnil+X77Ak/PQLBYzYNKQbNDys2rEziJQkFDO2bKVu+6+i71797q9dxNp/d247yfUnMC00Gw3kdNNltXPTitb7VZ91YRQn6zY/96+L1TDq30nvY6l+2fNldSxdU/Mfji3C+1WVlZ45JFHeOtb3sZodTWIbL4raTAKa8UFxTlOTlfxZJRU34DkcXuLRG6p4VdAszu+QZZTBSkOY6zu/MUJWaYRTTuNcfhxlaIOQ+Ik8ARhqZBNPOyMJFLkFDTGX0wpJUCYiI+ztaHY7ASsGRuemS+iZCCqEbiKMKv6ovRxKbccuIWDBw+2lBIR4YVDLzAzHJLQCF1bhzZSPKnZEjiDvqLmi5sCyfMeJpU640466uPT5Pe4PFohDTLD4dARQ3e3rYbdzRB3F0mfqj0pD9CFL12sXiM+1ZDrd9WfdSejv+C6pMWukXezmv3/uhCpe63uoqvjrYuq6WHOetp1v3N+fp65+TnMMpTShjOt3QE9ROvYPI5/83oKlRL1FIrzNSRyAJXFamBNLexzjJ78mqq+YFJxACZ4dvB0xqFBFycpUMhmlBw0k6CxWnJDdlqKnwR+gezcrmD+WkR+tN1/jUJARRM/tSg+1mSU8K80KCGkgiEeoFAfkqkyt2kD8/PzLVlVVbn22mu57YtfYLUUNm7cgBYfmgUb2BduHJfFKBRnAqRIXBZnKIuCNMWTirFo0eKUEwEdGcuLy2MbuP32260LfU6m0zRNm3Q9XdZazDIajRgOh+2C6Auk9X2e9dQpJtU+96HSYDA4IYk5TVh4Te1w+Br9U+PFF1/kyquuYu/eS50KkiQoHtLmCHJEhGosnRrPD6IgOaIl5rAJ8YSYJoWSUSnk5Bwqq5gjJUyLR4tybhm8vkA4rXFIMmiEkqSlswseyclSTxL3XzyRCGLF5QaiZLZSw2t+JuHObaJuAuo8KLF6i/V/Dgu1pk+C1hEOcRLP8D/1zFM89NBDnH/++QyHQy91Hgx44IEHKKUwPz9PaZq4txpVq5WINZIXLoJGwZa4RyZtrNzvQVGSed3LzOwsKQm7du0aEw+7jmyfaDiJRtENuU2Td+z/vMvd6i6++u8uhOpHlyoEqousr3LXvYd+sq7eU9c3miSjWRdJ9WO6i7DuYIcOHeLHP/B+ji0skSWyA6kWKKU2x13LUn3HcuydUoSjgk6NJqwUkNziYMtK1hTwSONKvggk+WJJgbFNGswyScopj6MN+yZjkEAbQwYNlMwwfKKSPN8S9u9JNcmIRj1HkByliEfGRoKm5KzxONMkxpCjTEDw7L1FWUESpWgIX2SLkoKoGMzC/iuu4Mtf/jI7duxobWJ5eZnLLrusjXh2Swb69tO3iYpQuqWw1fftRkyHw+GaIM2gL0ZQv7juntN0nLoZ9a5D3GXdttTfyHr2F0QdcH8xdk+P6kt0F0w3RNyv0OtH37rXn8TA7YsorK6unlBPXEphYWGByy+7jMWlZa+YK8kd5sDqKejfRkNmgBaPubvwgNKUQYxRIZnvxil2VC3+WREnFOILysSDrKoCNAgShU/J687l9MeRygCNYqriTA7PyquzcX0z953fiIRMtnEJbQ7elnrQQHMhaaIBp8cHLPOKkUqV0VYvQsy8ZiVqQ8Tpu2OonmBlZYX9+/dz5MgRtmzZsqaMtm8bw+FwzabaZ23X1+zs7Bok008kT5JYSl0j74ZtR6PRGojV3fFreLOLxfs+S5f+XXfe6mtMKputi6DrVPfpIX1fon5n15/o+g2T9GHrOJaXl9fkbUoprTJJHWddwE3T8MQTT/COH3oXpSmRqnP6tyexvKRUUMQG7luY1GgqiSF5UDynkSzwdZSamkQxj4dXsyWyQE7uvFrUwWrKEIVPOqgV36c/Do3TS6VGsiLWr2PlkAxYKo5zaiYcozHncGlAGEsgJUUdObhn4ZAmp2Acx2JHpBO50tZvMrE2ny1RHKXA277/bRw8eHCNXX237Sd1C4e6cKceMd2sdI3ydJ31SYXsdYDd1djdyfuwqgt3BoPBCSJjNRFZrzccDtes+vWUUvqJwvr+4XC4Jsxcd4+6+6SUGI1GHD16lAcffJD/4e/8HZaPL3nVWXCSPLTpLB1LbqopZGsQT4aliB5pyaTAtwWQQfAhtJCDqaqRlCtBabBhwnKJIiOLTDfQSOQrTn8czsNIHhUL6J0HOGwzJxUWEZJKsDIEy4ZJ9ipDrUojGg67JwuCKxwejuc1LIfJB8YXEY9WRZGXImQN1i+GpuSnWTGWV5b48Ic/zNfvvZejR4+uQTffLfuR27/0pdhCiAL6MUmM4J7Uyq5WmiU0kmqEo2oj1Z9JyLVU3GqRFfU5Cp+ge52uDx+7UJ3kVgFJWPO++pska+Vqqq+FdcbT+S4i4tJqRdXQUCSU3JeTljM1HA64+qorWS4N2VJ8jQYBLpMoQUWHAUKDix9U+ptj/cBI4nymAEvxQBwe+XXjHlJBtdIQ05hwh6JZSPo6xtFm68f3i4IFnZycQhBhnJF3H1yD4hIlsCpjxq6M6+NpqTIhAySKFKfiD5K11A93xI0qFlRTqV42HLkhEyQJDz74wASxD9pn1SGutQteqM+acRBhLBI2wZ7Hw2+t6/lDh2woQhG8drkaazUUBI00ewpqDClR1EXGqiZRq2IR0jE5HM+avZWITzsTMqInEb2oC0BDoCxJ8IoiopCCy+OsS6c1iPiR7xFFI6dQvqhiCjHlLfwQN6Lx/Xssp5iQrBpK5JJbdqrXSYiF1kegDM8ZBDkvplIl5igHLSMoH9XZFIOSa2WdeXVbZGpdWMfxuVRHH39fLFvPVai87nH4JsDaZ6WG5SBFVl6X1PmHsV5QhEQcCZcsAAAWiUlEQVTN/3S+VfIipBosE0FLzWRnf1Z4Vtp9J/WAXcpRvBVUrprIi/vGxpG2yOWf5FkJRdx+Bh6DeN32nCRKFyV2No1Yd12ViguMpZRiB/AEVor4u0VM2+LYN/Hj2LO6cXhGFVjoVDjetnqsBMUnDuVURS1IpOw7TqP12K8Lw5Nm7vA5dUDVs8MSnl8hwpKhzKfqIgWu3RScHgtjSw4l6s6SgtWKuhqHU9OkzbYWMyx1ggPm7FZJyZ1UBIsyToschguG+HcXxZN+kdmuQVdNJRJw1jlVtS2W+k6MQ8W8bDcMMhWjSfgmY8Vza6o+P8Hd0wjFWlQG1mNc8OfqGWev2WgipKzqBuf+T4kyFB9f0TzOktdEqLoWlpl4HQaN86LsVJ+VeaTvO2jPg6B6erRDIIdR13oD/02s+uQTSJvrdfwpUTBjA2sTR9IINlCkyWiuzM/sD0DMSS0mTkqzhKbiANpo2aClEXLc2LhYP7Kfgb/rSSvWtMk2y7G7hbSHVUigtcjIKMUX60iEQQOWa/DU0BIs2ahRdqLOd2aOihZee+UwRYsbQ3a2qmbIxb1hC1U3oQ1ZjRm7GnkFEXKLIYmEn4zRRYp6kXofFYIEydHLB4OK0RmHf5eChOYVY2q81edWhdrCc3B4GBC3as3Fs0rFoaDXllQYowEVfcMiiJh10Yt2TqzkTGE/GeS7OkeDFD5CSfFnOFxSAjRKwKIUxklGvC4TGRSk8aIXk8bLO1NyxuQgao6roYaRWlSEWZhiIlFaAw+tpMANKeHx8Ip5Ww5NPDj1YnpPPDmFuoqMWRz1VfAMgvgnhpVwxIrn5Er2IqEkvjMnySjFT6SUnX/0HZij44tHWVkdccnu3Zx9fe+/Btr4DuvUBW1hjiTfL1IpNAKDyNiqFefN+Kbv8Wp1LaVKoSdi89Iq7/lRlc0jKJqsfW9JNi7cJ3mMPRwlrUzTtoYldokorjZxcKniO4e6DIWvfMVLSXODufU7wcE8yVZq2FDHO3xj1SeSVr0jWUE1ofL65shILC6tsG/fZW3M/ezre/uVkBJVZo5HCacxyDruuJkTzqzSHrK4WFqFKWLkyOWk6kTWLHllZhYP3UXZekRliFj4uHorBSFMzOPdFllaB8w4F0Y8sqJVXdzEaxnCaTXxMkpxBVn/uqSh9FcimuEOutQQRUrOdkU8vBo+kNcCvP45SiI0zejswjiTFodLODaUCJ21YbzgpKSICnn9rbSliCYRprOE5OTOoLg2kJHIUQYq2aMKOVVpRtpoeKoymVLpy0FbSA66UjinxRLJ7RfLGUWcyyMOzCLC6pg4uUaTmKDZa4fropFU2miNk3BaXgdSwqlLige1amVdcvr2654j9zfOvs4gWEVxVW2rNc2iHg7P7qiJiDujppTqtBSw1CDmcXRWidqA8LOtuAYTTlOQKOUZkwIrv8ZFugbqWqzSOulxZBQNOU+HLSkcNi3GAEHzyIPDGkxRF0cKCqpiKaT7i7rwWBX6ipNINbtoQHJGJjmFbEsVFNOWkWq8zjkadRzDs68zBVa5wQ2DgpAkObOsRFSiCsdJxdgZyKHm4OFbBhG4SZW373FzHUR7lKBGWIT2UieLOtTIaUQtmvsblT7txDUlkzRXIqUnk5LnHyQWBknIqDvFklxVQ2sCLBYdCcmGWnJJTvFQoRYhDYKBKhGxyQRPKLVhz29njlxMwDVaObs2zjBYFUmdxqzF3yI1l5DaTKSiaEkgrhhHEmaGmc2bNjM7mHF4o5HOi2qvXEJu3/DC/uAQEU53FokkWxDGUtVX9TLHpDkUx+tWPBYTm8kDl6jJngjy/GotAfUQclRTen11VMah47BdUUgpBJ6DFaCUEAwzJGVmN8yxYdM8m+Y3QM7Vg4kkkTE7nJ06R5VHZHEAnV0bZxysiqysefioiDCIWmQstbyYZMllKkMndX5mA//3b/w//MnnPsett97K//qz/wuriwbZd+IaXUo11m8pdFIjc12MJJGbiOIUzFzvtR1P01bOEUS9lDOPPPQQr7z6Kju2n8cVV1zuSStxaUxyiCfXa5iHgEuQ5VxCMORhUE/IVapQUGFTSqwsL/E7v/uf+eY3v86RI0eYGQ65/PLLee973su1N1xPWVnh2OICn/+jz/P+D3wgAgedOTJXRS8mDCIjXSkjZ19nCqyKrKMUT+J5mt4CK9MamAZRKhnMzczyG//2N3jowQe56aab+PrX7yUxJCWLCJLDnMoZwlwNIqc4naQySR1Mlcp5CQl8SSn8F2lT+W5YnpRqSmHvnktJOfHoY4+ShkFYyzkSSNYqjbcyXuKEEq1Z+6iuz4RAcpw6szNz/Pmf/lf+3k/+JN969GG2bd/Gvn37uPiSSzh+fIGPf/IT/Itf+iWOHDvGRz/yc+Q8OHGOYuJUPNTbWGkTY2dfZ9DiKADFG5aIppYe4KJi2qrsIQ2iwuzcLP/+t/4D9993H9u2bUO1cPPNN6Ml5F5qWNZLgl260Wruo6qMp7arllrxgFHtHyFgxeVUUggwN5W8KL7INm3eiKJs2LQRBQ5+63FyErSx4PxUiFfpGR4CdqFwRTUFT6j4Yo6SycEg8cd//F/49Gf+kBuuvx5B2LZ1G9deey2X7N5N0YZ9+/axuLTEz/7sz7Jnz+4WgnbnyKNmrhiokS23s7DqzINViaalbZQcNGXR0AbKThxIgllhbm6WT/32b3P3XXezY8cOzIwtW7byD3/mH7K4shzdiYxG8IRfKzwfLMiiYeAaxfnFI0ollMilbY4HRaNqLXnmXDJWCkVgzyWX8sSTjzOcmWPzhs0cOX6EJ558kt2790TysJCCJtBUVTypQoBGyRp98ELmrHgTl8OHD/MHf/Bp9u3bx2g04qMf/Qh7du9meWWZLENKafh3/+Hf8/xzz3HFFVcE6zeoJDFHLvDhVBlVF1FGcoSlzxrcmeVz2ABSoYTSRAlYoCl7D4eggc8Mh3zmM3/A7bffwfnnnw/Azp07+djHPkajDefMDUNhI1rwBllNVVlcWvRdNFid3quCwP7aGo5ZioYr3gekcnA8cqWklMMHSly+7woee+IgOQ3YumULh189zLPPPsPFF+9qWxRr66iH6oc60SxriBCrO82ShJQGfPozf8TevXs5duwYv/iLv8imTedw7PhxhEQjixxfXOa+b/4V5+04b1xGGwVHqXK7teZSSnTZqnUTejaSe+YtDu82mkU6HYEyYh5gFVNSHvC5P/kTPv/5P+Oiiy5sDeOhhx7i3e9+d0igyLgntYybtm/cuJFf/79+nXM2nxPKEwnJ2tJKUu0BIerZZIWmKdx11x1ITuOWXLjgGSHfLyS2bN3Cls3nUFTZunUbrx0+zPPPvsCFF1zoY8rR6kqcqGgaogiR6fYwrUfWBnOzPPLwg2zffi6X7buM7du2szJaDSq28OLLr/LRj3yEiy++mKNHj3p8S4RmtQkWLeHZV3GxqvAXGFNbZvnZ15myOEwsIq+1j0EmpdKqSKDG7Pw8n/7MZ9izZ8+a6r9zzz2X8847b90vKKXhi1/8Eu99z4+5+28lEhgS7EpXscgpuzyKKK+8dIiLd+9hkMQ1YtMIs2FIygS1pOo6hR9hZLZu386hFw6x6+JdjJrGe3lHEZEnxx37ayTzarPHJmU2JGNpyWVZLrrgQlaa1SBOehRr1wUX8NnPfg60RPbeN4Dl0QrLxxfbXuKo530oNm4qGYIHdhZXnWGLwxVhnJEq4lDDosREjZShrK5y1VVXsbS0dNpfsLo6YveuXWhxDySJdy8ySSRV1LIr1WlpT565jZs5fuwIaWbW9Y0sk5JGHsPFYES974KKMDDH+0X9NGmaEs0nvejHlFbqsu19h4euNdiBRYW5uVnX2F1aIqsXz2jxSpOl0SrLr7ziaRJlXAVnRm6VA6tgW/FkYuuE51pOefZ1Ri0OCrkMKGmsnySB2ZNAo0JZXuEjH/kon/zkJ9bUY59//vlcffVV3tpM2sLTtrZPzNiydQs33ngTy6tLkSj0uolkng/IOHFPa2mjGlu3biJnf2+tx0gdSYFg/XPs+AJZ1DsUkVhZXuDSSy9DKYg5M9ijYt4FqaiQcnFNpWxYyd5ZVYSiDeeffz5NU7j77rv50E98iIWlBVqhm5JdtsYysxtmKKPG+wCKK3VX9JSTM38tNFqrOksKn+fs68x5ydPPPF116sPochSF+C5emyFIRGQ+8YmPt7W8zz77HH//7/8kb37zAe+akw1TbwxZBbUV7yCkVW81HOycDG0kmh5KW8stVVM1VUHxCO9aFMvgnKnXXn2Nlw4dYtu554IVFldX2Lt7D6Vx/ydngvIuURIqQYyM8leSJzsju52ScMcdt/OlL93O4uIiBw68mb/7d3+C5ZXlqGly3+uVl17iV37lV7nxxhv4n/7B/8xoZTWKZizyi937SO6UR4vjFw49z00HbjprdWdKnsOakFUxjQ6exYnehdDmHtdooIWPfexjlJDc2bXrIn7zN3+Tv/rmN5zuPYrrFHXcrRaG6Ht+MYNSEFXKyHMSpp4LMNShkXmyT83afm+VKFi1/I6+eoRnn3uGrdu3oRiLSyvsufgSmlGlo9decNCkWn9hjKJGo4QAcqNOFUmmFFPe8a53ISJs3ryZ2277Iv/q4/+Kl156iY0bNoHC5z77x/yjX/gFzr/gfP7irr9kNg+pnQHaA7VoKwEKhjVB3bez2fEz7uR48qknLJNbdQ9LtaC4qkDUckZvmSXJM9Sf/OQnWxmUgwcP8lu/9VssLi4g5CASWtCVkq+TWmgURfFAiHpVXaZg9YpHtCza9bbyjeIwaSYP+NrXv8auCy6ClFg8vsieS/d4F9bIp2RxkWLNtLXX0Zpi3M8uKPBaO8DEybi0uMSv/ZtfY252luXlZR5//HEWFhYYDAZccsklbN++nYWFBd73vvdx0803U7Q5YY6INsaVGZ+Sy8+8+PwhDhw4cNbqzqSTo2BRqFOiFtuL8FMIFFA0+jQ03p8tZX7+536e5RWP7uw4b4d/Pqjpg2gmoqqIGk2IhlkqFINGjSZOBFXvEJpKQa2BQqhIBPtcFGu8GaIUb86+aX4TBeP48aPs3rMbbUY0USCF+omgRKticzHjohpL1JeHJqUpTl+36HmtpmyY38A/+6f/hAsvuojRaMT+/fu5+aabuf6GG5ifn2eQB/zMz/wDvu+W76OUZuIcWaijazFUCqWRXlHX2dcZcXI88eTjZpJoJYTa5iJjwYFKwo7MhwscZKGMCnd/7S7edMONbJyb94hTkii2DwVwAaxBZNCWt0rkARSviZBilARZw1hTLcgfh4UsKvEkpPEXFo6zcdNm12K1VjmrrfKr2lOefmg1WECdS+b6JjZuqFgpLHhgYn7DPMeOH+eRRx7m6NGjzM7NcsnFl7D3sr0cO7rg2XCxqXOU1JuqJFwsLQ0yh154nptuOutznDmL44knDPHqORt4Ew/VHPUXIeyg4pSLUK3TkHMPcaiqTeFwJVH14d2g1ZyqHmL1Xq0aelUaurBZooVCrdgLmJNrfTmtTlGKL9boA6HiDUwkh8SPiod9XUCD1EQ31VSbqsQCiSYsYhJtvdplBGY0SRhaFc2JTqbqQoGCYqc4RzUhmtOAF188C6vOLFhFzYr7jq5BIdeooZBUQg3PXD+1lOiyGBhe3dFurGqQatvpE6JKLjXeQ6HVEKoOdpwQxXMY3qXHG40UDGk80lTEe+URkvtaqScWPSrCnyBgVJXsMUtobtqGj973O8iUNCGr0zj3KciNqr7gBhqkkLZ3hYXBW0uzP5U5MhOn47SaT2dfZ8zi0Ej21cahRLzes9niESh1yEEJdZCIHCW1tr2UiF+H6Nmg0RWxrbQTV6zTKmxEkPQ6X1xlHNUKAwnZzuR1TqUEEz3V0m9DdeCD01Atz3jVYTSalOLYvwRd3YoLOlSVESxakdnIGzhqRJWiM5IFrUXR1z1HVb3x7OsMSgIGEhmTG6L/AsGXkoznMGosn+QVdC01PYWyRwqZ+mjxS9u1xHddBMvFdYdLaRuyCDky8jXWFO1QrLiUTklRo+Rqikkt1MktZEejM1UIK9RbkFQV1r1iRC17UZVEaxcpURUYcEqhiPsz0nj0rKr6IfK650gH5ezaONNODqnE1xAIIKIsVVXDosmIR1b94edsnUIoGxtRLm1OoVXwVWtVDnNTF03VeM1eUpqsbdjYRKKvsg0zDmUkKSKlI1Zcuw+NW+VWX8ePIRdSbheLjFwNBD8NBiWa1BOOe/gG5rMShUoBM78Dc+Slv+msxZ1RPkfoQbmYQY3qgI4E1QYzx+Zq3uAU9SyzVawfjd2LetMUxXtEW/SK8B50OT4T6iMaHY5QShVIEPH6h+TizVWlRIMoWFTRIjTi/kkJyCYWbFtTirijXlXNVUucHrX/t2vrWiNOlykuueNhZ1opTO/zEi20NNqhvc450qawYX4Df3XffWsoOGdf38PRqscOPmYpFG1ShlSyc5kyUQvurXSlNBGFicBU1F20WlPquk2VLlLFvzUUsVPrRIdvUCKqU6nudY83acNg1tK9MySvIHRIpeTk6iWErGfkMaM/orcPQ1rdbvdtShrXkVeyjCilqrkXVzqR6NtXhcorn+t1z1HxnNIrr77KyspS9LUIXtkayFUZPbV1g7WdWaPXfCsKYViwVySawXTeYIzJjq3av7Tq7bWPNxEKr+OQWrIs2p6I1umjN+011oSvrSfCyOrvpBaGhSp7R4e3+px0tXbbga+9le/WHMljjx70pHg4qSqCyMhLSU1c87XqzVpoCIbUjSuXgKYQcDbI4vKZskauvmrcgmhGJSRzglflSt/RtsBcMsc0t4TDksbibN4ZKSrwxJCiHnatRVFt96DIrkdttySX1K+ZE4v0dTXmFCdUFonmMcEOiJyMiLbq79+xOZJOo4ToAe6+j7WLX6r5mDe7SUGt8QaQHgk0Fd94skb9irR+XKp6KTIOr0t0lR1InKhrxkGba5LiRNRstZeGz1OTooePpjVtjMfPKuar6kNXKqq6ovugfVZEi4BoU2AaWsUhB0vQ1uJ5EJWX3605annVIkKREp1Ds3cBjRZZIeCHiIuU1V3FzBscinn72kQJ/K2RSIwFIJVHFUVNRNutCN820SvDdbAij5E1yIdGrhQMIWTjSyvCTU7MRqjUhZ4tdi6NZF9oZsVNSLZxf47sLYNTZMyl+hrRMyKpRueMyHN8p+coKqBU1GnuGCWVttNq7R8jql6LbnGaRu9AojamCm1HcUtUZDZutBqSQeoVj2hBtbgGcJETx4GXAljxZ+bs6WjtXIxRSLYq6gvDAqKGwkpSIoEM0gQnwSo1SZgp3tO8RBsJgnemMVduG+NnpbUeJ/Fdn6OBVme0hmKJTp9tljlk4iWq8qLfRirxuTJuQqPRJqgemVrPqugYlELbqf62WHSASuIdf1o2cNDMq9+SQqbexp2anKBo0fsiGMSR3EvW0ERfDRkYTSPef1oEHakLrJVEoYE09Aw+CVd/tKCwZ3IqSBn4Qygh+fnXNEeSBt8T4zj7rMZzNPjKV75KbbLT9idogVhIeNZjrdvaqsrsmESuo9Mjq6NCMq61DvwvXdzr35GihUBtKmNRm60hNh05OMfHMZQkqdN2rYtvg9LRJiSqhm0kO10BoZUBSiYtDBtLhNSuFFVwOnlo+K9xjhLfG+M4+6zGc/T/A8/G/snZpSWJAAAAAElFTkSuQmCC);
+    display: none;
   }
-
-  * /deep/ tr-ui-e-chrome-cc-picture-debugger > tr-ui-a-generic-object-view {
-    -webkit-flex-direction: column;
-    display: -webkit-flex;
-    width: 400px;
+  #chrome-mid {
+    background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAABICAYAAADRa1RpAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAB3RJTUUH3QcNFycE5v9iFQAAAQtJREFUOMvtkjGSWzEMQx/0eYrM3v8k3vgqycalSwlI8Ufyl3OBFMtGIgUCIEd6PB6RBEASqvfONSrJXrDNbNkQ8ywA2y/SmayW+ZIESTsiyQsxo40xmMS2aUmYbheHpCVd0+UqJGGMsey3mUyldoUvlY3D9rIN0K7Wbe/WbZ+y1yWtaVtrp3VJzAEX6ZVjc2p7b2mtnYhNdl6m05rwtfV/ltx7XypJTpXeO7Y5juOlchzHaWxyrJmuhLapqgIJONv05+srThBgiQpBTSRwGOr3rwccgWHUhJ7P5/YNlbd/2XiL78L/WajP240AQUihfnx84EDJjCHKHjTAbkimQDgBjAJ1/3kHAgEk/gL71AHEWVXPGQAAAABJRU5ErkJggg==);
+    display: none;
   }
-
-  * /deep/ tr-ui-e-chrome-cc-picture-debugger > left-panel {
-    -webkit-flex-direction: column;
-    display: -webkit-flex;
-    min-width: 300px;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-picture-debugger > left-panel > picture-info {
-    -webkit-flex: 0 0 auto;
-    padding-top: 2px;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-picture-debugger > left-panel >
-        picture-info .title {
-    font-weight: bold;
-    margin-left: 5px;
-    margin-right: 5px;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-picture-debugger > tr-ui-b-drag-handle {
-    -webkit-flex: 0 0 auto;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-picture-debugger .filename {
-    -webkit-user-select: text;
-    margin-left: 5px;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-picture-debugger > right-panel {
-    -webkit-flex: 1 1 auto;
-    -webkit-flex-direction: column;
-    display: -webkit-flex;
-  }
-
-  * /deep/ tr-ui-e-chrome-cc-picture-debugger > right-panel >
-        tr-ui-e-chrome-cc-picture-ops-chart-view {
-    min-height: 150px;
-    min-width : 0;
-    overflow-x: auto;
-    overflow-y: hidden;
-  }
-
-  /*************************************************/
-
-  * /deep/ tr-ui-e-chrome-cc-picture-debugger raster-area {
-    background-color: #ddd;
-    min-height: 200px;
-    min-width: 200px;
-    overflow-y: auto;
-    padding-left: 5px;
+  #chrome-right {
+    background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAABICAYAAACaw4eEAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAB3RJTUUH3QcNFyghKmOqnQAADE1JREFUaN6dmsuyZsdRhb/M2uf07bREYDykPeIleAMibNx92i9BgEPBgyB5xlvgtgI8VDNBI41xhGkpQowERgqw3H0ue1cuBlm1T/3Vu4XNiWj9l12XrMyVK1fWL/v6668lCXdHEt/1Z2YnnyUhCTPbX8dn45pmRkR81z7/XUr59Pz8/K8ePnz47/bVV19pnDhu0t+Pmx0Z+Pv8zWv1/eZnZ2dntw8ePPizZXw4bj5/P3vq6G/eePZiX9fd9/Xng6/reg78/dInzxPG9+/auH83GjEbPUahj6m1Hoa6v1/X9c+XPrlP7INqrfuru7+10WzUkUHvOtTojPF1mPdHSzdqPPXo5vm046bdq0fhGr+bvXZk6OgAM2OZBx7hZD7hnCzbtp149Wid0YOjx+eE6t8tMzb659Ebkg5PPY8ZvXpEQWNCzck2M4H3BWeM1Fr31/6+GziPmTefM3tcYzQoIt4a3+cso2EzhsYTzAAdw9M9M3rviPv683dl/Oi9pdZKKeVk4piVRyDu1NI3mCtARFBKeWeGbtt2yHV9HXdnGUMyGjSfZq4K42ajYbPXx836XjO+jsj3rawcFx5dPgK8bzJ6eGbzI8yO3j4yaMToiWF98fl0c4bNSXBEJ/Ozd1HSEY8BLGOIxlONeCqlnHyWtGNoxteRMX38uP44fkyyPnfpp58zqy/s7jsGj0rOEcvPVaMD/sj4I/zWWllmMB/VviOwHumv+dkRGc9EOtOUu6fHZteOGBtDN/+NeJwPNRsxl54RU3PIO4x827a3wNwfdr45kib92WhAf9+fHem1I7FZa31rr+WIr45kzrjZsixvZWHHYcfqXFHGctM9ta7ridcigmVZWNf1DvyllN2wkatmHIxCby7kYzbPOD2qFCN39efrut55rE8YM3I+8VENHPFVa2VZlkOSdXe2bTuhmHdl+W5ox8T8YCbD/l2t9YQqRiNGjx8l1JEamVXKri56doyTuzfGhWd+OyLJjsNRlo+eHaX63Iy8ldnjQn3hbmA/yagGusfG7JwrxZytcxMyjpnH77VyPEEP65iVs5tntp4ldp8zlrG+x8z2Y9L1f91Jy+zeccGZn0Zv9nFHTH500BGbM6HOojMiWEZQf1cN7Aut68qyLCdeGFN+xuRYJ7tXu5fetU9EZCiPOp8xm8bTzLqpe2jkoDnzxjCOa8/VZByzzG7t8gQ4eT+GdO4Be0kZDTgq5kea/0g0RgS+rushNkbg93o6aqeejUeNR/fcUWmaqWLbtn39MdGWGcRHUrcb17E1jhszq3tvxNCsJuaE6VGZMbeMKTrL6LGelVL2k41jx6zuRbknSS9BI7WMdDRTxLi3z+VkDl3/7vb29oS3xhoZESdZOm4whrW/7/NHT83UtNze3u6c1I06Ozs7wdjc7PaQzsV8JNSOp7k97IDvtDPDYTdsvts6Pz8/MXCsm2PD2g/Tm+Vx0bHZHTNvjMyRyh2pajk/P0cIZEAHLLgXQLg5ckDCAFsKCwtIeHHAQGAmSnEkMAyZMBkin4lc3jBEM4a7MZgo7mBGhLD/+M1/qiCqDJflIjICYbknjlEtQEl81cBDYIaUi3aDwoEQ7mABuFMjcHOMQHLMRLSDhhlFQk4+k9IhLggZBREeVLN+NNwNCAhRwjGMimGyPJlA3owyIwiKEltWjTBHNchIGpLleIS5ITNKQHVDYRiBGUQI/83X/0XUyorhm2EKAsvT1IqFgwusgglCWARV3SuGmdNchwgiRHWQagcHIqCNJ7whJ6AI20AeUJ3A0ilP/vQJ33zzDdvNDbWkO91oAwphrah7wVGG1cHMqSHkggiwDJthmAcgjIIVg5rfWc1h2AZ7AgBLpMElMpQCUyOSX/3rr/j+9/+EGoEQTgKxKnDADRROmCiWySJBeILbMCxENVhwBISCnldm4EBEeiQRk1AJs/Y5ER2q7BX03v17SQnumDeXRqXgDaSA1cSdIExQDM+UgtoArTyMIjABJUPt4S2hRHEIgbdstV5LI4OusDvDMgMNqw3sHqi0HPcMotyRNqp5ArnmRrkLuBm4kHmjDAeEDMICk2PFMwomqjI2xYSHsJIUUnxoeBO7rdQUJ2qeJk8SLfdLGtgWCouEVzFUG7NXMAXVG1YqyDdMhSDgFuTpabUEiUguUw3AiAafbhoR4EtmpJknKArgytMaBHBmIozEIQ41M1dK7ySGEvxQ8NoI1w2WFh0XlsUaFYilJ5zhpuGKwBxXeygIqxlrE6Ih1wKPgi8L799/QGcJo4M5o9oYDfcKUZJmEFdX12zrikh2xwwrQA2KOeqETRlCGaKaUFXLpjQwy5Elu4dzflb4uw8/5MXP/wEsE6ORVX8hbVRzTVcN4ic/ec4HH3zA7XaTC1sQtZUXAm98Z7I7uvjii8+5ePw4pUiwu7TXuogM3cX7j/jhX/yIJz948gf/NPjll1/yy1/+E//z299RCGrL+AxI8krQfhk5Ab+6LmrGyDA1dvfkqOvXNzy7fMonn7w8umjafabmsDuowPPnz3nz5joLiN9VCwIqJDGHweixV59/weNHF4itZSMJbGq61kg3h3N2fs7D9x7jIdTwIzw3tCxrZo560U5U8frNFdu6URWJS8RmRukto3smv07uxwJrMa9uLDJCG1ZKI87AWJBvhEOsG9WEhSVcWBtu1A615da2kboiPaRW4hSRcBGEClhg0cTDycWdJR1XgUdkrN2hRqslGapydo+fffgRL37+Ir1opzrrJHZDAiB49vySv/3gp9zcRiqLCpsrjSLrnpQ27KH8/ItXPHz4PtRbRMoTajrBw6Hk4o8vLvjhj/6SH/w/wf/xx//I629/u9fPjkxLIZfVwmLwWBhQqUqgU1NZlCrkQVRwGW9urrl89pRPXr78gw27vHzO9dVVI2cIOYVIGHkrYXVDUQaPvXrFo4tHbFV7dnkjzGT+5BjXwnK/cPHovcRLI9hME3ZeM2+HtRwQAVdXb1ivr6ldzfYC3sSnPFAUZHW+HE7WtqamZL07avrcnYgKKtR6m/VKQTR9n0JQjZj7KqD2LCLY2h4quqsKNUWA5BQPatjAY1hTpuAO2iqlGLV1EQJ8C87vnfOzjz7ixS8+5vf93y+sFeZnl5f89K//htttw1bAW5d05rAK90awjOD//BUPHtynblmInXStyUHJR3jw3sV7/PjpU548eXJArvZ/gv/Fx7/g9bfftug4NfVKa7byd8pN9ZT5I9rFSM/wSPFXrOn5Tby5vubp0x/z8uU/t1Jx5/H9v3b3/q4YGJfPLrl+c0Pde8lgEWxN0znG1jG6e+zfXnHvwQNETdmMINqlSEeZJ1Dvn93j4uJiL+6jv8TQO9L6lya9f/fta26228wodVwZboFU2gLbqbqglZLarzTbdpvBEhWxNJI1bq5uuV6/SRCHt35AyAwPo5aKZzlIHRb5SqTR1nRSnitQtC4phNlyqvlTppRUlmZEQJizhCErbYSa57J8SNkLRm3s7RV54AHymjK9cYjUyg+wqV8XRCtfdzea+IZiFIoSsFKBEm1SE26SpXZCeDh7g9P64R4SrU2ZkC1btea5TMDsqCJ5UfUuZwO1BlnZ6tkgrWWWqjOgqhJmsLWa2dowsKZK0nuKlMWokWWBoBIeiJpZF6CqhtnMdHSHW6PdZLfijjISu2HX11dEjURrTza3BtymzaLV5NZwEGQYW4ekaLdCkXSDRCkidr2n/XKGUlOKjxc6oXZN0H4ZefXrVxQ3atTsjD1lkJpIDNEwlSCRZ53rp4zViNiQtqwEStHT1YoUOaclSY1MmmjXCelNz2Q1T5L/7LPPYDEePXqYNa0ENHnd7xeKKUFiAO2HBM97DZMoS1prMmQLrqCE8uZHIgVDNAFpFEW7BnGKWQtnYJ6GOmL54+99D0JEzfT1alRzikHtda+1/4nsxk/VqQZmlXXzJMUiqFu7nrJMe8v2LhteteuAvEcrVqk1m+Owdn9h7ZYSE6WAIrkjPCVIFua8s0jhWHfhZ5YZZ6rZNxoplZp3clg2uUSKAcmwYpgqUs1iFI5Z4rr3mliq3IVqVDbwM9CGkao1rN1IR6F4xepCEFht1wAhIKjRNH0Dv6ym5lHrEQw8JSlUtapghHJ+qiK13OyZ6yyf/sunSYqyVuPavVVq3bvSgrKxcKVGU7/s1U5ovXz1W5v9ftPVet68cbSehRo65ZNfUuB/AWHLchVUWJtFAAAAAElFTkSuQmCC);
+    display: none;
   }
   </style>
 
+  <div id="header"></div>
+  <input id="stacking-distance-slider" max="400" min="1" step="1" type="range"/>
+  
+  <div id="canvas-scroller">
+    <canvas id="canvas"></canvas>
+  </div>
+  <img id="chrome-left"/>
+  <img id="chrome-mid"/>
+  <img id="chrome-right"/>
+</template><template id="tr-ui-e-chrome-cc-layer-tree-quad-stack-view-template">
+  <style>
+  #input-event {
+    background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMnwAADJ8BPja39wAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAyNSURBVHic7Z1PTCPXHcc/4wWWVbJN2cJSLVqiQJuGpoIGEVWReoBNIlIF5RCRSysOK9EbksUeOHLIIQcULbLEEYk7oqduD6gSRoqUEyK7dCOabOHghCiAE/JntQtesHt4fuM3z2+MZzy2x8ZfaTTjN+Px4/fh9/7Pb6xMJkND4VGk2hloyKkGkJCpASRkagAJmRpAQqYGkJCpASRkaqp2BvzKsizf3w1z38sKc+ZUaQCuAFeB57P7q4AF/Kxsj4GnLrfL+6PDYofQAskCaAJ6gJeB6+QAFOvZpwgwPwOHwCNgN5uu/+H252raJHRALMu6ggDwCtALNAf8E88QUL5AAHqSTVcNUTU4oQBiWVYzMIiA0E3lGhtp4CsEnPtACgFDGqXiYKoKxLKsCPAaMIwojlzV1tZGV1cXHR0ddHR00N7ebh93dHQAcHh4aG/JZNI+3tvb4+jo6LzsPAY+QYA5Ix9KBsoPpmpALMt6BXgTaHe7pre3l5GREUZGRujv7/fdsspkMmxtbRGPx4nH4+zs7BS6/HtgHfgvOW9xeE05bVZxIJZldQNvATf1c5FIhMHBQYaHh7l16xbd3d1lyUMikWBtbY319XU2NzdJp9Omy74B1oAEAoa8yIZTDttVDIhlWZeB94Dfm86Pjo4SjUbLBsFNiUSCWCzG6uqq2yVfAv9CNKHTlNlbKgLEsqxrwF+BX+nnhoaGuHPnDv39/WXPRyFtbW1x9+5dNjY2TKePgBXgOwQUFUyg3lJ2IJZl9QAfAK1qek9PD9PT04yMjJT1970qHo8zPz/P7u6ufuoE+CewQw6Kw2OCsGVZgViW9SdgFNGLBqC1tZWZmRnGx8eJRMI5lJZOp1lZWWFubo7j42P1VAZR4W8gWmJn5KBAAEVYWYBkm7PvIvoWtjo7O1lYWKCvry/w3yyHtre3mZqaYn9/Xz/1EPg3ot+iQslQIpTAgWRh/A0x5GFrYGCAWCxGe7trKzeUSiaTRKNRHjx4oJ/6CvgHoigLDEo5yox30WCMjY2xtLRUczAA2tvbWVpaYmxsTD91E3gbMbTTBFxCFM0WYPntMwXqIdk64x3lM9FolMnJycB+o5paXFwkFovplfcniDrlNLvJXr4vTwnMQ7KtqVE1rZ5gAExOThKNRvXkPyMGQaWXlOQpgQDJ9jM+QGlNjY2N1RUMqcnJSb34shClwnVE8aVCAY9QSi6ysj3wv6N0+gYGBlhaWqKlpaWke4dVqVSK27dv6xX9j8AyYpDyGaL4svsqxdo5CA95DwVGZ2cnsVisbmEAtLS0EIvF6OzsVJNfQIzRlVTJlwQkO1Boj021traysLBQk60pr2pvb2dhYYHWVscAxEuI1pcKJYIHKKV6yFvqh5mZmZrp9AWhvr4+ZmZm9OQ3MAMpSr6BZOcz7CH0np4exsfH/d6uZjU+Pk5Pj6PbdR34LT69xBeQbG/8TTVteno6tGNT5VQkEmF6elpPfh24TK7VFaFIKH4t+BrKTN/Q0FDoRm0rqZGREYaGhtSkXyDqVs9Fl2cg2QUJw2ranTt3vN6m7mSwwR8R68dULzm31eXHQwZRFiSMjo5WfXIpDOrv72d01DFQcQXoQ3hI0V7iB8gr9pcjEdNQwoVVNBrV69EXcanccfEST0Cyi9jsSe/BwcGKz4GHWd3d3QwOOqaAOoDnMFfuRnn1kJfV7wwPD3v8ev1Ls4mF+Ac2FVsW5C8aLxpI9ou/U9Nu3brlOcP1LoNNbuJej+R5ihcPaQJ+Iz/09vY2iiuDuru76e3tVZN+jeiTyFHggsWWFyA9KAufL3K/4zxptrkE3MClYkcDUxQQU3HVAOIug226yHlIXvNXrUe8eEiHPGhra2v0PQqov7+ftrY2NekFzEVWSXWI3Rns6uoq6ZGyepdlWXR1dalJrRTwEFVegFyVB3L5f0Pu0mzUirC1CsPoJcUCuYLyGFkDyPnSbBQhB8VUZNm99nOBZC+8qqZdhBnBUmWw0RXMQHx5iOPpprB5yMbGBp999lm1s+GQwUZXKFBUSRULxOEhYQNy//59Hj58WO1sOOQCpGAfBOoESBhVwENMm61in/cOXRt3f3+f09NTAH766SdaWlrY29sDoLm5mevXr1cze25y9QypYoH8rH44PDwsIU/B6KOPPrLzcXBwQCQS4dNPPwXgxo0bfPzxx9XMnslGJ7h7hkX2GZOaBRKLxezjxcVFLl++zMTERBVz5JTBRseGy3zXIaEDEna5eAgENIX7WP2QTCaL/NrFlcFG0kMKLvIttsh6ilg83ATh85D3338/dGNrmo3SiAXYuvLgeImX9Rj4peHHqq5r165VOwt50mx0gjkqhJT92cvgol2P7O3thSa+VBiVyWTsJnhWsv4wBrZR5QWIjfzo6IitrS0vebxQ2tra0oPdPCbfQ4ze4gXII/VDPB73k9cLIYNtDnACUJ9td8gLkF2UiqkBxF2abc6AJOboD3lQzgWi1BWnCCgA7OzskEgk/Oa5bpVIJPTwT9+RCymoe4jvIkt+8Qs1cW1tzVem61kGm8jiKk1+gIE8eV25+Ihc3CjW19c9fr3+pdkkgwCiwsiL+oDyUKhXIE8QISUA2NzcbBRbihKJBJubm2rSD4h4KLLuOMMQRUiVn9XvdrGVTqcdg3wXXbFYTI9Op3qHuqlQHCoKSNadJNH7KGNbq6urjT4Jou+hRaVLIUoTE4zA6hD5Q5+oCXfv3vVxm/qSwQY7iG6C9BAZByWv6auOevgBIr3ke5mwsbFxofsl8XhcDw34BPgaYXg1KI0p6JlDRQPRiq0zRGQ1W/Pz827RPeta6XSa+fl5Pfl/5LxC3QrCAP9P4WYQcW2/kQm7u7usrKz4vF3tamVlRY/P+CPwLTlvcANiDN/kCYjiJXLv6AXNzc2xvb3t5ZY1re3tbebm5vRk2Vc7JReExgTDqFI8JIMIMvylTDw+PmZqaupCzCgmk0mmpqb0IJkHiLpV9Ypn5MA4oJimMDwD0eqSDCLIsD3WvL+/TzQaJZVKeb11zSiVShGNRvXgmE+Az8kVU8+UrSjvgNKCz8jxmaeIIMNyEoYHDx4wOztbwq3DrdnZWT1W1imi5XmCE0YKlyLLbYLPFxDlZhLKd4ggw/aJe/fusbi46Of2odbi4iL37t1TkzLAfxAzqmc4PcPkIQVVqofIfRrREVpXL4jFYnUFRQbB1PQIMZsqYaSUraiWlaqSQvxlV3rIFd2XEIsm/gL8Qb1ubGyMDz/8sGajzKVSKWZnZ3XPANHs/xxh+BSiyDrObifkirCiiisIDogK5TIwjvY6ijoMpHwEbCJAPCMHQIWhxl4sKmxsEEEwwQmlCQHlbeBV9do6CjX+DbBNDobqHSYYRQfCLDnimKEZfJbN0CpiENLOxf7+PhMTEywvL4d6mCWdTrO8vMzExIQOI4Pod31OPowTzHWHpz80kMjWyqpB6SXSU5oRQYbfARwVSA2+ruIU0ZrSK/ATnEBky8oxqlusnQMLNa4VXRa5Sr4JEYdwDPG8tkM18kKXJ+TmgWQ/Q3qDDsNTJa4r6NjvkA/lEsJTnkdEMX3J9N0Qv/LoAFFEyRaTbFFJGPK4ZBhQntdVgDuUZkTr6w2E1zgUspeC/YjoY3yPczgkZdhk568kGFC+F7qAE4qsU2S90owIpfo6ImCkUVV6bd4TxHzGtzgnmNThEN0rHK0pSngFUtleeeQCRa1XmhHN41eBAcRDka6qwIslU4jRhq/Jn8tQh0HUitttWtb3YvRyv4MKck8MyUeCZRGmeosMGPkiIshNpR72yCCW6hwgFiTI1pE0tDS6abDQ87BIMarEW9rAGUFNNot1MHL/HCIs3k1E8K9LAWfpDDEYepDd5Lopdc5b9Qx9r14nx/EgABhQASCQ109RizAdjApH9vhvIOJNvYCIFyJjhhSjNLlm6WMEgCS5tbbqAjbTlKsKwwTCHmCtmfcY2j/khCL3auwPNXyRGqOwifzQRq2IYk7dwDl8cYwwpjoqrRrSDYYKpdCaqpLrC5Oq8S5c+xCzx+hwTJtbEBdT3aMbUBpVXWvrtsnz+op1CNArVFXlbdEu3mICowJS9+cBsR/Exx2IaQG0af1tHggI1itUVft96vahsi/kOabPxQCRe93IaW3TAVQMhFRVgdiZMIORexOgQiDkXv3DdAObPMYIgAqBkAoFECmtJ+4Gp9Ax2rEORe51w+sQ7OOK17FhAqLKBY567AbBTSY4rsfVsktogagqACfvUpd0tz/SkR4GW9QEEFVBhtAI499ec0DqXf8H8f4X10jf2YAAAAAASUVORK5CYII=);
+    display: none;
+  }
+  </style>
+  <img id="input-event"/>
+</template><template id="tr-ui-e-chrome-cc-picture-debugger-template">
   <left-panel>
     <picture-info>
       <div>
@@ -817,39 +714,36 @@
     </tr-ui-e-chrome-cc-picture-ops-chart-view>
     <raster-area><canvas></canvas></raster-area>
   </right-panel>
-</template><style>
-* /deep/ .tr-ui-e-chrome-cc-picture-snapshot-view{-webkit-flex:0 1 auto!important;display:-webkit-flex}
-</style><polymer-element name="tr-ui-a-sub-view">
-  
-</polymer-element><polymer-element name="tr-ui-a-stack-frame">
+</template><dom-module id="tr-ui-a-stack-frame">
   <template>
     <style>
     :host {
       display: flex;
       flex-direction: row;
       align-items: center;
+      font-size: 12px;
     }
     </style>
     <tr-ui-b-table id="table"></tr-ui-b-table>
   </template>
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-event-sub-view">
+</dom-module><dom-module id="tr-ui-a-single-event-sub-view">
   <template>
     <style>
     :host {
       display: flex;
+      flex: 0 1;
       flex-direction: column;
     }
     #table {
-      flex: 1 1 auto;
+      flex: 0 1 auto;
       align-self: stretch;
+      font-size: 12px;
     }
     </style>
     <tr-ui-b-table id="table">
     </tr-ui-b-table>
   </template>
-  
-</polymer-element><polymer-element name="tr-ui-e-chrome-cc-raster-task-view">
+</dom-module><dom-module id="tr-ui-e-chrome-cc-raster-task-view">
   <template>
     <style>
     :host {
@@ -859,6 +753,9 @@
     #heading {
       flex: 0 0 auto;
     }
+    tr-ui-b-table {
+      font-size: 12px;
+    }
     </style>
 
     <div id="heading">
@@ -867,28 +764,77 @@
     </div>
     <tr-ui-b-table id="content"></tr-ui-b-table>
   </template>
+</dom-module><dom-module id="tr-ui-e-chrome-codesearch">
+  <template>
+    <style>
+      :host {
+        white-space: nowrap;
+      }
+      #codesearchLink {
+        font-size: x-small;
+        margin-left: 20px;
+        text-decoration: none;
+      }
+    </style>
+    <a id="codesearchLink" on-click="onClick" target="_blank">🔍</a>
+  </template>
+</dom-module><style>
+.tr-ui-e-chrome-gpu-state-snapshot-view{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAAZiS0dEAEwATABMYqp3KAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB90JCQsBMCH7ZqYAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAUElEQVRYw+3WwQkAIAiF4Vc0hTO5/wiuURvYIcQOv1cRPhDlDXffSsrMsrYiQi/zU80FAACAVX3nt3lWAABA/x+ovnPyAAAA5AHyAAAA3wMOd34Xd+lsglgAAAAASUVORK5CYII=);display:flex;overflow:auto}.tr-ui-e-chrome-gpu-state-snapshot-view img{display:block;margin:16px auto 16px auto}
+</style><dom-module id="tr-ui-a-layout-tree-sub-view">
+  <template>
+    <style>
+    tr-ui-b-table {
+      font-size: 12px;
+    }
+    </style>
+    <div id="content"></div>
+  </template>
+</dom-module><dom-module id="tr-ui-e-s-frame-data-side-panel">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      width: 600px;
+      flex-direction: column;
+    }
+    table-container {
+      display: flex;
+      overflow: auto;
+      font-size: 12px;
+    }
+    </style>
+    <div>
+      Organize by:
+      <select id="select">
+        <option value="none">None</option>
+        <option value="tree">Frame Tree</option>
+      </select>
+    </div>
+    <table-container>
+      <tr-ui-b-table id="table"></tr-ui-b-table>
+    </table-container>
+  </template>
+</dom-module><dom-module id="tr-ui-b-chart-legend-key">
+  <template>
+    <style>
+      #checkbox {
+        margin: 0;
+        visibility: hidden;
+        vertical-align: text-top;
+      }
+      #label, #link {
+        white-space: nowrap;
+        text-overflow: ellipsis;
+        overflow: hidden;
+        display: inline-block;
+      }
+    </style>
 
-  
-</polymer-element><style>
-.tr-ui-e-chrome-gpu-state-snapshot-view{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAAZiS0dEAEwATABMYqp3KAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB90JCQsBMCH7ZqYAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAUElEQVRYw+3WwQkAIAiF4Vc0hTO5/wiuURvYIcQOv1cRPhDlDXffSsrMsrYiQi/zU80FAACAVX3nt3lWAABA/x+ovnPyAAAA5AHyAAAA3wMOd34Xd+lsglgAAAAASUVORK5CYII=);display:-webkit-flex;overflow:auto}.tr-ui-e-chrome-gpu-state-snapshot-view img{display:block;margin:16px auto 16px auto}
-</style><style>
-  * /deep/ .chart-base #title {
-    font-size: 16pt;
-  }
-
-  * /deep/ .chart-base {
-    font-size: 12pt;
-    -webkit-user-select: none;
-    cursor: default;
-  }
-
-  * /deep/ .chart-base .axis path,
-  * /deep/ .chart-base .axis line {
-    fill: none;
-    shape-rendering: crispEdges;
-    stroke: #000;
-  }
-</style><template id="chart-base-template">
+    <input checked="" id="checkbox" type="checkbox"/>
+    <tr-ui-a-analysis-link id="link"></tr-ui-a-analysis-link>
+    <label id="label"></label>
+  </template>
+</dom-module><template id="chart-base-template">
   <svg> 
     <g id="chart-area" xmlns="http://www.w3.org/2000/svg">
       <g class="x axis"></g>
@@ -896,19 +842,7 @@
       <text id="title"></text>
     </g>
   </svg>
-</template><style>
-  * /deep/ .chart-base-2d.updating-brushing-state #brushes > * {
-    fill: rgb(103, 199, 165)
-  }
-
-  * /deep/ .chart-base-2d #brushes {
-    fill: rgb(213, 236, 229)
-  }
-</style><style>
-* /deep/ .line-chart .line{fill:none;stroke-width:1.5px}* /deep/ .line-chart #brushes>rect{fill:rgb(192,192,192)}
-</style><polymer-element name="tr-ui-side-panel">
-  
-</polymer-element><polymer-element extends="tr-ui-side-panel" name="tr-ui-e-s-input-latency-side-panel">
+</template><dom-module id="tr-ui-e-s-input-latency-side-panel">
   <template>
     <style>
     :host {
@@ -931,38 +865,7 @@
     <toolbar id="toolbar"></toolbar>
     <result-area id="result_area"></result-area>
   </template>
-
-  
-</polymer-element><style>
-* /deep/ .pie-chart .arc-text{font-size:8pt}* /deep/ .pie-chart .label{font-size:10pt}* /deep/ .pie-chart polyline{fill:none;stroke:black}
-</style><polymer-element extends="tr-ui-side-panel" name="tr-ui-e-s-time-summary-side-panel">
-  <template>
-    <style>
-    :host {
-      flex-direction: column;
-      display: flex;
-    }
-    toolbar {
-      flex: 0 0 auto;
-      border-bottom: 1px solid black;
-      display: flex;
-    }
-    result-area {
-      flex: 1 1 auto;
-      display: block;
-      min-height: 0;
-      overflow-y: auto;
-    }
-    </style>
-
-    <toolbar id="toolbar"></toolbar>
-    <result-area id="result_area"></result-area>
-  </template>
-
-  
-</polymer-element><style>
-.tr-ui-e-system-stats-snapshot-view .subhead{font-size:small;padding-bottom:10px}.tr-ui-e-system-stats-snapshot-view ul{background-position:0 5px;background-repeat:no-repeat;cursor:pointer;font-family:monospace;list-style:none;margin:0;padding-left:15px}.tr-ui-e-system-stats-snapshot-view li{background-position:0 5px;background-repeat:no-repeat;cursor:pointer;list-style:none;margin:0;padding-left:15px}
-</style><polymer-element name="tr-ui-heading">
+</dom-module><dom-module id="tr-ui-b-heading">
   <template>
     <style>
     :host {
@@ -983,7 +886,7 @@
     }
 
     #arrow {
-      -webkit-flex: 0 0 auto;
+      flex: 0 0 auto;
       font-family: sans-serif;
       margin-left: 5px;
       margin-right: 5px;
@@ -994,21 +897,132 @@
       display: none;
     }
     </style>
-    <heading id="heading" on-click="{{onHeadingDivClicked_}}">
+    <heading id="heading" on-click="onHeadingDivClicked_">
       <span id="arrow"></span>
       <span id="heading_content"></span>
       <tr-ui-a-analysis-link id="link"></tr-ui-a-analysis-link>
     </heading>
   </template>
-
-  
-</polymer-element><style>
+</dom-module><style>
 .track-button{background-color:rgba(255,255,255,0.5);border:1px solid rgba(0,0,0,0.1);color:rgba(0,0,0,0.2);font-size:10px;height:12px;text-align:center;width:12px}.track-button:hover{background-color:rgba(255,255,255,1.0);border:1px solid rgba(0,0,0,0.5);box-shadow:0 0 .05em rgba(0,0,0,0.4);color:rgba(0,0,0,1)}.track-close-button{left:2px;position:absolute;top:2px}.track-collapse-button{left:3px;position:absolute;top:2px}
 </style><style>
 .object-instance-track{height:18px}
 </style><style>
 .tr-ui-e-system-stats-instance-track{height:500px}.tr-ui-e-system-stats-instance-track ul{list-style:none;list-style-position:outside;margin:0;overflow:hidden}
-</style><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-alert-sub-view">
+</style><style>
+.tr-ui-e-system-stats-snapshot-view .subhead{font-size:small;padding-bottom:10px}.tr-ui-e-system-stats-snapshot-view ul{background-position:0 5px;background-repeat:no-repeat;cursor:pointer;font-family:monospace;list-style:none;margin:0;padding-left:15px}.tr-ui-e-system-stats-snapshot-view li{background-position:0 5px;background-repeat:no-repeat;cursor:pointer;list-style:none;margin:0;padding-left:15px}
+</style><dom-module id="tr-ui-e-v8-gc-objects-stats-table">
+  <template>
+    <style>
+    tr-ui-b-table {
+      flex: 0 0 auto;
+      align-self: stretch;
+      margin-top: 1em;
+      font-size: 12px;
+    }
+    .diff {
+      display: inline-block;
+      margin-top: 1em;
+      margin-left: 0.8em;
+    }
+    </style>
+    <div class="diff" id="diffOption">
+      Diff
+    </div>
+    <tr-ui-b-table id="diffTable"></tr-ui-b-table>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+</dom-module><dom-module id="tr-ui-e-multi-v8-gc-stats-thread-slice-sub-view">
+  <template>
+    <style>
+    </style>
+    <tr-ui-e-v8-gc-objects-stats-table id="gcObjectsStats">
+    </tr-ui-e-v8-gc-objects-stats-table>
+  </template>
+</dom-module><dom-module id="tr-ui-e-v8-ic-stats-table">
+  <template>
+    <style>
+    tr-ui-b-table {
+      flex: 0 0 auto;
+      align-self: stretch;
+      margin-top: 1em;
+      font-size: 12px;
+    }
+    #total {
+      margin-top: 1em;
+      margin-left: 0.8em;
+    }
+    #groupOption {
+      display: inline-block;
+      margin-top: 1em;
+      margin-left: 0.8em;
+    }
+    </style>
+    <div style="padding-right: 200px">
+      <div style="float:right;  border-style: solid; border-width: 1px; padding:20px">
+        X no feedback<br/>
+        0 uninitialized<br/>
+        . premonomorphic<br/>
+        1 monomorphic<br/>
+        ^ recompute handler<br/>
+        P polymorphic<br/>
+        N megamorphic<br/>
+        G generic
+      </div>
+    </div>
+    <div id="total">
+    </div>
+    <div id="groupOption">
+      Group Key
+    </div>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+</dom-module><dom-module id="tr-ui-e-multi-v8-ic-stats-thread-slice-sub-view">
+  <template>
+    <tr-ui-e-v8-ic-stats-table id="table">
+    </tr-ui-e-v8-ic-stats-table>
+  </template>
+</dom-module><dom-module id="tr-ui-e-v8-runtime-call-stats-table">
+  <template>
+    <style>
+    #table, #blink_rcs_table {
+      flex: 0 0 auto;
+      align-self: stretch;
+      margin-top: 1em;
+      font-size: 12px;
+    }
+
+    #v8_rcs_heading, #blink_rcs_heading {
+        padding-top: 1em;
+        font-size: 18px;
+    }
+    </style>
+    <h1 id="v8_rcs_heading"></h1>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+    <h1 id="blink_rcs_heading"></h1>
+    <tr-ui-b-table id="blink_rcs_table"></tr-ui-b-table>
+  </template>
+</dom-module><dom-module id="tr-ui-e-multi-v8-thread-slice-sub-view">
+  <template>
+    <tr-ui-a-multi-thread-slice-sub-view id="content"></tr-ui-a-multi-thread-slice-sub-view>
+    <tr-ui-e-v8-runtime-call-stats-table id="runtimeCallStats"></tr-ui-e-v8-runtime-call-stats-table>
+  </template>
+</dom-module><dom-module id="tr-ui-e-single-v8-gc-stats-thread-slice-sub-view">
+  <template>
+    <tr-ui-a-single-event-sub-view id="content"></tr-ui-a-single-event-sub-view>
+    <tr-ui-e-v8-gc-objects-stats-table id="gcObjectsStats"></tr-ui-e-v8-gc-objects-stats-table>
+  </template>
+</dom-module><dom-module id="tr-ui-e-single-v8-ic-stats-thread-slice-sub-view">
+  <template>
+    <tr-ui-e-v8-ic-stats-table id="table">
+    </tr-ui-e-v8-ic-stats-table>
+  </template>
+</dom-module><dom-module id="tr-ui-e-single-v8-thread-slice-sub-view">
+  <template>
+    <tr-ui-a-single-thread-slice-sub-view id="content"></tr-ui-a-single-thread-slice-sub-view>
+    <tr-ui-e-v8-runtime-call-stats-table id="runtimeCallStats"></tr-ui-e-v8-runtime-call-stats-table>
+  </template>
+</dom-module><dom-module id="tr-ui-a-alert-sub-view">
   <template>
     <style>
     :host {
@@ -1018,15 +1032,117 @@
     #table {
       flex: 1 1 auto;
       align-self: stretch;
+      font-size: 12px;
     }
     </style>
     <tr-ui-b-table id="table">
     </tr-ui-b-table>
   </template>
-  
-</polymer-element><polymer-element name="tr-ui-a-stacked-pane">
-  
-</polymer-element><polymer-element extends="tr-ui-a-stacked-pane" name="tr-ui-a-memory-dump-heap-details-pane">
+</dom-module><dom-module id="tr-ui-b-tab-view">
+  <template>
+    <style>
+      :host {
+        display: flex;
+        flex-direction: column;
+      }
+
+      #selection_description, #tabs {
+        font-size: 12px;
+      }
+
+      #selection_description {
+        display: inline-block;
+        font-weight: bold;
+        margin: 9px 0px 4px 20px;
+      }
+
+      #tabs {
+        flex: 0 0 auto;
+        border-top: 1px solid #8e8e8e;
+        border-bottom: 1px solid #8e8e8e;
+        background-color: #ececec;
+        overflow: hidden;
+        margin: 0;
+      }
+
+      #tabs input[type=radio] {
+        display: none;
+      }
+
+      #tabs tab label {
+        cursor: pointer;
+        display: inline-block;
+        border: 1px solid #ececec;
+        margin: 5px 0px 0px 15px;
+        padding: 3px 10px 3px 10px;
+      }
+
+      #tabs tab label span {
+        font-weight: bold;
+      }
+
+      #tabs:focus input[type=radio]:checked ~ label {
+        outline: dotted 1px #8e8e8e;
+        outline-offset: -2px;
+      }
+
+      #tabs input[type=radio]:checked ~ label {
+        background-color: white;
+        border: 1px solid #8e8e8e;
+        border-bottom: 1px solid white;
+      }
+
+      #subView {
+        flex: 1 1 auto;
+        min-width: 0;
+        display: flex;
+      }
+
+      #subView > * {
+        flex: 1 1 auto;
+        min-width: 0;
+      }
+    </style>
+    <div hidden="[[tabsHidden]]" id="tabs">
+      <label id="selection_description">[[label_]]</label>
+      <template is="dom-repeat" items="[[subViews_]]">
+        <tab>
+          <input checked="[[isChecked_(item)]]" id$="[[computeRadioId_(item)]]" name="tabs" on-change="onTabChanged_" type="radio"/>
+          <label for$="[[computeRadioId_(item)]]">
+            <template if="[[item.tabIcon]]" is="dom-if">
+              <span style$="[[item.tabIcon.style]]">[[item.tabIcon.text]]</span>
+            </template>
+            [[item.tabLabel]]
+          </label>
+        </tab>
+      </template>
+    </div>
+    <div id="subView"></div>
+    <slot>
+    </slot>
+  </template>
+</dom-module><dom-module id="tr-ui-a-memory-dump-heap-details-breakdown-view">
+  <template>
+    <tr-ui-b-tab-view id="tabs"></tr-ui-b-tab-view>
+  </template>
+</dom-module><dom-module id="tr-ui-a-memory-dump-heap-details-breakdown-view-tab">
+  <template>
+    <tr-v-ui-scalar-context-controller></tr-v-ui-scalar-context-controller>
+    <tr-ui-b-info-bar hidden="" id="info"></tr-ui-b-info-bar>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+</dom-module><dom-module id="tr-ui-a-memory-dump-heap-details-path-view">
+  <template>
+    <style>
+      :host {
+        display: flex;
+        flex-direction: column;
+      }
+    </style>
+    <tr-v-ui-scalar-context-controller></tr-v-ui-scalar-context-controller>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+</dom-module><dom-module id="tr-ui-a-memory-dump-heap-details-pane">
   <template>
     <style>
       :host {
@@ -1048,7 +1164,7 @@
       #label {
         flex: 1 1 auto;
         padding: 8px;
-        font-size:  15px;
+        font-size: 15px;
         font-weight: bold;
       }
 
@@ -1072,10 +1188,24 @@
         text-align: center;
       }
 
-      #table {
+      #split_view {
         display: none;  /* Hide until memory allocator dumps are set. */
         flex: 1 0 auto;
         align-self: stretch;
+        flex-direction: row;
+      }
+
+      #path_view {
+        width: 50%;
+      }
+
+      #breakdown_view {
+        flex: 1 1 auto;
+        width: 0;
+      }
+
+      #path_view, #breakdown_view {
+        overflow-x: auto;  /* Show scrollbar if necessary. */
       }
     </style>
     <div id="header">
@@ -1086,13 +1216,21 @@
       </div>
     </div>
     <div id="contents">
-      <tr-ui-b-info-bar class="info-bar-hidden" id="info_bar">
+      <tr-ui-b-info-bar hidden="" id="info_bar">
       </tr-ui-b-info-bar>
+
       <div id="info_text">No heap dump selected</div>
-      <tr-ui-b-table id="table"></tr-ui-b-table>
+
+      <div id="split_view">
+        <tr-ui-a-memory-dump-heap-details-path-view id="path_view">
+        </tr-ui-a-memory-dump-heap-details-path-view>
+        <tr-ui-b-drag-handle id="drag_handle"></tr-ui-b-drag-handle>
+        <tr-ui-a-memory-dump-heap-details-breakdown-view id="breakdown_view">
+        </tr-ui-a-memory-dump-heap-details-breakdown-view>
+      </div>
     </div>
   </template>
-</polymer-element><polymer-element extends="tr-ui-a-stacked-pane" name="tr-ui-a-memory-dump-allocator-details-pane">
+</dom-module><dom-module id="tr-ui-a-memory-dump-allocator-details-pane">
   <template>
     <style>
       :host {
@@ -1129,6 +1267,7 @@
         display: none;  /* Hide until memory allocator dumps are set. */
         flex: 1 0 auto;
         align-self: stretch;
+        font-size: 12px;
       }
     </style>
     <div id="label">Component details</div>
@@ -1137,7 +1276,7 @@
       <tr-ui-b-table id="table"></tr-ui-b-table>
     </div>
   </template>
-</polymer-element><polymer-element extends="tr-ui-a-stacked-pane" name="tr-ui-a-memory-dump-vm-regions-details-pane">
+</dom-module><dom-module id="tr-ui-a-memory-dump-vm-regions-details-pane">
   <template>
     <style>
       :host {
@@ -1174,6 +1313,7 @@
         display: none;  /* Hide until memory dumps are set. */
         flex: 1 0 auto;
         align-self: stretch;
+        font-size: 12px;
       }
     </style>
     <div id="label">Memory maps</div>
@@ -1182,7 +1322,7 @@
       <tr-ui-b-table id="table"></tr-ui-b-table>
     </div>
   </template>
-</polymer-element><polymer-element name="tr-ui-b-color-legend">
+</dom-module><dom-module id="tr-ui-b-color-legend">
   <template>
     <style>
     :host {
@@ -1197,10 +1337,9 @@
     <span id="square"></span>
     <span id="label"></span>
   </template>
-  
-</polymer-element><polymer-element name="tr-ui-b-view-specific-brushing-state">
-  
-</polymer-element><polymer-element extends="tr-ui-a-stacked-pane" name="tr-ui-a-memory-dump-overview-pane">
+</dom-module><dom-module id="tr-ui-b-view-specific-brushing-state">
+  <template></template>
+</dom-module><dom-module id="tr-ui-a-memory-dump-overview-pane">
   <template>
     <style>
       :host {
@@ -1220,10 +1359,16 @@
         font-weight: bold;
       }
 
+      #label a {
+        font-weight: normal;
+        float: right;
+      }
+
       #contents {
         flex: 1 0 auto;
         align-self: stretch;
         font-size: 12px;
+        overflow: auto;
       }
 
       #info_text {
@@ -1237,17 +1382,18 @@
         display: none;  /* Hide until memory dumps are set. */
         flex: 1 0 auto;
         align-self: stretch;
+        font-size: 12px;
       }
     </style>
     <tr-ui-b-view-specific-brushing-state id="state" view-id="analysis.memory_dump_overview_pane">
     </tr-ui-b-view-specific-brushing-state>
-    <div id="label">Overview</div>
+    <div id="label">Overview <a href="https://chromium.googlesource.com/chromium/src/+/master/docs/memory-infra">Help</a></div>
     <div id="contents">
       <div id="info_text">No memory memory dumps selected</div>
       <tr-ui-b-table id="table"></tr-ui-b-table>
     </div>
   </template>
-</polymer-element><polymer-element extends="tr-ui-a-stacked-pane" name="tr-ui-a-memory-dump-header-pane">
+</dom-module><dom-module id="tr-ui-a-memory-dump-header-pane">
   <template>
     <style>
       :host {
@@ -1280,7 +1426,7 @@
       
     </div>
   </template>
-</polymer-element><polymer-element name="tr-ui-a-stacked-pane-view">
+</dom-module><dom-module id="tr-ui-a-stacked-pane-view">
   <template>
     <style>
     :host {
@@ -1295,26 +1441,29 @@
     <div id="pane_container">
     </div>
   </template>
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-container-memory-dump-sub-view">
+</dom-module><dom-module id="tr-ui-a-container-memory-dump-sub-view">
   <template>
+    <style>
+    tr-ui-b-table {
+      font-size: 12px;
+    }
+    </style>
     <div id="content"></div>
   </template>
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-counter-sample-sub-view">
+</dom-module><dom-module id="tr-ui-a-counter-sample-sub-view">
   <template>
     <style>
     :host {
       display: flex;
       flex-direction: column;
     }
+    tr-ui-b-table {
+      font-size: 12px;
+    }
     </style>
     <tr-ui-b-table id="table"></tr-ui-b-table>
   </template>
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-layout-tree-sub-view">
-  <template>
-    <div id="content"></div>
-  </template>
-</polymer-element><polymer-element name="tr-ui-a-selection-summary-table">
+</dom-module><dom-module id="tr-ui-a-multi-event-summary-table">
   <template>
     <style>
     :host {
@@ -1323,14 +1472,14 @@
     #table {
       flex: 1 1 auto;
       align-self: stretch;
+      font-size: 12px;
     }
     </style>
     <tr-ui-b-table id="table">
     </tr-ui-b-table>
     
   </template>
-  
-</polymer-element><polymer-element name="tr-ui-a-multi-event-summary-table">
+</dom-module><dom-module id="tr-ui-a-selection-summary-table">
   <template>
     <style>
     :host {
@@ -1339,41 +1488,136 @@
     #table {
       flex: 1 1 auto;
       align-self: stretch;
+      font-size: 12px;
     }
     </style>
     <tr-ui-b-table id="table">
     </tr-ui-b-table>
     
   </template>
-  
-</polymer-element><polymer-element name="tr-ui-a-multi-event-details-table">
+</dom-module><dom-module id="tr-ui-b-radio-picker">
+  <template>
+    <style>
+    :host([vertical]) #container {
+      flex-direction: column;
+    }
+    :host(:not[vertical]) #container {
+      flex-direction: row;
+    }
+    #container {
+      display: flex;
+    }
+    #container > div {
+      padding-left: 1em;
+      padding-bottom: 0.5em;
+    }
+    </style>
+    <div id="container"></div>
+  </template>
+</dom-module><dom-module id="tr-v-ui-breakdown-span">
   <template>
     <style>
     :host {
       display: flex;
       flex-direction: column;
     }
+    #table_container {
+      display: flex;
+      flex: 0 0 auto;
+    }
     #table {
-      flex: 1 1 auto;
-      align-self: stretch;
-    }
-
-    #titletable {
-      font-weight: bold;
-    }
-
-    #title-info {
-      font-size: 12px;
+      max-height: 150px;
+      overflow-y: auto;
     }
     </style>
-    <tr-ui-b-table id="titletable">
-    </tr-ui-b-table>
-    <tr-ui-b-table id="table">
-    </tr-ui-b-table>
-  </template>
 
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-event-sub-view">
+    <div id="empty">(empty)</div>
+    <div id="table_container">
+      <div id="container"></div>
+      <span>
+        <tr-ui-b-table id="table"></tr-ui-b-table>
+      </span>
+    </div>
+  </template>
+</dom-module><dom-module id="tr-v-ui-collected-related-event-set-span">
+</dom-module><dom-module id="tr-v-ui-date-range-span">
+  <template>
+    <content></content>
+  </template>
+</dom-module><dom-module id="tr-v-ui-generic-set-span">
+  <template>
+    <style>
+      a {
+        display: block;
+      }
+    </style>
+
+    <tr-ui-a-generic-object-view id="generic"></tr-ui-a-generic-object-view>
+
+    <div id="links"></div>
+  </template>
+</dom-module><dom-module id="tr-v-ui-related-event-set-span">
+</dom-module><dom-module id="tr-v-ui-scalar-diagnostic-span">
+  <template>
+    <tr-v-ui-scalar-span id="scalar"></tr-v-ui-scalar-span>
+  </template>
+</dom-module><dom-module id="tr-v-ui-unmergeable-diagnostic-set-span">
+</dom-module><dom-module id="tr-v-ui-diagnostic-map-table">
+  <template>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+</dom-module><dom-module id="tr-v-ui-scalar-map-table">
+  <template>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+</dom-module><dom-module id="tr-v-ui-histogram-span">
+  <template>
+    <style>
+    #container {
+      display: flex;
+      flex-direction: row;
+      justify-content: space-between;
+    }
+    #chart {
+      flex-grow: 1;
+      display: none;
+    }
+    #drag_handle, #diagnostics_tab_templates {
+      display: none;
+    }
+    #chart svg {
+      display: block;
+    }
+    #stats_container {
+      overflow-y: auto;
+    }
+    </style>
+
+    <div id="container">
+      <div id="chart"></div>
+      <div id="stats_container">
+        <tr-v-ui-scalar-map-table id="stats"></tr-v-ui-scalar-map-table>
+      </div>
+    </div>
+    <tr-ui-b-drag-handle id="drag_handle"></tr-ui-b-drag-handle>
+
+    <tr-ui-b-tab-view id="diagnostics"></tr-ui-b-tab-view>
+
+    <div id="diagnostics_tab_templates">
+      <tr-v-ui-diagnostic-map-table id="metric_diagnostics"></tr-v-ui-diagnostic-map-table>
+
+      <tr-v-ui-diagnostic-map-table id="metadata_diagnostics"></tr-v-ui-diagnostic-map-table>
+
+      <div id="sample_diagnostics_container">
+        <div id="merge_sample_diagnostics_container">
+          <input checked="" id="merge_sample_diagnostics" on-change="updateDiagnostics_" type="checkbox"/>
+          <label for="merge_sample_diagnostics">Merge Sample Diagnostics</label>
+        </div>
+        <tr-v-ui-diagnostic-map-table id="sample_diagnostics"></tr-v-ui-diagnostic-map-table>
+      </div>
+    </div>
+  </template>
+</dom-module><dom-module id="tr-ui-a-multi-event-sub-view">
   <template>
     <style>
     :host {
@@ -1390,6 +1634,10 @@
       flex: 0 0 auto;
       align-self: stretch;
     }
+    #histogramContainer {
+      display: flex;
+    }
+
     tr-ui-a-multi-event-summary-table {
       border-bottom: 1px solid #aaa;
     }
@@ -1403,10 +1651,20 @@
       border-bottom: 1px solid #aaa;
     }
     </style>
-    <div id="content"></div>
+    <div id="content">
+      <tr-ui-a-multi-event-summary-table id="eventSummaryTable">
+      </tr-ui-a-multi-event-summary-table>
+      <tr-ui-a-selection-summary-table id="selectionSummaryTable">
+      </tr-ui-a-selection-summary-table>
+      <tr-ui-b-radio-picker id="radioPicker">
+      </tr-ui-b-radio-picker>
+      <div id="histogramContainer">
+        <tr-v-ui-histogram-span id="histogramSpan">
+        </tr-v-ui-histogram-span>
+      </div>
+    </div>
   </template>
-  
-</polymer-element><polymer-element name="tr-ui-a-related-events">
+</dom-module><dom-module id="tr-ui-a-related-events">
   <template>
     <style>
     :host {
@@ -1416,13 +1674,12 @@
     #table {
       flex: 1 1 auto;
       align-self: stretch;
+      font-size: 12px;
     }
     </style>
     <tr-ui-b-table id="table"></tr-ui-b-table>
   </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-async-slice-sub-view">
+</dom-module><dom-module id="tr-ui-a-multi-async-slice-sub-view">
   <template>
     <style>
     :host {
@@ -1444,9 +1701,7 @@
       </div>
     </div>
   </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-cpu-slice-sub-view">
+</dom-module><dom-module id="tr-ui-a-multi-cpu-slice-sub-view">
   <template>
     <style>
     :host {
@@ -1458,9 +1713,7 @@
     </style>
     <tr-ui-a-multi-event-sub-view id="content"></tr-ui-a-multi-event-sub-view>
   </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-flow-event-sub-view">
+</dom-module><dom-module id="tr-ui-a-multi-flow-event-sub-view">
   <template>
     <style>
     :host {
@@ -1469,11 +1722,7 @@
     </style>
     <tr-ui-a-multi-event-sub-view id="content"></tr-ui-a-multi-event-sub-view>
   </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-frame-sub-view">
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-instant-event-sub-view">
+</dom-module><dom-module id="tr-ui-a-multi-instant-event-sub-view">
   <template>
     <style>
     :host {
@@ -1482,37 +1731,30 @@
     </style>
     <div id="content"></div>
   </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-object-sub-view">
+</dom-module><dom-module id="tr-ui-a-multi-object-sub-view">
   <template>
     <style>
     :host {
       display: flex;
+      font-size: 12px;
     }
     </style>
     <tr-ui-b-table id="content"></tr-ui-b-table>
   </template>
-  
-</polymer-element><polymer-element name="tr-ui-a-frame-power-usage-chart">
+</dom-module><dom-module id="tr-ui-a-frame-power-usage-chart">
   <template>
     <div id="content"></div>
   </template>
-</polymer-element><polymer-element name="tr-ui-a-power-sample-summary-table">
-  <template>
-    <tr-ui-b-table id="table"></tr-ui-b-table>
-  </template>
-  
-</polymer-element><polymer-element name="tr-ui-a-power-sample-table">
+</dom-module><dom-module id="tr-ui-a-power-sample-summary-table">
   <template>
     <style>
-    :host {
-      display: flex;
+    tr-ui-b-table {
+      font-size: 12px;
     }
     </style>
     <tr-ui-b-table id="table"></tr-ui-b-table>
   </template>
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-power-sample-sub-view">
+</dom-module><dom-module id="tr-ui-a-multi-power-sample-sub-view">
   <template>
     <style>
     :host {
@@ -1531,13 +1773,11 @@
     <div id="tables">
       <tr-ui-a-power-sample-summary-table id="summaryTable">
       </tr-ui-a-power-sample-summary-table>
-      <tr-ui-a-power-sample-table id="samplesTable">
-      </tr-ui-a-power-sample-table>
     </div>
     <tr-ui-a-frame-power-usage-chart id="chart">
     </tr-ui-a-frame-power-usage-chart>
   </template>
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-sample-sub-view">
+</dom-module><dom-module id="tr-ui-a-multi-sample-sub-view">
   <template>
     <style>
     :host { display: block; }
@@ -1557,6 +1797,9 @@
       margin: 1px;
       margin-right: 2px;
     }
+    tr-ui-b-table {
+      font-size: 12px;
+    }
     </style>
     <div id="control">
       Sample View Option
@@ -1564,9 +1807,7 @@
     <tr-ui-b-table id="table">
     </tr-ui-b-table>
   </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-thread-slice-sub-view">
+</dom-module><dom-module id="tr-ui-a-multi-thread-slice-sub-view">
   <template>
     <style>
     :host {
@@ -1575,6 +1816,7 @@
     #content {
       display: flex;
       flex: 1 1 auto;
+      min-width: 0;
     }
     #content > tr-ui-a-related-events {
       margin-left: 8px;
@@ -1583,9 +1825,7 @@
     </style>
     <div id="content"></div>
   </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-thread-time-slice-sub-view">
+</dom-module><dom-module id="tr-ui-a-multi-thread-time-slice-sub-view">
   <template>
     <style>
     :host {
@@ -1593,15 +1833,40 @@
     }
     #content {
       flex: 1 1 auto;
+      min-width: 0;
     }
     </style>
     <tr-ui-a-multi-event-sub-view id="content"></tr-ui-a-multi-event-sub-view>
   </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-user-expectation-sub-view">
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-async-slice-sub-view">
+</dom-module><dom-module id="tr-ui-a-user-expectation-related-samples-table">
+  <template>
+    <style>
+    #table {
+      flex: 1 1 auto;
+      align-self: stretch;
+      font-size: 12px;
+    }
+    </style>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+</dom-module><dom-module id="tr-ui-a-multi-user-expectation-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex: 1 1 auto;
+    }
+    #events {
+      margin-left: 8px;
+      flex: 0 1 200px;
+    }
+    </style>
+    <tr-ui-a-multi-event-sub-view id="realView"></tr-ui-a-multi-event-sub-view>
+    <div id="events">
+      <tr-ui-a-user-expectation-related-samples-table id="relatedSamples"></tr-ui-a-user-expectation-related-samples-table>
+    </div>
+  </template>
+</dom-module><dom-module id="tr-ui-a-single-async-slice-sub-view">
   <template>
     <style>
     :host {
@@ -1618,9 +1883,7 @@
       <tr-ui-a-related-events id="relatedEvents"></tr-ui-a-related-events>
     </div>
   </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-cpu-slice-sub-view">
+</dom-module><dom-module id="tr-ui-a-single-cpu-slice-sub-view">
   <template>
     <style>
     table {
@@ -1685,11 +1948,17 @@
       </tr>
     </tbody></table>
   </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-single-event-sub-view" name="tr-ui-a-single-flow-event-sub-view">
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-frame-sub-view">
+</dom-module><dom-module id="tr-ui-a-single-flow-event-sub-view">
+  <template>
+    <style>
+    :host {
+      display: block;
+    }
+    </style>
+    <tr-ui-a-single-event-sub-view id="singleEventSubView">
+    </tr-ui-a-single-event-sub-view>
+  </template>
+</dom-module><dom-module id="tr-ui-a-single-frame-sub-view">
   <template>
     <style>
     :host {
@@ -1704,8 +1973,7 @@
     <tr-ui-a-alert-sub-view id="asv">
     </tr-ui-a-alert-sub-view>
   </template>
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-instant-event-sub-view">
+</dom-module><dom-module id="tr-ui-a-single-instant-event-sub-view">
   <template>
     <style>
     :host {
@@ -1714,9 +1982,7 @@
     </style>
     <div id="content"></div>
   </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-object-instance-sub-view">
+</dom-module><dom-module id="tr-ui-a-single-object-instance-sub-view">
   <template>
     <style>
     :host {
@@ -1749,8 +2015,7 @@
     </style>
     <div id="content"></div>
   </template>
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-object-snapshot-sub-view">
+</dom-module><dom-module id="tr-ui-a-single-object-snapshot-sub-view">
   <template>
     <style>
     #args {
@@ -1777,10 +2042,19 @@
       vertical-align: top;
     }
     </style>
-    <content></content>
+    <slot></slot>
   </template>
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-power-sample-sub-view">
+</dom-module><dom-module id="tr-ui-a-power-sample-table">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      font-size: 12px;
+    }
+    </style>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+</dom-module><dom-module id="tr-ui-a-single-power-sample-sub-view">
   <template>
     <style>
     :host { display: block; }
@@ -1788,19 +2062,17 @@
     <tr-ui-a-power-sample-table id="samplesTable">
     </tr-ui-a-power-sample-table>
   </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-sample-sub-view">
+</dom-module><dom-module id="tr-ui-a-single-sample-sub-view">
   <template>
     <style>
     :host {
       display: flex;
+      font-size: 12px;
     }
     </style>
     <tr-ui-b-table id="content"></tr-ui-b-table>
   </template>
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-thread-slice-sub-view">
+</dom-module><dom-module id="tr-ui-a-single-thread-slice-sub-view">
   <template>
     <style>
     :host {
@@ -1819,9 +2091,7 @@
       </tr-ui-a-related-events>
     </div>
   </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-thread-time-slice-sub-view">
+</dom-module><dom-module id="tr-ui-a-single-thread-time-slice-sub-view">
   <template>
     <style>
     table {
@@ -1892,101 +2162,24 @@
       </tr>
     </tbody></table>
   </template>
-
-  
-</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-user-expectation-sub-view">
-  
-</polymer-element><polymer-element constructor="TracingAnalysisTabView" name="tr-ui-a-tab-view">
+</dom-module><dom-module id="tr-ui-a-single-user-expectation-sub-view">
   <template>
     <style>
-      :host {
-        display: flex;
-        flex-flow: column nowrap;
-        overflow: hidden;
-        box-sizing: border-box;
-      }
-
-      tab-strip[tabs-hidden] {
-        display: none;
-      }
-
-      tab-strip {
-        background-color: rgb(236, 236, 236);
-        border-bottom: 1px solid #8e8e8e;
-        display: flex;
-        flex: 0 0 auto;
-        flex-flow: row;
-        overflow-x: auto;
-        padding: 0 10px 0 10px;
-        font-size: 12px;
-      }
-
-      tab-button {
-        display: block;
-        flex: 0 0 auto;
-        padding: 4px 15px 1px 15px;
-        margin-top: 2px;
-      }
-
-      tab-button[selected=true] {
-        background-color: white;
-        border: 1px solid rgb(163, 163, 163);
-        border-bottom: none;
-        padding: 3px 14px 1px 14px;
-      }
-
-      tabs-content-container {
-        display: flex;
-        flex: 1 1 auto;
-        overflow: auto;
-        width: 100%;
-      }
-
-      ::content > * {
-        flex: 1 1 auto;
-      }
-
-      ::content > *:not([selected]) {
-        display: none;
-      }
-
-      button-label {
-        display: inline;
-      }
-
-      tab-strip-heading {
-        display: block;
-        flex: 0 0 auto;
-        padding: 4px 15px 1px 15px;
-        margin-top: 2px;
-        margin-before: 20px;
-        margin-after: 10px;
-      }
-      #tsh {
-        display: inline;
-        font-weight: bold;
-      }
+    :host {
+      display: flex;
+      flex-direction: row;
+    }
+    #events {
+      display: flex;
+      flex-direction: column;
+    }
     </style>
-
-    <tab-strip>
-      <tab-strip-heading id="tshh">
-        <span id="tsh"></span>
-      </tab-strip-heading>
-      <template repeat="{{tab in tabs_}}">
-        <tab-button button-id="{{ tab.id }}" on-click="{{ tabButtonSelectHandler_ }}" selected="{{ selectedTab_.id === tab.id }}">
-          <button-label>{{ tab.label ? tab.label : 'No Label'}}</button-label>
-        </tab-button>
-      </template>
-    </tab-strip>
-
-    <tabs-content-container id="content-container">
-        <content></content>
-    </tabs-content-container>
-
+    <tr-ui-a-single-event-sub-view id="realView"></tr-ui-a-single-event-sub-view>
+    <div id="events">
+      <tr-ui-a-user-expectation-related-samples-table id="relatedSamples"></tr-ui-a-user-expectation-related-samples-table>
+    </div>
   </template>
-
-  
-</polymer-element><polymer-element name="tr-ui-a-analysis-view">
+</dom-module><dom-module id="tr-ui-a-analysis-view">
   <template>
     <style>
       :host {
@@ -2000,75 +2193,34 @@
       :host(.tall-mode) {
         height: 525px;
       }
-
-      ::content > * {
-        flex: 1 0 auto;
-      }
     </style>
-    <content></content>
+    <slot></slot>
   </template>
-  
-</polymer-element><polymer-element name="tr-ui-b-dropdown">
+</dom-module><dom-module id="tr-ui-b-dropdown">
   <template>
     <style>
-    :host {
-      position: relative;
-      display: flex;
+    button {
+      @apply --dropdown-button;
     }
-    #outer {
-      display: flex;
-      flex: 0 0 auto;
-      padding: 1px 4px 1px 4px;
-      -webkit-user-select: none;
-      cursor: default;
-    }
-
-    #state {
-      display: flex;
-      flex: 0 0 auto;
-      margin-left: 2px;
-      margin-right: 0px;
-      flex: 0 0 auto;
-    }
-
-    #icon {
-      display: flex;
-      flex: 0 0 auto;
-      flex: 0 0 auto;
+    button.open {
+      @apply --dropdown-button-open;
     }
     dialog {
       position: absolute;
-      padding: 0;
-      border: 0;
       margin: 0;
-    }
-    dialog::backdrop {
-      background: rgba(0,0,0,.05);
-    }
-
-    #dialog-frame {
-      background-color: #fff;
-      display: flex;
-      flex-direction: column;
-      flex: 1 1 auto;
-      padding: 6px;
-      border: 1px solid black;
-      -webkit-user-select: none;
-      cursor: default;
+      padding: 1em;
+      border: 1px solid darkgrey;
+      @apply --dropdown-dialog;
     }
     </style>
-    <tr-ui-b-toolbar-button id="outer" on-click="{{ onOuterClick_ }}" on-keydown="{{ onOuterKeyDown_ }}">
-      <div id="icon">⚙</div>
-      <div id="state">▾</div>
-    </tr-ui-b-toolbar-button>
-    <dialog id="dialog" on-cancel="{{ onDialogCancel_ }}" on-click="{{ onDialogClick_ }}">
-      <div id="dialog-frame">
-        <content></content>
-      </div>
+
+    <button id="button" on-tap="open">[[label]]</button>
+
+    <dialog id="dialog" on-cancel="close" on-tap="onDialogTap_">
+      <slot></slot>
     </dialog>
   </template>
-  
-</polymer-element><polymer-element is="HTMLUnknownElement" name="tr-ui-b-info-bar-group">
+</dom-module><dom-module id="tr-ui-b-info-bar-group">
   <template>
     <style>
     :host {
@@ -2079,9 +2231,7 @@
     </style>
     <div id="messages"></div>
   </template>
-
-  
-</polymer-element><polymer-element name="tr-ui-b-toolbar-button" noscript="">
+</dom-module><dom-module id="tr-ui-b-toolbar-button">
   <template>
     <style>
     :host {
@@ -2108,11 +2258,11 @@
     }
     </style>
     <div id="aligner">
-      <content></content>
+      <slot></slot>
     </div>
   </template>
-</polymer-element><style>
-.drawing-container{-webkit-box-flex:1;display:inline;overflow:auto;overflow-x:hidden;position:relative}.drawing-container-canvas{-webkit-box-flex:1;display:block;pointer-events:none;position:absolute;top:0}
+</dom-module><style>
+.drawing-container{display:inline;overflow:auto;overflow-x:hidden;position:relative}.drawing-container-canvas{display:block;pointer-events:none;position:absolute;top:0}
 </style><style>
 .letter-dot-track {
   height: 18px;
@@ -2123,6 +2273,10 @@
   position: relative;
 }
 </style><style>
+.cpu-usage-track {
+  height: 90px;
+}
+</style><style>
 .power-series-track {
   height: 90px;
 }
@@ -2131,21 +2285,27 @@
 </style><style>
 .rect-track{height:18px}
 </style><style>
-.thread-track{-webkit-box-orient:vertical;display:-webkit-box;position:relative}
+.thread-track{flex-direction:column;display:flex;position:relative}
 </style><style>
-.process-track-header{-webkit-flex:0 0 auto;background-image:-webkit-gradient(linear,0 0,100% 0,from(#E5E5E5),to(#D1D1D1));border-bottom:1px solid #8e8e8e;border-top:1px solid white;font-size:75%}.process-track-name:before{content:'\25B8';padding:0 5px}.process-track-base.expanded .process-track-name:before{content:'\25BE'}
+.process-track-header{display:flex;flex:0 0 auto;background-image:-webkit-gradient(linear,0 0,100% 0,from(#E5E5E5),to(#D1D1D1));border-bottom:1px solid #8e8e8e;border-top:1px solid white;font-size:75%}.process-track-name{flex-grow:1}.process-track-name:before{content:'\25B8';padding:0 5px}.process-track-base.expanded .process-track-name:before{content:'\25BE'}.process-track-close{color:black;border:1px solid transparent;padding:0px 2px}.process-track-close:hover{border:1px solid grey}
 </style><style>
 .model-track {
-  -webkit-box-flex: 1;
+  flex-grow: 1;
 }
 </style><style>
-.ruler-track{height:12px}.ruler-track.tall-mode{height:30px}
-</style><polymer-element name="tr-ui-timeline-track-view">
+.x-axis-track {
+  height: 12px;
+}
+
+.x-axis-track.tall-mode {
+  height: 30px;
+}
+</style><dom-module id="tr-ui-timeline-track-view">
   <template>
     <style>
     :host {
-      -webkit-box-orient: vertical;
-      display: -webkit-box;
+      flex-direction: column;
+      display: flex;
       position: relative;
     }
 
@@ -2168,7 +2328,7 @@
       font-size: 8pt;
     }
     </style>
-    <content></content>
+    <slot></slot>
 
     <div id="drag_box"></div>
     <div id="hint_text"></div>
@@ -2176,14 +2336,12 @@
     <tv-ui-b-hotkey-controller id="hotkey_controller">
     </tv-ui-b-hotkey-controller>
   </template>
-
-  
-</polymer-element><polymer-element name="tr-ui-find-control">
+</dom-module><dom-module id="tr-ui-find-control">
   <template>
     <style>
       :host {
         -webkit-user-select: none;
-        display: -webkit-flex;
+        display: flex;
         position: relative;
       }
       input {
@@ -2226,25 +2384,21 @@
         border-bottom: 2px solid rgba(0, 0, 0, 0.5);
         border-right: 2px solid rgba(0, 0, 0, 0.5);
         border-radius: 50%;
-
-        animation: spin 1s linear infinite;
       }
       @keyframes spin { 100% { transform: rotate(360deg); } }
     </style>
 
-    <input id="filter" on-blur="{{ filterBlur }}" on-focus="{{ filterFocus }}" on-input="{{ filterTextChanged }}" on-keydown="{{ filterKeyDown }}" on-mouseup="{{ filterMouseUp }}" type="text"/>
+    <input id="filter" on-blur="filterBlur" on-focus="filterFocus" on-input="filterTextChanged" on-keydown="filterKeyDown" on-mouseup="filterMouseUp" type="text"/>
     <div id="spinner"></div>
-    <tr-ui-b-toolbar-button on-click="{{ findPrevious }}">
+    <tr-ui-b-toolbar-button on-click="findPrevious">

     </tr-ui-b-toolbar-button>
-    <tr-ui-b-toolbar-button on-click="{{ findNext }}">
+    <tr-ui-b-toolbar-button on-click="findNext">

     </tr-ui-b-toolbar-button>
     <div id="hitCount">0 of 0</div>
   </template>
-
-  
-</polymer-element><polymer-element name="tr-ui-scripting-control">
+</dom-module><dom-module id="tr-ui-scripting-control">
   <template>
     <style>
       :host {
@@ -2281,45 +2435,52 @@
         -webkit-user-select: text;
         color: #777;
       }
+      #promptContainer {
+        display: flex;
+      }
+      #promptMark {
+        width: 1em;
+        color: #468;
+      }
       #prompt {
-        -webkit-user-select: text;
-        -webkit-user-modify: read-write-plaintext-only;
+        flex: 1;
+        width: 100%;
+        border: none !important;
+        background-color: inherit !important;
+        font: inherit !important;
         text-overflow: clip !important;
         text-decoration: none !important;
       }
       #prompt:focus {
         outline: none;
       }
-      #prompt br {
-        display: none;
-      }
-      #prompt ::before {
-        content: ">";
-        color: #468;
-      }
     </style>
 
-    <div class="root hidden" id="root" on-focus="{{ onConsoleFocus }}" tabindex="0">
+    <div class="root hidden" id="root" on-focus="onConsoleFocus" tabindex="0">
       <div id="history"></div>
-      <div id="prompt" on-blur="{{ onConsoleBlur }}" on-keydown="{{ promptKeyDown }}" on-keypress="{{ promptKeyPress }}"></div>
+      <div id="promptContainer">
+        <span id="promptMark">&gt;</span>
+        <input id="prompt" on-blur="onConsoleBlur" on-keydown="promptKeyDown" on-keypress="promptKeyPress" type="text"/>
+       </div>
     </div>
   </template>
-
-  
-</polymer-element><polymer-element is="HTMLUnknownElement" name="tr-ui-side-panel-container">
+</dom-module><dom-module id="tr-ui-side-panel-container">
   <template>
     <style>
     :host {
       align-items: stretch;
-      display: -webkit-flex;
+      display: flex;
+      background-color: white;
     }
 
+    :host([expanded]) > #side_panel_drag_handle,
     :host([expanded]) > active-panel-container {
-      -webkit-flex: 1 1 auto;
+      flex: 1 1 auto;
       border-left: 1px solid black;
-      display: -webkit-flex;
+      display: flex;
     }
 
+    :host(:not([expanded])) > #side_panel_drag_handle,
     :host(:not([expanded])) > active-panel-container {
       display: none;
     }
@@ -2329,20 +2490,22 @@
     }
 
     tab-strip {
-      -webkit-flex: 0 0 auto;
-      -webkit-flex-direction: column;
+      flex: 0 0 auto;
+      flex-direction: column;
       -webkit-user-select: none;
       background-color: rgb(236, 236, 236);
       border-left: 1px solid black;
       cursor: default;
-      display: -webkit-flex;
+      display: flex;
       min-width: 18px; /* workaround for flexbox and writing-mode mixing bug */
       padding: 10px 0 10px 0;
       font-size: 12px;
     }
 
     tab-strip > tab-strip-label {
+      flex-shrink: 0;
       -webkit-writing-mode: vertical-rl;
+      white-space: nowrap;
       display: inline;
       margin-right: 1px;
       min-height: 20px;
@@ -2360,21 +2523,24 @@
       border-left: none;
       padding: 14px 2px 14px 1px;
     }
+
+    #active_panel_container {
+      overflow: auto;
+    }
     </style>
 
+    <tr-ui-b-drag-handle id="side_panel_drag_handle"></tr-ui-b-drag-handle>
     <active-panel-container id="active_panel_container">
     </active-panel-container>
     <tab-strip id="tab_strip"></tab-strip>
   </template>
-
-  
-</polymer-element><polymer-element name="tr-ui-timeline-view-help-overlay">
+</dom-module><dom-module id="tr-ui-timeline-view-help-overlay">
   <template>
     <style>
     :host {
-      -webkit-flex: 1 1 auto;
-      -webkit-flex-direction: row;
-      display: -webkit-flex;
+      flex: 1 1 auto;
+      flex-direction: row;
+      display: flex;
       width: 700px;
     }
     .column {
@@ -2392,9 +2558,9 @@
       margin-top: 10px;
     }
     .pair {
-      -webkit-flex: 1 1 auto;
-      -webkit-flex-direction: row;
-      display: -webkit-flex;
+      flex: 1 1 auto;
+      flex-direction: row;
+      display: flex;
     }
     .command {
       font-family: monospace;
@@ -2462,7 +2628,7 @@
       </div>
 
       <h3>
-        <tr-ui-b-mouse-mode-icon modename="SELECTION"></tr-ui-b-mouse-mode-icon>
+        <tr-ui-b-mouse-mode-icon mode-name="SELECTION"></tr-ui-b-mouse-mode-icon>
         Select mode
       </h3>
       <div class="pair">
@@ -2481,7 +2647,7 @@
       </div>
 
       <h3>
-        <tr-ui-b-mouse-mode-icon modename="PANSCAN"></tr-ui-b-mouse-mode-icon>
+        <tr-ui-b-mouse-mode-icon mode-name="PANSCAN"></tr-ui-b-mouse-mode-icon>
         Pan mode
       </h3>
       <div class="pair">
@@ -2490,7 +2656,7 @@
       </div>
 
       <h3>
-        <tr-ui-b-mouse-mode-icon modename="ZOOM"></tr-ui-b-mouse-mode-icon>
+        <tr-ui-b-mouse-mode-icon mode-name="ZOOM"></tr-ui-b-mouse-mode-icon>
         Zoom mode
       </h3>
       <div class="pair">
@@ -2499,7 +2665,7 @@
       </div>
 
       <h3>
-        <tr-ui-b-mouse-mode-icon modename="TIMING"></tr-ui-b-mouse-mode-icon>
+        <tr-ui-b-mouse-mode-icon mode-name="TIMING"></tr-ui-b-mouse-mode-icon>
         Timing mode
       </h3>
       <div class="pair">
@@ -2571,6 +2737,11 @@
       </div>
 
       <div class="pair">
+        <div class="command">p</div>
+        <div class="action">Select power samples over current selection interval</div>
+      </div>
+
+      <div class="pair">
         <div class="command">`</div>
         <div class="action">Show or hide the scripting console</div>
       </div>
@@ -2581,26 +2752,7 @@
       </div>
     </div>
   </template>
-
-  
-</polymer-element><polymer-element name="tr-v-ui-array-of-numbers-span">
-  <template>
-  </template>
-  
-</polymer-element><polymer-element name="tr-v-ui-generic-table-view">
-  <template>
-    <style>
-    :host {
-    display: flex;
-    }
-    #table {
-      flex: 1 1 auto;
-      align-self: stretch;
-    }
-    </style>
-    <tr-ui-b-table id="table"></tr-ui-b-table>
-  </template>
-</polymer-element><polymer-element name="tr-ui-timeline-view-metadata-overlay">
+</dom-module><dom-module id="tr-ui-timeline-view-metadata-overlay">
   <template>
     <style>
     :host {
@@ -2609,13 +2761,9 @@
       overflow: auto;
     }
     </style>
-    <tr-v-ui-generic-table-view id="gtv"></tr-v-ui-generic-table-view>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
   </template>
-
-  
-</polymer-element><polymer-element name="tr-v-ui-preferred-display-unit">
-  
-</polymer-element><polymer-element name="tr-ui-timeline-view">
+</dom-module><dom-module id="tr-ui-timeline-view">
   <template>
     <style>
     :host {
@@ -2675,12 +2823,27 @@
       display: flex;
       min-height: 0;
       min-width: 0;
+      overflow-x: hidden;
     }
 
     middle-container ::content track-view-container > * { flex: 1 1 auto; }
     middle-container > x-timeline-view-side-panel-container { flex: 0 0 auto; }
     tr-ui-b-drag-handle { flex: 0 0 auto; }
     tr-ui-a-analysis-view { flex: 0 0 auto; }
+
+    #view_options_dropdown, #process_filter_dropdown {
+      --dropdown-button: {
+        -webkit-appearance: none;
+        align-items: normal;
+        background-color: rgb(248, 248, 248);
+        border: 1px solid rgba(0, 0, 0, 0.5);
+        box-sizing: content-box;
+        color: rgba(0, 0, 0, 0.8);
+        font-family: sans-serif;
+        font-size: 12px;
+        padding: 2px 5px;
+      }
+    }
     </style>
 
     <tv-ui-b-hotkey-controller id="hkc"></tv-ui-b-hotkey-controller>
@@ -2689,10 +2852,11 @@
         <div id="left_controls"></div>
         <div id="title">^_^</div>
         <div id="right_controls">
+          <tr-ui-b-dropdown id="process_filter_dropdown" label="Processes"></tr-ui-b-dropdown>
           <tr-ui-b-toolbar-button id="view_metadata_button">
             M
           </tr-ui-b-toolbar-button>
-          <tr-ui-b-dropdown id="view_options_dropdown"></tr-ui-b-dropdown>
+          <tr-ui-b-dropdown id="view_options_dropdown" label="View Options"></tr-ui-b-dropdown>
           <tr-ui-find-control id="view_find_control"></tr-ui-find-control>
           <tr-ui-b-toolbar-button id="view_console_button">
             »
@@ -2707,7 +2871,7 @@
       </tr-ui-b-info-bar-group>
     </div>
     <middle-container>
-      <content></content>
+      <slot></slot>
 
       <tr-ui-side-panel-container id="side_panel_container">
       </tr-ui-side-panel-container>
@@ -2718,9 +2882,7 @@
     <tr-v-ui-preferred-display-unit id="display_unit">
     </tr-v-ui-preferred-display-unit>
   </template>
-
-  
-</polymer-element><polymer-element name="tr-ui-b-grouping-table">
+</dom-module><dom-module id="tr-ui-b-grouping-table">
   <template>
     <style>
     :host {
@@ -2728,67 +2890,49 @@
     }
     #table {
       flex: 1 1 auto;
+      font-size: 12px;
     }
     </style>
     <tr-ui-b-table id="table"></tr-ui-b-table>
   </template>
-</polymer-element><polymer-element name="tr-ui-b-grouping-table-groupby-picker">
+</dom-module><dom-module id="tr-ui-b-grouping-table-groupby-picker">
+  <template>
+    <style>
+    #container {
+      display: flex;
+    }
+    #container *:not(:first-child) {
+      padding-left: 3px;
+      border-left: 1px solid black;
+      margin-left: 3px;
+    }
+    </style>
+
+    <div id="container"></div>
+  </template>
+</dom-module><dom-module id="tr-ui-b-grouping-table-groupby-picker-group">
   <template>
     <style>
     :host {
-      display: flex;
-      flex-direction: row;
-      align-items: center;
+      white-space: nowrap;
     }
-    groups {
-      -webkit-user-select: none;
-      display: flex;
-      flex-direction: row;
-      padding-left: 10px;
-    }
-
-    group, possible-group {
-      display: span;
-      padding-right: 10px;
-      padding-left: 10px;
-    }
-
-    group {
-      border-left: 1px solid rgba(0,0,0,0);
-      cursor: move;
-    }
-
-    group.dragging {
-      opacity: 0.2;
-    }
-
-    group.drop-targeted {
-      border-left: 1px solid black;
-    }
-
-
-    #remove {
-      cursor: default;
-    }
-
-    #remove:not([hovered]) {
-      visibility: hidden;
+    #left, #right {
+      user-select: none;
+      cursor: pointer;
     }
     </style>
-    <groups>
-    </groups>
-    <tr-ui-b-dropdown id="add-group"></tr-ui-b-dropdown>
+
+    <span id="left" on-click="moveLeft_">◀</span>
+    <input id="enabled" on-change="onEnableChanged_" type="checkbox"/>
+    <label for="enabled" id="label"></label>
+    <span id="right" on-click="moveRight_">▶</span>
   </template>
-</polymer-element><template id="tr-ui-b-grouping-table-groupby-picker-group-template">
-  <span id="key"></span>
-  <span id="remove">×</span>
-</template><polymer-element extends="tr-ui-side-panel" name="tr-ui-sp-file-size-stats-side-panel">
+</dom-module><dom-module id="tr-ui-sp-file-size-stats-side-panel">
   <template>
     <style>
     :host {
       display: flex;
       flex-direction: column;
-      width: 600px;
     }
     toolbar {
       align-items: center;
@@ -2817,7 +2961,675 @@
       <tr-ui-b-grouping-table id="table"></tr-ui-b-grouping-table>
     </table-container>
   </template>
-</polymer-element><polymer-element extends="tr-ui-side-panel" name="tr-ui-e-s-alerts-side-panel">
+</dom-module><dom-module id="tr-v-ui-histogram-set-controls-export">
+  <template>
+    <style>
+    :host {
+      display: grid;
+      grid-gap: 1em;
+      grid-template-rows: auto auto;
+      grid-template-columns: auto auto;
+    }
+    button {
+      -webkit-appearance: none;
+      border: 0;
+      font-size: initial;
+      padding: 5px;
+    }
+    </style>
+
+    <button on-tap="exportRawCsv_">raw CSV</button>
+    <button on-tap="exportRawJson_">raw JSON</button>
+    <button on-tap="exportMergedCsv_">merged CSV</button>
+    <button on-tap="exportMergedJson_">merged JSON</button>
+  </template>
+</dom-module><dom-module id="tr-v-ui-histogram-set-controls">
+  <template>
+    <style>
+    :host {
+      display: block;
+    }
+
+    #help, #feedback {
+      display: none;
+      margin-left: 20px;
+    }
+
+    #search_container {
+      display: inline-flex;
+      margin-right: 20px;
+      padding-bottom: 1px;
+      border-bottom: 1px solid darkgrey;
+    }
+
+    #search {
+      border: 0;
+      max-width: 20em;
+      outline: none;
+    }
+
+    #clear_search {
+      visibility: hidden;
+      height: 1em;
+      stroke: black;
+      stroke-width: 16;
+    }
+
+    #controls {
+      white-space: nowrap;
+    }
+
+    #show_overview, #hide_overview {
+      height: 1em;
+      margin-right: 20px;
+    }
+
+    #show_overview {
+      stroke: blue;
+      stroke-width: 16;
+    }
+
+    #show_overview:hover {
+      background: blue;
+      stroke: white;
+    }
+
+    #hide_overview {
+      display: none;
+      stroke-width: 18;
+      stroke: black;
+    }
+
+    #hide_overview:hover {
+      background: black;
+      stroke: white;
+    }
+
+    #reference_display_label {
+      display: none;
+      margin-right: 20px;
+    }
+
+    #alpha, #alpha_slider_container {
+      display: none;
+    }
+
+    #alpha {
+      margin-right: 20px;
+    }
+
+    #alpha_slider_container {
+      background: white;
+      border: 1px solid black;
+      flex-direction: column;
+      padding: 0.5em;
+      position: absolute;
+      z-index: 10; /* scalar-span uses z-index :-( */
+    }
+
+    #alpha_slider {
+      -webkit-appearance: slider-vertical;
+      align-self: center;
+      height: 200px;
+      width: 30px;
+    }
+
+    #statistic {
+      display: none;
+      margin-right: 20px;
+    }
+
+    #show_visualization {
+      margin-right: 20px;
+    }
+
+    #export {
+      margin-right: 20px;
+    }
+    </style>
+
+    <div id="controls">
+      <span id="search_container">
+        <input id="search" placeholder="Find Histogram name" value="{{searchQuery::keyup}}"/>
+        <svg id="clear_search" on-tap="clearSearch_" viewBox="0 0 128 128">
+          <g>
+          <title>Clear search</title>
+          <line x1="28" x2="100" y1="28" y2="100"></line>
+          <line x1="28" x2="100" y1="100" y2="28"></line>
+          </g>
+        </svg>
+      </span>
+
+      <svg id="show_overview" on-tap="toggleOverviewLineCharts_" viewBox="0 0 128 128">
+        <g>
+        <title>Show overview charts</title>
+        <line x1="19" x2="49" y1="109" y2="49"></line>
+        <line x1="49" x2="79" y1="49" y2="79"></line>
+        <line x1="79" x2="109" y1="79" y2="19"></line>
+        </g>
+      </svg>
+      <svg id="hide_overview" on-tap="toggleOverviewLineCharts_" viewBox="0 0 128 128">
+        <g>
+        <title>Hide overview charts</title>
+        <line x1="28" x2="100" y1="28" y2="100"></line>
+        <line x1="28" x2="100" y1="100" y2="28"></line>
+        </g>
+      </svg>
+
+      <select id="reference_display_label" value="{{referenceDisplayLabel::change}}">
+        <option value="">Select a reference column</option>
+      </select>
+
+      <button id="alpha" on-tap="openAlphaSlider_">α=[[alphaString]]</button>
+      <div id="alpha_slider_container">
+        <input id="alpha_slider" max="18" min="0" on-blur="closeAlphaSlider_" on-input="updateAlpha_" type="range" value="{{alphaIndex::change}}"/>
+      </div>
+
+      <select id="statistic" value="{{displayStatisticName::change}}">
+      </select>
+
+      <button id="show_visualization" on-tap="loadVisualization_">Visualize</button>
+
+      <tr-ui-b-dropdown label="Export">
+        <tr-v-ui-histogram-set-controls-export>
+        </tr-v-ui-histogram-set-controls-export>
+      </tr-ui-b-dropdown>
+
+      <input checked="{{showAll::change}}" id="show_all" title="When unchecked, less important histograms are hidden." type="checkbox"/>
+      <label for="show_all" title="When unchecked, less important histograms are hidden.">Show all</label>
+
+      <a id="help">Help</a>
+      <a id="feedback">Feedback</a>
+    </div>
+
+    <tr-ui-b-grouping-table-groupby-picker id="picker">
+    </tr-ui-b-grouping-table-groupby-picker>
+  </template>
+</dom-module><dom-module id="tr-v-ui-histogram-set-table-cell">
+  <template>
+    <style>
+    #histogram_container {
+      display: flex;
+      flex-direction: row;
+    }
+
+    #missing, #empty, #unmergeable, #scalar {
+      flex-grow: 1;
+    }
+
+    #open_histogram, #close_histogram, #open_histogram svg, #close_histogram svg {
+      height: 1em;
+    }
+
+    #open_histogram svg {
+      margin-left: 4px;
+      stroke-width: 0;
+      stroke: blue;
+      fill: blue;
+    }
+    :host(:hover) #open_histogram svg {
+      background: blue;
+      stroke: white;
+      fill: white;
+    }
+
+    #scalar {
+      flex-grow: 1;
+      white-space: nowrap;
+    }
+
+    #histogram {
+      flex-grow: 1;
+    }
+
+    #close_histogram svg line {
+      stroke-width: 18;
+      stroke: black;
+    }
+    #close_histogram:hover svg {
+      background: black;
+    }
+    #close_histogram:hover svg line {
+      stroke: white;
+    }
+
+    #overview_container {
+      display: none;
+    }
+    </style>
+
+    <div id="histogram_container">
+      <span id="missing">(missing)</span>
+      <span id="empty">(empty)</span>
+      <span id="unmergeable">(unmergeable)</span>
+
+      <tr-v-ui-scalar-span id="scalar" on-click="openHistogram_"></tr-v-ui-scalar-span>
+
+      <span id="open_histogram" on-click="openHistogram_">
+        <svg viewBox="0 0 128 128">
+          <rect height="16" width="32" x="16" y="24"></rect>
+          <rect height="16" width="96" x="16" y="56"></rect>
+          <rect height="16" width="64" x="16" y="88"></rect>
+        </svg>
+      </span>
+
+      <span id="histogram"></span>
+
+      <span id="close_histogram" on-click="closeHistogram_">
+        <svg viewBox="0 0 128 128">
+          <line x1="28" x2="100" y1="28" y2="100"></line>
+          <line x1="28" x2="100" y1="100" y2="28"></line>
+        </svg>
+      </span>
+    </div>
+
+    <div id="overview_container">
+    </div>
+  </template>
+</dom-module><dom-module id="tr-v-ui-histogram-set-table-name-cell">
+  <template>
+    <style>
+    #name_container {
+      display: flex;
+    }
+
+    #name {
+      overflow: hidden;
+      white-space: nowrap;
+      text-overflow: ellipsis;
+    }
+
+    #show_overview, #hide_overview, #show_overview svg, #hide_overview svg {
+      height: 1em;
+      margin-left: 5px;
+    }
+
+    #show_overview svg {
+      stroke: blue;
+      stroke-width: 16;
+    }
+
+    #show_overview:hover svg {
+      background: blue;
+      stroke: white;
+    }
+
+    #hide_overview {
+      display: none;
+    }
+
+    #hide_overview svg {
+      stroke-width: 18;
+      stroke: black;
+    }
+
+    #hide_overview:hover svg {
+      background: black;
+      stroke: white;
+    }
+
+    #open_histograms, #close_histograms, #open_histograms svg, #close_histograms svg {
+      height: 1em;
+    }
+
+    #close_histograms {
+      display: none;
+    }
+
+    #open_histograms svg {
+      margin-left: 4px;
+      stroke-width: 0;
+      stroke: blue;
+      fill: blue;
+    }
+    #open_histograms:hover svg {
+      background: blue;
+      stroke: white;
+      fill: white;
+    }
+
+    #close_histograms line {
+      stroke-width: 18;
+      stroke: black;
+    }
+    #close_histograms:hover {
+      background: black;
+    }
+    #close_histograms:hover line {
+      stroke: white;
+    }
+
+    #overview_container {
+      display: none;
+    }
+    </style>
+
+    <div id="name_container">
+      <span id="name"></span>
+
+      <span id="show_overview" on-click="showOverview_">
+        <svg viewBox="0 0 128 128">
+          <line x1="19" x2="49" y1="109" y2="49"></line>
+          <line x1="49" x2="79" y1="49" y2="79"></line>
+          <line x1="79" x2="109" y1="79" y2="19"></line>
+        </svg>
+      </span>
+
+      <span id="hide_overview" on-click="hideOverview_">
+        <svg viewBox="0 0 128 128">
+          <line x1="28" x2="100" y1="28" y2="100"></line>
+          <line x1="28" x2="100" y1="100" y2="28"></line>
+        </svg>
+      </span>
+
+      <span id="open_histograms" on-click="openHistograms_">
+        <svg viewBox="0 0 128 128">
+          <rect height="16" width="32" x="16" y="24"></rect>
+          <rect height="16" width="96" x="16" y="56"></rect>
+          <rect height="16" width="64" x="16" y="88"></rect>
+        </svg>
+      </span>
+
+      <span id="close_histograms" on-click="closeHistograms_">
+        <svg viewBox="0 0 128 128">
+          <line x1="28" x2="100" y1="28" y2="100"></line>
+          <line x1="28" x2="100" y1="100" y2="28"></line>
+        </svg>
+      </span>
+    </div>
+
+    <div id="overview_container">
+    </div>
+  </template>
+</dom-module><dom-module id="tr-v-ui-histogram-set-table">
+  <template>
+    <style>
+    :host {
+      min-height: 0px;
+      overflow: auto;
+    }
+    #table {
+      margin-top: 5px;
+    }
+    </style>
+
+    <tr-ui-b-table id="table">
+  </tr-ui-b-table></template>
+</dom-module><dom-module id="tr-v-ui-metrics-visualization">
+  <template>
+    <style>
+      button {
+        padding: 5px;
+        font-size: 14px;
+      }
+
+      .text_input {
+        width: 50px;
+        padding: 4px;
+        font-size: 14px;
+      }
+
+      .error {
+        color: red;
+        display: none;
+      }
+
+      .container {
+        position: relative;
+        display: inline-block;
+        margin-left: 15px;
+      }
+
+      #title {
+        font-size: 20px;
+        font-weight: bold;
+        padding-bottom: 5px;
+      }
+
+      #selectors {
+        display: block;
+        padding-bottom: 10px;
+      }
+
+      #search_page {
+        width: 200px;
+        margin-left: 30px;
+      }
+
+      #close {
+        display: none;
+        vertical-align: top;
+      }
+
+      #close svg{
+        height: 1em;
+      }
+
+      #close svg line {
+        stroke-width: 18;
+        stroke: black;
+      }
+
+      #close:hover svg {
+        background: black;
+      }
+
+      #close:hover svg line {
+        stroke: white;
+      }
+    </style>
+      <span class="container" id="aggregateContainer">
+      </span>
+      <span class="container" id="pageByPageContainer">
+        <span id="selectors">
+          <span id="percentile_label">Percentile Range:</span>
+          <input class="text_input" id="start" placeholder="0"/>
+          <input class="text_input" id="end" placeholder="100"/>
+          <button id="filter" on-tap="filterByPercentile_">Filter</button>
+          <input class="text_input" id="search_page" placeholder="Page Name"/>
+          <button id="search" on-tap="searchByPage_">Search</button>
+          <span class="error" id="search_error">Sorry, could not find that page!</span>
+        </span>
+      </span>
+      <div display="block" id="submetricsContainer">
+        <span id="close">
+          <svg viewBox="0 0 128 128">
+            <line x1="28" x2="100" y1="28" y2="100"></line>
+            <line x1="28" x2="100" y1="100" y2="28"></line>
+          </svg>
+        </span>
+      </div>
+  </template>
+</dom-module><dom-module id="tr-v-ui-raster-visualization">
+  <template>
+    <style>
+      button {
+        padding: 5px;
+        font-size: 14px;
+      }
+      .error {
+        color: red;
+        display: none;
+      }
+
+      .text_input {
+        width: 200px;
+        padding: 4px;
+        font-size: 14px;
+      }
+
+      .selector_container{
+        padding: 5px;
+      }
+
+      #search {
+        display: inline-block;
+        padding-bottom: 10px;
+      }
+
+      #search_page {
+        width: 200px;
+      }
+
+      #pageSelector {
+        display: inline-block;
+        font-size: 12pt;
+      }
+
+      #close {
+        display: none;
+        vertical-align: top;
+      }
+
+      #close svg{
+        height: 1em;
+      }
+
+      #close svg line {
+        stroke-width: 18;
+        stroke: black;
+      }
+
+      #close:hover svg {
+        background: black;
+      }
+
+      #close:hover svg line {
+        stroke: white;
+      }
+    </style>
+    <span id="aggregateContainer">
+      <div>
+        <div class="selector_container">
+          <span id="select_page_label">Individual Page Results:</span>
+          <select id="pageSelector">
+            <option id="select_page" value="">Select a page</option>
+          </select>
+        </div>
+        <div class="selector_container">
+          <div id="search_page_label">Search for a page:</div>
+          <input class="text_input" id="search_page" placeholder="Page Name"/>
+          <button id="search_button">Search</button>
+          <div class="error" id="search_error">Sorry, could not find that page!</div>
+        </div>
+      </div>
+    </span>
+    <span id="pageContainer">
+      <span id="close">
+          <svg viewBox="0 0 128 128">
+            <line x1="28" x2="100" y1="28" y2="100"></line>
+            <line x1="28" x2="100" y1="100" y2="28"></line>
+          </svg>
+        </span>
+      </span>
+  </template>
+</dom-module><meta charset="utf-8"/><dom-module id="tr-v-ui-visualizations-data-container">
+  <template>
+    <style>
+      .error {
+        color: red;
+        display: none;
+      }
+
+      .sample{
+        display: none;
+      }
+
+      .subtitle{
+        font-size: 20px;
+        font-weight: bold;
+        padding-bottom: 5px;
+      }
+
+      .description{
+        font-size: 15px;
+        padding-bottom: 5px;
+      }
+
+      #title {
+        font-size: 30px;
+        font-weight: bold;
+        padding-bottom: 5px;
+      }
+    </style>
+    <div id="title">Visualizations</div>
+    <div class="error" id="data_error">Invalid data provided.</div>
+    <div id="pipeline_per_frame_container">
+      <div class="subtitle">Graphics Pipeline and Raster Tasks</div>
+      <div class="description">
+        When raster tasks are completed in comparison to the rest of the graphics pipeline.<br/>
+        Only pages where raster tasks are completed after beginFrame is issued are included.
+      </div>
+      <tr-v-ui-raster-visualization id="rasterVisualization">
+      </tr-v-ui-raster-visualization>
+    </div>
+    <div id="metrics_container">
+      <div class="subtitle">Metrics</div>
+      <div class="description">Total amount of time taken for the indicated metrics.</div>
+      <tr-v-ui-metrics-visualization class="sample" id="metricsVisualization">
+      </tr-v-ui-metrics-visualization>
+    </div>
+  </template>
+</dom-module><dom-module id="tr-v-ui-histogram-set-view">
+  <template>
+    <style>
+    :host {
+      font-family: sans-serif;
+    }
+
+    #zero {
+      color: red;
+      /* histogram-set-table is used by both metrics-side-panel and results.html.
+       * This font-size rule has no effect in results.html, but improves
+       * legibility in the metrics-side-panel, which sets font-size in order to
+       * make this table denser.
+       */
+      font-size: initial;
+    }
+
+    #container {
+      display: none;
+    }
+
+    #visualizations{
+      display: none;
+    }
+    </style>
+
+    <div id="zero">zero Histograms</div>
+
+    <div id="container">
+      <tr-v-ui-histogram-set-controls id="controls">
+      </tr-v-ui-histogram-set-controls>
+
+      <tr-v-ui-visualizations-data-container id="visualizations">
+      </tr-v-ui-visualizations-data-container>
+
+      <tr-v-ui-histogram-set-table id="table"></tr-v-ui-histogram-set-table>
+    </div>
+  </template>
+</dom-module><dom-module id="tr-ui-sp-metrics-side-panel">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+    }
+    div#error {
+      color: red;
+    }
+    #results {
+      font-size: 12px;
+    }
+    </style>
+
+    <top-left-controls id="top_left_controls"></top-left-controls>
+
+    <tr-v-ui-histogram-set-view id="results"></tr-v-ui-histogram-set-view>
+
+    <div id="error"></div>
+  </template>
+</dom-module><dom-module id="tr-ui-e-s-alerts-side-panel">
   <template>
     <style>
     :host {
@@ -2828,6 +3640,9 @@
       flex-direction: column;
       display: flex;
     }
+    tr-ui-b-table {
+      font-size: 12px;
+    }
     </style>
 
     <div id="content">
@@ -2835,9 +3650,7 @@
       <result-area id="result_area"></result-area>
     </div>
   </template>
-
-  
-</polymer-element><script>
+</dom-module><script>
 
 // Copyright 2015 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
@@ -2848,4769 +3661,6746 @@
  * Do not edit directly.
  */
 
-/**
- * @license
- * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
- * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
- * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
- * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
- * Code distributed by Google as part of the polymer project is also
- * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
- */
-// @version 0.5.5
-window.PolymerGestures={},function(a){var b=!1,c=document.createElement("meta");if(c.createShadowRoot){var d=c.createShadowRoot(),e=document.createElement("span");d.appendChild(e),c.addEventListener("testpath",function(a){a.path&&(b=a.path[0]===e),a.stopPropagation()});var f=new CustomEvent("testpath",{bubbles:!0});document.head.appendChild(c),e.dispatchEvent(f),c.parentNode.removeChild(c),d=e=null}c=null;var g={shadow:function(a){return a?a.shadowRoot||a.webkitShadowRoot:void 0},canTarget:function(a){return a&&Boolean(a.elementFromPoint)},targetingShadow:function(a){var b=this.shadow(a);return this.canTarget(b)?b:void 0},olderShadow:function(a){var b=a.olderShadowRoot;if(!b){var c=a.querySelector("shadow");c&&(b=c.olderShadowRoot)}return b},allShadows:function(a){for(var b=[],c=this.shadow(a);c;)b.push(c),c=this.olderShadow(c);return b},searchRoot:function(a,b,c){var d,e;return a?(d=a.elementFromPoint(b,c),d?e=this.targetingShadow(d):a!==document&&(e=this.olderShadow(a)),this.searchRoot(e,b,c)||d):void 0},owner:function(a){if(!a)return document;for(var b=a;b.parentNode;)b=b.parentNode;return b.nodeType!=Node.DOCUMENT_NODE&&b.nodeType!=Node.DOCUMENT_FRAGMENT_NODE&&(b=document),b},findTarget:function(a){if(b&&a.path&&a.path.length)return a.path[0];var c=a.clientX,d=a.clientY,e=this.owner(a.target);return e.elementFromPoint(c,d)||(e=document),this.searchRoot(e,c,d)},findTouchAction:function(a){var c;if(b&&a.path&&a.path.length){for(var d=a.path,e=0;e<d.length;e++)if(c=d[e],c.nodeType===Node.ELEMENT_NODE&&c.hasAttribute("touch-action"))return c.getAttribute("touch-action")}else for(c=a.target;c;){if(c.nodeType===Node.ELEMENT_NODE&&c.hasAttribute("touch-action"))return c.getAttribute("touch-action");c=c.parentNode||c.host}return"auto"},LCA:function(a,b){if(a===b)return a;if(a&&!b)return a;if(b&&!a)return b;if(!b&&!a)return document;if(a.contains&&a.contains(b))return a;if(b.contains&&b.contains(a))return b;var c=this.depth(a),d=this.depth(b),e=c-d;for(e>=0?a=this.walk(a,e):b=this.walk(b,-e);a&&b&&a!==b;)a=a.parentNode||a.host,b=b.parentNode||b.host;return a},walk:function(a,b){for(var c=0;a&&b>c;c++)a=a.parentNode||a.host;return a},depth:function(a){for(var b=0;a;)b++,a=a.parentNode||a.host;return b},deepContains:function(a,b){var c=this.LCA(a,b);return c===a},insideNode:function(a,b,c){var d=a.getBoundingClientRect();return d.left<=b&&b<=d.right&&d.top<=c&&c<=d.bottom},path:function(a){var c;if(b&&a.path&&a.path.length)c=a.path;else{c=[];for(var d=this.findTarget(a);d;)c.push(d),d=d.parentNode||d.host}return c}};a.targetFinding=g,a.findTarget=g.findTarget.bind(g),a.deepContains=g.deepContains.bind(g),a.insideNode=g.insideNode}(window.PolymerGestures),function(){function a(a){return"html /deep/ "+b(a)}function b(a){return'[touch-action="'+a+'"]'}function c(a){return"{ -ms-touch-action: "+a+"; touch-action: "+a+";}"}var d=["none","auto","pan-x","pan-y",{rule:"pan-x pan-y",selectors:["pan-x pan-y","pan-y pan-x"]},"manipulation"],e="",f="string"==typeof document.head.style.touchAction,g=!window.ShadowDOMPolyfill&&document.head.createShadowRoot;if(f){d.forEach(function(d){String(d)===d?(e+=b(d)+c(d)+"\n",g&&(e+=a(d)+c(d)+"\n")):(e+=d.selectors.map(b)+c(d.rule)+"\n",g&&(e+=d.selectors.map(a)+c(d.rule)+"\n"))});var h=document.createElement("style");h.textContent=e,document.head.appendChild(h)}}(),function(a){var b=["bubbles","cancelable","view","detail","screenX","screenY","clientX","clientY","ctrlKey","altKey","shiftKey","metaKey","button","relatedTarget","pageX","pageY"],c=[!1,!1,null,null,0,0,0,0,!1,!1,!1,!1,0,null,0,0],d=function(){return function(){}},e={preventTap:d,makeBaseEvent:function(a,b){var c=document.createEvent("Event");return c.initEvent(a,b.bubbles||!1,b.cancelable||!1),c.preventTap=e.preventTap(c),c},makeGestureEvent:function(a,b){b=b||Object.create(null);for(var c,d=this.makeBaseEvent(a,b),e=0,f=Object.keys(b);e<f.length;e++)c=f[e],"bubbles"!==c&&"cancelable"!==c&&(d[c]=b[c]);return d},makePointerEvent:function(a,d){d=d||Object.create(null);for(var e,f=this.makeBaseEvent(a,d),g=2;g<b.length;g++)e=b[g],f[e]=d[e]||c[g];f.buttons=d.buttons||0;var h=0;return h=d.pressure?d.pressure:f.buttons?.5:0,f.x=f.clientX,f.y=f.clientY,f.pointerId=d.pointerId||0,f.width=d.width||0,f.height=d.height||0,f.pressure=h,f.tiltX=d.tiltX||0,f.tiltY=d.tiltY||0,f.pointerType=d.pointerType||"",f.hwTimestamp=d.hwTimestamp||0,f.isPrimary=d.isPrimary||!1,f._source=d._source||"",f}};a.eventFactory=e}(window.PolymerGestures),function(a){function b(){if(c){var a=new Map;return a.pointers=d,a}this.keys=[],this.values=[]}var c=window.Map&&window.Map.prototype.forEach,d=function(){return this.size};b.prototype={set:function(a,b){var c=this.keys.indexOf(a);c>-1?this.values[c]=b:(this.keys.push(a),this.values.push(b))},has:function(a){return this.keys.indexOf(a)>-1},"delete":function(a){var b=this.keys.indexOf(a);b>-1&&(this.keys.splice(b,1),this.values.splice(b,1))},get:function(a){var b=this.keys.indexOf(a);return this.values[b]},clear:function(){this.keys.length=0,this.values.length=0},forEach:function(a,b){this.values.forEach(function(c,d){a.call(b,c,this.keys[d],this)},this)},pointers:function(){return this.keys.length}},a.PointerMap=b}(window.PolymerGestures),function(a){var b,c=["bubbles","cancelable","view","detail","screenX","screenY","clientX","clientY","ctrlKey","altKey","shiftKey","metaKey","button","relatedTarget","buttons","pointerId","width","height","pressure","tiltX","tiltY","pointerType","hwTimestamp","isPrimary","type","target","currentTarget","which","pageX","pageY","timeStamp","preventTap","tapPrevented","_source"],d=[!1,!1,null,null,0,0,0,0,!1,!1,!1,!1,0,null,0,0,0,0,0,0,0,"",0,!1,"",null,null,0,0,0,0,function(){},!1],e="undefined"!=typeof SVGElementInstance,f=a.eventFactory,g={IS_IOS:!1,pointermap:new a.PointerMap,requiredGestures:new a.PointerMap,eventMap:Object.create(null),eventSources:Object.create(null),eventSourceList:[],gestures:[],dependencyMap:{down:{listeners:0,index:-1},up:{listeners:0,index:-1}},gestureQueue:[],registerSource:function(a,b){var c=b,d=c.events;d&&(d.forEach(function(a){c[a]&&(this.eventMap[a]=c[a].bind(c))},this),this.eventSources[a]=c,this.eventSourceList.push(c))},registerGesture:function(a,b){var c=Object.create(null);c.listeners=0,c.index=this.gestures.length;for(var d,e=0;e<b.exposes.length;e++)d=b.exposes[e].toLowerCase(),this.dependencyMap[d]=c;this.gestures.push(b)},register:function(a,b){for(var c,d=this.eventSourceList.length,e=0;d>e&&(c=this.eventSourceList[e]);e++)c.register.call(c,a,b)},unregister:function(a){for(var b,c=this.eventSourceList.length,d=0;c>d&&(b=this.eventSourceList[d]);d++)b.unregister.call(b,a)},down:function(a){this.requiredGestures.set(a.pointerId,b),this.fireEvent("down",a)},move:function(a){a.type="move",this.fillGestureQueue(a)},up:function(a){this.fireEvent("up",a),this.requiredGestures["delete"](a.pointerId)},cancel:function(a){a.tapPrevented=!0,this.fireEvent("up",a),this.requiredGestures["delete"](a.pointerId)},addGestureDependency:function(a,b){var c=a._pgEvents;if(c&&b)for(var d,e,f,g=Object.keys(c),h=0;h<g.length;h++)f=g[h],c[f]>0&&(d=this.dependencyMap[f],e=d?d.index:-1,b[e]=!0)},eventHandler:function(c){var d=c.type;if("touchstart"===d||"mousedown"===d||"pointerdown"===d||"MSPointerDown"===d)if(c._handledByPG||(b={}),this.IS_IOS){var e=c;if("touchstart"===d){var f=c.changedTouches[0];e={target:c.target,clientX:f.clientX,clientY:f.clientY,path:c.path}}for(var g,h=c.path||a.targetFinding.path(e),i=0;i<h.length;i++)g=h[i],this.addGestureDependency(g,b)}else this.addGestureDependency(c.currentTarget,b);if(!c._handledByPG){var j=this.eventMap&&this.eventMap[d];j&&j(c),c._handledByPG=!0}},listen:function(a,b){for(var c,d=0,e=b.length;e>d&&(c=b[d]);d++)this.addEvent(a,c)},unlisten:function(a,b){for(var c,d=0,e=b.length;e>d&&(c=b[d]);d++)this.removeEvent(a,c)},addEvent:function(a,b){a.addEventListener(b,this.boundHandler)},removeEvent:function(a,b){a.removeEventListener(b,this.boundHandler)},makeEvent:function(a,b){var c=f.makePointerEvent(a,b);return c.preventDefault=b.preventDefault,c.tapPrevented=b.tapPrevented,c._target=c._target||b.target,c},fireEvent:function(a,b){var c=this.makeEvent(a,b);return this.dispatchEvent(c)},cloneEvent:function(a){for(var b,f=Object.create(null),g=0;g<c.length;g++)b=c[g],f[b]=a[b]||d[g],("target"===b||"relatedTarget"===b)&&e&&f[b]instanceof SVGElementInstance&&(f[b]=f[b].correspondingUseElement);return f.preventDefault=function(){a.preventDefault()},f},dispatchEvent:function(a){var b=a._target;if(b){b.dispatchEvent(a);var c=this.cloneEvent(a);c.target=b,this.fillGestureQueue(c)}},gestureTrigger:function(){for(var a,b,c=0;c<this.gestureQueue.length;c++)if(a=this.gestureQueue[c],b=a._requiredGestures)for(var d,e,f=0;f<this.gestures.length;f++)b[f]&&(d=this.gestures[f],e=d[a.type],e&&e.call(d,a));this.gestureQueue.length=0},fillGestureQueue:function(a){this.gestureQueue.length||requestAnimationFrame(this.boundGestureTrigger),a._requiredGestures=this.requiredGestures.get(a.pointerId),this.gestureQueue.push(a)}};g.boundHandler=g.eventHandler.bind(g),g.boundGestureTrigger=g.gestureTrigger.bind(g),a.dispatcher=g,a.activateGesture=function(a,b){var c=b.toLowerCase(),d=g.dependencyMap[c];if(d){var e=g.gestures[d.index];if(a._pgListeners||(g.register(a),a._pgListeners=0),e){var f,h=e.defaultActions&&e.defaultActions[c];switch(a.nodeType){case Node.ELEMENT_NODE:f=a;break;case Node.DOCUMENT_FRAGMENT_NODE:f=a.host;break;default:f=null}h&&f&&!f.hasAttribute("touch-action")&&f.setAttribute("touch-action",h)}a._pgEvents||(a._pgEvents={}),a._pgEvents[c]=(a._pgEvents[c]||0)+1,a._pgListeners++}return Boolean(d)},a.addEventListener=function(b,c,d,e){d&&(a.activateGesture(b,c),b.addEventListener(c,d,e))},a.deactivateGesture=function(a,b){var c=b.toLowerCase(),d=g.dependencyMap[c];return d&&(a._pgListeners>0&&a._pgListeners--,0===a._pgListeners&&g.unregister(a),a._pgEvents&&(a._pgEvents[c]>0?a._pgEvents[c]--:a._pgEvents[c]=0)),Boolean(d)},a.removeEventListener=function(b,c,d,e){d&&(a.deactivateGesture(b,c),b.removeEventListener(c,d,e))}}(window.PolymerGestures),function(a){var b=a.dispatcher,c=b.pointermap,d=25,e=[0,1,4,2],f=0,g=/Linux.*Firefox\//i,h=function(){if(g.test(navigator.userAgent))return!1;try{return 1===new MouseEvent("test",{buttons:1}).buttons}catch(a){return!1}}(),i={POINTER_ID:1,POINTER_TYPE:"mouse",events:["mousedown","mousemove","mouseup"],exposes:["down","up","move"],register:function(a){b.listen(a,this.events)},unregister:function(a){a.nodeType!==Node.DOCUMENT_NODE&&b.unlisten(a,this.events)},lastTouches:[],isEventSimulatedFromTouch:function(a){for(var b,c=this.lastTouches,e=a.clientX,f=a.clientY,g=0,h=c.length;h>g&&(b=c[g]);g++){var i=Math.abs(e-b.x),j=Math.abs(f-b.y);if(d>=i&&d>=j)return!0}},prepareEvent:function(a){var c=b.cloneEvent(a);if(c.pointerId=this.POINTER_ID,c.isPrimary=!0,c.pointerType=this.POINTER_TYPE,c._source="mouse",!h){var d=a.type,g=e[a.which]||0;"mousedown"===d?f|=g:"mouseup"===d&&(f&=~g),c.buttons=f}return c},mousedown:function(d){if(!this.isEventSimulatedFromTouch(d)){var e=(c.has(this.POINTER_ID),this.prepareEvent(d));e.target=a.findTarget(d),c.set(this.POINTER_ID,e.target),b.down(e)}},mousemove:function(a){if(!this.isEventSimulatedFromTouch(a)){var d=c.get(this.POINTER_ID);if(d){var e=this.prepareEvent(a);e.target=d,0===(h?e.buttons:e.which)?(h||(f=e.buttons=0),b.cancel(e),this.cleanupMouse(e.buttons)):b.move(e)}}},mouseup:function(d){if(!this.isEventSimulatedFromTouch(d)){var e=this.prepareEvent(d);e.relatedTarget=a.findTarget(d),e.target=c.get(this.POINTER_ID),b.up(e),this.cleanupMouse(e.buttons)}},cleanupMouse:function(a){0===a&&c["delete"](this.POINTER_ID)}};a.mouseEvents=i}(window.PolymerGestures),function(a){var b=a.dispatcher,c=(a.targetFinding.allShadows.bind(a.targetFinding),b.pointermap),d=(Array.prototype.map.call.bind(Array.prototype.map),2500),e=25,f=200,g=20,h=!1,i={IS_IOS:!1,events:["touchstart","touchmove","touchend","touchcancel"],exposes:["down","up","move"],register:function(a,c){(this.IS_IOS?c:!c)&&b.listen(a,this.events)},unregister:function(a){this.IS_IOS||b.unlisten(a,this.events)},scrollTypes:{EMITTER:"none",XSCROLLER:"pan-x",YSCROLLER:"pan-y"},touchActionToScrollType:function(a){var b=a,c=this.scrollTypes;return b===c.EMITTER?"none":b===c.XSCROLLER?"X":b===c.YSCROLLER?"Y":"XY"},POINTER_TYPE:"touch",firstTouch:null,isPrimaryTouch:function(a){return this.firstTouch===a.identifier},setPrimaryTouch:function(a){(0===c.pointers()||1===c.pointers()&&c.has(1))&&(this.firstTouch=a.identifier,this.firstXY={X:a.clientX,Y:a.clientY},this.firstTarget=a.target,this.scrolling=null,this.cancelResetClickCount())},removePrimaryPointer:function(a){a.isPrimary&&(this.firstTouch=null,this.firstXY=null,this.resetClickCount())},clickCount:0,resetId:null,resetClickCount:function(){var a=function(){this.clickCount=0,this.resetId=null}.bind(this);this.resetId=setTimeout(a,f)},cancelResetClickCount:function(){this.resetId&&clearTimeout(this.resetId)},typeToButtons:function(a){var b=0;return("touchstart"===a||"touchmove"===a)&&(b=1),b},findTarget:function(b,d){if("touchstart"===this.currentTouchEvent.type){if(this.isPrimaryTouch(b)){var e={clientX:b.clientX,clientY:b.clientY,path:this.currentTouchEvent.path,target:this.currentTouchEvent.target};return a.findTarget(e)}return a.findTarget(b)}return c.get(d)},touchToPointer:function(a){var c=this.currentTouchEvent,d=b.cloneEvent(a),e=d.pointerId=a.identifier+2;d.target=this.findTarget(a,e),d.bubbles=!0,d.cancelable=!0,d.detail=this.clickCount,d.buttons=this.typeToButtons(c.type),d.width=a.webkitRadiusX||a.radiusX||0,d.height=a.webkitRadiusY||a.radiusY||0,d.pressure=a.webkitForce||a.force||.5,d.isPrimary=this.isPrimaryTouch(a),d.pointerType=this.POINTER_TYPE,d._source="touch";var f=this;return d.preventDefault=function(){f.scrolling=!1,f.firstXY=null,c.preventDefault()},d},processTouches:function(a,b){var d=a.changedTouches;this.currentTouchEvent=a;for(var e,f,g=0;g<d.length;g++)e=d[g],f=this.touchToPointer(e),"touchstart"===a.type&&c.set(f.pointerId,f.target),c.has(f.pointerId)&&b.call(this,f),("touchend"===a.type||a._cancel)&&this.cleanUpPointer(f)},shouldScroll:function(b){if(this.firstXY){var c,d=a.targetFinding.findTouchAction(b),e=this.touchActionToScrollType(d);if("none"===e)c=!1;else if("XY"===e)c=!0;else{var f=b.changedTouches[0],g=e,h="Y"===e?"X":"Y",i=Math.abs(f["client"+g]-this.firstXY[g]),j=Math.abs(f["client"+h]-this.firstXY[h]);c=i>=j}return c}},findTouch:function(a,b){for(var c,d=0,e=a.length;e>d&&(c=a[d]);d++)if(c.identifier===b)return!0},vacuumTouches:function(a){var b=a.touches;if(c.pointers()>=b.length){var d=[];c.forEach(function(a,c){if(1!==c&&!this.findTouch(b,c-2)){var e=a;d.push(e)}},this),d.forEach(function(a){this.cancel(a),c["delete"](a.pointerId)},this)}},touchstart:function(a){this.vacuumTouches(a),this.setPrimaryTouch(a.changedTouches[0]),this.dedupSynthMouse(a),this.scrolling||(this.clickCount++,this.processTouches(a,this.down))},down:function(a){b.down(a)},touchmove:function(a){if(h)a.cancelable&&this.processTouches(a,this.move);else if(this.scrolling){if(this.firstXY){var b=a.changedTouches[0],c=b.clientX-this.firstXY.X,d=b.clientY-this.firstXY.Y,e=Math.sqrt(c*c+d*d);e>=g&&(this.touchcancel(a),this.scrolling=!0,this.firstXY=null)}}else null===this.scrolling&&this.shouldScroll(a)?this.scrolling=!0:(this.scrolling=!1,a.preventDefault(),this.processTouches(a,this.move))},move:function(a){b.move(a)},touchend:function(a){this.dedupSynthMouse(a),this.processTouches(a,this.up)},up:function(c){c.relatedTarget=a.findTarget(c),b.up(c)},cancel:function(a){b.cancel(a)},touchcancel:function(a){a._cancel=!0,this.processTouches(a,this.cancel)},cleanUpPointer:function(a){c["delete"](a.pointerId),this.removePrimaryPointer(a)},dedupSynthMouse:function(b){var c=a.mouseEvents.lastTouches,e=b.changedTouches[0];if(this.isPrimaryTouch(e)){var f={x:e.clientX,y:e.clientY};c.push(f);var g=function(a,b){var c=a.indexOf(b);c>-1&&a.splice(c,1)}.bind(null,c,f);setTimeout(g,d)}}},j=Event.prototype.stopImmediatePropagation||Event.prototype.stopPropagation;document.addEventListener("click",function(b){var c=b.clientX,d=b.clientY,f=function(a){var b=Math.abs(c-a.x),f=Math.abs(d-a.y);return e>=b&&e>=f},g=a.mouseEvents.lastTouches.some(f),h=a.targetFinding.path(b);if(g){for(var k=0;k<h.length;k++)if(h[k]===i.firstTarget)return;b.preventDefault(),j.call(b)}},!0),a.touchEvents=i}(window.PolymerGestures),function(a){var b=a.dispatcher,c=b.pointermap,d=window.MSPointerEvent&&"number"==typeof window.MSPointerEvent.MSPOINTER_TYPE_MOUSE,e={events:["MSPointerDown","MSPointerMove","MSPointerUp","MSPointerCancel"],register:function(a){b.listen(a,this.events)},unregister:function(a){a.nodeType!==Node.DOCUMENT_NODE&&b.unlisten(a,this.events)},POINTER_TYPES:["","unavailable","touch","pen","mouse"],prepareEvent:function(a){var c=a;return c=b.cloneEvent(a),d&&(c.pointerType=this.POINTER_TYPES[a.pointerType]),c._source="ms",c},cleanup:function(a){c["delete"](a)},MSPointerDown:function(d){var e=this.prepareEvent(d);e.target=a.findTarget(d),c.set(d.pointerId,e.target),b.down(e)},MSPointerMove:function(a){var d=c.get(a.pointerId);if(d){var e=this.prepareEvent(a);e.target=d,b.move(e)}},MSPointerUp:function(d){var e=this.prepareEvent(d);e.relatedTarget=a.findTarget(d),e.target=c.get(e.pointerId),b.up(e),this.cleanup(d.pointerId)},MSPointerCancel:function(d){var e=this.prepareEvent(d);e.relatedTarget=a.findTarget(d),e.target=c.get(e.pointerId),b.cancel(e),this.cleanup(d.pointerId)}};a.msEvents=e}(window.PolymerGestures),function(a){var b=a.dispatcher,c=b.pointermap,d={events:["pointerdown","pointermove","pointerup","pointercancel"],prepareEvent:function(a){var c=b.cloneEvent(a);return c._source="pointer",c},register:function(a){b.listen(a,this.events)},unregister:function(a){a.nodeType!==Node.DOCUMENT_NODE&&b.unlisten(a,this.events)},cleanup:function(a){c["delete"](a)},pointerdown:function(d){var e=this.prepareEvent(d);e.target=a.findTarget(d),c.set(e.pointerId,e.target),b.down(e)},pointermove:function(a){var d=c.get(a.pointerId);if(d){var e=this.prepareEvent(a);e.target=d,b.move(e)}},pointerup:function(d){var e=this.prepareEvent(d);e.relatedTarget=a.findTarget(d),e.target=c.get(e.pointerId),b.up(e),this.cleanup(d.pointerId)},pointercancel:function(d){var e=this.prepareEvent(d);e.relatedTarget=a.findTarget(d),e.target=c.get(e.pointerId),b.cancel(e),this.cleanup(d.pointerId)}};a.pointerEvents=d}(window.PolymerGestures),function(a){var b=a.dispatcher,c=window.navigator;window.PointerEvent?b.registerSource("pointer",a.pointerEvents):c.msPointerEnabled?b.registerSource("ms",a.msEvents):(b.registerSource("mouse",a.mouseEvents),void 0!==window.ontouchstart&&b.registerSource("touch",a.touchEvents));var d=navigator.userAgent,e=d.match(/iPad|iPhone|iPod/)&&"ontouchstart"in window;b.IS_IOS=e,a.touchEvents.IS_IOS=e,b.register(document,!0)}(window.PolymerGestures),function(a){var b=a.dispatcher,c=a.eventFactory,d=new a.PointerMap,e={events:["down","move","up"],exposes:["trackstart","track","trackx","tracky","trackend"],defaultActions:{track:"none",trackx:"pan-y",tracky:"pan-x"},WIGGLE_THRESHOLD:4,clampDir:function(a){return a>0?1:-1},calcPositionDelta:function(a,b){var c=0,d=0;return a&&b&&(c=b.pageX-a.pageX,d=b.pageY-a.pageY),{x:c,y:d}},fireTrack:function(a,b,d){var e=d,f=this.calcPositionDelta(e.downEvent,b),g=this.calcPositionDelta(e.lastMoveEvent,b);if(g.x)e.xDirection=this.clampDir(g.x);else if("trackx"===a)return;if(g.y)e.yDirection=this.clampDir(g.y);else if("tracky"===a)return;var h={bubbles:!0,cancelable:!0,trackInfo:e.trackInfo,relatedTarget:b.relatedTarget,pointerType:b.pointerType,pointerId:b.pointerId,_source:"track"};"tracky"!==a&&(h.x=b.x,h.dx=f.x,h.ddx=g.x,h.clientX=b.clientX,h.pageX=b.pageX,h.screenX=b.screenX,h.xDirection=e.xDirection),"trackx"!==a&&(h.dy=f.y,h.ddy=g.y,h.y=b.y,h.clientY=b.clientY,h.pageY=b.pageY,h.screenY=b.screenY,h.yDirection=e.yDirection);var i=c.makeGestureEvent(a,h);e.downTarget.dispatchEvent(i)},down:function(a){if(a.isPrimary&&("mouse"===a.pointerType?1===a.buttons:!0)){var b={downEvent:a,downTarget:a.target,trackInfo:{},lastMoveEvent:null,xDirection:0,yDirection:0,tracking:!1};d.set(a.pointerId,b)}},move:function(a){var b=d.get(a.pointerId);if(b){if(!b.tracking){var c=this.calcPositionDelta(b.downEvent,a),e=c.x*c.x+c.y*c.y;e>this.WIGGLE_THRESHOLD&&(b.tracking=!0,b.lastMoveEvent=b.downEvent,this.fireTrack("trackstart",a,b))}b.tracking&&(this.fireTrack("track",a,b),this.fireTrack("trackx",a,b),this.fireTrack("tracky",a,b)),b.lastMoveEvent=a}},up:function(a){var b=d.get(a.pointerId);b&&(b.tracking&&this.fireTrack("trackend",a,b),d["delete"](a.pointerId))}};b.registerGesture("track",e)}(window.PolymerGestures),function(a){var b=a.dispatcher,c=a.eventFactory,d={HOLD_DELAY:200,WIGGLE_THRESHOLD:16,events:["down","move","up"],exposes:["hold","holdpulse","release"],heldPointer:null,holdJob:null,pulse:function(){var a=Date.now()-this.heldPointer.timeStamp,b=this.held?"holdpulse":"hold";this.fireHold(b,a),this.held=!0},cancel:function(){clearInterval(this.holdJob),this.held&&this.fireHold("release"),this.held=!1,this.heldPointer=null,this.target=null,this.holdJob=null},down:function(a){a.isPrimary&&!this.heldPointer&&(this.heldPointer=a,this.target=a.target,this.holdJob=setInterval(this.pulse.bind(this),this.HOLD_DELAY))},up:function(a){this.heldPointer&&this.heldPointer.pointerId===a.pointerId&&this.cancel()},move:function(a){if(this.heldPointer&&this.heldPointer.pointerId===a.pointerId){var b=a.clientX-this.heldPointer.clientX,c=a.clientY-this.heldPointer.clientY;b*b+c*c>this.WIGGLE_THRESHOLD&&this.cancel()}},fireHold:function(a,b){var d={bubbles:!0,cancelable:!0,pointerType:this.heldPointer.pointerType,pointerId:this.heldPointer.pointerId,x:this.heldPointer.clientX,y:this.heldPointer.clientY,_source:"hold"};b&&(d.holdTime=b);var e=c.makeGestureEvent(a,d);this.target.dispatchEvent(e)}};b.registerGesture("hold",d)}(window.PolymerGestures),function(a){var b=a.dispatcher,c=a.eventFactory,d=new a.PointerMap,e={events:["down","up"],exposes:["tap"],down:function(a){a.isPrimary&&!a.tapPrevented&&d.set(a.pointerId,{target:a.target,buttons:a.buttons,x:a.clientX,y:a.clientY})},shouldTap:function(a,b){var c=!0;return"mouse"===a.pointerType&&(c=1^a.buttons&&1&b.buttons),c&&!a.tapPrevented},up:function(b){var e=d.get(b.pointerId);if(e&&this.shouldTap(b,e)){var f=a.targetFinding.LCA(e.target,b.relatedTarget);if(f){var g=c.makeGestureEvent("tap",{bubbles:!0,cancelable:!0,x:b.clientX,y:b.clientY,detail:b.detail,pointerType:b.pointerType,pointerId:b.pointerId,altKey:b.altKey,ctrlKey:b.ctrlKey,metaKey:b.metaKey,shiftKey:b.shiftKey,_source:"tap"});f.dispatchEvent(g)}}d["delete"](b.pointerId)}};c.preventTap=function(a){return function(){a.tapPrevented=!0,d["delete"](a.pointerId)}},b.registerGesture("tap",e)}(window.PolymerGestures),function(a){var b=a.dispatcher,c=a.eventFactory,d=new a.PointerMap,e=180/Math.PI,f={events:["down","up","move","cancel"],exposes:["pinchstart","pinch","pinchend","rotate"],defaultActions:{pinch:"none",rotate:"none"},reference:{},down:function(b){if(d.set(b.pointerId,b),2==d.pointers()){var c=this.calcChord(),e=this.calcAngle(c);this.reference={angle:e,diameter:c.diameter,target:a.targetFinding.LCA(c.a.target,c.b.target)},this.firePinch("pinchstart",c.diameter,c)}},up:function(a){var b=d.get(a.pointerId),c=d.pointers();if(b){if(2===c){var e=this.calcChord();this.firePinch("pinchend",e.diameter,e)}d["delete"](a.pointerId)}},move:function(a){d.has(a.pointerId)&&(d.set(a.pointerId,a),d.pointers()>1&&this.calcPinchRotate())},cancel:function(a){this.up(a)},firePinch:function(a,b,d){var e=b/this.reference.diameter,f=c.makeGestureEvent(a,{bubbles:!0,cancelable:!0,scale:e,centerX:d.center.x,centerY:d.center.y,_source:"pinch"});this.reference.target.dispatchEvent(f)},fireRotate:function(a,b){var d=Math.round((a-this.reference.angle)%360),e=c.makeGestureEvent("rotate",{bubbles:!0,cancelable:!0,angle:d,centerX:b.center.x,centerY:b.center.y,_source:"pinch"});this.reference.target.dispatchEvent(e)},calcPinchRotate:function(){var a=this.calcChord(),b=a.diameter,c=this.calcAngle(a);b!=this.reference.diameter&&this.firePinch("pinch",b,a),c!=this.reference.angle&&this.fireRotate(c,a)},calcChord:function(){var a=[];d.forEach(function(b){a.push(b)});for(var b,c,e,f=0,g={a:a[0],b:a[1]},h=0;h<a.length;h++)for(var i=a[h],j=h+1;j<a.length;j++){var k=a[j];b=Math.abs(i.clientX-k.clientX),c=Math.abs(i.clientY-k.clientY),e=b+c,e>f&&(f=e,g={a:i,b:k})}return b=Math.abs(g.a.clientX+g.b.clientX)/2,c=Math.abs(g.a.clientY+g.b.clientY)/2,g.center={x:b,y:c},g.diameter=f,g},calcAngle:function(a){var b=a.a.clientX-a.b.clientX,c=a.a.clientY-a.b.clientY;return(360+Math.atan2(c,b)*e)%360}};b.registerGesture("pinch",f)}(window.PolymerGestures),function(a){"use strict";function b(a,b){if(!a)throw new Error("ASSERT: "+b)}function c(a){return a>=48&&57>=a}function d(a){return 32===a||9===a||11===a||12===a||160===a||a>=5760&&" ᠎              ".indexOf(String.fromCharCode(a))>0}function e(a){return 10===a||13===a||8232===a||8233===a}function f(a){return 36===a||95===a||a>=65&&90>=a||a>=97&&122>=a}function g(a){return 36===a||95===a||a>=65&&90>=a||a>=97&&122>=a||a>=48&&57>=a}function h(a){return"this"===a}function i(){for(;Y>X&&d(W.charCodeAt(X));)++X}function j(){var a,b;for(a=X++;Y>X&&(b=W.charCodeAt(X),g(b));)++X;return W.slice(a,X)}function k(){var a,b,c;return a=X,b=j(),c=1===b.length?S.Identifier:h(b)?S.Keyword:"null"===b?S.NullLiteral:"true"===b||"false"===b?S.BooleanLiteral:S.Identifier,{type:c,value:b,range:[a,X]}}function l(){var a,b,c=X,d=W.charCodeAt(X),e=W[X];switch(d){case 46:case 40:case 41:case 59:case 44:case 123:case 125:case 91:case 93:case 58:case 63:return++X,{type:S.Punctuator,value:String.fromCharCode(d),range:[c,X]};default:if(a=W.charCodeAt(X+1),61===a)switch(d){case 37:case 38:case 42:case 43:case 45:case 47:case 60:case 62:case 124:return X+=2,{type:S.Punctuator,value:String.fromCharCode(d)+String.fromCharCode(a),range:[c,X]};case 33:case 61:return X+=2,61===W.charCodeAt(X)&&++X,{type:S.Punctuator,value:W.slice(c,X),range:[c,X]}}}return b=W[X+1],e===b&&"&|".indexOf(e)>=0?(X+=2,{type:S.Punctuator,value:e+b,range:[c,X]}):"<>=!+-*%&|^/".indexOf(e)>=0?(++X,{type:S.Punctuator,value:e,range:[c,X]}):void s({},V.UnexpectedToken,"ILLEGAL")}function m(){var a,d,e;if(e=W[X],b(c(e.charCodeAt(0))||"."===e,"Numeric literal must start with a decimal digit or a decimal point"),d=X,a="","."!==e){for(a=W[X++],e=W[X],"0"===a&&e&&c(e.charCodeAt(0))&&s({},V.UnexpectedToken,"ILLEGAL");c(W.charCodeAt(X));)a+=W[X++];e=W[X]}if("."===e){for(a+=W[X++];c(W.charCodeAt(X));)a+=W[X++];e=W[X]}if("e"===e||"E"===e)if(a+=W[X++],e=W[X],("+"===e||"-"===e)&&(a+=W[X++]),c(W.charCodeAt(X)))for(;c(W.charCodeAt(X));)a+=W[X++];else s({},V.UnexpectedToken,"ILLEGAL");return f(W.charCodeAt(X))&&s({},V.UnexpectedToken,"ILLEGAL"),{type:S.NumericLiteral,value:parseFloat(a),range:[d,X]}}function n(){var a,c,d,f="",g=!1;for(a=W[X],b("'"===a||'"'===a,"String literal must starts with a quote"),c=X,++X;Y>X;){if(d=W[X++],d===a){a="";break}if("\\"===d)if(d=W[X++],d&&e(d.charCodeAt(0)))"\r"===d&&"\n"===W[X]&&++X;else switch(d){case"n":f+="\n";break;case"r":f+="\r";break;case"t":f+="	";break;case"b":f+="\b";break;case"f":f+="\f";break;case"v":f+="";break;default:f+=d}else{if(e(d.charCodeAt(0)))break;f+=d}}return""!==a&&s({},V.UnexpectedToken,"ILLEGAL"),{type:S.StringLiteral,value:f,octal:g,range:[c,X]}}function o(a){return a.type===S.Identifier||a.type===S.Keyword||a.type===S.BooleanLiteral||a.type===S.NullLiteral}function p(){var a;return i(),X>=Y?{type:S.EOF,range:[X,X]}:(a=W.charCodeAt(X),40===a||41===a||58===a?l():39===a||34===a?n():f(a)?k():46===a?c(W.charCodeAt(X+1))?m():l():c(a)?m():l())}function q(){var a;return a=$,X=a.range[1],$=p(),X=a.range[1],a}function r(){var a;a=X,$=p(),X=a}function s(a,c){var d,e=Array.prototype.slice.call(arguments,2),f=c.replace(/%(\d)/g,function(a,c){return b(c<e.length,"Message reference must be in range"),e[c]});throw d=new Error(f),d.index=X,d.description=f,d}function t(a){s(a,V.UnexpectedToken,a.value)}function u(a){var b=q();(b.type!==S.Punctuator||b.value!==a)&&t(b)}function v(a){return $.type===S.Punctuator&&$.value===a}function w(a){return $.type===S.Keyword&&$.value===a}function x(){var a=[];for(u("[");!v("]");)v(",")?(q(),a.push(null)):(a.push(bb()),v("]")||u(","));return u("]"),Z.createArrayExpression(a)}function y(){var a;return i(),a=q(),a.type===S.StringLiteral||a.type===S.NumericLiteral?Z.createLiteral(a):Z.createIdentifier(a.value)}function z(){var a,b;return a=$,i(),(a.type===S.EOF||a.type===S.Punctuator)&&t(a),b=y(),u(":"),Z.createProperty("init",b,bb())}function A(){var a=[];for(u("{");!v("}");)a.push(z()),v("}")||u(",");return u("}"),Z.createObjectExpression(a)}function B(){var a;return u("("),a=bb(),u(")"),a}function C(){var a,b,c;return v("(")?B():(a=$.type,a===S.Identifier?c=Z.createIdentifier(q().value):a===S.StringLiteral||a===S.NumericLiteral?c=Z.createLiteral(q()):a===S.Keyword?w("this")&&(q(),c=Z.createThisExpression()):a===S.BooleanLiteral?(b=q(),b.value="true"===b.value,c=Z.createLiteral(b)):a===S.NullLiteral?(b=q(),b.value=null,c=Z.createLiteral(b)):v("[")?c=x():v("{")&&(c=A()),c?c:void t(q()))}function D(){var a=[];if(u("("),!v(")"))for(;Y>X&&(a.push(bb()),!v(")"));)u(",");return u(")"),a}function E(){var a;return a=q(),o(a)||t(a),Z.createIdentifier(a.value)}function F(){return u("."),E()}function G(){var a;return u("["),a=bb(),u("]"),a}function H(){var a,b,c;for(a=C();;)if(v("["))c=G(),a=Z.createMemberExpression("[",a,c);else if(v("."))c=F(),a=Z.createMemberExpression(".",a,c);else{if(!v("("))break;b=D(),a=Z.createCallExpression(a,b)}return a}function I(){var a,b;return $.type!==S.Punctuator&&$.type!==S.Keyword?b=ab():v("+")||v("-")||v("!")?(a=q(),b=I(),b=Z.createUnaryExpression(a.value,b)):w("delete")||w("void")||w("typeof")?s({},V.UnexpectedToken):b=ab(),b}function J(a){var b=0;if(a.type!==S.Punctuator&&a.type!==S.Keyword)return 0;switch(a.value){case"||":b=1;break;case"&&":b=2;break;case"==":case"!=":case"===":case"!==":b=6;break;case"<":case">":case"<=":case">=":case"instanceof":b=7;break;case"in":b=7;break;case"+":case"-":b=9;break;case"*":case"/":case"%":b=11}return b}function K(){var a,b,c,d,e,f,g,h;if(g=I(),b=$,c=J(b),0===c)return g;for(b.prec=c,q(),e=I(),d=[g,b,e];(c=J($))>0;){for(;d.length>2&&c<=d[d.length-2].prec;)e=d.pop(),f=d.pop().value,g=d.pop(),a=Z.createBinaryExpression(f,g,e),d.push(a);b=q(),b.prec=c,d.push(b),a=I(),d.push(a)}for(h=d.length-1,a=d[h];h>1;)a=Z.createBinaryExpression(d[h-1].value,d[h-2],a),h-=2;return a}function L(){var a,b,c;return a=K(),v("?")&&(q(),b=L(),u(":"),c=L(),a=Z.createConditionalExpression(a,b,c)),a}function M(){var a,b;return a=q(),a.type!==S.Identifier&&t(a),b=v("(")?D():[],Z.createFilter(a.value,b)}function N(){for(;v("|");)q(),M()}function O(){i(),r();var a=bb();a&&(","===$.value||"in"==$.value&&a.type===U.Identifier?Q(a):(N(),"as"===$.value?P(a):Z.createTopLevel(a))),$.type!==S.EOF&&t($)}function P(a){q();var b=q().value;Z.createAsExpression(a,b)}function Q(a){var b;","===$.value&&(q(),$.type!==S.Identifier&&t($),b=q().value),q();var c=bb();N(),Z.createInExpression(a.name,b,c)}function R(a,b){return Z=b,W=a,X=0,Y=W.length,$=null,_={labelSet:{}},O()}var S,T,U,V,W,X,Y,Z,$,_;S={BooleanLiteral:1,EOF:2,Identifier:3,Keyword:4,NullLiteral:5,NumericLiteral:6,Punctuator:7,StringLiteral:8},T={},T[S.BooleanLiteral]="Boolean",T[S.EOF]="<end>",T[S.Identifier]="Identifier",T[S.Keyword]="Keyword",T[S.NullLiteral]="Null",T[S.NumericLiteral]="Numeric",T[S.Punctuator]="Punctuator",T[S.StringLiteral]="String",U={ArrayExpression:"ArrayExpression",BinaryExpression:"BinaryExpression",CallExpression:"CallExpression",ConditionalExpression:"ConditionalExpression",EmptyStatement:"EmptyStatement",ExpressionStatement:"ExpressionStatement",Identifier:"Identifier",Literal:"Literal",LabeledStatement:"LabeledStatement",LogicalExpression:"LogicalExpression",MemberExpression:"MemberExpression",ObjectExpression:"ObjectExpression",Program:"Program",Property:"Property",ThisExpression:"ThisExpression",UnaryExpression:"UnaryExpression"},V={UnexpectedToken:"Unexpected token %0",UnknownLabel:"Undefined label '%0'",Redeclaration:"%0 '%1' has already been declared"};
-var ab=H,bb=L;a.esprima={parse:R}}(this),function(a){"use strict";function b(a,b,d,e){var f;try{if(f=c(a),f.scopeIdent&&(d.nodeType!==Node.ELEMENT_NODE||"TEMPLATE"!==d.tagName||"bind"!==b&&"repeat"!==b))throw Error("as and in can only be used within <template bind/repeat>")}catch(g){return void console.error("Invalid expression syntax: "+a,g)}return function(a,b,c){var d=f.getBinding(a,e,c);return f.scopeIdent&&d&&(b.polymerExpressionScopeIdent_=f.scopeIdent,f.indexIdent&&(b.polymerExpressionIndexIdent_=f.indexIdent)),d}}function c(a){var b=q[a];if(!b){var c=new j;esprima.parse(a,c),b=new l(c),q[a]=b}return b}function d(a){this.value=a,this.valueFn_=void 0}function e(a){this.name=a,this.path=Path.get(a)}function f(a,b,c){this.computed="["==c,this.dynamicDeps="function"==typeof a||a.dynamicDeps||this.computed&&!(b instanceof d),this.simplePath=!this.dynamicDeps&&(b instanceof e||b instanceof d)&&(a instanceof f||a instanceof e),this.object=this.simplePath?a:i(a),this.property=!this.computed||this.simplePath?b:i(b)}function g(a,b){this.name=a,this.args=[];for(var c=0;c<b.length;c++)this.args[c]=i(b[c])}function h(){throw Error("Not Implemented")}function i(a){return"function"==typeof a?a:a.valueFn()}function j(){this.expression=null,this.filters=[],this.deps={},this.currentPath=void 0,this.scopeIdent=void 0,this.indexIdent=void 0,this.dynamicDeps=!1}function k(a){this.value_=a}function l(a){if(this.scopeIdent=a.scopeIdent,this.indexIdent=a.indexIdent,!a.expression)throw Error("No expression found.");this.expression=a.expression,i(this.expression),this.filters=a.filters,this.dynamicDeps=a.dynamicDeps}function m(a){return String(a).replace(/[A-Z]/g,function(a){return"-"+a.toLowerCase()})}function n(a,b){for(;a[t]&&!Object.prototype.hasOwnProperty.call(a,b);)a=a[t];return a}function o(a){switch(a){case"":return!1;case"false":case"null":case"true":return!0}return isNaN(Number(a))?!1:!0}function p(){}var q=Object.create(null);d.prototype={valueFn:function(){if(!this.valueFn_){var a=this.value;this.valueFn_=function(){return a}}return this.valueFn_}},e.prototype={valueFn:function(){if(!this.valueFn_){var a=(this.name,this.path);this.valueFn_=function(b,c){return c&&c.addPath(b,a),a.getValueFrom(b)}}return this.valueFn_},setValue:function(a,b){return 1==this.path.length&&(a=n(a,this.path[0])),this.path.setValueFrom(a,b)}},f.prototype={get fullPath(){if(!this.fullPath_){var a=this.object instanceof f?this.object.fullPath.slice():[this.object.name];a.push(this.property instanceof e?this.property.name:this.property.value),this.fullPath_=Path.get(a)}return this.fullPath_},valueFn:function(){if(!this.valueFn_){var a=this.object;if(this.simplePath){var b=this.fullPath;this.valueFn_=function(a,c){return c&&c.addPath(a,b),b.getValueFrom(a)}}else if(this.computed){var c=this.property;this.valueFn_=function(b,d,e){var f=a(b,d,e),g=c(b,d,e);return d&&d.addPath(f,[g]),f?f[g]:void 0}}else{var b=Path.get(this.property.name);this.valueFn_=function(c,d,e){var f=a(c,d,e);return d&&d.addPath(f,b),b.getValueFrom(f)}}}return this.valueFn_},setValue:function(a,b){if(this.simplePath)return this.fullPath.setValueFrom(a,b),b;var c=this.object(a),d=this.property instanceof e?this.property.name:this.property(a);return c[d]=b}},g.prototype={transform:function(a,b,c,d,e){var f=a,g=f[this.name];if(!g&&(g=c[this.name],!g))return void console.error("Cannot find function or filter: "+this.name);if(d?g=g.toModel:"function"==typeof g.toDOM&&(g=g.toDOM),"function"!=typeof g)return void console.error("Cannot find function or filter: "+this.name);for(var h=e||[],j=0;j<this.args.length;j++)h.push(i(this.args[j])(a,b,c));return g.apply(f,h)}};var r={"+":function(a){return+a},"-":function(a){return-a},"!":function(a){return!a}},s={"+":function(a,b){return a+b},"-":function(a,b){return a-b},"*":function(a,b){return a*b},"/":function(a,b){return a/b},"%":function(a,b){return a%b},"<":function(a,b){return b>a},">":function(a,b){return a>b},"<=":function(a,b){return b>=a},">=":function(a,b){return a>=b},"==":function(a,b){return a==b},"!=":function(a,b){return a!=b},"===":function(a,b){return a===b},"!==":function(a,b){return a!==b},"&&":function(a,b){return a&&b},"||":function(a,b){return a||b}};j.prototype={createUnaryExpression:function(a,b){if(!r[a])throw Error("Disallowed operator: "+a);return b=i(b),function(c,d,e){return r[a](b(c,d,e))}},createBinaryExpression:function(a,b,c){if(!s[a])throw Error("Disallowed operator: "+a);switch(b=i(b),c=i(c),a){case"||":return this.dynamicDeps=!0,function(a,d,e){return b(a,d,e)||c(a,d,e)};case"&&":return this.dynamicDeps=!0,function(a,d,e){return b(a,d,e)&&c(a,d,e)}}return function(d,e,f){return s[a](b(d,e,f),c(d,e,f))}},createConditionalExpression:function(a,b,c){return a=i(a),b=i(b),c=i(c),this.dynamicDeps=!0,function(d,e,f){return a(d,e,f)?b(d,e,f):c(d,e,f)}},createIdentifier:function(a){var b=new e(a);return b.type="Identifier",b},createMemberExpression:function(a,b,c){var d=new f(b,c,a);return d.dynamicDeps&&(this.dynamicDeps=!0),d},createCallExpression:function(a,b){if(!(a instanceof e))throw Error("Only identifier function invocations are allowed");var c=new g(a.name,b);return function(a,b,d){return c.transform(a,b,d,!1)}},createLiteral:function(a){return new d(a.value)},createArrayExpression:function(a){for(var b=0;b<a.length;b++)a[b]=i(a[b]);return function(b,c,d){for(var e=[],f=0;f<a.length;f++)e.push(a[f](b,c,d));return e}},createProperty:function(a,b,c){return{key:b instanceof e?b.name:b.value,value:c}},createObjectExpression:function(a){for(var b=0;b<a.length;b++)a[b].value=i(a[b].value);return function(b,c,d){for(var e={},f=0;f<a.length;f++)e[a[f].key]=a[f].value(b,c,d);return e}},createFilter:function(a,b){this.filters.push(new g(a,b))},createAsExpression:function(a,b){this.expression=a,this.scopeIdent=b},createInExpression:function(a,b,c){this.expression=c,this.scopeIdent=a,this.indexIdent=b},createTopLevel:function(a){this.expression=a},createThisExpression:h},k.prototype={open:function(){return this.value_},discardChanges:function(){return this.value_},deliver:function(){},close:function(){}},l.prototype={getBinding:function(a,b,c){function d(){if(h)return h=!1,g;i.dynamicDeps&&f.startReset();var c=i.getValue(a,i.dynamicDeps?f:void 0,b);return i.dynamicDeps&&f.finishReset(),c}function e(c){return i.setValue(a,c,b),c}if(c)return this.getValue(a,void 0,b);var f=new CompoundObserver,g=this.getValue(a,f,b),h=!0,i=this;return new ObserverTransform(f,d,e,!0)},getValue:function(a,b,c){for(var d=i(this.expression)(a,b,c),e=0;e<this.filters.length;e++)d=this.filters[e].transform(a,b,c,!1,[d]);return d},setValue:function(a,b,c){for(var d=this.filters?this.filters.length:0;d-->0;)b=this.filters[d].transform(a,void 0,c,!0,[b]);return this.expression.setValue?this.expression.setValue(a,b):void 0}};var t="@"+Math.random().toString(36).slice(2);p.prototype={styleObject:function(a){var b=[];for(var c in a)b.push(m(c)+": "+a[c]);return b.join("; ")},tokenList:function(a){var b=[];for(var c in a)a[c]&&b.push(c);return b.join(" ")},prepareInstancePositionChanged:function(a){var b=a.polymerExpressionIndexIdent_;if(b)return function(a,c){a.model[b]=c}},prepareBinding:function(a,c,d){var e=Path.get(a);{if(o(a)||!e.valid)return b(a,c,d,this);if(1==e.length)return function(a,b,c){if(c)return e.getValueFrom(a);var d=n(a,e[0]);return new PathObserver(d,e)}}},prepareInstanceModel:function(a){var b=a.polymerExpressionScopeIdent_;if(b){var c=a.templateInstance?a.templateInstance.model:a.model,d=a.polymerExpressionIndexIdent_;return function(a){return u(c,a,b,d)}}}};var u="__proto__"in{}?function(a,b,c,d){var e={};return e[c]=b,e[d]=void 0,e[t]=a,e.__proto__=a,e}:function(a,b,c,d){var e=Object.create(a);return Object.defineProperty(e,c,{value:b,configurable:!0,writable:!0}),Object.defineProperty(e,d,{value:void 0,configurable:!0,writable:!0}),Object.defineProperty(e,t,{value:a,configurable:!0,writable:!0}),e};a.PolymerExpressions=p,p.getExpression=c}(this),Polymer={version:"0.5.5"},"function"==typeof window.Polymer&&(Polymer={}),function(a){function b(a,b){return b=b||[],b.map||(b=[b]),a.apply(this,b.map(d))}function c(a,c,d){var e;switch(arguments.length){case 0:return;case 1:e=null;break;case 2:e=c.apply(this);break;default:e=b(d,c)}f[a]=e}function d(a){return f[a]}function e(a,c){HTMLImports.whenImportsReady(function(){b(c,a)})}var f={};a.marshal=d,a.modularize=c,a.using=e}(window),window.WebComponents||(window.WebComponents||(WebComponents={flush:function(){},flags:{log:{}}},Platform=WebComponents,CustomElements={useNative:!0,ready:!0,takeRecords:function(){},"instanceof":function(a,b){return a instanceof b}},HTMLImports={useNative:!0},addEventListener("HTMLImportsLoaded",function(){document.dispatchEvent(new CustomEvent("WebComponentsReady",{bubbles:!0}))}),ShadowDOMPolyfill=null,wrap=unwrap=function(a){return a}),window.HTMLImports=window.HTMLImports||{flags:{}},function(a){function b(a,b){b=b||o,d(function(){f(a,b)},b)}function c(a){return"complete"===a.readyState||a.readyState===r}function d(a,b){if(c(b))a&&a();else{var e=function(){("complete"===b.readyState||b.readyState===r)&&(b.removeEventListener(s,e),d(a,b))};b.addEventListener(s,e)}}function e(a){a.target.__loaded=!0}function f(a,b){function c(){h==i&&a&&a()}function d(a){e(a),h++,c()}var f=b.querySelectorAll("link[rel=import]"),h=0,i=f.length;if(i)for(var j,k=0;i>k&&(j=f[k]);k++)g(j)?d.call(j,{target:j}):(j.addEventListener("load",d),j.addEventListener("error",d));else c()}function g(a){return l?a.__loaded||a["import"]&&"loading"!==a["import"].readyState:a.__importParsed}function h(a){for(var b,c=0,d=a.length;d>c&&(b=a[c]);c++)i(b)&&j(b)}function i(a){return"link"===a.localName&&"import"===a.rel}function j(a){var b=a["import"];b?e({target:a}):(a.addEventListener("load",e),a.addEventListener("error",e))}var k="import",l=Boolean(k in document.createElement("link")),m=Boolean(window.ShadowDOMPolyfill),n=function(a){return m?ShadowDOMPolyfill.wrapIfNeeded(a):a},o=n(document),p={get:function(){var a=HTMLImports.currentScript||document.currentScript||("complete"!==document.readyState?document.scripts[document.scripts.length-1]:null);return n(a)},configurable:!0};Object.defineProperty(document,"_currentScript",p),Object.defineProperty(o,"_currentScript",p);var q=/Trident/.test(navigator.userAgent),r=q?"complete":"interactive",s="readystatechange";l&&(new MutationObserver(function(a){for(var b,c=0,d=a.length;d>c&&(b=a[c]);c++)b.addedNodes&&h(b.addedNodes)}).observe(document.head,{childList:!0}),function(){if("loading"===document.readyState)for(var a,b=document.querySelectorAll("link[rel=import]"),c=0,d=b.length;d>c&&(a=b[c]);c++)j(a)}()),b(function(){HTMLImports.ready=!0,HTMLImports.readyTime=(new Date).getTime(),o.dispatchEvent(new CustomEvent("HTMLImportsLoaded",{bubbles:!0}))}),a.IMPORT_LINK_TYPE=k,a.useNative=l,a.rootDocument=o,a.whenReady=b,a.isIE=q}(HTMLImports),function(){var a=document.createElement("style");a.textContent="body {transition: opacity ease-in 0.2s; } \nbody[unresolved] {opacity: 0; display: block; overflow: hidden; } \n";var b=document.querySelector("head");b.insertBefore(a,b.firstChild)}(Platform)),function(a){"use strict";function b(){function a(a){b=a}if("function"!=typeof Object.observe||"function"!=typeof Array.observe)return!1;var b=[],c={},d=[];return Object.observe(c,a),Array.observe(d,a),c.id=1,c.id=2,delete c.id,d.push(1,2),d.length=0,Object.deliverChangeRecords(a),5!==b.length?!1:"add"!=b[0].type||"update"!=b[1].type||"delete"!=b[2].type||"splice"!=b[3].type||"splice"!=b[4].type?!1:(Object.unobserve(c,a),Array.unobserve(d,a),!0)}function c(){if("undefined"!=typeof chrome&&chrome.app&&chrome.app.runtime)return!1;if("undefined"!=typeof navigator&&navigator.getDeviceStorage)return!1;try{var a=new Function("","return true;");return a()}catch(b){return!1}}function d(a){return+a===a>>>0&&""!==a}function e(a){return+a}function f(a){return a===Object(a)}function g(a,b){return a===b?0!==a||1/a===1/b:R(a)&&R(b)?!0:a!==a&&b!==b}function h(a){if(void 0===a)return"eof";var b=a.charCodeAt(0);switch(b){case 91:case 93:case 46:case 34:case 39:case 48:return a;case 95:case 36:return"ident";case 32:case 9:case 10:case 13:case 160:case 65279:case 8232:case 8233:return"ws"}return b>=97&&122>=b||b>=65&&90>=b?"ident":b>=49&&57>=b?"number":"else"}function i(){}function j(a){function b(){if(!(m>=a.length)){var b=a[m+1];return"inSingleQuote"==n&&"'"==b||"inDoubleQuote"==n&&'"'==b?(m++,d=b,o.append(),!0):void 0}}for(var c,d,e,f,g,j,k,l=[],m=-1,n="beforePath",o={push:function(){void 0!==e&&(l.push(e),e=void 0)},append:function(){void 0===e?e=d:e+=d}};n;)if(m++,c=a[m],"\\"!=c||!b(n)){if(f=h(c),k=W[n],g=k[f]||k["else"]||"error","error"==g)return;if(n=g[0],j=o[g[1]]||i,d=void 0===g[2]?c:g[2],j(),"afterPath"===n)return l}}function k(a){return V.test(a)}function l(a,b){if(b!==X)throw Error("Use Path.get to retrieve path objects");for(var c=0;c<a.length;c++)this.push(String(a[c]));Q&&this.length&&(this.getValueFrom=this.compiledGetValueFromFn())}function m(a){if(a instanceof l)return a;if((null==a||0==a.length)&&(a=""),"string"!=typeof a){if(d(a.length))return new l(a,X);a=String(a)}var b=Y[a];if(b)return b;var c=j(a);if(!c)return Z;var b=new l(c,X);return Y[a]=b,b}function n(a){return d(a)?"["+a+"]":'["'+a.replace(/"/g,'\\"')+'"]'}function o(b){for(var c=0;_>c&&b.check_();)c++;return O&&(a.dirtyCheckCycleCount=c),c>0}function p(a){for(var b in a)return!1;return!0}function q(a){return p(a.added)&&p(a.removed)&&p(a.changed)}function r(a,b){var c={},d={},e={};for(var f in b){var g=a[f];(void 0===g||g!==b[f])&&(f in a?g!==b[f]&&(e[f]=g):d[f]=void 0)}for(var f in a)f in b||(c[f]=a[f]);return Array.isArray(a)&&a.length!==b.length&&(e.length=a.length),{added:c,removed:d,changed:e}}function s(){if(!ab.length)return!1;for(var a=0;a<ab.length;a++)ab[a]();return ab.length=0,!0}function t(){function a(a){b&&b.state_===fb&&!d&&b.check_(a)}var b,c,d=!1,e=!0;return{open:function(c){if(b)throw Error("ObservedObject in use");e||Object.deliverChangeRecords(a),b=c,e=!1},observe:function(b,d){c=b,d?Array.observe(c,a):Object.observe(c,a)},deliver:function(b){d=b,Object.deliverChangeRecords(a),d=!1},close:function(){b=void 0,Object.unobserve(c,a),cb.push(this)}}}function u(a,b,c){var d=cb.pop()||t();return d.open(a),d.observe(b,c),d}function v(){function a(b,f){b&&(b===d&&(e[f]=!0),h.indexOf(b)<0&&(h.push(b),Object.observe(b,c)),a(Object.getPrototypeOf(b),f))}function b(a){for(var b=0;b<a.length;b++){var c=a[b];if(c.object!==d||e[c.name]||"setPrototype"===c.type)return!1}return!0}function c(c){if(!b(c)){for(var d,e=0;e<g.length;e++)d=g[e],d.state_==fb&&d.iterateObjects_(a);for(var e=0;e<g.length;e++)d=g[e],d.state_==fb&&d.check_()}}var d,e,f=0,g=[],h=[],i={objects:h,get rootObject(){return d},set rootObject(a){d=a,e={}},open:function(b){g.push(b),f++,b.iterateObjects_(a)},close:function(){if(f--,!(f>0)){for(var a=0;a<h.length;a++)Object.unobserve(h[a],c),x.unobservedCount++;g.length=0,h.length=0,d=void 0,e=void 0,db.push(this),$===this&&($=null)}}};return i}function w(a,b){return $&&$.rootObject===b||($=db.pop()||v(),$.rootObject=b),$.open(a,b),$}function x(){this.state_=eb,this.callback_=void 0,this.target_=void 0,this.directObserver_=void 0,this.value_=void 0,this.id_=ib++}function y(a){x._allObserversCount++,kb&&jb.push(a)}function z(){x._allObserversCount--}function A(a){x.call(this),this.value_=a,this.oldObject_=void 0}function B(a){if(!Array.isArray(a))throw Error("Provided object is not an Array");A.call(this,a)}function C(a,b){x.call(this),this.object_=a,this.path_=m(b),this.directObserver_=void 0}function D(a){x.call(this),this.reportChangesOnOpen_=a,this.value_=[],this.directObserver_=void 0,this.observed_=[]}function E(a){return a}function F(a,b,c,d){this.callback_=void 0,this.target_=void 0,this.value_=void 0,this.observable_=a,this.getValueFn_=b||E,this.setValueFn_=c||E,this.dontPassThroughSet_=d}function G(a,b,c){for(var d={},e={},f=0;f<b.length;f++){var g=b[f];nb[g.type]?(g.name in c||(c[g.name]=g.oldValue),"update"!=g.type&&("add"!=g.type?g.name in d?(delete d[g.name],delete c[g.name]):e[g.name]=!0:g.name in e?delete e[g.name]:d[g.name]=!0)):(console.error("Unknown changeRecord type: "+g.type),console.error(g))}for(var h in d)d[h]=a[h];for(var h in e)e[h]=void 0;var i={};for(var h in c)if(!(h in d||h in e)){var j=a[h];c[h]!==j&&(i[h]=j)}return{added:d,removed:e,changed:i}}function H(a,b,c){return{index:a,removed:b,addedCount:c}}function I(){}function J(a,b,c,d,e,f){return sb.calcSplices(a,b,c,d,e,f)}function K(a,b,c,d){return c>b||a>d?-1:b==c||d==a?0:c>a?d>b?b-c:d-c:b>d?d-a:b-a}function L(a,b,c,d){for(var e=H(b,c,d),f=!1,g=0,h=0;h<a.length;h++){var i=a[h];if(i.index+=g,!f){var j=K(e.index,e.index+e.removed.length,i.index,i.index+i.addedCount);if(j>=0){a.splice(h,1),h--,g-=i.addedCount-i.removed.length,e.addedCount+=i.addedCount-j;var k=e.removed.length+i.removed.length-j;if(e.addedCount||k){var c=i.removed;if(e.index<i.index){var l=e.removed.slice(0,i.index-e.index);Array.prototype.push.apply(l,c),c=l}if(e.index+e.removed.length>i.index+i.addedCount){var m=e.removed.slice(i.index+i.addedCount-e.index);Array.prototype.push.apply(c,m)}e.removed=c,i.index<e.index&&(e.index=i.index)}else f=!0}else if(e.index<i.index){f=!0,a.splice(h,0,e),h++;var n=e.addedCount-e.removed.length;i.index+=n,g+=n}}}f||a.push(e)}function M(a,b){for(var c=[],f=0;f<b.length;f++){var g=b[f];switch(g.type){case"splice":L(c,g.index,g.removed.slice(),g.addedCount);break;case"add":case"update":case"delete":if(!d(g.name))continue;var h=e(g.name);if(0>h)continue;L(c,h,[g.oldValue],1);break;default:console.error("Unexpected record type: "+JSON.stringify(g))}}return c}function N(a,b){var c=[];return M(a,b).forEach(function(b){return 1==b.addedCount&&1==b.removed.length?void(b.removed[0]!==a[b.index]&&c.push(b)):void(c=c.concat(J(a,b.index,b.index+b.addedCount,b.removed,0,b.removed.length)))}),c}var O=a.testingExposeCycleCount,P=b(),Q=c(),R=a.Number.isNaN||function(b){return"number"==typeof b&&a.isNaN(b)},S="__proto__"in{}?function(a){return a}:function(a){var b=a.__proto__;if(!b)return a;var c=Object.create(b);return Object.getOwnPropertyNames(a).forEach(function(b){Object.defineProperty(c,b,Object.getOwnPropertyDescriptor(a,b))}),c},T="[$_a-zA-Z]",U="[$_a-zA-Z0-9]",V=new RegExp("^"+T+"+"+U+"*$"),W={beforePath:{ws:["beforePath"],ident:["inIdent","append"],"[":["beforeElement"],eof:["afterPath"]},inPath:{ws:["inPath"],".":["beforeIdent"],"[":["beforeElement"],eof:["afterPath"]},beforeIdent:{ws:["beforeIdent"],ident:["inIdent","append"]},inIdent:{ident:["inIdent","append"],0:["inIdent","append"],number:["inIdent","append"],ws:["inPath","push"],".":["beforeIdent","push"],"[":["beforeElement","push"],eof:["afterPath","push"]},beforeElement:{ws:["beforeElement"],0:["afterZero","append"],number:["inIndex","append"],"'":["inSingleQuote","append",""],'"':["inDoubleQuote","append",""]},afterZero:{ws:["afterElement","push"],"]":["inPath","push"]},inIndex:{0:["inIndex","append"],number:["inIndex","append"],ws:["afterElement"],"]":["inPath","push"]},inSingleQuote:{"'":["afterElement"],eof:["error"],"else":["inSingleQuote","append"]},inDoubleQuote:{'"':["afterElement"],eof:["error"],"else":["inDoubleQuote","append"]},afterElement:{ws:["afterElement"],"]":["inPath","push"]}},X={},Y={};l.get=m,l.prototype=S({__proto__:[],valid:!0,toString:function(){for(var a="",b=0;b<this.length;b++){var c=this[b];a+=k(c)?b?"."+c:c:n(c)}return a},getValueFrom:function(a){for(var b=0;b<this.length;b++){if(null==a)return;a=a[this[b]]}return a},iterateObjects:function(a,b){for(var c=0;c<this.length;c++){if(c&&(a=a[this[c-1]]),!f(a))return;b(a,this[c])}},compiledGetValueFromFn:function(){var a="",b="obj";a+="if (obj != null";for(var c,d=0;d<this.length-1;d++)c=this[d],b+=k(c)?"."+c:n(c),a+=" &&\n     "+b+" != null";a+=")\n";var c=this[d];return b+=k(c)?"."+c:n(c),a+="  return "+b+";\nelse\n  return undefined;",new Function("obj",a)},setValueFrom:function(a,b){if(!this.length)return!1;for(var c=0;c<this.length-1;c++){if(!f(a))return!1;a=a[this[c]]}return f(a)?(a[this[c]]=b,!0):!1}});var Z=new l("",X);Z.valid=!1,Z.getValueFrom=Z.setValueFrom=function(){};var $,_=1e3,ab=[],bb=P?function(){return function(a){return Promise.resolve().then(a)}}():function(){return function(a){ab.push(a)}}(),cb=[],db=[],eb=0,fb=1,gb=2,hb=3,ib=1;x.prototype={open:function(a,b){if(this.state_!=eb)throw Error("Observer has already been opened.");return y(this),this.callback_=a,this.target_=b,this.connect_(),this.state_=fb,this.value_},close:function(){this.state_==fb&&(z(this),this.disconnect_(),this.value_=void 0,this.callback_=void 0,this.target_=void 0,this.state_=gb)},deliver:function(){this.state_==fb&&o(this)},report_:function(a){try{this.callback_.apply(this.target_,a)}catch(b){x._errorThrownDuringCallback=!0,console.error("Exception caught during observer callback: "+(b.stack||b))}},discardChanges:function(){return this.check_(void 0,!0),this.value_}};var jb,kb=!P;x._allObserversCount=0,kb&&(jb=[]);var lb=!1;a.Platform=a.Platform||{},a.Platform.performMicrotaskCheckpoint=function(){if(!lb&&kb){lb=!0;var b,c,d=0;do{d++,c=jb,jb=[],b=!1;for(var e=0;e<c.length;e++){var f=c[e];f.state_==fb&&(f.check_()&&(b=!0),jb.push(f))}s()&&(b=!0)}while(_>d&&b);O&&(a.dirtyCheckCycleCount=d),lb=!1}},kb&&(a.Platform.clearObservers=function(){jb=[]}),A.prototype=S({__proto__:x.prototype,arrayObserve:!1,connect_:function(){P?this.directObserver_=u(this,this.value_,this.arrayObserve):this.oldObject_=this.copyObject(this.value_)},copyObject:function(a){var b=Array.isArray(a)?[]:{};for(var c in a)b[c]=a[c];return Array.isArray(a)&&(b.length=a.length),b},check_:function(a){var b,c;if(P){if(!a)return!1;c={},b=G(this.value_,a,c)}else c=this.oldObject_,b=r(this.value_,this.oldObject_);return q(b)?!1:(P||(this.oldObject_=this.copyObject(this.value_)),this.report_([b.added||{},b.removed||{},b.changed||{},function(a){return c[a]}]),!0)},disconnect_:function(){P?(this.directObserver_.close(),this.directObserver_=void 0):this.oldObject_=void 0},deliver:function(){this.state_==fb&&(P?this.directObserver_.deliver(!1):o(this))},discardChanges:function(){return this.directObserver_?this.directObserver_.deliver(!0):this.oldObject_=this.copyObject(this.value_),this.value_}}),B.prototype=S({__proto__:A.prototype,arrayObserve:!0,copyObject:function(a){return a.slice()},check_:function(a){var b;if(P){if(!a)return!1;b=N(this.value_,a)}else b=J(this.value_,0,this.value_.length,this.oldObject_,0,this.oldObject_.length);return b&&b.length?(P||(this.oldObject_=this.copyObject(this.value_)),this.report_([b]),!0):!1}}),B.applySplices=function(a,b,c){c.forEach(function(c){for(var d=[c.index,c.removed.length],e=c.index;e<c.index+c.addedCount;)d.push(b[e]),e++;Array.prototype.splice.apply(a,d)})},C.prototype=S({__proto__:x.prototype,get path(){return this.path_},connect_:function(){P&&(this.directObserver_=w(this,this.object_)),this.check_(void 0,!0)},disconnect_:function(){this.value_=void 0,this.directObserver_&&(this.directObserver_.close(this),this.directObserver_=void 0)},iterateObjects_:function(a){this.path_.iterateObjects(this.object_,a)},check_:function(a,b){var c=this.value_;return this.value_=this.path_.getValueFrom(this.object_),b||g(this.value_,c)?!1:(this.report_([this.value_,c,this]),!0)},setValue:function(a){this.path_&&this.path_.setValueFrom(this.object_,a)}});var mb={};D.prototype=S({__proto__:x.prototype,connect_:function(){if(P){for(var a,b=!1,c=0;c<this.observed_.length;c+=2)if(a=this.observed_[c],a!==mb){b=!0;break}b&&(this.directObserver_=w(this,a))}this.check_(void 0,!this.reportChangesOnOpen_)},disconnect_:function(){for(var a=0;a<this.observed_.length;a+=2)this.observed_[a]===mb&&this.observed_[a+1].close();this.observed_.length=0,this.value_.length=0,this.directObserver_&&(this.directObserver_.close(this),this.directObserver_=void 0)},addPath:function(a,b){if(this.state_!=eb&&this.state_!=hb)throw Error("Cannot add paths once started.");var b=m(b);if(this.observed_.push(a,b),this.reportChangesOnOpen_){var c=this.observed_.length/2-1;this.value_[c]=b.getValueFrom(a)}},addObserver:function(a){if(this.state_!=eb&&this.state_!=hb)throw Error("Cannot add observers once started.");if(this.observed_.push(mb,a),this.reportChangesOnOpen_){var b=this.observed_.length/2-1;this.value_[b]=a.open(this.deliver,this)}},startReset:function(){if(this.state_!=fb)throw Error("Can only reset while open");this.state_=hb,this.disconnect_()},finishReset:function(){if(this.state_!=hb)throw Error("Can only finishReset after startReset");return this.state_=fb,this.connect_(),this.value_},iterateObjects_:function(a){for(var b,c=0;c<this.observed_.length;c+=2)b=this.observed_[c],b!==mb&&this.observed_[c+1].iterateObjects(b,a)},check_:function(a,b){for(var c,d=0;d<this.observed_.length;d+=2){var e,f=this.observed_[d],h=this.observed_[d+1];if(f===mb){var i=h;e=this.state_===eb?i.open(this.deliver,this):i.discardChanges()}else e=h.getValueFrom(f);b?this.value_[d/2]=e:g(e,this.value_[d/2])||(c=c||[],c[d/2]=this.value_[d/2],this.value_[d/2]=e)}return c?(this.report_([this.value_,c,this.observed_]),!0):!1}}),F.prototype={open:function(a,b){return this.callback_=a,this.target_=b,this.value_=this.getValueFn_(this.observable_.open(this.observedCallback_,this)),this.value_},observedCallback_:function(a){if(a=this.getValueFn_(a),!g(a,this.value_)){var b=this.value_;this.value_=a,this.callback_.call(this.target_,this.value_,b)}},discardChanges:function(){return this.value_=this.getValueFn_(this.observable_.discardChanges()),this.value_},deliver:function(){return this.observable_.deliver()},setValue:function(a){return a=this.setValueFn_(a),!this.dontPassThroughSet_&&this.observable_.setValue?this.observable_.setValue(a):void 0},close:function(){this.observable_&&this.observable_.close(),this.callback_=void 0,this.target_=void 0,this.observable_=void 0,this.value_=void 0,this.getValueFn_=void 0,this.setValueFn_=void 0}};var nb={add:!0,update:!0,"delete":!0},ob=0,pb=1,qb=2,rb=3;I.prototype={calcEditDistances:function(a,b,c,d,e,f){for(var g=f-e+1,h=c-b+1,i=new Array(g),j=0;g>j;j++)i[j]=new Array(h),i[j][0]=j;for(var k=0;h>k;k++)i[0][k]=k;for(var j=1;g>j;j++)for(var k=1;h>k;k++)if(this.equals(a[b+k-1],d[e+j-1]))i[j][k]=i[j-1][k-1];else{var l=i[j-1][k]+1,m=i[j][k-1]+1;i[j][k]=m>l?l:m}return i},spliceOperationsFromEditDistances:function(a){for(var b=a.length-1,c=a[0].length-1,d=a[b][c],e=[];b>0||c>0;)if(0!=b)if(0!=c){var f,g=a[b-1][c-1],h=a[b-1][c],i=a[b][c-1];f=i>h?g>h?h:g:g>i?i:g,f==g?(g==d?e.push(ob):(e.push(pb),d=g),b--,c--):f==h?(e.push(rb),b--,d=h):(e.push(qb),c--,d=i)}else e.push(rb),b--;else e.push(qb),c--;return e.reverse(),e},calcSplices:function(a,b,c,d,e,f){var g=0,h=0,i=Math.min(c-b,f-e);if(0==b&&0==e&&(g=this.sharedPrefix(a,d,i)),c==a.length&&f==d.length&&(h=this.sharedSuffix(a,d,i-g)),b+=g,e+=g,c-=h,f-=h,c-b==0&&f-e==0)return[];if(b==c){for(var j=H(b,[],0);f>e;)j.removed.push(d[e++]);return[j]}if(e==f)return[H(b,[],c-b)];for(var k=this.spliceOperationsFromEditDistances(this.calcEditDistances(a,b,c,d,e,f)),j=void 0,l=[],m=b,n=e,o=0;o<k.length;o++)switch(k[o]){case ob:j&&(l.push(j),j=void 0),m++,n++;break;case pb:j||(j=H(m,[],0)),j.addedCount++,m++,j.removed.push(d[n]),n++;break;case qb:j||(j=H(m,[],0)),j.addedCount++,m++;break;case rb:j||(j=H(m,[],0)),j.removed.push(d[n]),n++}return j&&l.push(j),l},sharedPrefix:function(a,b,c){for(var d=0;c>d;d++)if(!this.equals(a[d],b[d]))return d;return c},sharedSuffix:function(a,b,c){for(var d=a.length,e=b.length,f=0;c>f&&this.equals(a[--d],b[--e]);)f++;return f},calculateSplices:function(a,b){return this.calcSplices(a,0,a.length,b,0,b.length)},equals:function(a,b){return a===b}};var sb=new I,tb=a;"undefined"==typeof exports||exports.nodeType||("undefined"!=typeof module&&module.exports&&(exports=module.exports),tb=exports),tb.Observer=x,tb.Observer.runEOM_=bb,tb.Observer.observerSentinel_=mb,tb.Observer.hasObjectObserve=P,tb.ArrayObserver=B,tb.ArrayObserver.calculateSplices=function(a,b){return sb.calculateSplices(a,b)},tb.ArraySplice=I,tb.ObjectObserver=A,tb.PathObserver=C,tb.CompoundObserver=D,tb.Path=l,tb.ObserverTransform=F}("undefined"!=typeof global&&global&&"undefined"!=typeof module&&module?global:this||window),function(){"use strict";function a(a){for(;a.parentNode;)a=a.parentNode;return"function"==typeof a.getElementById?a:null}function b(a,b,c){var d=a.bindings_;return d||(d=a.bindings_={}),d[b]&&c[b].close(),d[b]=c}function c(a,b,c){return c}function d(a){return null==a?"":a}function e(a,b){a.data=d(b)}function f(a){return function(b){return e(a,b)}}function g(a,b,c,e){return c?void(e?a.setAttribute(b,""):a.removeAttribute(b)):void a.setAttribute(b,d(e))}function h(a,b,c){return function(d){g(a,b,c,d)}}function i(a){switch(a.type){case"checkbox":return u;case"radio":case"select-multiple":case"select-one":return"change";case"range":if(/Trident|MSIE/.test(navigator.userAgent))return"change";default:return"input"}}function j(a,b,c,e){a[b]=(e||d)(c)}function k(a,b,c){return function(d){return j(a,b,d,c)}}function l(){}function m(a,b,c,d){function e(){var e="value"==b&&"number"==a.type;c.setValue(e?a.valueAsNumber:a[b]),c.discardChanges(),(d||l)(a),Platform.performMicrotaskCheckpoint()}var f=i(a);return a.addEventListener(f,e),{close:function(){a.removeEventListener(f,e),c.close()},observable_:c}}function n(a){return Boolean(a)}function o(b){if(b.form)return s(b.form.elements,function(a){return a!=b&&"INPUT"==a.tagName&&"radio"==a.type&&a.name==b.name});var c=a(b);if(!c)return[];var d=c.querySelectorAll('input[type="radio"][name="'+b.name+'"]');return s(d,function(a){return a!=b&&!a.form})}function p(a){"INPUT"===a.tagName&&"radio"===a.type&&o(a).forEach(function(a){var b=a.bindings_.checked;b&&b.observable_.setValue(!1)})}function q(a,b){var c,e,f,g=a.parentNode;g instanceof HTMLSelectElement&&g.bindings_&&g.bindings_.value&&(c=g,e=c.bindings_.value,f=c.value),a.value=d(b),c&&c.value!=f&&(e.observable_.setValue(c.value),e.observable_.discardChanges(),Platform.performMicrotaskCheckpoint())}function r(a){return function(b){q(a,b)}}var s=Array.prototype.filter.call.bind(Array.prototype.filter);Node.prototype.bind=function(a,b){console.error("Unhandled binding to Node: ",this,a,b)},Node.prototype.bindFinished=function(){};var t=c;Object.defineProperty(Platform,"enableBindingsReflection",{get:function(){return t===b},set:function(a){return t=a?b:c,a},configurable:!0}),Text.prototype.bind=function(a,b,c){if("textContent"!==a)return Node.prototype.bind.call(this,a,b,c);if(c)return e(this,b);var d=b;return e(this,d.open(f(this))),t(this,a,d)},Element.prototype.bind=function(a,b,c){var d="?"==a[a.length-1];if(d&&(this.removeAttribute(a),a=a.slice(0,-1)),c)return g(this,a,d,b);var e=b;return g(this,a,d,e.open(h(this,a,d))),t(this,a,e)};var u;!function(){var a=document.createElement("div"),b=a.appendChild(document.createElement("input"));b.setAttribute("type","checkbox");var c,d=0;b.addEventListener("click",function(){d++,c=c||"click"}),b.addEventListener("change",function(){d++,c=c||"change"});var e=document.createEvent("MouseEvent");e.initMouseEvent("click",!0,!0,window,0,0,0,0,0,!1,!1,!1,!1,0,null),b.dispatchEvent(e),u=1==d?"change":c}(),HTMLInputElement.prototype.bind=function(a,c,e){if("value"!==a&&"checked"!==a)return HTMLElement.prototype.bind.call(this,a,c,e);this.removeAttribute(a);var f="checked"==a?n:d,g="checked"==a?p:l;if(e)return j(this,a,c,f);var h=c,i=m(this,a,h,g);return j(this,a,h.open(k(this,a,f)),f),b(this,a,i)},HTMLTextAreaElement.prototype.bind=function(a,b,c){if("value"!==a)return HTMLElement.prototype.bind.call(this,a,b,c);if(this.removeAttribute("value"),c)return j(this,"value",b);var e=b,f=m(this,"value",e);return j(this,"value",e.open(k(this,"value",d))),t(this,a,f)},HTMLOptionElement.prototype.bind=function(a,b,c){if("value"!==a)return HTMLElement.prototype.bind.call(this,a,b,c);if(this.removeAttribute("value"),c)return q(this,b);var d=b,e=m(this,"value",d);
-return q(this,d.open(r(this))),t(this,a,e)},HTMLSelectElement.prototype.bind=function(a,c,d){if("selectedindex"===a&&(a="selectedIndex"),"selectedIndex"!==a&&"value"!==a)return HTMLElement.prototype.bind.call(this,a,c,d);if(this.removeAttribute(a),d)return j(this,a,c);var e=c,f=m(this,a,e);return j(this,a,e.open(k(this,a))),b(this,a,f)}}(this),function(a){"use strict";function b(a){if(!a)throw new Error("Assertion failed")}function c(a){for(var b;b=a.parentNode;)a=b;return a}function d(a,b){if(b){for(var d,e="#"+b;!d&&(a=c(a),a.protoContent_?d=a.protoContent_.querySelector(e):a.getElementById&&(d=a.getElementById(b)),!d&&a.templateCreator_);)a=a.templateCreator_;return d}}function e(a){return"template"==a.tagName&&"http://www.w3.org/2000/svg"==a.namespaceURI}function f(a){return"TEMPLATE"==a.tagName&&"http://www.w3.org/1999/xhtml"==a.namespaceURI}function g(a){return Boolean(L[a.tagName]&&a.hasAttribute("template"))}function h(a){return void 0===a.isTemplate_&&(a.isTemplate_="TEMPLATE"==a.tagName||g(a)),a.isTemplate_}function i(a,b){var c=a.querySelectorAll(N);h(a)&&b(a),G(c,b)}function j(a){function b(a){HTMLTemplateElement.decorate(a)||j(a.content)}i(a,b)}function k(a,b){Object.getOwnPropertyNames(b).forEach(function(c){Object.defineProperty(a,c,Object.getOwnPropertyDescriptor(b,c))})}function l(a){var b=a.ownerDocument;if(!b.defaultView)return b;var c=b.templateContentsOwner_;if(!c){for(c=b.implementation.createHTMLDocument("");c.lastChild;)c.removeChild(c.lastChild);b.templateContentsOwner_=c}return c}function m(a){if(!a.stagingDocument_){var b=a.ownerDocument;if(!b.stagingDocument_){b.stagingDocument_=b.implementation.createHTMLDocument(""),b.stagingDocument_.isStagingDocument=!0;var c=b.stagingDocument_.createElement("base");c.href=document.baseURI,b.stagingDocument_.head.appendChild(c),b.stagingDocument_.stagingDocument_=b.stagingDocument_}a.stagingDocument_=b.stagingDocument_}return a.stagingDocument_}function n(a){var b=a.ownerDocument.createElement("template");a.parentNode.insertBefore(b,a);for(var c=a.attributes,d=c.length;d-->0;){var e=c[d];K[e.name]&&("template"!==e.name&&b.setAttribute(e.name,e.value),a.removeAttribute(e.name))}return b}function o(a){var b=a.ownerDocument.createElement("template");a.parentNode.insertBefore(b,a);for(var c=a.attributes,d=c.length;d-->0;){var e=c[d];b.setAttribute(e.name,e.value),a.removeAttribute(e.name)}return a.parentNode.removeChild(a),b}function p(a,b,c){var d=a.content;if(c)return void d.appendChild(b);for(var e;e=b.firstChild;)d.appendChild(e)}function q(a){P?a.__proto__=HTMLTemplateElement.prototype:k(a,HTMLTemplateElement.prototype)}function r(a){a.setModelFn_||(a.setModelFn_=function(){a.setModelFnScheduled_=!1;var b=z(a,a.delegate_&&a.delegate_.prepareBinding);w(a,b,a.model_)}),a.setModelFnScheduled_||(a.setModelFnScheduled_=!0,Observer.runEOM_(a.setModelFn_))}function s(a,b,c,d){if(a&&a.length){for(var e,f=a.length,g=0,h=0,i=0,j=!0;f>h;){var g=a.indexOf("{{",h),k=a.indexOf("[[",h),l=!1,m="}}";if(k>=0&&(0>g||g>k)&&(g=k,l=!0,m="]]"),i=0>g?-1:a.indexOf(m,g+2),0>i){if(!e)return;e.push(a.slice(h));break}e=e||[],e.push(a.slice(h,g));var n=a.slice(g+2,i).trim();e.push(l),j=j&&l;var o=d&&d(n,b,c);e.push(null==o?Path.get(n):null),e.push(o),h=i+2}return h===f&&e.push(""),e.hasOnePath=5===e.length,e.isSimplePath=e.hasOnePath&&""==e[0]&&""==e[4],e.onlyOneTime=j,e.combinator=function(a){for(var b=e[0],c=1;c<e.length;c+=4){var d=e.hasOnePath?a:a[(c-1)/4];void 0!==d&&(b+=d),b+=e[c+3]}return b},e}}function t(a,b,c,d){if(b.hasOnePath){var e=b[3],f=e?e(d,c,!0):b[2].getValueFrom(d);return b.isSimplePath?f:b.combinator(f)}for(var g=[],h=1;h<b.length;h+=4){var e=b[h+2];g[(h-1)/4]=e?e(d,c):b[h+1].getValueFrom(d)}return b.combinator(g)}function u(a,b,c,d){var e=b[3],f=e?e(d,c,!1):new PathObserver(d,b[2]);return b.isSimplePath?f:new ObserverTransform(f,b.combinator)}function v(a,b,c,d){if(b.onlyOneTime)return t(a,b,c,d);if(b.hasOnePath)return u(a,b,c,d);for(var e=new CompoundObserver,f=1;f<b.length;f+=4){var g=b[f],h=b[f+2];if(h){var i=h(d,c,g);g?e.addPath(i):e.addObserver(i)}else{var j=b[f+1];g?e.addPath(j.getValueFrom(d)):e.addPath(d,j)}}return new ObserverTransform(e,b.combinator)}function w(a,b,c,d){for(var e=0;e<b.length;e+=2){var f=b[e],g=b[e+1],h=v(f,g,a,c),i=a.bind(f,h,g.onlyOneTime);i&&d&&d.push(i)}if(a.bindFinished(),b.isTemplate){a.model_=c;var j=a.processBindingDirectives_(b);d&&j&&d.push(j)}}function x(a,b,c){var d=a.getAttribute(b);return s(""==d?"{{}}":d,b,a,c)}function y(a,c){b(a);for(var d=[],e=0;e<a.attributes.length;e++){for(var f=a.attributes[e],g=f.name,i=f.value;"_"===g[0];)g=g.substring(1);if(!h(a)||g!==J&&g!==H&&g!==I){var j=s(i,g,a,c);j&&d.push(g,j)}}return h(a)&&(d.isTemplate=!0,d["if"]=x(a,J,c),d.bind=x(a,H,c),d.repeat=x(a,I,c),!d["if"]||d.bind||d.repeat||(d.bind=s("{{}}",H,a,c))),d}function z(a,b){if(a.nodeType===Node.ELEMENT_NODE)return y(a,b);if(a.nodeType===Node.TEXT_NODE){var c=s(a.data,"textContent",a,b);if(c)return["textContent",c]}return[]}function A(a,b,c,d,e,f,g){for(var h=b.appendChild(c.importNode(a,!1)),i=0,j=a.firstChild;j;j=j.nextSibling)A(j,h,c,d.children[i++],e,f,g);return d.isTemplate&&(HTMLTemplateElement.decorate(h,a),f&&h.setDelegate_(f)),w(h,d,e,g),h}function B(a,b){var c=z(a,b);c.children={};for(var d=0,e=a.firstChild;e;e=e.nextSibling)c.children[d++]=B(e,b);return c}function C(a){var b=a.id_;return b||(b=a.id_=S++),b}function D(a,b){var c=C(a);if(b){var d=b.bindingMaps[c];return d||(d=b.bindingMaps[c]=B(a,b.prepareBinding)||[]),d}var d=a.bindingMap_;return d||(d=a.bindingMap_=B(a,void 0)||[]),d}function E(a){this.closed=!1,this.templateElement_=a,this.instances=[],this.deps=void 0,this.iteratedValue=[],this.presentValue=void 0,this.arrayObserver=void 0}var F,G=Array.prototype.forEach.call.bind(Array.prototype.forEach);a.Map&&"function"==typeof a.Map.prototype.forEach?F=a.Map:(F=function(){this.keys=[],this.values=[]},F.prototype={set:function(a,b){var c=this.keys.indexOf(a);0>c?(this.keys.push(a),this.values.push(b)):this.values[c]=b},get:function(a){var b=this.keys.indexOf(a);if(!(0>b))return this.values[b]},"delete":function(a){var b=this.keys.indexOf(a);return 0>b?!1:(this.keys.splice(b,1),this.values.splice(b,1),!0)},forEach:function(a,b){for(var c=0;c<this.keys.length;c++)a.call(b||this,this.values[c],this.keys[c],this)}});"function"!=typeof document.contains&&(Document.prototype.contains=function(a){return a===this||a.parentNode===this?!0:this.documentElement.contains(a)});var H="bind",I="repeat",J="if",K={template:!0,repeat:!0,bind:!0,ref:!0,"if":!0},L={THEAD:!0,TBODY:!0,TFOOT:!0,TH:!0,TR:!0,TD:!0,COLGROUP:!0,COL:!0,CAPTION:!0,OPTION:!0,OPTGROUP:!0},M="undefined"!=typeof HTMLTemplateElement;M&&!function(){var a=document.createElement("template"),b=a.content.ownerDocument,c=b.appendChild(b.createElement("html")),d=c.appendChild(b.createElement("head")),e=b.createElement("base");e.href=document.baseURI,d.appendChild(e)}();var N="template, "+Object.keys(L).map(function(a){return a.toLowerCase()+"[template]"}).join(", ");document.addEventListener("DOMContentLoaded",function(){j(document),Platform.performMicrotaskCheckpoint()},!1),M||(a.HTMLTemplateElement=function(){throw TypeError("Illegal constructor")});var O,P="__proto__"in{};"function"==typeof MutationObserver&&(O=new MutationObserver(function(a){for(var b=0;b<a.length;b++)a[b].target.refChanged_()})),HTMLTemplateElement.decorate=function(a,c){if(a.templateIsDecorated_)return!1;var d=a;d.templateIsDecorated_=!0;var h=f(d)&&M,i=h,k=!h,m=!1;if(h||(g(d)?(b(!c),d=n(a),d.templateIsDecorated_=!0,h=M,m=!0):e(d)&&(d=o(a),d.templateIsDecorated_=!0,h=M)),!h){q(d);var r=l(d);d.content_=r.createDocumentFragment()}return c?d.instanceRef_=c:k?p(d,a,m):i&&j(d.content),!0},HTMLTemplateElement.bootstrap=j;var Q=a.HTMLUnknownElement||HTMLElement,R={get:function(){return this.content_},enumerable:!0,configurable:!0};M||(HTMLTemplateElement.prototype=Object.create(Q.prototype),Object.defineProperty(HTMLTemplateElement.prototype,"content",R)),k(HTMLTemplateElement.prototype,{bind:function(a,b,c){if("ref"!=a)return Element.prototype.bind.call(this,a,b,c);var d=this,e=c?b:b.open(function(a){d.setAttribute("ref",a),d.refChanged_()});return this.setAttribute("ref",e),this.refChanged_(),c?void 0:(this.bindings_?this.bindings_.ref=b:this.bindings_={ref:b},b)},processBindingDirectives_:function(a){return this.iterator_&&this.iterator_.closeDeps(),a["if"]||a.bind||a.repeat?(this.iterator_||(this.iterator_=new E(this)),this.iterator_.updateDependencies(a,this.model_),O&&O.observe(this,{attributes:!0,attributeFilter:["ref"]}),this.iterator_):void(this.iterator_&&(this.iterator_.close(),this.iterator_=void 0))},createInstance:function(a,b,c){b?c=this.newDelegate_(b):c||(c=this.delegate_),this.refContent_||(this.refContent_=this.ref_.content);var d=this.refContent_;if(null===d.firstChild)return T;var e=D(d,c),f=m(this),g=f.createDocumentFragment();g.templateCreator_=this,g.protoContent_=d,g.bindings_=[],g.terminator_=null;for(var h=g.templateInstance_={firstNode:null,lastNode:null,model:a},i=0,j=!1,k=d.firstChild;k;k=k.nextSibling){null===k.nextSibling&&(j=!0);var l=A(k,g,f,e.children[i++],a,c,g.bindings_);l.templateInstance_=h,j&&(g.terminator_=l)}return h.firstNode=g.firstChild,h.lastNode=g.lastChild,g.templateCreator_=void 0,g.protoContent_=void 0,g},get model(){return this.model_},set model(a){this.model_=a,r(this)},get bindingDelegate(){return this.delegate_&&this.delegate_.raw},refChanged_:function(){this.iterator_&&this.refContent_!==this.ref_.content&&(this.refContent_=void 0,this.iterator_.valueChanged(),this.iterator_.updateIteratedValue(this.iterator_.getUpdatedValue()))},clear:function(){this.model_=void 0,this.delegate_=void 0,this.bindings_&&this.bindings_.ref&&this.bindings_.ref.close(),this.refContent_=void 0,this.iterator_&&(this.iterator_.valueChanged(),this.iterator_.close(),this.iterator_=void 0)},setDelegate_:function(a){this.delegate_=a,this.bindingMap_=void 0,this.iterator_&&(this.iterator_.instancePositionChangedFn_=void 0,this.iterator_.instanceModelFn_=void 0)},newDelegate_:function(a){function b(b){var c=a&&a[b];if("function"==typeof c)return function(){return c.apply(a,arguments)}}if(a)return{bindingMaps:{},raw:a,prepareBinding:b("prepareBinding"),prepareInstanceModel:b("prepareInstanceModel"),prepareInstancePositionChanged:b("prepareInstancePositionChanged")}},set bindingDelegate(a){if(this.delegate_)throw Error("Template must be cleared before a new bindingDelegate can be assigned");this.setDelegate_(this.newDelegate_(a))},get ref_(){var a=d(this,this.getAttribute("ref"));if(a||(a=this.instanceRef_),!a)return this;var b=a.ref_;return b?b:a}});var S=1;Object.defineProperty(Node.prototype,"templateInstance",{get:function(){var a=this.templateInstance_;return a?a:this.parentNode?this.parentNode.templateInstance:void 0}});var T=document.createDocumentFragment();T.bindings_=[],T.terminator_=null,E.prototype={closeDeps:function(){var a=this.deps;a&&(a.ifOneTime===!1&&a.ifValue.close(),a.oneTime===!1&&a.value.close())},updateDependencies:function(a,b){this.closeDeps();var c=this.deps={},d=this.templateElement_,e=!0;if(a["if"]){if(c.hasIf=!0,c.ifOneTime=a["if"].onlyOneTime,c.ifValue=v(J,a["if"],d,b),e=c.ifValue,c.ifOneTime&&!e)return void this.valueChanged();c.ifOneTime||(e=e.open(this.updateIfValue,this))}a.repeat?(c.repeat=!0,c.oneTime=a.repeat.onlyOneTime,c.value=v(I,a.repeat,d,b)):(c.repeat=!1,c.oneTime=a.bind.onlyOneTime,c.value=v(H,a.bind,d,b));var f=c.value;return c.oneTime||(f=f.open(this.updateIteratedValue,this)),e?void this.updateValue(f):void this.valueChanged()},getUpdatedValue:function(){var a=this.deps.value;return this.deps.oneTime||(a=a.discardChanges()),a},updateIfValue:function(a){return a?void this.updateValue(this.getUpdatedValue()):void this.valueChanged()},updateIteratedValue:function(a){if(this.deps.hasIf){var b=this.deps.ifValue;if(this.deps.ifOneTime||(b=b.discardChanges()),!b)return void this.valueChanged()}this.updateValue(a)},updateValue:function(a){this.deps.repeat||(a=[a]);var b=this.deps.repeat&&!this.deps.oneTime&&Array.isArray(a);this.valueChanged(a,b)},valueChanged:function(a,b){Array.isArray(a)||(a=[]),a!==this.iteratedValue&&(this.unobserve(),this.presentValue=a,b&&(this.arrayObserver=new ArrayObserver(this.presentValue),this.arrayObserver.open(this.handleSplices,this)),this.handleSplices(ArrayObserver.calculateSplices(this.presentValue,this.iteratedValue)))},getLastInstanceNode:function(a){if(-1==a)return this.templateElement_;var b=this.instances[a],c=b.terminator_;if(!c)return this.getLastInstanceNode(a-1);if(c.nodeType!==Node.ELEMENT_NODE||this.templateElement_===c)return c;var d=c.iterator_;return d?d.getLastTemplateNode():c},getLastTemplateNode:function(){return this.getLastInstanceNode(this.instances.length-1)},insertInstanceAt:function(a,b){var c=this.getLastInstanceNode(a-1),d=this.templateElement_.parentNode;this.instances.splice(a,0,b),d.insertBefore(b,c.nextSibling)},extractInstanceAt:function(a){for(var b=this.getLastInstanceNode(a-1),c=this.getLastInstanceNode(a),d=this.templateElement_.parentNode,e=this.instances.splice(a,1)[0];c!==b;){var f=b.nextSibling;f==c&&(c=b),e.appendChild(d.removeChild(f))}return e},getDelegateFn:function(a){return a=a&&a(this.templateElement_),"function"==typeof a?a:null},handleSplices:function(a){if(!this.closed&&a.length){var b=this.templateElement_;if(!b.parentNode)return void this.close();ArrayObserver.applySplices(this.iteratedValue,this.presentValue,a);var c=b.delegate_;void 0===this.instanceModelFn_&&(this.instanceModelFn_=this.getDelegateFn(c&&c.prepareInstanceModel)),void 0===this.instancePositionChangedFn_&&(this.instancePositionChangedFn_=this.getDelegateFn(c&&c.prepareInstancePositionChanged));for(var d=new F,e=0,f=0;f<a.length;f++){for(var g=a[f],h=g.removed,i=0;i<h.length;i++){var j=h[i],k=this.extractInstanceAt(g.index+e);k!==T&&d.set(j,k)}e-=g.addedCount}for(var f=0;f<a.length;f++)for(var g=a[f],l=g.index;l<g.index+g.addedCount;l++){var j=this.iteratedValue[l],k=d.get(j);k?d["delete"](j):(this.instanceModelFn_&&(j=this.instanceModelFn_(j)),k=void 0===j?T:b.createInstance(j,void 0,c)),this.insertInstanceAt(l,k)}d.forEach(function(a){this.closeInstanceBindings(a)},this),this.instancePositionChangedFn_&&this.reportInstancesMoved(a)}},reportInstanceMoved:function(a){var b=this.instances[a];b!==T&&this.instancePositionChangedFn_(b.templateInstance_,a)},reportInstancesMoved:function(a){for(var b=0,c=0,d=0;d<a.length;d++){var e=a[d];if(0!=c)for(;b<e.index;)this.reportInstanceMoved(b),b++;else b=e.index;for(;b<e.index+e.addedCount;)this.reportInstanceMoved(b),b++;c+=e.addedCount-e.removed.length}if(0!=c)for(var f=this.instances.length;f>b;)this.reportInstanceMoved(b),b++},closeInstanceBindings:function(a){for(var b=a.bindings_,c=0;c<b.length;c++)b[c].close()},unobserve:function(){this.arrayObserver&&(this.arrayObserver.close(),this.arrayObserver=void 0)},close:function(){if(!this.closed){this.unobserve();for(var a=0;a<this.instances.length;a++)this.closeInstanceBindings(this.instances[a]);this.instances.length=0,this.closeDeps(),this.templateElement_.iterator_=void 0,this.closed=!0}}},HTMLTemplateElement.forAllTemplatesFrom_=i}(this),function(a){"use strict";function b(a){return void 0!==m[a]}function c(){h.call(this),this._isInvalid=!0}function d(a){return""==a&&c.call(this),a.toLowerCase()}function e(a){var b=a.charCodeAt(0);return b>32&&127>b&&-1==[34,35,60,62,63,96].indexOf(b)?a:encodeURIComponent(a)}function f(a){var b=a.charCodeAt(0);return b>32&&127>b&&-1==[34,35,60,62,96].indexOf(b)?a:encodeURIComponent(a)}function g(a,g,h){function i(a){t.push(a)}var j=g||"scheme start",k=0,l="",r=!1,s=!1,t=[];a:for(;(a[k-1]!=o||0==k)&&!this._isInvalid;){var u=a[k];switch(j){case"scheme start":if(!u||!p.test(u)){if(g){i("Invalid scheme.");break a}l="",j="no scheme";continue}l+=u.toLowerCase(),j="scheme";break;case"scheme":if(u&&q.test(u))l+=u.toLowerCase();else{if(":"!=u){if(g){if(o==u)break a;i("Code point not allowed in scheme: "+u);break a}l="",k=0,j="no scheme";continue}if(this._scheme=l,l="",g)break a;b(this._scheme)&&(this._isRelative=!0),j="file"==this._scheme?"relative":this._isRelative&&h&&h._scheme==this._scheme?"relative or authority":this._isRelative?"authority first slash":"scheme data"}break;case"scheme data":"?"==u?(query="?",j="query"):"#"==u?(this._fragment="#",j="fragment"):o!=u&&"	"!=u&&"\n"!=u&&"\r"!=u&&(this._schemeData+=e(u));break;case"no scheme":if(h&&b(h._scheme)){j="relative";continue}i("Missing scheme."),c.call(this);break;case"relative or authority":if("/"!=u||"/"!=a[k+1]){i("Expected /, got: "+u),j="relative";continue}j="authority ignore slashes";break;case"relative":if(this._isRelative=!0,"file"!=this._scheme&&(this._scheme=h._scheme),o==u){this._host=h._host,this._port=h._port,this._path=h._path.slice(),this._query=h._query;break a}if("/"==u||"\\"==u)"\\"==u&&i("\\ is an invalid code point."),j="relative slash";else if("?"==u)this._host=h._host,this._port=h._port,this._path=h._path.slice(),this._query="?",j="query";else{if("#"!=u){var v=a[k+1],w=a[k+2];("file"!=this._scheme||!p.test(u)||":"!=v&&"|"!=v||o!=w&&"/"!=w&&"\\"!=w&&"?"!=w&&"#"!=w)&&(this._host=h._host,this._port=h._port,this._path=h._path.slice(),this._path.pop()),j="relative path";continue}this._host=h._host,this._port=h._port,this._path=h._path.slice(),this._query=h._query,this._fragment="#",j="fragment"}break;case"relative slash":if("/"!=u&&"\\"!=u){"file"!=this._scheme&&(this._host=h._host,this._port=h._port),j="relative path";continue}"\\"==u&&i("\\ is an invalid code point."),j="file"==this._scheme?"file host":"authority ignore slashes";break;case"authority first slash":if("/"!=u){i("Expected '/', got: "+u),j="authority ignore slashes";continue}j="authority second slash";break;case"authority second slash":if(j="authority ignore slashes","/"!=u){i("Expected '/', got: "+u);continue}break;case"authority ignore slashes":if("/"!=u&&"\\"!=u){j="authority";continue}i("Expected authority, got: "+u);break;case"authority":if("@"==u){r&&(i("@ already seen."),l+="%40"),r=!0;for(var x=0;x<l.length;x++){var y=l[x];if("	"!=y&&"\n"!=y&&"\r"!=y)if(":"!=y||null!==this._password){var z=e(y);null!==this._password?this._password+=z:this._username+=z}else this._password="";else i("Invalid whitespace in authority.")}l=""}else{if(o==u||"/"==u||"\\"==u||"?"==u||"#"==u){k-=l.length,l="",j="host";continue}l+=u}break;case"file host":if(o==u||"/"==u||"\\"==u||"?"==u||"#"==u){2!=l.length||!p.test(l[0])||":"!=l[1]&&"|"!=l[1]?0==l.length?j="relative path start":(this._host=d.call(this,l),l="",j="relative path start"):j="relative path";continue}"	"==u||"\n"==u||"\r"==u?i("Invalid whitespace in file host."):l+=u;break;case"host":case"hostname":if(":"!=u||s){if(o==u||"/"==u||"\\"==u||"?"==u||"#"==u){if(this._host=d.call(this,l),l="",j="relative path start",g)break a;continue}"	"!=u&&"\n"!=u&&"\r"!=u?("["==u?s=!0:"]"==u&&(s=!1),l+=u):i("Invalid code point in host/hostname: "+u)}else if(this._host=d.call(this,l),l="",j="port","hostname"==g)break a;break;case"port":if(/[0-9]/.test(u))l+=u;else{if(o==u||"/"==u||"\\"==u||"?"==u||"#"==u||g){if(""!=l){var A=parseInt(l,10);A!=m[this._scheme]&&(this._port=A+""),l=""}if(g)break a;j="relative path start";continue}"	"==u||"\n"==u||"\r"==u?i("Invalid code point in port: "+u):c.call(this)}break;case"relative path start":if("\\"==u&&i("'\\' not allowed in path."),j="relative path","/"!=u&&"\\"!=u)continue;break;case"relative path":if(o!=u&&"/"!=u&&"\\"!=u&&(g||"?"!=u&&"#"!=u))"	"!=u&&"\n"!=u&&"\r"!=u&&(l+=e(u));else{"\\"==u&&i("\\ not allowed in relative path.");var B;(B=n[l.toLowerCase()])&&(l=B),".."==l?(this._path.pop(),"/"!=u&&"\\"!=u&&this._path.push("")):"."==l&&"/"!=u&&"\\"!=u?this._path.push(""):"."!=l&&("file"==this._scheme&&0==this._path.length&&2==l.length&&p.test(l[0])&&"|"==l[1]&&(l=l[0]+":"),this._path.push(l)),l="","?"==u?(this._query="?",j="query"):"#"==u&&(this._fragment="#",j="fragment")}break;case"query":g||"#"!=u?o!=u&&"	"!=u&&"\n"!=u&&"\r"!=u&&(this._query+=f(u)):(this._fragment="#",j="fragment");break;case"fragment":o!=u&&"	"!=u&&"\n"!=u&&"\r"!=u&&(this._fragment+=u)}k++}}function h(){this._scheme="",this._schemeData="",this._username="",this._password=null,this._host="",this._port="",this._path=[],this._query="",this._fragment="",this._isInvalid=!1,this._isRelative=!1}function i(a,b){void 0===b||b instanceof i||(b=new i(String(b))),this._url=a,h.call(this);var c=a.replace(/^[ \t\r\n\f]+|[ \t\r\n\f]+$/g,"");g.call(this,c,null,b)}var j=!1;if(!a.forceJURL)try{var k=new URL("b","http://a");k.pathname="c%20d",j="http://a/c%20d"===k.href}catch(l){}if(!j){var m=Object.create(null);m.ftp=21,m.file=0,m.gopher=70,m.http=80,m.https=443,m.ws=80,m.wss=443;var n=Object.create(null);n["%2e"]=".",n[".%2e"]="..",n["%2e."]="..",n["%2e%2e"]="..";var o=void 0,p=/[a-zA-Z]/,q=/[a-zA-Z0-9\+\-\.]/;i.prototype={get href(){if(this._isInvalid)return this._url;var a="";return(""!=this._username||null!=this._password)&&(a=this._username+(null!=this._password?":"+this._password:"")+"@"),this.protocol+(this._isRelative?"//"+a+this.host:"")+this.pathname+this._query+this._fragment},set href(a){h.call(this),g.call(this,a)},get protocol(){return this._scheme+":"},set protocol(a){this._isInvalid||g.call(this,a+":","scheme start")},get host(){return this._isInvalid?"":this._port?this._host+":"+this._port:this._host},set host(a){!this._isInvalid&&this._isRelative&&g.call(this,a,"host")},get hostname(){return this._host},set hostname(a){!this._isInvalid&&this._isRelative&&g.call(this,a,"hostname")},get port(){return this._port},set port(a){!this._isInvalid&&this._isRelative&&g.call(this,a,"port")},get pathname(){return this._isInvalid?"":this._isRelative?"/"+this._path.join("/"):this._schemeData},set pathname(a){!this._isInvalid&&this._isRelative&&(this._path=[],g.call(this,a,"relative path start"))},get search(){return this._isInvalid||!this._query||"?"==this._query?"":this._query},set search(a){!this._isInvalid&&this._isRelative&&(this._query="?","?"==a[0]&&(a=a.slice(1)),g.call(this,a,"query"))},get hash(){return this._isInvalid||!this._fragment||"#"==this._fragment?"":this._fragment},set hash(a){this._isInvalid||(this._fragment="#","#"==a[0]&&(a=a.slice(1)),g.call(this,a,"fragment"))},get origin(){var a;if(this._isInvalid||!this._scheme)return"";switch(this._scheme){case"data":case"file":case"javascript":case"mailto":return"null"}return a=this.host,a?this._scheme+"://"+a:""}};var r=a.URL;r&&(i.createObjectURL=function(){return r.createObjectURL.apply(r,arguments)},i.revokeObjectURL=function(a){r.revokeObjectURL(a)}),a.URL=i}}(this),function(a){function b(a){f.textContent=d++,e.push(a)}function c(){for(;e.length;)e.shift()()}var d=0,e=[],f=document.createTextNode("");new(window.MutationObserver||JsMutationObserver)(c).observe(f,{characterData:!0}),a.endOfMicrotask=b,Platform.endOfMicrotask=b}(Polymer),function(a){function b(){g||(g=!0,c(function(){g=!1,d.data&&console.group("flush"),Platform.performMicrotaskCheckpoint(),d.data&&console.groupEnd()}))}var c=a.endOfMicrotask,d=window.WebComponents?WebComponents.flags.log:{},e=document.createElement("style");e.textContent="template {display: none !important;} /* injected by platform.js */";var f=document.querySelector("head");f.insertBefore(e,f.firstChild);var g;if(Observer.hasObjectObserve)b=function(){};else{var h=125;window.addEventListener("WebComponentsReady",function(){b();var c=function(){"hidden"===document.visibilityState?a.flushPoll&&clearInterval(a.flushPoll):a.flushPoll=setInterval(b,h)};"string"==typeof document.visibilityState&&document.addEventListener("visibilitychange",c),c()})}if(window.CustomElements&&!CustomElements.useNative){var i=Document.prototype.importNode;Document.prototype.importNode=function(a,b){var c=i.call(this,a,b);return CustomElements.upgradeAll(c),c}}a.flush=b,Platform.flush=b}(window.Polymer),function(a){function b(a){var b=new URL(a.ownerDocument.baseURI);return b.search="",b.hash="",b}function c(a,b,c,e){return a.replace(e,function(a,e,f,g){var h=f.replace(/["']/g,"");return h=d(b,h,c),e+"'"+h+"'"+g})}function d(a,b,c){if(b&&"/"===b[0])return b;if(b&&"#"===b[0])return b;var d=new URL(b,a);return c?d.href:e(d.href)}function e(a){var c=b(document.documentElement),d=new URL(a,c);return d.host===c.host&&d.port===c.port&&d.protocol===c.protocol?f(c,d):a}function f(a,b){for(var c=a.pathname,d=b.pathname,e=c.split("/"),f=d.split("/");e.length&&e[0]===f[0];)e.shift(),f.shift();for(var g=0,h=e.length-1;h>g;g++)f.unshift("..");var i=b.href.slice(-1)===m?m:b.hash;return f.join("/")+b.search+i}var g={resolveDom:function(a,c){c=c||b(a),this.resolveAttributes(a,c),this.resolveStyles(a,c);var d=a.querySelectorAll("template");if(d)for(var e,f=0,g=d.length;g>f&&(e=d[f]);f++)e.content&&this.resolveDom(e.content,c)},resolveTemplate:function(a){this.resolveDom(a.content,b(a))},resolveStyles:function(a,b){var c=a.querySelectorAll("style");if(c)for(var d,e=0,f=c.length;f>e&&(d=c[e]);e++)this.resolveStyle(d,b)},resolveStyle:function(a,c){c=c||b(a),a.textContent=this.resolveCssText(a.textContent,c)},resolveCssText:function(a,b,d){return a=c(a,b,d,h),c(a,b,d,i)},resolveAttributes:function(a,b){a.hasAttributes&&a.hasAttributes()&&this.resolveElementAttributes(a,b);var c=a&&a.querySelectorAll(k);if(c)for(var d,e=0,f=c.length;f>e&&(d=c[e]);e++)this.resolveElementAttributes(d,b)},resolveElementAttributes:function(a,e){e=e||b(a),j.forEach(function(b){var f,g=a.attributes[b],i=g&&g.value;i&&i.search(l)<0&&(f="style"===b?c(i,e,!1,h):d(e,i),g.value=f)})}},h=/(url\()([^)]*)(\))/g,i=/(@import[\s]+(?!url\())([^;]*)(;)/g,j=["href","src","action","style","url"],k="["+j.join("],[")+"]",l="{{.*}}",m="#";a.urlResolver=g}(Polymer),function(a){function b(a){this.cache=Object.create(null),this.map=Object.create(null),this.requests=0,this.regex=a}var c=Polymer.endOfMicrotask;b.prototype={extractUrls:function(a,b){for(var c,d,e=[];c=this.regex.exec(a);)d=new URL(c[1],b),e.push({matched:c[0],url:d.href});return e},process:function(a,b,c){var d=this.extractUrls(a,b),e=c.bind(null,this.map);this.fetch(d,e)},fetch:function(a,b){var c=a.length;if(!c)return b();for(var d,e,f,g=function(){0===--c&&b()},h=0;c>h;h++)d=a[h],f=d.url,e=this.cache[f],e||(e=this.xhr(f),e.match=d,this.cache[f]=e),e.wait(g)},handleXhr:function(a){var b=a.match,c=b.url,d=a.response||a.responseText||"";this.map[c]=d,this.fetch(this.extractUrls(d,c),a.resolve)},xhr:function(a){this.requests++;var b=new XMLHttpRequest;return b.open("GET",a,!0),b.send(),b.onerror=b.onload=this.handleXhr.bind(this,b),b.pending=[],b.resolve=function(){for(var a=b.pending,c=0;c<a.length;c++)a[c]();b.pending=null},b.wait=function(a){b.pending?b.pending.push(a):c(a)},b}},a.Loader=b}(Polymer),function(a){function b(){this.loader=new d(this.regex)}var c=a.urlResolver,d=a.Loader;b.prototype={regex:/@import\s+(?:url)?["'\(]*([^'"\)]*)['"\)]*;/g,resolve:function(a,b,c){var d=function(d){c(this.flatten(a,b,d))}.bind(this);this.loader.process(a,b,d)},resolveNode:function(a,b,c){var d=a.textContent,e=function(b){a.textContent=b,c(a)};this.resolve(d,b,e)},flatten:function(a,b,d){for(var e,f,g,h=this.loader.extractUrls(a,b),i=0;i<h.length;i++)e=h[i],f=e.url,g=c.resolveCssText(d[f],f,!0),g=this.flatten(g,b,d),a=a.replace(e.matched,g);return a},loadStyles:function(a,b,c){function d(){f++,f===g&&c&&c()}for(var e,f=0,g=a.length,h=0;g>h&&(e=a[h]);h++)this.resolveNode(e,b,d)}};var e=new b;a.styleResolver=e}(Polymer),function(a){function b(a,b){return a&&b&&Object.getOwnPropertyNames(b).forEach(function(c){var d=Object.getOwnPropertyDescriptor(b,c);d&&(Object.defineProperty(a,c,d),"function"==typeof d.value&&(d.value.nom=c))}),a}function c(a){for(var b=a||{},c=1;c<arguments.length;c++){var e=arguments[c];try{for(var f in e)d(f,e,b)}catch(g){}}return b}function d(a,b,c){var d=e(b,a);Object.defineProperty(c,a,d)}function e(a,b){if(a){var c=Object.getOwnPropertyDescriptor(a,b);return c||e(Object.getPrototypeOf(a),b)}}a.extend=b,a.mixin=c,Platform.mixin=c}(Polymer),function(a){function b(a,b,d){return a?a.stop():a=new c(this),a.go(b,d),a}var c=function(a){this.context=a,this.boundComplete=this.complete.bind(this)};c.prototype={go:function(a,b){this.callback=a;var c;b?(c=setTimeout(this.boundComplete,b),this.handle=function(){clearTimeout(c)}):(c=requestAnimationFrame(this.boundComplete),this.handle=function(){cancelAnimationFrame(c)})},stop:function(){this.handle&&(this.handle(),this.handle=null)},complete:function(){this.handle&&(this.stop(),this.callback.call(this.context))}},a.job=b}(Polymer),function(a){function b(a,b,c){var d="string"==typeof a?document.createElement(a):a.cloneNode(!0);if(d.innerHTML=b,c)for(var e in c)d.setAttribute(e,c[e]);return d}var c={};HTMLElement.register=function(a,b){c[a]=b},HTMLElement.getPrototypeForTag=function(a){var b=a?c[a]:HTMLElement.prototype;return b||Object.getPrototypeOf(document.createElement(a))};var d=Event.prototype.stopPropagation;Event.prototype.stopPropagation=function(){this.cancelBubble=!0,d.apply(this,arguments)};var e=DOMTokenList.prototype.add,f=DOMTokenList.prototype.remove;DOMTokenList.prototype.add=function(){for(var a=0;a<arguments.length;a++)e.call(this,arguments[a])},DOMTokenList.prototype.remove=function(){for(var a=0;a<arguments.length;a++)f.call(this,arguments[a])},DOMTokenList.prototype.toggle=function(a,b){1==arguments.length&&(b=!this.contains(a)),b?this.add(a):this.remove(a)},DOMTokenList.prototype["switch"]=function(a,b){a&&this.remove(a),b&&this.add(b)};var g=function(){return Array.prototype.slice.call(this)},h=window.NamedNodeMap||window.MozNamedAttrMap||{};NodeList.prototype.array=g,h.prototype.array=g,HTMLCollection.prototype.array=g,a.createDOM=b}(Polymer),function(a){function b(a){var e=b.caller,g=e.nom,h=e._super;h||(g||(g=e.nom=c.call(this,e)),g||console.warn("called super() on a method not installed declaratively (has no .nom property)"),h=d(e,g,f(this)));var i=h[g];return i?(i._super||d(i,g,h),i.apply(this,a||[])):void 0}function c(a){for(var b=this.__proto__;b&&b!==HTMLElement.prototype;){for(var c,d=Object.getOwnPropertyNames(b),e=0,f=d.length;f>e&&(c=d[e]);e++){var g=Object.getOwnPropertyDescriptor(b,c);if("function"==typeof g.value&&g.value===a)return c}b=b.__proto__}}function d(a,b,c){var d=e(c,b,a);return d[b]&&(d[b].nom=b),a._super=d}function e(a,b,c){for(;a;){if(a[b]!==c&&a[b])return a;a=f(a)}return Object}function f(a){return a.__proto__}a["super"]=b}(Polymer),function(a){function b(a){return a}function c(a,b){var c=typeof b;return b instanceof Date&&(c="date"),d[c](a,b)}var d={string:b,undefined:b,date:function(a){return new Date(Date.parse(a)||Date.now())},"boolean":function(a){return""===a?!0:"false"===a?!1:!!a},number:function(a){var b=parseFloat(a);return 0===b&&(b=parseInt(a)),isNaN(b)?a:b},object:function(a,b){if(null===b)return a;try{return JSON.parse(a.replace(/'/g,'"'))}catch(c){return a}},"function":function(a,b){return b}};a.deserializeValue=c}(Polymer),function(a){var b=a.extend,c={};c.declaration={},c.instance={},c.publish=function(a,c){for(var d in a)b(c,a[d])},a.api=c}(Polymer),function(a){var b={async:function(a,b,c){Polymer.flush(),b=b&&b.length?b:[b];var d=function(){(this[a]||a).apply(this,b)}.bind(this),e=c?setTimeout(d,c):requestAnimationFrame(d);return c?e:~e},cancelAsync:function(a){0>a?cancelAnimationFrame(~a):clearTimeout(a)},fire:function(a,b,c,d,e){var f=c||this,b=null===b||void 0===b?{}:b,g=new CustomEvent(a,{bubbles:void 0!==d?d:!0,cancelable:void 0!==e?e:!0,detail:b});return f.dispatchEvent(g),g},asyncFire:function(){this.async("fire",arguments)},classFollows:function(a,b,c){b&&b.classList.remove(c),a&&a.classList.add(c)},injectBoundHTML:function(a,b){var c=document.createElement("template");c.innerHTML=a;var d=this.instanceTemplate(c);return b&&(b.textContent="",b.appendChild(d)),d}},c=function(){},d={};b.asyncMethod=b.async,a.api.instance.utils=b,a.nop=c,a.nob=d}(Polymer),function(a){var b=window.WebComponents?WebComponents.flags.log:{},c="on-",d={EVENT_PREFIX:c,addHostListeners:function(){var a=this.eventDelegates;
-b.events&&Object.keys(a).length>0&&console.log("[%s] addHostListeners:",this.localName,a);for(var c in a){var d=a[c];PolymerGestures.addEventListener(this,c,this.element.getEventHandler(this,this,d))}},dispatchMethod:function(a,c,d){if(a){b.events&&console.group("[%s] dispatch [%s]",a.localName,c);var e="function"==typeof c?c:a[c];e&&e[d?"apply":"call"](a,d),b.events&&console.groupEnd(),Polymer.flush()}}};a.api.instance.events=d,a.addEventListener=function(a,b,c,d){PolymerGestures.addEventListener(wrap(a),b,c,d)},a.removeEventListener=function(a,b,c,d){PolymerGestures.removeEventListener(wrap(a),b,c,d)}}(Polymer),function(a){var b={copyInstanceAttributes:function(){var a=this._instanceAttributes;for(var b in a)this.hasAttribute(b)||this.setAttribute(b,a[b])},takeAttributes:function(){if(this._publishLC)for(var a,b=0,c=this.attributes,d=c.length;(a=c[b])&&d>b;b++)this.attributeToProperty(a.name,a.value)},attributeToProperty:function(b,c){var b=this.propertyForAttribute(b);if(b){if(c&&c.search(a.bindPattern)>=0)return;var d=this[b],c=this.deserializeValue(c,d);c!==d&&(this[b]=c)}},propertyForAttribute:function(a){var b=this._publishLC&&this._publishLC[a];return b},deserializeValue:function(b,c){return a.deserializeValue(b,c)},serializeValue:function(a,b){return"boolean"===b?a?"":void 0:"object"!==b&&"function"!==b&&void 0!==a?a:void 0},reflectPropertyToAttribute:function(a){var b=typeof this[a],c=this.serializeValue(this[a],b);void 0!==c?this.setAttribute(a,c):"boolean"===b&&this.removeAttribute(a)}};a.api.instance.attributes=b}(Polymer),function(a){function b(a,b){return a===b?0!==a||1/a===1/b:f(a)&&f(b)?!0:a!==a&&b!==b}function c(a,b){return void 0===b&&null===a?b:null===b||void 0===b?a:b}var d=window.WebComponents?WebComponents.flags.log:{},e={object:void 0,type:"update",name:void 0,oldValue:void 0},f=Number.isNaN||function(a){return"number"==typeof a&&isNaN(a)},g={createPropertyObserver:function(){var a=this._observeNames;if(a&&a.length){var b=this._propertyObserver=new CompoundObserver(!0);this.registerObserver(b);for(var c,d=0,e=a.length;e>d&&(c=a[d]);d++)b.addPath(this,c),this.observeArrayValue(c,this[c],null)}},openPropertyObserver:function(){this._propertyObserver&&this._propertyObserver.open(this.notifyPropertyChanges,this)},notifyPropertyChanges:function(a,b,c){var d,e,f={};for(var g in b)if(d=c[2*g+1],e=this.observe[d]){var h=b[g],i=a[g];this.observeArrayValue(d,i,h),f[e]||(void 0!==h&&null!==h||void 0!==i&&null!==i)&&(f[e]=!0,this.invokeMethod(e,[h,i,arguments]))}},invokeMethod:function(a,b){var c=this[a]||a;"function"==typeof c&&c.apply(this,b)},deliverChanges:function(){this._propertyObserver&&this._propertyObserver.deliver()},observeArrayValue:function(a,b,c){var e=this.observe[a];if(e&&(Array.isArray(c)&&(d.observe&&console.log("[%s] observeArrayValue: unregister observer [%s]",this.localName,a),this.closeNamedObserver(a+"__array")),Array.isArray(b))){d.observe&&console.log("[%s] observeArrayValue: register observer [%s]",this.localName,a,b);var f=new ArrayObserver(b);f.open(function(a){this.invokeMethod(e,[a])},this),this.registerNamedObserver(a+"__array",f)}},emitPropertyChangeRecord:function(a,c,d){if(!b(c,d)&&(this._propertyChanged(a,c,d),Observer.hasObjectObserve)){var f=this._objectNotifier;f||(f=this._objectNotifier=Object.getNotifier(this)),e.object=this,e.name=a,e.oldValue=d,f.notify(e)}},_propertyChanged:function(a){this.reflect[a]&&this.reflectPropertyToAttribute(a)},bindProperty:function(a,b,d){if(d)return void(this[a]=b);var e=this.element.prototype.computed;if(e&&e[a]){var f=a+"ComputedBoundObservable_";return void(this[f]=b)}return this.bindToAccessor(a,b,c)},bindToAccessor:function(a,c,d){function e(b,c){j[f]=b;var d=j[h];d&&"function"==typeof d.setValue&&d.setValue(b),j.emitPropertyChangeRecord(a,b,c)}var f=a+"_",g=a+"Observable_",h=a+"ComputedBoundObservable_";this[g]=c;var i=this[f],j=this,k=c.open(e);if(d&&!b(i,k)){var l=d(i,k);b(k,l)||(k=l,c.setValue&&c.setValue(k))}e(k,i);var m={close:function(){c.close(),j[g]=void 0,j[h]=void 0}};return this.registerObserver(m),m},createComputedProperties:function(){if(this._computedNames)for(var a=0;a<this._computedNames.length;a++){var b=this._computedNames[a],c=this.computed[b];try{var d=PolymerExpressions.getExpression(c),e=d.getBinding(this,this.element.syntax);this.bindToAccessor(b,e)}catch(f){console.error("Failed to create computed property",f)}}},registerObserver:function(a){return this._observers?void this._observers.push(a):void(this._observers=[a])},closeObservers:function(){if(this._observers){for(var a=this._observers,b=0;b<a.length;b++){var c=a[b];c&&"function"==typeof c.close&&c.close()}this._observers=[]}},registerNamedObserver:function(a,b){var c=this._namedObservers||(this._namedObservers={});c[a]=b},closeNamedObserver:function(a){var b=this._namedObservers;return b&&b[a]?(b[a].close(),b[a]=null,!0):void 0},closeNamedObservers:function(){if(this._namedObservers){for(var a in this._namedObservers)this.closeNamedObserver(a);this._namedObservers={}}}};a.api.instance.properties=g}(Polymer),function(a){var b=window.WebComponents?WebComponents.flags.log:{},c={instanceTemplate:function(a){HTMLTemplateElement.decorate(a);for(var b=this.syntax||!a.bindingDelegate&&this.element.syntax,c=a.createInstance(this,b),d=c.bindings_,e=0;e<d.length;e++)this.registerObserver(d[e]);return c},bind:function(a,b,c){var d=this.propertyForAttribute(a);if(d){var e=this.bindProperty(d,b,c);return Platform.enableBindingsReflection&&e&&(e.path=b.path_,this._recordBinding(d,e)),this.reflect[d]&&this.reflectPropertyToAttribute(d),e}return this.mixinSuper(arguments)},_recordBinding:function(a,b){this.bindings_=this.bindings_||{},this.bindings_[a]=b},bindFinished:function(){this.makeElementReady()},asyncUnbindAll:function(){this._unbound||(b.unbind&&console.log("[%s] asyncUnbindAll",this.localName),this._unbindAllJob=this.job(this._unbindAllJob,this.unbindAll,0))},unbindAll:function(){this._unbound||(this.closeObservers(),this.closeNamedObservers(),this._unbound=!0)},cancelUnbindAll:function(){return this._unbound?void(b.unbind&&console.warn("[%s] already unbound, cannot cancel unbindAll",this.localName)):(b.unbind&&console.log("[%s] cancelUnbindAll",this.localName),void(this._unbindAllJob&&(this._unbindAllJob=this._unbindAllJob.stop())))}},d=/\{\{([^{}]*)}}/;a.bindPattern=d,a.api.instance.mdv=c}(Polymer),function(a){function b(a){return a.hasOwnProperty("PolymerBase")}function c(){}var d={PolymerBase:!0,job:function(a,b,c){if("string"!=typeof a)return Polymer.job.call(this,a,b,c);var d="___"+a;this[d]=Polymer.job.call(this,this[d],b,c)},"super":Polymer["super"],created:function(){},ready:function(){},createdCallback:function(){this.templateInstance&&this.templateInstance.model&&console.warn("Attributes on "+this.localName+" were data bound prior to Polymer upgrading the element. This may result in incorrect binding types."),this.created(),this.prepareElement(),this.ownerDocument.isStagingDocument||this.makeElementReady()},prepareElement:function(){return this._elementPrepared?void console.warn("Element already prepared",this.localName):(this._elementPrepared=!0,this.shadowRoots={},this.createPropertyObserver(),this.openPropertyObserver(),this.copyInstanceAttributes(),this.takeAttributes(),void this.addHostListeners())},makeElementReady:function(){this._readied||(this._readied=!0,this.createComputedProperties(),this.parseDeclarations(this.__proto__),this.removeAttribute("unresolved"),this.ready())},attributeChangedCallback:function(a){"class"!==a&&"style"!==a&&this.attributeToProperty(a,this.getAttribute(a)),this.attributeChanged&&this.attributeChanged.apply(this,arguments)},attachedCallback:function(){this.cancelUnbindAll(),this.attached&&this.attached(),this.hasBeenAttached||(this.hasBeenAttached=!0,this.domReady&&this.async("domReady"))},detachedCallback:function(){this.preventDispose||this.asyncUnbindAll(),this.detached&&this.detached(),this.leftView&&this.leftView()},parseDeclarations:function(a){a&&a.element&&(this.parseDeclarations(a.__proto__),a.parseDeclaration.call(this,a.element))},parseDeclaration:function(a){var b=this.fetchTemplate(a);if(b){var c=this.shadowFromTemplate(b);this.shadowRoots[a.name]=c}},fetchTemplate:function(a){return a.querySelector("template")},shadowFromTemplate:function(a){if(a){var b=this.createShadowRoot(),c=this.instanceTemplate(a);return b.appendChild(c),this.shadowRootReady(b,a),b}},lightFromTemplate:function(a,b){if(a){this.eventController=this;var c=this.instanceTemplate(a);return b?this.insertBefore(c,b):this.appendChild(c),this.shadowRootReady(this),c}},shadowRootReady:function(a){this.marshalNodeReferences(a)},marshalNodeReferences:function(a){var b=this.$=this.$||{};if(a)for(var c,d=a.querySelectorAll("[id]"),e=0,f=d.length;f>e&&(c=d[e]);e++)b[c.id]=c},onMutation:function(a,b){var c=new MutationObserver(function(a){b.call(this,c,a),c.disconnect()}.bind(this));c.observe(a,{childList:!0,subtree:!0})}};c.prototype=d,d.constructor=c,a.Base=c,a.isBase=b,a.api.instance.base=d}(Polymer),function(a){function b(a){return a.__proto__}function c(a,b){var c="",d=!1;b&&(c=b.localName,d=b.hasAttribute("is"));var e=WebComponents.ShadowCSS.makeScopeSelector(c,d);return WebComponents.ShadowCSS.shimCssText(a,e)}var d=(window.WebComponents?WebComponents.flags.log:{},window.ShadowDOMPolyfill),e="element",f="controller",g={STYLE_SCOPE_ATTRIBUTE:e,installControllerStyles:function(){var a=this.findStyleScope();if(a&&!this.scopeHasNamedStyle(a,this.localName)){for(var c=b(this),d="";c&&c.element;)d+=c.element.cssTextForScope(f),c=b(c);d&&this.installScopeCssText(d,a)}},installScopeStyle:function(a,b,c){var c=c||this.findStyleScope(),b=b||"";if(c&&!this.scopeHasNamedStyle(c,this.localName+b)){var d="";if(a instanceof Array)for(var e,f=0,g=a.length;g>f&&(e=a[f]);f++)d+=e.textContent+"\n\n";else d=a.textContent;this.installScopeCssText(d,c,b)}},installScopeCssText:function(a,b,e){if(b=b||this.findStyleScope(),e=e||"",b){d&&(a=c(a,b.host));var g=this.element.cssTextToScopeStyle(a,f);Polymer.applyStyleToScope(g,b),this.styleCacheForScope(b)[this.localName+e]=!0}},findStyleScope:function(a){for(var b=a||this;b.parentNode;)b=b.parentNode;return b},scopeHasNamedStyle:function(a,b){var c=this.styleCacheForScope(a);return c[b]},styleCacheForScope:function(a){if(d){var b=a.host?a.host.localName:a.localName;return h[b]||(h[b]={})}return a._scopeStyles=a._scopeStyles||{}}},h={};a.api.instance.styles=g}(Polymer),function(a){function b(a,b){if("string"!=typeof a){var c=b||document._currentScript;if(b=a,a=c&&c.parentNode&&c.parentNode.getAttribute?c.parentNode.getAttribute("name"):"",!a)throw"Element name could not be inferred."}if(f(a))throw"Already registered (Polymer) prototype for element "+a;e(a,b),d(a)}function c(a,b){i[a]=b}function d(a){i[a]&&(i[a].registerWhenReady(),delete i[a])}function e(a,b){return j[a]=b||{}}function f(a){return j[a]}function g(a,b){if("string"!=typeof b)return!1;var c=HTMLElement.getPrototypeForTag(b),d=c&&c.constructor;return d?CustomElements["instanceof"]?CustomElements["instanceof"](a,d):a instanceof d:!1}var h=a.extend,i=(a.api,{}),j={};a.getRegisteredPrototype=f,a.waitingForPrototype=c,a.instanceOfType=g,window.Polymer=b,h(Polymer,a),WebComponents.consumeDeclarations&&WebComponents.consumeDeclarations(function(a){if(a)for(var c,d=0,e=a.length;e>d&&(c=a[d]);d++)b.apply(null,c)})}(Polymer),function(a){var b={resolveElementPaths:function(a){Polymer.urlResolver.resolveDom(a)},addResolvePathApi:function(){var a=this.getAttribute("assetpath")||"",b=new URL(a,this.ownerDocument.baseURI);this.prototype.resolvePath=function(a,c){var d=new URL(a,c||b);return d.href}}};a.api.declaration.path=b}(Polymer),function(a){function b(a,b){var c=new URL(a.getAttribute("href"),b).href;return"@import '"+c+"';"}function c(a,b){if(a){b===document&&(b=document.head),i&&(b=document.head);var c=d(a.textContent),e=a.getAttribute(h);e&&c.setAttribute(h,e);var f=b.firstElementChild;if(b===document.head){var g="style["+h+"]",j=document.head.querySelectorAll(g);j.length&&(f=j[j.length-1].nextElementSibling)}b.insertBefore(c,f)}}function d(a,b){b=b||document,b=b.createElement?b:b.ownerDocument;var c=b.createElement("style");return c.textContent=a,c}function e(a){return a&&a.__resource||""}function f(a,b){return q?q.call(a,b):void 0}var g=(window.WebComponents?WebComponents.flags.log:{},a.api.instance.styles),h=g.STYLE_SCOPE_ATTRIBUTE,i=window.ShadowDOMPolyfill,j="style",k="@import",l="link[rel=stylesheet]",m="global",n="polymer-scope",o={loadStyles:function(a){var b=this.fetchTemplate(),c=b&&this.templateContent();if(c){this.convertSheetsToStyles(c);var d=this.findLoadableStyles(c);if(d.length){var e=b.ownerDocument.baseURI;return Polymer.styleResolver.loadStyles(d,e,a)}}a&&a()},convertSheetsToStyles:function(a){for(var c,e,f=a.querySelectorAll(l),g=0,h=f.length;h>g&&(c=f[g]);g++)e=d(b(c,this.ownerDocument.baseURI),this.ownerDocument),this.copySheetAttributes(e,c),c.parentNode.replaceChild(e,c)},copySheetAttributes:function(a,b){for(var c,d=0,e=b.attributes,f=e.length;(c=e[d])&&f>d;d++)"rel"!==c.name&&"href"!==c.name&&a.setAttribute(c.name,c.value)},findLoadableStyles:function(a){var b=[];if(a)for(var c,d=a.querySelectorAll(j),e=0,f=d.length;f>e&&(c=d[e]);e++)c.textContent.match(k)&&b.push(c);return b},installSheets:function(){this.cacheSheets(),this.cacheStyles(),this.installLocalSheets(),this.installGlobalStyles()},cacheSheets:function(){this.sheets=this.findNodes(l),this.sheets.forEach(function(a){a.parentNode&&a.parentNode.removeChild(a)})},cacheStyles:function(){this.styles=this.findNodes(j+"["+n+"]"),this.styles.forEach(function(a){a.parentNode&&a.parentNode.removeChild(a)})},installLocalSheets:function(){var a=this.sheets.filter(function(a){return!a.hasAttribute(n)}),b=this.templateContent();if(b){var c="";if(a.forEach(function(a){c+=e(a)+"\n"}),c){var f=d(c,this.ownerDocument);b.insertBefore(f,b.firstChild)}}},findNodes:function(a,b){var c=this.querySelectorAll(a).array(),d=this.templateContent();if(d){var e=d.querySelectorAll(a).array();c=c.concat(e)}return b?c.filter(b):c},installGlobalStyles:function(){var a=this.styleForScope(m);c(a,document.head)},cssTextForScope:function(a){var b="",c="["+n+"="+a+"]",d=function(a){return f(a,c)},g=this.sheets.filter(d);g.forEach(function(a){b+=e(a)+"\n\n"});var h=this.styles.filter(d);return h.forEach(function(a){b+=a.textContent+"\n\n"}),b},styleForScope:function(a){var b=this.cssTextForScope(a);return this.cssTextToScopeStyle(b,a)},cssTextToScopeStyle:function(a,b){if(a){var c=d(a);return c.setAttribute(h,this.getAttribute("name")+"-"+b),c}}},p=HTMLElement.prototype,q=p.matches||p.matchesSelector||p.webkitMatchesSelector||p.mozMatchesSelector;a.api.declaration.styles=o,a.applyStyleToScope=c}(Polymer),function(a){var b=(window.WebComponents?WebComponents.flags.log:{},a.api.instance.events),c=b.EVENT_PREFIX,d={};["webkitAnimationStart","webkitAnimationEnd","webkitTransitionEnd","DOMFocusOut","DOMFocusIn","DOMMouseScroll"].forEach(function(a){d[a.toLowerCase()]=a});var e={parseHostEvents:function(){var a=this.prototype.eventDelegates;this.addAttributeDelegates(a)},addAttributeDelegates:function(a){for(var b,c=0;b=this.attributes[c];c++)this.hasEventPrefix(b.name)&&(a[this.removeEventPrefix(b.name)]=b.value.replace("{{","").replace("}}","").trim())},hasEventPrefix:function(a){return a&&"o"===a[0]&&"n"===a[1]&&"-"===a[2]},removeEventPrefix:function(a){return a.slice(f)},findController:function(a){for(;a.parentNode;){if(a.eventController)return a.eventController;a=a.parentNode}return a.host},getEventHandler:function(a,b,c){var d=this;return function(e){a&&a.PolymerBase||(a=d.findController(b));var f=[e,e.detail,e.currentTarget];a.dispatchMethod(a,c,f)}},prepareEventBinding:function(a,b){if(this.hasEventPrefix(b)){var c=this.removeEventPrefix(b);c=d[c]||c;var e=this;return function(b,d,f){function g(){return"{{ "+a+" }}"}var h=e.getEventHandler(void 0,d,a);return PolymerGestures.addEventListener(d,c,h),f?void 0:{open:g,discardChanges:g,close:function(){PolymerGestures.removeEventListener(d,c,h)}}}}}},f=c.length;a.api.declaration.events=e}(Polymer),function(a){var b=["attribute"],c={inferObservers:function(a){var b,c=a.observe;for(var d in a)"Changed"===d.slice(-7)&&(b=d.slice(0,-7),this.canObserveProperty(b)&&(c||(c=a.observe={}),c[b]=c[b]||d))},canObserveProperty:function(a){return b.indexOf(a)<0},explodeObservers:function(a){var b=a.observe;if(b){var c={};for(var d in b)for(var e,f=d.split(" "),g=0;e=f[g];g++)c[e]=b[d];a.observe=c}},optimizePropertyMaps:function(a){if(a.observe){var b=a._observeNames=[];for(var c in a.observe)for(var d,e=c.split(" "),f=0;d=e[f];f++)b.push(d)}if(a.publish){var b=a._publishNames=[];for(var c in a.publish)b.push(c)}if(a.computed){var b=a._computedNames=[];for(var c in a.computed)b.push(c)}},publishProperties:function(a,b){var c=a.publish;c&&(this.requireProperties(c,a,b),this.filterInvalidAccessorNames(c),a._publishLC=this.lowerCaseMap(c));var d=a.computed;d&&this.filterInvalidAccessorNames(d)},filterInvalidAccessorNames:function(a){for(var b in a)this.propertyNameBlacklist[b]&&(console.warn('Cannot define property "'+b+'" for element "'+this.name+'" because it has the same name as an HTMLElement property, and not all browsers support overriding that. Consider giving it a different name.'),delete a[b])},requireProperties:function(a,b){b.reflect=b.reflect||{};for(var c in a){var d=a[c];d&&void 0!==d.reflect&&(b.reflect[c]=Boolean(d.reflect),d=d.value),void 0!==d&&(b[c]=d)}},lowerCaseMap:function(a){var b={};for(var c in a)b[c.toLowerCase()]=c;return b},createPropertyAccessor:function(a,b){var c=this.prototype,d=a+"_",e=a+"Observable_";c[d]=c[a],Object.defineProperty(c,a,{get:function(){var a=this[e];return a&&a.deliver(),this[d]},set:function(c){if(b)return this[d];var f=this[e];if(f)return void f.setValue(c);var g=this[d];return this[d]=c,this.emitPropertyChangeRecord(a,c,g),c},configurable:!0})},createPropertyAccessors:function(a){var b=a._computedNames;if(b&&b.length)for(var c,d=0,e=b.length;e>d&&(c=b[d]);d++)this.createPropertyAccessor(c,!0);var b=a._publishNames;if(b&&b.length)for(var c,d=0,e=b.length;e>d&&(c=b[d]);d++)a.computed&&a.computed[c]||this.createPropertyAccessor(c)},propertyNameBlacklist:{children:1,"class":1,id:1,hidden:1,style:1,title:1}};a.api.declaration.properties=c}(Polymer),function(a){var b="attributes",c=/\s|,/,d={inheritAttributesObjects:function(a){this.inheritObject(a,"publishLC"),this.inheritObject(a,"_instanceAttributes")},publishAttributes:function(a){var d=this.getAttribute(b);if(d)for(var e,f=a.publish||(a.publish={}),g=d.split(c),h=0,i=g.length;i>h;h++)e=g[h].trim(),e&&void 0===f[e]&&(f[e]=void 0)},accumulateInstanceAttributes:function(){for(var a,b=this.prototype._instanceAttributes,c=this.attributes,d=0,e=c.length;e>d&&(a=c[d]);d++)this.isInstanceAttribute(a.name)&&(b[a.name]=a.value)},isInstanceAttribute:function(a){return!this.blackList[a]&&"on-"!==a.slice(0,3)},blackList:{name:1,"extends":1,constructor:1,noscript:1,assetpath:1,"cache-csstext":1}};d.blackList[b]=1,a.api.declaration.attributes=d}(Polymer),function(a){var b=a.api.declaration.events,c=new PolymerExpressions,d=c.prepareBinding;c.prepareBinding=function(a,e,f){return b.prepareEventBinding(a,e,f)||d.call(c,a,e,f)};var e={syntax:c,fetchTemplate:function(){return this.querySelector("template")},templateContent:function(){var a=this.fetchTemplate();return a&&a.content},installBindingDelegate:function(a){a&&(a.bindingDelegate=this.syntax)}};a.api.declaration.mdv=e}(Polymer),function(a){function b(a){if(!Object.__proto__){var b=Object.getPrototypeOf(a);a.__proto__=b,d(b)&&(b.__proto__=Object.getPrototypeOf(b))}}var c=a.api,d=a.isBase,e=a.extend,f=window.ShadowDOMPolyfill,g={register:function(a,b){this.buildPrototype(a,b),this.registerPrototype(a,b),this.publishConstructor()},buildPrototype:function(b,c){var d=a.getRegisteredPrototype(b),e=this.generateBasePrototype(c);this.desugarBeforeChaining(d,e),this.prototype=this.chainPrototypes(d,e),this.desugarAfterChaining(b,c)},desugarBeforeChaining:function(a,b){a.element=this,this.publishAttributes(a,b),this.publishProperties(a,b),this.inferObservers(a),this.explodeObservers(a)},chainPrototypes:function(a,c){this.inheritMetaData(a,c);var d=this.chainObject(a,c);return b(d),d},inheritMetaData:function(a,b){this.inheritObject("observe",a,b),this.inheritObject("publish",a,b),this.inheritObject("reflect",a,b),this.inheritObject("_publishLC",a,b),this.inheritObject("_instanceAttributes",a,b),this.inheritObject("eventDelegates",a,b)},desugarAfterChaining:function(a,b){this.optimizePropertyMaps(this.prototype),this.createPropertyAccessors(this.prototype),this.installBindingDelegate(this.fetchTemplate()),this.installSheets(),this.resolveElementPaths(this),this.accumulateInstanceAttributes(),this.parseHostEvents(),this.addResolvePathApi(),f&&WebComponents.ShadowCSS.shimStyling(this.templateContent(),a,b),this.prototype.registerCallback&&this.prototype.registerCallback(this)},publishConstructor:function(){var a=this.getAttribute("constructor");a&&(window[a]=this.ctor)},generateBasePrototype:function(a){var b=this.findBasePrototype(a);if(!b){var b=HTMLElement.getPrototypeForTag(a);b=this.ensureBaseApi(b),h[a]=b}return b},findBasePrototype:function(a){return h[a]},ensureBaseApi:function(a){if(a.PolymerBase)return a;var b=Object.create(a);return c.publish(c.instance,b),this.mixinMethod(b,a,c.instance.mdv,"bind"),b},mixinMethod:function(a,b,c,d){var e=function(a){return b[d].apply(this,a)};a[d]=function(){return this.mixinSuper=e,c[d].apply(this,arguments)}},inheritObject:function(a,b,c){var d=b[a]||{};b[a]=this.chainObject(d,c[a])},registerPrototype:function(a,b){var c={prototype:this.prototype},d=this.findTypeExtension(b);d&&(c["extends"]=d),HTMLElement.register(a,this.prototype),this.ctor=document.registerElement(a,c)},findTypeExtension:function(a){if(a&&a.indexOf("-")<0)return a;var b=this.findBasePrototype(a);return b.element?this.findTypeExtension(b.element["extends"]):void 0}},h={};g.chainObject=Object.__proto__?function(a,b){return a&&b&&a!==b&&(a.__proto__=b),a}:function(a,b){if(a&&b&&a!==b){var c=Object.create(b);a=e(c,a)}return a},c.declaration.prototype=g}(Polymer),function(a){function b(a){return document.contains(a)?j:i}function c(){return i.length?i[0]:j[0]}function d(a){f.waitToReady=!0,Polymer.endOfMicrotask(function(){HTMLImports.whenReady(function(){f.addReadyCallback(a),f.waitToReady=!1,f.check()})})}function e(a){if(void 0===a)return void f.ready();var b=setTimeout(function(){f.ready()},a);Polymer.whenReady(function(){clearTimeout(b)})}var f={wait:function(a){a.__queue||(a.__queue={},g.push(a))},enqueue:function(a,c,d){var e=a.__queue&&!a.__queue.check;return e&&(b(a).push(a),a.__queue.check=c,a.__queue.go=d),0!==this.indexOf(a)},indexOf:function(a){var c=b(a).indexOf(a);return c>=0&&document.contains(a)&&(c+=HTMLImports.useNative||HTMLImports.ready?i.length:1e9),c},go:function(a){var b=this.remove(a);b&&(a.__queue.flushable=!0,this.addToFlushQueue(b),this.check())},remove:function(a){var c=this.indexOf(a);if(0===c)return b(a).shift()},check:function(){var a=this.nextElement();return a&&a.__queue.check.call(a),this.canReady()?(this.ready(),!0):void 0},nextElement:function(){return c()},canReady:function(){return!this.waitToReady&&this.isEmpty()},isEmpty:function(){for(var a,b=0,c=g.length;c>b&&(a=g[b]);b++)if(a.__queue&&!a.__queue.flushable)return;return!0},addToFlushQueue:function(a){h.push(a)},flush:function(){if(!this.flushing){this.flushing=!0;for(var a;h.length;)a=h.shift(),a.__queue.go.call(a),a.__queue=null;this.flushing=!1}},ready:function(){var a=CustomElements.ready;CustomElements.ready=!1,this.flush(),CustomElements.useNative||CustomElements.upgradeDocumentTree(document),CustomElements.ready=a,Polymer.flush(),requestAnimationFrame(this.flushReadyCallbacks)},addReadyCallback:function(a){a&&k.push(a)},flushReadyCallbacks:function(){if(k)for(var a;k.length;)(a=k.shift())()},waitingFor:function(){for(var a,b=[],c=0,d=g.length;d>c&&(a=g[c]);c++)a.__queue&&!a.__queue.flushable&&b.push(a);return b},waitToReady:!0},g=[],h=[],i=[],j=[],k=[];a.elements=g,a.waitingFor=f.waitingFor.bind(f),a.forceReady=e,a.queue=f,a.whenReady=a.whenPolymerReady=d}(Polymer),function(a){function b(a){return Boolean(HTMLElement.getPrototypeForTag(a))}function c(a){return a&&a.indexOf("-")>=0}var d=a.extend,e=a.api,f=a.queue,g=a.whenReady,h=a.getRegisteredPrototype,i=a.waitingForPrototype,j=d(Object.create(HTMLElement.prototype),{createdCallback:function(){this.getAttribute("name")&&this.init()},init:function(){this.name=this.getAttribute("name"),this["extends"]=this.getAttribute("extends"),f.wait(this),this.loadResources(),this.registerWhenReady()},registerWhenReady:function(){this.registered||this.waitingForPrototype(this.name)||this.waitingForQueue()||this.waitingForResources()||f.go(this)},_register:function(){c(this["extends"])&&!b(this["extends"])&&console.warn("%s is attempting to extend %s, an unregistered element or one that was not registered with Polymer.",this.name,this["extends"]),this.register(this.name,this["extends"]),this.registered=!0},waitingForPrototype:function(a){return h(a)?void 0:(i(a,this),this.handleNoScript(a),!0)},handleNoScript:function(a){this.hasAttribute("noscript")&&!this.noscript&&(this.noscript=!0,Polymer(a))},waitingForResources:function(){return this._needsResources},waitingForQueue:function(){return f.enqueue(this,this.registerWhenReady,this._register)},loadResources:function(){this._needsResources=!0,this.loadStyles(function(){this._needsResources=!1,this.registerWhenReady()}.bind(this))}});e.publish(e.declaration,j),g(function(){document.body.removeAttribute("unresolved"),document.dispatchEvent(new CustomEvent("polymer-ready",{bubbles:!0}))}),document.registerElement("polymer-element",{prototype:j})}(Polymer),function(a){function b(a,b){a?(document.head.appendChild(a),d(b)):b&&b()}function c(a,c){if(a&&a.length){for(var d,e,f=document.createDocumentFragment(),g=0,h=a.length;h>g&&(d=a[g]);g++)e=document.createElement("link"),e.rel="import",e.href=d,f.appendChild(e);b(f,c)}else c&&c()}var d=a.whenReady;a["import"]=c,a.importElements=b}(Polymer),function(){var a=document.createElement("polymer-element");a.setAttribute("name","auto-binding"),a.setAttribute("extends","template"),a.init(),Polymer("auto-binding",{createdCallback:function(){this.syntax=this.bindingDelegate=this.makeSyntax(),Polymer.whenPolymerReady(function(){this.model=this,this.setAttribute("bind",""),this.async(function(){this.marshalNodeReferences(this.parentNode),this.fire("template-bound")})}.bind(this))},makeSyntax:function(){var a=Object.create(Polymer.api.declaration.events),b=this;a.findController=function(){return b.model};var c=new PolymerExpressions,d=c.prepareBinding;return c.prepareBinding=function(b,e,f){return a.prepareEventBinding(b,e,f)||d.call(c,b,e,f)},c}})}();'use strict';var global=this;this.tr=(function(){if(global.tr){console.warn('Base was multiply initialized. First init wins.');return global.tr;}
-function exportPath(name){var parts=name.split('.');var cur=global;for(var part;parts.length&&(part=parts.shift());){if(part in cur){cur=cur[part];}else{cur=cur[part]={};}}
-return cur;};function isExported(name){var parts=name.split('.');var cur=global;for(var part;parts.length&&(part=parts.shift());){if(part in cur){cur=cur[part];}else{return false;}}
+'use strict';if(window.Polymer){throw new Error('Cannot proceed. Polymer already present.');}
+window.Polymer={};window.Polymer.dom='shadow';(function(){function resolve(){document.body.removeAttribute('unresolved');}
+if(window.WebComponents){addEventListener('WebComponentsReady',resolve);}else{if(document.readyState==='interactive'||document.readyState==='complete'){resolve();}else{addEventListener('DOMContentLoaded',resolve);}}}());window.Polymer={Settings:function(){var settings=window.Polymer||{};if(!settings.noUrlSettings){var parts=location.search.slice(1).split('&');for(var i=0,o;i<parts.length&&(o=parts[i]);i++){o=o.split('=');o[0]&&(settings[o[0]]=o[1]||true);}}
+settings.wantShadow=settings.dom==='shadow';settings.hasShadow=Boolean(Element.prototype.createShadowRoot);settings.nativeShadow=settings.hasShadow&&!window.ShadowDOMPolyfill;settings.useShadow=settings.wantShadow&&settings.hasShadow;settings.hasNativeImports=Boolean('import'in document.createElement('link'));settings.useNativeImports=settings.hasNativeImports;settings.useNativeCustomElements=!window.CustomElements||window.CustomElements.useNative;settings.useNativeShadow=settings.useShadow&&settings.nativeShadow;settings.usePolyfillProto=!settings.useNativeCustomElements&&!Object.__proto__;settings.hasNativeCSSProperties=!navigator.userAgent.match(/AppleWebKit\/601|Edge\/15/)&&window.CSS&&CSS.supports&&CSS.supports('box-shadow','0 0 0 var(--foo)');settings.useNativeCSSProperties=settings.hasNativeCSSProperties&&settings.lazyRegister&&settings.useNativeCSSProperties;settings.isIE=navigator.userAgent.match('Trident');settings.passiveTouchGestures=settings.passiveTouchGestures||false;return settings;}()};(function(){var userPolymer=window.Polymer;window.Polymer=function(prototype){if(typeof prototype==='function'){prototype=prototype.prototype;}
+if(!prototype){prototype={};}
+prototype=desugar(prototype);var customCtor=prototype===prototype.constructor.prototype?prototype.constructor:null;var options={prototype:prototype};if(prototype.extends){options.extends=prototype.extends;}
+Polymer.telemetry._registrate(prototype);var ctor=document.registerElement(prototype.is,options);return customCtor||ctor;};var desugar=function(prototype){var base=Polymer.Base;if(prototype.extends){base=Polymer.Base._getExtendedPrototype(prototype.extends);}
+prototype=Polymer.Base.chainObject(prototype,base);prototype.registerCallback();return prototype;};if(userPolymer){for(var i in userPolymer){Polymer[i]=userPolymer[i];}}
+Polymer.Class=function(prototype){if(!prototype.factoryImpl){prototype.factoryImpl=function(){};}
+return desugar(prototype).constructor;};}());Polymer.telemetry={registrations:[],_regLog:function(prototype){console.log('['+prototype.is+']: registered');},_registrate:function(prototype){this.registrations.push(prototype);Polymer.log&&this._regLog(prototype);},dumpRegistrations:function(){this.registrations.forEach(this._regLog);}};Object.defineProperty(window,'currentImport',{enumerable:true,configurable:true,get:function(){return(document._currentScript||document.currentScript||{}).ownerDocument;}});Polymer.RenderStatus={_ready:false,_callbacks:[],whenReady:function(cb){if(this._ready){cb();}else{this._callbacks.push(cb);}},_makeReady:function(){this._ready=true;for(var i=0;i<this._callbacks.length;i++){this._callbacks[i]();}
+this._callbacks=[];},_catchFirstRender:function(){requestAnimationFrame(function(){Polymer.RenderStatus._makeReady();});},_afterNextRenderQueue:[],_waitingNextRender:false,afterNextRender:function(element,fn,args){this._watchNextRender();this._afterNextRenderQueue.push([element,fn,args]);},hasRendered:function(){return this._ready;},_watchNextRender:function(){if(!this._waitingNextRender){this._waitingNextRender=true;var fn=function(){Polymer.RenderStatus._flushNextRender();};if(!this._ready){this.whenReady(fn);}else{requestAnimationFrame(fn);}}},_flushNextRender:function(){var self=this;setTimeout(function(){self._flushRenderCallbacks(self._afterNextRenderQueue);self._afterNextRenderQueue=[];self._waitingNextRender=false;});},_flushRenderCallbacks:function(callbacks){for(var i=0,h;i<callbacks.length;i++){h=callbacks[i];h[1].apply(h[0],h[2]||Polymer.nar);}}};if(window.HTMLImports){HTMLImports.whenReady(function(){Polymer.RenderStatus._catchFirstRender();});}else{Polymer.RenderStatus._catchFirstRender();}
+Polymer.ImportStatus=Polymer.RenderStatus;Polymer.ImportStatus.whenLoaded=Polymer.ImportStatus.whenReady;(function(){'use strict';var settings=Polymer.Settings;Polymer.Base={__isPolymerInstance__:true,_addFeature:function(feature){this.mixin(this,feature);},registerCallback:function(){if(settings.lazyRegister==='max'){if(this.beforeRegister){this.beforeRegister();}}else{this._desugarBehaviors();for(var i=0,b;i<this.behaviors.length;i++){b=this.behaviors[i];if(b.beforeRegister){b.beforeRegister.call(this);}}
+if(this.beforeRegister){this.beforeRegister();}}
+this._registerFeatures();if(!settings.lazyRegister){this.ensureRegisterFinished();}},createdCallback:function(){if(settings.disableUpgradeEnabled){if(this.hasAttribute('disable-upgrade')){this._propertySetter=disableUpgradePropertySetter;this._configValue=null;this.__data__={};return;}else{this.__hasInitialized=true;}}
+this.__initialize();},__initialize:function(){if(!this.__hasRegisterFinished){this._ensureRegisterFinished(this.__proto__);}
+Polymer.telemetry.instanceCount++;this.root=this;for(var i=0,b;i<this.behaviors.length;i++){b=this.behaviors[i];if(b.created){b.created.call(this);}}
+if(this.created){this.created();}
+this._initFeatures();},ensureRegisterFinished:function(){this._ensureRegisterFinished(this);},_ensureRegisterFinished:function(proto){if(proto.__hasRegisterFinished!==proto.is||!proto.is){if(settings.lazyRegister==='max'){proto._desugarBehaviors();for(var i=0,b;i<proto.behaviors.length;i++){b=proto.behaviors[i];if(b.beforeRegister){b.beforeRegister.call(proto);}}}
+proto.__hasRegisterFinished=proto.is;if(proto._finishRegisterFeatures){proto._finishRegisterFeatures();}
+for(var j=0,pb;j<proto.behaviors.length;j++){pb=proto.behaviors[j];if(pb.registered){pb.registered.call(proto);}}
+if(proto.registered){proto.registered();}
+if(settings.usePolyfillProto&&proto!==this){proto.extend(this,proto);}}},attachedCallback:function(){var self=this;Polymer.RenderStatus.whenReady(function(){self.isAttached=true;for(var i=0,b;i<self.behaviors.length;i++){b=self.behaviors[i];if(b.attached){b.attached.call(self);}}
+if(self.attached){self.attached();}});},detachedCallback:function(){var self=this;Polymer.RenderStatus.whenReady(function(){self.isAttached=false;for(var i=0,b;i<self.behaviors.length;i++){b=self.behaviors[i];if(b.detached){b.detached.call(self);}}
+if(self.detached){self.detached();}});},attributeChangedCallback:function(name,oldValue,newValue){this._attributeChangedImpl(name);for(var i=0,b;i<this.behaviors.length;i++){b=this.behaviors[i];if(b.attributeChanged){b.attributeChanged.call(this,name,oldValue,newValue);}}
+if(this.attributeChanged){this.attributeChanged(name,oldValue,newValue);}},_attributeChangedImpl:function(name){this._setAttributeToProperty(this,name);},extend:function(target,source){if(target&&source){var n$=Object.getOwnPropertyNames(source);for(var i=0,n;i<n$.length&&(n=n$[i]);i++){this.copyOwnProperty(n,source,target);}}
+return target||source;},mixin:function(target,source){for(var i in source){target[i]=source[i];}
+return target;},copyOwnProperty:function(name,source,target){var pd=Object.getOwnPropertyDescriptor(source,name);if(pd){Object.defineProperty(target,name,pd);}},_logger:function(level,args){if(args.length===1&&Array.isArray(args[0])){args=args[0];}
+switch(level){case'log':case'warn':case'error':console[level].apply(console,args);break;}},_log:function(){var args=Array.prototype.slice.call(arguments,0);this._logger('log',args);},_warn:function(){var args=Array.prototype.slice.call(arguments,0);this._logger('warn',args);},_error:function(){var args=Array.prototype.slice.call(arguments,0);this._logger('error',args);},_logf:function(){return this._logPrefix.concat(this.is).concat(Array.prototype.slice.call(arguments,0));}};Polymer.Base._logPrefix=function(){var color=window.chrome&&!/edge/i.test(navigator.userAgent)||/firefox/i.test(navigator.userAgent);return color?['%c[%s::%s]:','font-weight: bold; background-color:#EEEE00;']:['[%s::%s]:'];}();Polymer.Base.chainObject=function(object,inherited){if(object&&inherited&&object!==inherited){if(!Object.__proto__){object=Polymer.Base.extend(Object.create(inherited),object);}
+object.__proto__=inherited;}
+return object;};Polymer.Base=Polymer.Base.chainObject(Polymer.Base,HTMLElement.prototype);Polymer.BaseDescriptors={};var disableUpgradePropertySetter;if(settings.disableUpgradeEnabled){disableUpgradePropertySetter=function(property,value){this.__data__[property]=value;};var origAttributeChangedCallback=Polymer.Base.attributeChangedCallback;Polymer.Base.attributeChangedCallback=function(name,oldValue,newValue){if(!this.__hasInitialized&&name==='disable-upgrade'){this.__hasInitialized=true;this._propertySetter=Polymer.Bind._modelApi._propertySetter;this._configValue=Polymer.Base._configValue;this.__initialize();}
+origAttributeChangedCallback.call(this,name,oldValue,newValue);};}
+if(window.CustomElements){Polymer.instanceof=CustomElements.instanceof;}else{Polymer.instanceof=function(obj,ctor){return obj instanceof ctor;};}
+Polymer.isInstance=function(obj){return Boolean(obj&&obj.__isPolymerInstance__);};Polymer.telemetry.instanceCount=0;}());(function(){var modules={};var lcModules={};var findModule=function(id){return modules[id]||lcModules[id.toLowerCase()];};var DomModule=function(){return document.createElement('dom-module');};DomModule.prototype=Object.create(HTMLElement.prototype);Polymer.Base.mixin(DomModule.prototype,{createdCallback:function(){this.register();},register:function(id){id=id||this.id||this.getAttribute('name')||this.getAttribute('is');if(id){this.id=id;modules[id]=this;lcModules[id.toLowerCase()]=this;}},import:function(id,selector){if(id){var m=findModule(id);if(!m){forceDomModulesUpgrade();m=findModule(id);}
+if(m&&selector){m=m.querySelector(selector);}
+return m;}}});Object.defineProperty(DomModule.prototype,'constructor',{value:DomModule,configurable:true,writable:true});var cePolyfill=window.CustomElements&&!CustomElements.useNative;document.registerElement('dom-module',DomModule);function forceDomModulesUpgrade(){if(cePolyfill){var script=document._currentScript||document.currentScript;var doc=script&&script.ownerDocument||document;var modules=doc.querySelectorAll('dom-module');for(var i=modules.length-1,m;i>=0&&(m=modules[i]);i--){if(m.__upgraded__){return;}else{CustomElements.upgrade(m);}}}}}());Polymer.Base._addFeature({_prepIs:function(){if(!this.is){var module=(document._currentScript||document.currentScript).parentNode;if(module.localName==='dom-module'){var id=module.id||module.getAttribute('name')||module.getAttribute('is');this.is=id;}}
+if(this.is){this.is=this.is.toLowerCase();}}});Polymer.Base._addFeature({behaviors:[],_desugarBehaviors:function(){if(this.behaviors.length){this.behaviors=this._desugarSomeBehaviors(this.behaviors);}},_desugarSomeBehaviors:function(behaviors){var behaviorSet=[];behaviors=this._flattenBehaviorsList(behaviors);for(var i=behaviors.length-1;i>=0;i--){var b=behaviors[i];if(behaviorSet.indexOf(b)===-1){this._mixinBehavior(b);behaviorSet.unshift(b);}}
+return behaviorSet;},_flattenBehaviorsList:function(behaviors){var flat=[];for(var i=0;i<behaviors.length;i++){var b=behaviors[i];if(b instanceof Array){flat=flat.concat(this._flattenBehaviorsList(b));}else if(b){flat.push(b);}else{this._warn(this._logf('_flattenBehaviorsList','behavior is null, check for missing or 404 import'));}}
+return flat;},_mixinBehavior:function(b){var n$=Object.getOwnPropertyNames(b);var useAssignment=b._noAccessors;for(var i=0,n;i<n$.length&&(n=n$[i]);i++){if(!Polymer.Base._behaviorProperties[n]&&!this.hasOwnProperty(n)){if(useAssignment){this[n]=b[n];}else{this.copyOwnProperty(n,b,this);}}}},_prepBehaviors:function(){this._prepFlattenedBehaviors(this.behaviors);},_prepFlattenedBehaviors:function(behaviors){for(var i=0,l=behaviors.length;i<l;i++){this._prepBehavior(behaviors[i]);}
+this._prepBehavior(this);},_marshalBehaviors:function(){for(var i=0;i<this.behaviors.length;i++){this._marshalBehavior(this.behaviors[i]);}
+this._marshalBehavior(this);}});Polymer.Base._behaviorProperties={hostAttributes:true,beforeRegister:true,registered:true,properties:true,observers:true,listeners:true,created:true,attached:true,detached:true,attributeChanged:true,ready:true,_noAccessors:true};Polymer.Base._addFeature({_getExtendedPrototype:function(tag){return this._getExtendedNativePrototype(tag);},_nativePrototypes:{},_getExtendedNativePrototype:function(tag){var p=this._nativePrototypes[tag];if(!p){p=Object.create(this.getNativePrototype(tag));var p$=Object.getOwnPropertyNames(Polymer.Base);for(var i=0,n;i<p$.length&&(n=p$[i]);i++){if(!Polymer.BaseDescriptors[n]){p[n]=Polymer.Base[n];}}
+Object.defineProperties(p,Polymer.BaseDescriptors);this._nativePrototypes[tag]=p;}
+return p;},getNativePrototype:function(tag){return Object.getPrototypeOf(document.createElement(tag));}});Polymer.Base._addFeature({_prepConstructor:function(){this._factoryArgs=this.extends?[this.extends,this.is]:[this.is];var ctor=function(){return this._factory(arguments);};if(this.hasOwnProperty('extends')){ctor.extends=this.extends;}
+Object.defineProperty(this,'constructor',{value:ctor,writable:true,configurable:true});ctor.prototype=this;},_factory:function(args){var elt=document.createElement.apply(document,this._factoryArgs);if(this.factoryImpl){this.factoryImpl.apply(elt,args);}
+return elt;}});Polymer.nob=Object.create(null);Polymer.Base._addFeature({getPropertyInfo:function(property){var info=this._getPropertyInfo(property,this.properties);if(!info){for(var i=0;i<this.behaviors.length;i++){info=this._getPropertyInfo(property,this.behaviors[i].properties);if(info){return info;}}}
+return info||Polymer.nob;},_getPropertyInfo:function(property,properties){var p=properties&&properties[property];if(typeof p==='function'){p=properties[property]={type:p};}
+if(p){p.defined=true;}
+return p;},_prepPropertyInfo:function(){this._propertyInfo={};for(var i=0;i<this.behaviors.length;i++){this._addPropertyInfo(this._propertyInfo,this.behaviors[i].properties);}
+this._addPropertyInfo(this._propertyInfo,this.properties);this._addPropertyInfo(this._propertyInfo,this._propertyEffects);},_addPropertyInfo:function(target,source){if(source){var t,s;for(var i in source){t=target[i];s=source[i];if(i[0]==='_'&&!s.readOnly){continue;}
+if(!target[i]){target[i]={type:typeof s==='function'?s:s.type,readOnly:s.readOnly,attribute:Polymer.CaseMap.camelToDashCase(i)};}else{if(!t.type){t.type=s.type;}
+if(!t.readOnly){t.readOnly=s.readOnly;}}}}}});(function(){var propertiesDesc={configurable:true,writable:true,enumerable:true,value:{}};Polymer.BaseDescriptors.properties=propertiesDesc;Object.defineProperty(Polymer.Base,'properties',propertiesDesc);}());Polymer.CaseMap={_caseMap:{},_rx:{dashToCamel:/-[a-z]/g,camelToDash:/([A-Z])/g},dashToCamelCase:function(dash){return this._caseMap[dash]||(this._caseMap[dash]=dash.indexOf('-')<0?dash:dash.replace(this._rx.dashToCamel,function(m){return m[1].toUpperCase();}));},camelToDashCase:function(camel){return this._caseMap[camel]||(this._caseMap[camel]=camel.replace(this._rx.camelToDash,'-$1').toLowerCase());}};Polymer.Base._addFeature({_addHostAttributes:function(attributes){if(!this._aggregatedAttributes){this._aggregatedAttributes={};}
+if(attributes){this.mixin(this._aggregatedAttributes,attributes);}},_marshalHostAttributes:function(){if(this._aggregatedAttributes){this._applyAttributes(this,this._aggregatedAttributes);}},_applyAttributes:function(node,attr$){for(var n in attr$){if(!this.hasAttribute(n)&&n!=='class'){var v=attr$[n];this.serializeValueToAttribute(v,n,this);}}},_marshalAttributes:function(){this._takeAttributesToModel(this);},_takeAttributesToModel:function(model){if(this.hasAttributes()){for(var i in this._propertyInfo){var info=this._propertyInfo[i];if(this.hasAttribute(info.attribute)){this._setAttributeToProperty(model,info.attribute,i,info);}}}},_setAttributeToProperty:function(model,attribute,property,info){if(!this._serializing){property=property||Polymer.CaseMap.dashToCamelCase(attribute);info=info||this._propertyInfo&&this._propertyInfo[property];if(info&&!info.readOnly){var v=this.getAttribute(attribute);model[property]=this.deserialize(v,info.type);}}},_serializing:false,reflectPropertyToAttribute:function(property,attribute,value){this._serializing=true;value=value===undefined?this[property]:value;this.serializeValueToAttribute(value,attribute||Polymer.CaseMap.camelToDashCase(property));this._serializing=false;},serializeValueToAttribute:function(value,attribute,node){var str=this.serialize(value);node=node||this;if(str===undefined){node.removeAttribute(attribute);}else{node.setAttribute(attribute,str);}},deserialize:function(value,type){switch(type){case Number:value=Number(value);break;case Boolean:value=value!=null;break;case Object:try{value=JSON.parse(value);}catch(x){}
+break;case Array:try{value=JSON.parse(value);}catch(x){value=null;console.warn('Polymer::Attributes: couldn`t decode Array as JSON');}
+break;case Date:value=new Date(value);break;case String:default:break;}
+return value;},serialize:function(value){switch(typeof value){case'boolean':return value?'':undefined;case'object':if(value instanceof Date){return value.toString();}else if(value){try{return JSON.stringify(value);}catch(x){return'';}}
+default:return value!=null?value:undefined;}}});Polymer.version="1.11.3";Polymer.Base._addFeature({_registerFeatures:function(){this._prepIs();this._prepBehaviors();this._prepConstructor();this._prepPropertyInfo();},_prepBehavior:function(b){this._addHostAttributes(b.hostAttributes);},_marshalBehavior:function(b){},_initFeatures:function(){this._marshalHostAttributes();this._marshalBehaviors();}});(function(){function resolveCss(cssText,ownerDocument){return cssText.replace(CSS_URL_RX,function(m,pre,url,post){return pre+'\''+resolve(url.replace(/["']/g,''),ownerDocument)+'\''+post;});}
+function resolveAttrs(element,ownerDocument){for(var name in URL_ATTRS){var a$=URL_ATTRS[name];for(var i=0,l=a$.length,a,at,v;i<l&&(a=a$[i]);i++){if(name==='*'||element.localName===name){at=element.attributes[a];v=at&&at.value;if(v&&v.search(BINDING_RX)<0){at.value=a==='style'?resolveCss(v,ownerDocument):resolve(v,ownerDocument);}}}}}
+function resolve(url,ownerDocument){if(url&&ABS_URL.test(url)){return url;}
+var resolver=getUrlResolver(ownerDocument);resolver.href=url;return resolver.href||url;}
+var tempDoc;var tempDocBase;function resolveUrl(url,baseUri){if(!tempDoc){tempDoc=document.implementation.createHTMLDocument('temp');tempDocBase=tempDoc.createElement('base');tempDoc.head.appendChild(tempDocBase);}
+tempDocBase.href=baseUri;return resolve(url,tempDoc);}
+function getUrlResolver(ownerDocument){return ownerDocument.body.__urlResolver||(ownerDocument.body.__urlResolver=ownerDocument.createElement('a'));}
+function pathFromUrl(url){return url.substring(0,url.lastIndexOf('/')+1);}
+var CSS_URL_RX=/(url\()([^)]*)(\))/g;var URL_ATTRS={'*':['href','src','style','url'],form:['action']};var ABS_URL=/(^\/)|(^#)|(^[\w-\d]*:)/;var BINDING_RX=/\{\{|\[\[/;Polymer.ResolveUrl={resolveCss:resolveCss,resolveAttrs:resolveAttrs,resolveUrl:resolveUrl,pathFromUrl:pathFromUrl};Polymer.rootPath=Polymer.Settings.rootPath||pathFromUrl(document.baseURI||window.location.href);}());Polymer.Base._addFeature({_prepTemplate:function(){var module;if(this._template===undefined){module=Polymer.DomModule.import(this.is);this._template=module&&module.querySelector('template');}
+if(module){var assetPath=module.getAttribute('assetpath')||'';var importURL=Polymer.ResolveUrl.resolveUrl(assetPath,module.ownerDocument.baseURI);this._importPath=Polymer.ResolveUrl.pathFromUrl(importURL);}else{this._importPath='';}
+if(this._template&&this._template.hasAttribute('is')){this._warn(this._logf('_prepTemplate','top-level Polymer template '+'must not be a type-extension, found',this._template,'Move inside simple <template>.'));}
+if(this._template&&!this._template.content&&window.HTMLTemplateElement&&HTMLTemplateElement.decorate){HTMLTemplateElement.decorate(this._template);}},_stampTemplate:function(){if(this._template){this.root=this.instanceTemplate(this._template);}},instanceTemplate:function(template){var dom=document.importNode(template._content||template.content,true);return dom;}});(function(){var baseAttachedCallback=Polymer.Base.attachedCallback;var baseDetachedCallback=Polymer.Base.detachedCallback;Polymer.Base._addFeature({_hostStack:[],ready:function(){},_registerHost:function(host){this.dataHost=host=host||Polymer.Base._hostStack[Polymer.Base._hostStack.length-1];if(host&&host._clients){host._clients.push(this);}
+this._clients=null;this._clientsReadied=false;},_beginHosting:function(){Polymer.Base._hostStack.push(this);if(!this._clients){this._clients=[];}},_endHosting:function(){Polymer.Base._hostStack.pop();},_tryReady:function(){this._readied=false;if(this._canReady()){this._ready();}},_canReady:function(){return!this.dataHost||this.dataHost._clientsReadied;},_ready:function(){this._beforeClientsReady();if(this._template){this._setupRoot();this._readyClients();}
+this._clientsReadied=true;this._clients=null;this._afterClientsReady();this._readySelf();},_readyClients:function(){this._beginDistribute();var c$=this._clients;if(c$){for(var i=0,l=c$.length,c;i<l&&(c=c$[i]);i++){c._ready();}}
+this._finishDistribute();},_readySelf:function(){for(var i=0,b;i<this.behaviors.length;i++){b=this.behaviors[i];if(b.ready){b.ready.call(this);}}
+if(this.ready){this.ready();}
+this._readied=true;if(this._attachedPending){this._attachedPending=false;this.attachedCallback();}},_beforeClientsReady:function(){},_afterClientsReady:function(){},_beforeAttached:function(){},attachedCallback:function(){if(this._readied){this._beforeAttached();baseAttachedCallback.call(this);}else{this._attachedPending=true;}},detachedCallback:function(){if(this._readied){baseDetachedCallback.call(this);}else{this._attachedPending=false;}}});}());Polymer.ArraySplice=function(){function newSplice(index,removed,addedCount){return{index:index,removed:removed,addedCount:addedCount};}
+var EDIT_LEAVE=0;var EDIT_UPDATE=1;var EDIT_ADD=2;var EDIT_DELETE=3;function ArraySplice(){}
+ArraySplice.prototype={calcEditDistances:function(current,currentStart,currentEnd,old,oldStart,oldEnd){var rowCount=oldEnd-oldStart+1;var columnCount=currentEnd-currentStart+1;var distances=new Array(rowCount);for(var i=0;i<rowCount;i++){distances[i]=new Array(columnCount);distances[i][0]=i;}
+for(var j=0;j<columnCount;j++)
+distances[0][j]=j;for(i=1;i<rowCount;i++){for(j=1;j<columnCount;j++){if(this.equals(current[currentStart+j-1],old[oldStart+i-1]))
+distances[i][j]=distances[i-1][j-1];else{var north=distances[i-1][j]+1;var west=distances[i][j-1]+1;distances[i][j]=north<west?north:west;}}}
+return distances;},spliceOperationsFromEditDistances:function(distances){var i=distances.length-1;var j=distances[0].length-1;var current=distances[i][j];var edits=[];while(i>0||j>0){if(i==0){edits.push(EDIT_ADD);j--;continue;}
+if(j==0){edits.push(EDIT_DELETE);i--;continue;}
+var northWest=distances[i-1][j-1];var west=distances[i-1][j];var north=distances[i][j-1];var min;if(west<north)
+min=west<northWest?west:northWest;else
+min=north<northWest?north:northWest;if(min==northWest){if(northWest==current){edits.push(EDIT_LEAVE);}else{edits.push(EDIT_UPDATE);current=northWest;}
+i--;j--;}else if(min==west){edits.push(EDIT_DELETE);i--;current=west;}else{edits.push(EDIT_ADD);j--;current=north;}}
+edits.reverse();return edits;},calcSplices:function(current,currentStart,currentEnd,old,oldStart,oldEnd){var prefixCount=0;var suffixCount=0;var minLength=Math.min(currentEnd-currentStart,oldEnd-oldStart);if(currentStart==0&&oldStart==0)
+prefixCount=this.sharedPrefix(current,old,minLength);if(currentEnd==current.length&&oldEnd==old.length)
+suffixCount=this.sharedSuffix(current,old,minLength-prefixCount);currentStart+=prefixCount;oldStart+=prefixCount;currentEnd-=suffixCount;oldEnd-=suffixCount;if(currentEnd-currentStart==0&&oldEnd-oldStart==0)
+return[];if(currentStart==currentEnd){var splice=newSplice(currentStart,[],0);while(oldStart<oldEnd)
+splice.removed.push(old[oldStart++]);return[splice];}else if(oldStart==oldEnd)
+return[newSplice(currentStart,[],currentEnd-currentStart)];var ops=this.spliceOperationsFromEditDistances(this.calcEditDistances(current,currentStart,currentEnd,old,oldStart,oldEnd));splice=undefined;var splices=[];var index=currentStart;var oldIndex=oldStart;for(var i=0;i<ops.length;i++){switch(ops[i]){case EDIT_LEAVE:if(splice){splices.push(splice);splice=undefined;}
+index++;oldIndex++;break;case EDIT_UPDATE:if(!splice)
+splice=newSplice(index,[],0);splice.addedCount++;index++;splice.removed.push(old[oldIndex]);oldIndex++;break;case EDIT_ADD:if(!splice)
+splice=newSplice(index,[],0);splice.addedCount++;index++;break;case EDIT_DELETE:if(!splice)
+splice=newSplice(index,[],0);splice.removed.push(old[oldIndex]);oldIndex++;break;}}
+if(splice){splices.push(splice);}
+return splices;},sharedPrefix:function(current,old,searchLength){for(var i=0;i<searchLength;i++)
+if(!this.equals(current[i],old[i]))
+return i;return searchLength;},sharedSuffix:function(current,old,searchLength){var index1=current.length;var index2=old.length;var count=0;while(count<searchLength&&this.equals(current[--index1],old[--index2]))
+count++;return count;},calculateSplices:function(current,previous){return this.calcSplices(current,0,current.length,previous,0,previous.length);},equals:function(currentValue,previousValue){return currentValue===previousValue;}};return new ArraySplice();}();Polymer.domInnerHTML=function(){var escapeAttrRegExp=/[&\u00A0"]/g;var escapeDataRegExp=/[&\u00A0<>]/g;function escapeReplace(c){switch(c){case'&':return'&amp;';case'<':return'&lt;';case'>':return'&gt;';case'"':return'&quot;';case'\xA0':return'&nbsp;';}}
+function escapeAttr(s){return s.replace(escapeAttrRegExp,escapeReplace);}
+function escapeData(s){return s.replace(escapeDataRegExp,escapeReplace);}
+function makeSet(arr){var set={};for(var i=0;i<arr.length;i++){set[arr[i]]=true;}
+return set;}
+var voidElements=makeSet(['area','base','br','col','command','embed','hr','img','input','keygen','link','meta','param','source','track','wbr']);var plaintextParents=makeSet(['style','script','xmp','iframe','noembed','noframes','plaintext','noscript']);function getOuterHTML(node,parentNode,composed){switch(node.nodeType){case Node.ELEMENT_NODE:var tagName=node.localName;var s='<'+tagName;var attrs=node.attributes;for(var i=0,attr;attr=attrs[i];i++){s+=' '+attr.name+'="'+escapeAttr(attr.value)+'"';}
+s+='>';if(voidElements[tagName]){return s;}
+return s+getInnerHTML(node,composed)+'</'+tagName+'>';case Node.TEXT_NODE:var data=node.data;if(parentNode&&plaintextParents[parentNode.localName]){return data;}
+return escapeData(data);case Node.COMMENT_NODE:return'<!--'+node.data+'-->';default:console.error(node);throw new Error('not implemented');}}
+function getInnerHTML(node,composed){if(node instanceof HTMLTemplateElement)
+node=node.content;var s='';var c$=Polymer.dom(node).childNodes;for(var i=0,l=c$.length,child;i<l&&(child=c$[i]);i++){s+=getOuterHTML(child,node,composed);}
+return s;}
+return{getInnerHTML:getInnerHTML};}();(function(){'use strict';var nativeInsertBefore=Element.prototype.insertBefore;var nativeAppendChild=Element.prototype.appendChild;var nativeRemoveChild=Element.prototype.removeChild;Polymer.TreeApi={arrayCopyChildNodes:function(parent){var copy=[],i=0;for(var n=parent.firstChild;n;n=n.nextSibling){copy[i++]=n;}
+return copy;},arrayCopyChildren:function(parent){var copy=[],i=0;for(var n=parent.firstElementChild;n;n=n.nextElementSibling){copy[i++]=n;}
+return copy;},arrayCopy:function(a$){var l=a$.length;var copy=new Array(l);for(var i=0;i<l;i++){copy[i]=a$[i];}
+return copy;}};Polymer.TreeApi.Logical={hasParentNode:function(node){return Boolean(node.__dom&&node.__dom.parentNode);},hasChildNodes:function(node){return Boolean(node.__dom&&node.__dom.childNodes!==undefined);},getChildNodes:function(node){return this.hasChildNodes(node)?this._getChildNodes(node):node.childNodes;},_getChildNodes:function(node){if(!node.__dom.childNodes){node.__dom.childNodes=[];for(var n=node.__dom.firstChild;n;n=n.__dom.nextSibling){node.__dom.childNodes.push(n);}}
+return node.__dom.childNodes;},getParentNode:function(node){return node.__dom&&node.__dom.parentNode!==undefined?node.__dom.parentNode:node.parentNode;},getFirstChild:function(node){return node.__dom&&node.__dom.firstChild!==undefined?node.__dom.firstChild:node.firstChild;},getLastChild:function(node){return node.__dom&&node.__dom.lastChild!==undefined?node.__dom.lastChild:node.lastChild;},getNextSibling:function(node){return node.__dom&&node.__dom.nextSibling!==undefined?node.__dom.nextSibling:node.nextSibling;},getPreviousSibling:function(node){return node.__dom&&node.__dom.previousSibling!==undefined?node.__dom.previousSibling:node.previousSibling;},getFirstElementChild:function(node){return node.__dom&&node.__dom.firstChild!==undefined?this._getFirstElementChild(node):node.firstElementChild;},_getFirstElementChild:function(node){var n=node.__dom.firstChild;while(n&&n.nodeType!==Node.ELEMENT_NODE){n=n.__dom.nextSibling;}
+return n;},getLastElementChild:function(node){return node.__dom&&node.__dom.lastChild!==undefined?this._getLastElementChild(node):node.lastElementChild;},_getLastElementChild:function(node){var n=node.__dom.lastChild;while(n&&n.nodeType!==Node.ELEMENT_NODE){n=n.__dom.previousSibling;}
+return n;},getNextElementSibling:function(node){return node.__dom&&node.__dom.nextSibling!==undefined?this._getNextElementSibling(node):node.nextElementSibling;},_getNextElementSibling:function(node){var n=node.__dom.nextSibling;while(n&&n.nodeType!==Node.ELEMENT_NODE){n=n.__dom.nextSibling;}
+return n;},getPreviousElementSibling:function(node){return node.__dom&&node.__dom.previousSibling!==undefined?this._getPreviousElementSibling(node):node.previousElementSibling;},_getPreviousElementSibling:function(node){var n=node.__dom.previousSibling;while(n&&n.nodeType!==Node.ELEMENT_NODE){n=n.__dom.previousSibling;}
+return n;},saveChildNodes:function(node){if(!this.hasChildNodes(node)){node.__dom=node.__dom||{};node.__dom.firstChild=node.firstChild;node.__dom.lastChild=node.lastChild;node.__dom.childNodes=[];for(var n=node.firstChild;n;n=n.nextSibling){n.__dom=n.__dom||{};n.__dom.parentNode=node;node.__dom.childNodes.push(n);n.__dom.nextSibling=n.nextSibling;n.__dom.previousSibling=n.previousSibling;}}},recordInsertBefore:function(node,container,ref_node){container.__dom.childNodes=null;if(node.nodeType===Node.DOCUMENT_FRAGMENT_NODE){for(var n=node.firstChild;n;n=n.nextSibling){this._linkNode(n,container,ref_node);}}else{this._linkNode(node,container,ref_node);}},_linkNode:function(node,container,ref_node){node.__dom=node.__dom||{};container.__dom=container.__dom||{};if(ref_node){ref_node.__dom=ref_node.__dom||{};}
+node.__dom.previousSibling=ref_node?ref_node.__dom.previousSibling:container.__dom.lastChild;if(node.__dom.previousSibling){node.__dom.previousSibling.__dom.nextSibling=node;}
+node.__dom.nextSibling=ref_node||null;if(node.__dom.nextSibling){node.__dom.nextSibling.__dom.previousSibling=node;}
+node.__dom.parentNode=container;if(ref_node){if(ref_node===container.__dom.firstChild){container.__dom.firstChild=node;}}else{container.__dom.lastChild=node;if(!container.__dom.firstChild){container.__dom.firstChild=node;}}
+container.__dom.childNodes=null;},recordRemoveChild:function(node,container){node.__dom=node.__dom||{};container.__dom=container.__dom||{};if(node===container.__dom.firstChild){container.__dom.firstChild=node.__dom.nextSibling;}
+if(node===container.__dom.lastChild){container.__dom.lastChild=node.__dom.previousSibling;}
+var p=node.__dom.previousSibling;var n=node.__dom.nextSibling;if(p){p.__dom.nextSibling=n;}
+if(n){n.__dom.previousSibling=p;}
+node.__dom.parentNode=node.__dom.previousSibling=node.__dom.nextSibling=undefined;container.__dom.childNodes=null;}};Polymer.TreeApi.Composed={getChildNodes:function(node){return Polymer.TreeApi.arrayCopyChildNodes(node);},getParentNode:function(node){return node.parentNode;},clearChildNodes:function(node){node.textContent='';},insertBefore:function(parentNode,newChild,refChild){return nativeInsertBefore.call(parentNode,newChild,refChild||null);},appendChild:function(parentNode,newChild){return nativeAppendChild.call(parentNode,newChild);},removeChild:function(parentNode,node){return nativeRemoveChild.call(parentNode,node);}};}());Polymer.DomApi=function(){'use strict';var Settings=Polymer.Settings;var TreeApi=Polymer.TreeApi;var DomApi=function(node){this.node=needsToWrap?DomApi.wrap(node):node;};var needsToWrap=Settings.hasShadow&&!Settings.nativeShadow;DomApi.wrap=window.wrap?window.wrap:function(node){return node;};DomApi.prototype={flush:function(){Polymer.dom.flush();},deepContains:function(node){if(this.node.contains(node)){return true;}
+var n=node;var doc=node.ownerDocument;while(n&&n!==doc&&n!==this.node){n=Polymer.dom(n).parentNode||n.host;}
+return n===this.node;},queryDistributedElements:function(selector){var c$=this.getEffectiveChildNodes();var list=[];for(var i=0,l=c$.length,c;i<l&&(c=c$[i]);i++){if(c.nodeType===Node.ELEMENT_NODE&&DomApi.matchesSelector.call(c,selector)){list.push(c);}}
+return list;},getEffectiveChildNodes:function(){var list=[];var c$=this.childNodes;for(var i=0,l=c$.length,c;i<l&&(c=c$[i]);i++){if(c.localName===CONTENT){var d$=dom(c).getDistributedNodes();for(var j=0;j<d$.length;j++){list.push(d$[j]);}}else{list.push(c);}}
+return list;},observeNodes:function(callback){if(callback){if(!this.observer){this.observer=this.node.localName===CONTENT?new DomApi.DistributedNodesObserver(this):new DomApi.EffectiveNodesObserver(this);}
+return this.observer.addListener(callback);}},unobserveNodes:function(handle){if(this.observer){this.observer.removeListener(handle);}},notifyObserver:function(){if(this.observer){this.observer.notify();}},_query:function(matcher,node,halter){node=node||this.node;var list=[];this._queryElements(TreeApi.Logical.getChildNodes(node),matcher,halter,list);return list;},_queryElements:function(elements,matcher,halter,list){for(var i=0,l=elements.length,c;i<l&&(c=elements[i]);i++){if(c.nodeType===Node.ELEMENT_NODE){if(this._queryElement(c,matcher,halter,list)){return true;}}}},_queryElement:function(node,matcher,halter,list){var result=matcher(node);if(result){list.push(node);}
+if(halter&&halter(result)){return result;}
+this._queryElements(TreeApi.Logical.getChildNodes(node),matcher,halter,list);}};var CONTENT=DomApi.CONTENT='content';var dom=DomApi.factory=function(node){node=node||document;if(!node.__domApi){node.__domApi=new DomApi.ctor(node);}
+return node.__domApi;};DomApi.hasApi=function(node){return Boolean(node.__domApi);};DomApi.ctor=DomApi;Polymer.dom=function(obj,patch){if(obj instanceof Event){return Polymer.EventApi.factory(obj);}else{return DomApi.factory(obj,patch);}};var p=Element.prototype;DomApi.matchesSelector=p.matches||p.matchesSelector||p.mozMatchesSelector||p.msMatchesSelector||p.oMatchesSelector||p.webkitMatchesSelector;return DomApi;}();(function(){'use strict';var Settings=Polymer.Settings;var DomApi=Polymer.DomApi;var dom=DomApi.factory;var TreeApi=Polymer.TreeApi;var getInnerHTML=Polymer.domInnerHTML.getInnerHTML;var CONTENT=DomApi.CONTENT;if(Settings.useShadow){return;}
+var nativeCloneNode=Element.prototype.cloneNode;var nativeImportNode=Document.prototype.importNode;Polymer.Base.mixin(DomApi.prototype,{_lazyDistribute:function(host){if(host.shadyRoot&&host.shadyRoot._distributionClean){host.shadyRoot._distributionClean=false;Polymer.dom.addDebouncer(host.debounce('_distribute',host._distributeContent));}},appendChild:function(node){return this.insertBefore(node);},insertBefore:function(node,ref_node){if(ref_node&&TreeApi.Logical.getParentNode(ref_node)!==this.node){throw Error('The ref_node to be inserted before is not a child '+'of this node');}
+if(node.nodeType!==Node.DOCUMENT_FRAGMENT_NODE){var parent=TreeApi.Logical.getParentNode(node);if(parent){if(DomApi.hasApi(parent)){dom(parent).notifyObserver();}
+this._removeNode(node);}else{this._removeOwnerShadyRoot(node);}}
+if(!this._addNode(node,ref_node)){if(ref_node){ref_node=ref_node.localName===CONTENT?this._firstComposedNode(ref_node):ref_node;}
+var container=this.node._isShadyRoot?this.node.host:this.node;if(ref_node){TreeApi.Composed.insertBefore(container,node,ref_node);}else{TreeApi.Composed.appendChild(container,node);}}
+this.notifyObserver();return node;},_addNode:function(node,ref_node){var root=this.getOwnerRoot();if(root){var ipAdded=this._maybeAddInsertionPoint(node,this.node);if(!root._invalidInsertionPoints){root._invalidInsertionPoints=ipAdded;}
+this._addNodeToHost(root.host,node);}
+if(TreeApi.Logical.hasChildNodes(this.node)){TreeApi.Logical.recordInsertBefore(node,this.node,ref_node);}
+var handled=this._maybeDistribute(node)||this.node.shadyRoot;if(handled){if(node.nodeType===Node.DOCUMENT_FRAGMENT_NODE){while(node.firstChild){TreeApi.Composed.removeChild(node,node.firstChild);}}else{var parent=TreeApi.Composed.getParentNode(node);if(parent){TreeApi.Composed.removeChild(parent,node);}}}
+return handled;},removeChild:function(node){if(TreeApi.Logical.getParentNode(node)!==this.node){throw Error('The node to be removed is not a child of this node: '+node);}
+if(!this._removeNode(node)){var container=this.node._isShadyRoot?this.node.host:this.node;var parent=TreeApi.Composed.getParentNode(node);if(container===parent){TreeApi.Composed.removeChild(container,node);}}
+this.notifyObserver();return node;},_removeNode:function(node){var logicalParent=TreeApi.Logical.hasParentNode(node)&&TreeApi.Logical.getParentNode(node);var distributed;var root=this._ownerShadyRootForNode(node);if(logicalParent){distributed=dom(node)._maybeDistributeParent();TreeApi.Logical.recordRemoveChild(node,logicalParent);if(root&&this._removeDistributedChildren(root,node)){root._invalidInsertionPoints=true;this._lazyDistribute(root.host);}}
+this._removeOwnerShadyRoot(node);if(root){this._removeNodeFromHost(root.host,node);}
+return distributed;},replaceChild:function(node,ref_node){this.insertBefore(node,ref_node);this.removeChild(ref_node);return node;},_hasCachedOwnerRoot:function(node){return Boolean(node._ownerShadyRoot!==undefined);},getOwnerRoot:function(){return this._ownerShadyRootForNode(this.node);},_ownerShadyRootForNode:function(node){if(!node){return;}
+var root=node._ownerShadyRoot;if(root===undefined){if(node._isShadyRoot){root=node;}else{var parent=TreeApi.Logical.getParentNode(node);if(parent){root=parent._isShadyRoot?parent:this._ownerShadyRootForNode(parent);}else{root=null;}}
+if(root||document.documentElement.contains(node)){node._ownerShadyRoot=root;}}
+return root;},_maybeDistribute:function(node){var fragContent=node.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&!node.__noContent&&dom(node).querySelector(CONTENT);var wrappedContent=fragContent&&TreeApi.Logical.getParentNode(fragContent).nodeType!==Node.DOCUMENT_FRAGMENT_NODE;var hasContent=fragContent||node.localName===CONTENT;if(hasContent){var root=this.getOwnerRoot();if(root){this._lazyDistribute(root.host);}}
+var needsDist=this._nodeNeedsDistribution(this.node);if(needsDist){this._lazyDistribute(this.node);}
+return needsDist||hasContent&&!wrappedContent;},_maybeAddInsertionPoint:function(node,parent){var added;if(node.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&!node.__noContent){var c$=dom(node).querySelectorAll(CONTENT);for(var i=0,n,np,na;i<c$.length&&(n=c$[i]);i++){np=TreeApi.Logical.getParentNode(n);if(np===node){np=parent;}
+na=this._maybeAddInsertionPoint(n,np);added=added||na;}}else if(node.localName===CONTENT){TreeApi.Logical.saveChildNodes(parent);TreeApi.Logical.saveChildNodes(node);added=true;}
+return added;},_updateInsertionPoints:function(host){var i$=host.shadyRoot._insertionPoints=dom(host.shadyRoot).querySelectorAll(CONTENT);for(var i=0,c;i<i$.length;i++){c=i$[i];TreeApi.Logical.saveChildNodes(c);TreeApi.Logical.saveChildNodes(TreeApi.Logical.getParentNode(c));}},_nodeNeedsDistribution:function(node){return node&&node.shadyRoot&&DomApi.hasInsertionPoint(node.shadyRoot);},_addNodeToHost:function(host,node){if(host._elementAdd){host._elementAdd(node);}},_removeNodeFromHost:function(host,node){if(host._elementRemove){host._elementRemove(node);}},_removeDistributedChildren:function(root,container){var hostNeedsDist;var ip$=root._insertionPoints;for(var i=0;i<ip$.length;i++){var content=ip$[i];if(this._contains(container,content)){var dc$=dom(content).getDistributedNodes();for(var j=0;j<dc$.length;j++){hostNeedsDist=true;var node=dc$[j];var parent=TreeApi.Composed.getParentNode(node);if(parent){TreeApi.Composed.removeChild(parent,node);}}}}
+return hostNeedsDist;},_contains:function(container,node){while(node){if(node==container){return true;}
+node=TreeApi.Logical.getParentNode(node);}},_removeOwnerShadyRoot:function(node){if(this._hasCachedOwnerRoot(node)){var c$=TreeApi.Logical.getChildNodes(node);for(var i=0,l=c$.length,n;i<l&&(n=c$[i]);i++){this._removeOwnerShadyRoot(n);}}
+node._ownerShadyRoot=undefined;},_firstComposedNode:function(content){var n$=dom(content).getDistributedNodes();for(var i=0,l=n$.length,n,p$;i<l&&(n=n$[i]);i++){p$=dom(n).getDestinationInsertionPoints();if(p$[p$.length-1]===content){return n;}}},querySelector:function(selector){var result=this._query(function(n){return DomApi.matchesSelector.call(n,selector);},this.node,function(n){return Boolean(n);})[0];return result||null;},querySelectorAll:function(selector){return this._query(function(n){return DomApi.matchesSelector.call(n,selector);},this.node);},getDestinationInsertionPoints:function(){return this.node._destinationInsertionPoints||[];},getDistributedNodes:function(){return this.node._distributedNodes||[];},_clear:function(){while(this.childNodes.length){this.removeChild(this.childNodes[0]);}},setAttribute:function(name,value){this.node.setAttribute(name,value);this._maybeDistributeParent();},removeAttribute:function(name){this.node.removeAttribute(name);this._maybeDistributeParent();},_maybeDistributeParent:function(){if(this._nodeNeedsDistribution(this.parentNode)){this._lazyDistribute(this.parentNode);return true;}},cloneNode:function(deep){var n=nativeCloneNode.call(this.node,false);if(deep){var c$=this.childNodes;var d=dom(n);for(var i=0,nc;i<c$.length;i++){nc=dom(c$[i]).cloneNode(true);d.appendChild(nc);}}
+return n;},importNode:function(externalNode,deep){var doc=this.node instanceof Document?this.node:this.node.ownerDocument;var n=nativeImportNode.call(doc,externalNode,false);if(deep){var c$=TreeApi.Logical.getChildNodes(externalNode);var d=dom(n);for(var i=0,nc;i<c$.length;i++){nc=dom(doc).importNode(c$[i],true);d.appendChild(nc);}}
+return n;},_getComposedInnerHTML:function(){return getInnerHTML(this.node,true);}});Object.defineProperties(DomApi.prototype,{activeElement:{get:function(){var active=document.activeElement;if(!active){return null;}
+var isShadyRoot=!!this.node._isShadyRoot;if(this.node!==document){if(!isShadyRoot){return null;}
+if(this.node.host===active||!this.node.host.contains(active)){return null;}}
+var activeRoot=dom(active).getOwnerRoot();while(activeRoot&&activeRoot!==this.node){active=activeRoot.host;activeRoot=dom(active).getOwnerRoot();}
+if(this.node===document){return activeRoot?null:active;}else{return activeRoot===this.node?active:null;}},configurable:true},childNodes:{get:function(){var c$=TreeApi.Logical.getChildNodes(this.node);return Array.isArray(c$)?c$:TreeApi.arrayCopyChildNodes(this.node);},configurable:true},children:{get:function(){if(TreeApi.Logical.hasChildNodes(this.node)){return Array.prototype.filter.call(this.childNodes,function(n){return n.nodeType===Node.ELEMENT_NODE;});}else{return TreeApi.arrayCopyChildren(this.node);}},configurable:true},parentNode:{get:function(){return TreeApi.Logical.getParentNode(this.node);},configurable:true},firstChild:{get:function(){return TreeApi.Logical.getFirstChild(this.node);},configurable:true},lastChild:{get:function(){return TreeApi.Logical.getLastChild(this.node);},configurable:true},nextSibling:{get:function(){return TreeApi.Logical.getNextSibling(this.node);},configurable:true},previousSibling:{get:function(){return TreeApi.Logical.getPreviousSibling(this.node);},configurable:true},firstElementChild:{get:function(){return TreeApi.Logical.getFirstElementChild(this.node);},configurable:true},lastElementChild:{get:function(){return TreeApi.Logical.getLastElementChild(this.node);},configurable:true},nextElementSibling:{get:function(){return TreeApi.Logical.getNextElementSibling(this.node);},configurable:true},previousElementSibling:{get:function(){return TreeApi.Logical.getPreviousElementSibling(this.node);},configurable:true},textContent:{get:function(){var nt=this.node.nodeType;if(nt===Node.TEXT_NODE||nt===Node.COMMENT_NODE){return this.node.textContent;}else{var tc=[];for(var i=0,cn=this.childNodes,c;c=cn[i];i++){if(c.nodeType!==Node.COMMENT_NODE){tc.push(c.textContent);}}
+return tc.join('');}},set:function(text){var nt=this.node.nodeType;if(nt===Node.TEXT_NODE||nt===Node.COMMENT_NODE){this.node.textContent=text;}else{this._clear();if(text){this.appendChild(document.createTextNode(text));}}},configurable:true},innerHTML:{get:function(){var nt=this.node.nodeType;if(nt===Node.TEXT_NODE||nt===Node.COMMENT_NODE){return null;}else{return getInnerHTML(this.node);}},set:function(text){var nt=this.node.nodeType;if(nt!==Node.TEXT_NODE||nt!==Node.COMMENT_NODE){this._clear();var d=document.createElement('div');d.innerHTML=text;var c$=TreeApi.arrayCopyChildNodes(d);for(var i=0;i<c$.length;i++){this.appendChild(c$[i]);}}},configurable:true}});DomApi.hasInsertionPoint=function(root){return Boolean(root&&root._insertionPoints.length);};}());(function(){'use strict';var Settings=Polymer.Settings;var TreeApi=Polymer.TreeApi;var DomApi=Polymer.DomApi;if(!Settings.useShadow){return;}
+Polymer.Base.mixin(DomApi.prototype,{querySelectorAll:function(selector){return TreeApi.arrayCopy(this.node.querySelectorAll(selector));},getOwnerRoot:function(){var n=this.node;while(n){if(n.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&n.host){return n;}
+n=n.parentNode;}},importNode:function(externalNode,deep){var doc=this.node instanceof Document?this.node:this.node.ownerDocument;return doc.importNode(externalNode,deep);},getDestinationInsertionPoints:function(){var n$=this.node.getDestinationInsertionPoints&&this.node.getDestinationInsertionPoints();return n$?TreeApi.arrayCopy(n$):[];},getDistributedNodes:function(){var n$=this.node.getDistributedNodes&&this.node.getDistributedNodes();return n$?TreeApi.arrayCopy(n$):[];}});Object.defineProperties(DomApi.prototype,{activeElement:{get:function(){var node=DomApi.wrap(this.node);var activeElement=node.activeElement;return node.contains(activeElement)?activeElement:null;},configurable:true},childNodes:{get:function(){return TreeApi.arrayCopyChildNodes(this.node);},configurable:true},children:{get:function(){return TreeApi.arrayCopyChildren(this.node);},configurable:true},textContent:{get:function(){return this.node.textContent;},set:function(value){return this.node.textContent=value;},configurable:true},innerHTML:{get:function(){return this.node.innerHTML;},set:function(value){return this.node.innerHTML=value;},configurable:true}});var forwardMethods=function(m$){for(var i=0;i<m$.length;i++){forwardMethod(m$[i]);}};var forwardMethod=function(method){DomApi.prototype[method]=function(){return this.node[method].apply(this.node,arguments);};};forwardMethods(['cloneNode','appendChild','insertBefore','removeChild','replaceChild','setAttribute','removeAttribute','querySelector']);var forwardProperties=function(f$){for(var i=0;i<f$.length;i++){forwardProperty(f$[i]);}};var forwardProperty=function(name){Object.defineProperty(DomApi.prototype,name,{get:function(){return this.node[name];},configurable:true});};forwardProperties(['parentNode','firstChild','lastChild','nextSibling','previousSibling','firstElementChild','lastElementChild','nextElementSibling','previousElementSibling']);}());Polymer.Base.mixin(Polymer.dom,{_flushGuard:0,_FLUSH_MAX:100,_needsTakeRecords:!Polymer.Settings.useNativeCustomElements,_debouncers:[],_staticFlushList:[],_finishDebouncer:null,flush:function(){this._flushGuard=0;this._prepareFlush();while(this._debouncers.length&&this._flushGuard<this._FLUSH_MAX){while(this._debouncers.length){this._debouncers.shift().complete();}
+if(this._finishDebouncer){this._finishDebouncer.complete();}
+this._prepareFlush();this._flushGuard++;}
+if(this._flushGuard>=this._FLUSH_MAX){console.warn('Polymer.dom.flush aborted. Flush may not be complete.');}},_prepareFlush:function(){if(this._needsTakeRecords){CustomElements.takeRecords();}
+for(var i=0;i<this._staticFlushList.length;i++){this._staticFlushList[i]();}},addStaticFlush:function(fn){this._staticFlushList.push(fn);},removeStaticFlush:function(fn){var i=this._staticFlushList.indexOf(fn);if(i>=0){this._staticFlushList.splice(i,1);}},addDebouncer:function(debouncer){this._debouncers.push(debouncer);this._finishDebouncer=Polymer.Debounce(this._finishDebouncer,this._finishFlush);},_finishFlush:function(){Polymer.dom._debouncers=[];}});Polymer.EventApi=function(){'use strict';var DomApi=Polymer.DomApi.ctor;var Settings=Polymer.Settings;DomApi.Event=function(event){this.event=event;};if(Settings.useShadow){DomApi.Event.prototype={get rootTarget(){return this.event.path[0];},get localTarget(){return this.event.target;},get path(){var path=this.event.path;if(!Array.isArray(path)){path=Array.prototype.slice.call(path);}
+return path;}};}else{DomApi.Event.prototype={get rootTarget(){return this.event.target;},get localTarget(){var current=this.event.currentTarget;var currentRoot=current&&Polymer.dom(current).getOwnerRoot();var p$=this.path;for(var i=0;i<p$.length;i++){if(Polymer.dom(p$[i]).getOwnerRoot()===currentRoot){return p$[i];}}},get path(){if(!this.event._path){var path=[];var current=this.rootTarget;while(current){path.push(current);var insertionPoints=Polymer.dom(current).getDestinationInsertionPoints();if(insertionPoints.length){for(var i=0;i<insertionPoints.length-1;i++){path.push(insertionPoints[i]);}
+current=insertionPoints[insertionPoints.length-1];}else{current=Polymer.dom(current).parentNode||current.host;}}
+path.push(window);this.event._path=path;}
+return this.event._path;}};}
+var factory=function(event){if(!event.__eventApi){event.__eventApi=new DomApi.Event(event);}
+return event.__eventApi;};return{factory:factory};}();(function(){'use strict';var DomApi=Polymer.DomApi.ctor;var useShadow=Polymer.Settings.useShadow;Object.defineProperty(DomApi.prototype,'classList',{get:function(){if(!this._classList){this._classList=new DomApi.ClassList(this);}
+return this._classList;},configurable:true});DomApi.ClassList=function(host){this.domApi=host;this.node=host.node;};DomApi.ClassList.prototype={add:function(){this.node.classList.add.apply(this.node.classList,arguments);this._distributeParent();},remove:function(){this.node.classList.remove.apply(this.node.classList,arguments);this._distributeParent();},toggle:function(){this.node.classList.toggle.apply(this.node.classList,arguments);this._distributeParent();},_distributeParent:function(){if(!useShadow){this.domApi._maybeDistributeParent();}},contains:function(){return this.node.classList.contains.apply(this.node.classList,arguments);}};}());(function(){'use strict';var DomApi=Polymer.DomApi.ctor;var Settings=Polymer.Settings;DomApi.EffectiveNodesObserver=function(domApi){this.domApi=domApi;this.node=this.domApi.node;this._listeners=[];};DomApi.EffectiveNodesObserver.prototype={addListener:function(callback){if(!this._isSetup){this._setup();this._isSetup=true;}
+var listener={fn:callback,_nodes:[]};this._listeners.push(listener);this._scheduleNotify();return listener;},removeListener:function(handle){var i=this._listeners.indexOf(handle);if(i>=0){this._listeners.splice(i,1);handle._nodes=[];}
+if(!this._hasListeners()){this._cleanup();this._isSetup=false;}},_setup:function(){this._observeContentElements(this.domApi.childNodes);},_cleanup:function(){this._unobserveContentElements(this.domApi.childNodes);},_hasListeners:function(){return Boolean(this._listeners.length);},_scheduleNotify:function(){if(this._debouncer){this._debouncer.stop();}
+this._debouncer=Polymer.Debounce(this._debouncer,this._notify);this._debouncer.context=this;Polymer.dom.addDebouncer(this._debouncer);},notify:function(){if(this._hasListeners()){this._scheduleNotify();}},_notify:function(){this._beforeCallListeners();this._callListeners();},_beforeCallListeners:function(){this._updateContentElements();},_updateContentElements:function(){this._observeContentElements(this.domApi.childNodes);},_observeContentElements:function(elements){for(var i=0,n;i<elements.length&&(n=elements[i]);i++){if(this._isContent(n)){n.__observeNodesMap=n.__observeNodesMap||new WeakMap();if(!n.__observeNodesMap.has(this)){n.__observeNodesMap.set(this,this._observeContent(n));}}}},_observeContent:function(content){var self=this;var h=Polymer.dom(content).observeNodes(function(){self._scheduleNotify();});h._avoidChangeCalculation=true;return h;},_unobserveContentElements:function(elements){for(var i=0,n,h;i<elements.length&&(n=elements[i]);i++){if(this._isContent(n)){h=n.__observeNodesMap.get(this);if(h){Polymer.dom(n).unobserveNodes(h);n.__observeNodesMap.delete(this);}}}},_isContent:function(node){return node.localName==='content';},_callListeners:function(){var o$=this._listeners;var nodes=this._getEffectiveNodes();for(var i=0,o;i<o$.length&&(o=o$[i]);i++){var info=this._generateListenerInfo(o,nodes);if(info||o._alwaysNotify){this._callListener(o,info);}}},_getEffectiveNodes:function(){return this.domApi.getEffectiveChildNodes();},_generateListenerInfo:function(listener,newNodes){if(listener._avoidChangeCalculation){return true;}
+var oldNodes=listener._nodes;var info={target:this.node,addedNodes:[],removedNodes:[]};var splices=Polymer.ArraySplice.calculateSplices(newNodes,oldNodes);for(var i=0,s;i<splices.length&&(s=splices[i]);i++){for(var j=0,n;j<s.removed.length&&(n=s.removed[j]);j++){info.removedNodes.push(n);}}
+for(i=0,s;i<splices.length&&(s=splices[i]);i++){for(j=s.index;j<s.index+s.addedCount;j++){info.addedNodes.push(newNodes[j]);}}
+listener._nodes=newNodes;if(info.addedNodes.length||info.removedNodes.length){return info;}},_callListener:function(listener,info){return listener.fn.call(this.node,info);},enableShadowAttributeTracking:function(){}};if(Settings.useShadow){var baseSetup=DomApi.EffectiveNodesObserver.prototype._setup;var baseCleanup=DomApi.EffectiveNodesObserver.prototype._cleanup;Polymer.Base.mixin(DomApi.EffectiveNodesObserver.prototype,{_setup:function(){if(!this._observer){var self=this;this._mutationHandler=function(mxns){if(mxns&&mxns.length){self._scheduleNotify();}};this._observer=new MutationObserver(this._mutationHandler);this._boundFlush=function(){self._flush();};Polymer.dom.addStaticFlush(this._boundFlush);this._observer.observe(this.node,{childList:true});}
+baseSetup.call(this);},_cleanup:function(){this._observer.disconnect();this._observer=null;this._mutationHandler=null;Polymer.dom.removeStaticFlush(this._boundFlush);baseCleanup.call(this);},_flush:function(){if(this._observer){this._mutationHandler(this._observer.takeRecords());}},enableShadowAttributeTracking:function(){if(this._observer){this._makeContentListenersAlwaysNotify();this._observer.disconnect();this._observer.observe(this.node,{childList:true,attributes:true,subtree:true});var root=this.domApi.getOwnerRoot();var host=root&&root.host;if(host&&Polymer.dom(host).observer){Polymer.dom(host).observer.enableShadowAttributeTracking();}}},_makeContentListenersAlwaysNotify:function(){for(var i=0,h;i<this._listeners.length;i++){h=this._listeners[i];h._alwaysNotify=h._isContentListener;}}});}}());(function(){'use strict';var DomApi=Polymer.DomApi.ctor;var Settings=Polymer.Settings;DomApi.DistributedNodesObserver=function(domApi){DomApi.EffectiveNodesObserver.call(this,domApi);};DomApi.DistributedNodesObserver.prototype=Object.create(DomApi.EffectiveNodesObserver.prototype);Polymer.Base.mixin(DomApi.DistributedNodesObserver.prototype,{_setup:function(){},_cleanup:function(){},_beforeCallListeners:function(){},_getEffectiveNodes:function(){return this.domApi.getDistributedNodes();}});if(Settings.useShadow){Polymer.Base.mixin(DomApi.DistributedNodesObserver.prototype,{_setup:function(){if(!this._observer){var root=this.domApi.getOwnerRoot();var host=root&&root.host;if(host){var self=this;this._observer=Polymer.dom(host).observeNodes(function(){self._scheduleNotify();});this._observer._isContentListener=true;if(this._hasAttrSelect()){Polymer.dom(host).observer.enableShadowAttributeTracking();}}}},_hasAttrSelect:function(){var select=this.node.getAttribute('select');return select&&select.match(/[[.]+/);},_cleanup:function(){var root=this.domApi.getOwnerRoot();var host=root&&root.host;if(host){Polymer.dom(host).unobserveNodes(this._observer);}
+this._observer=null;}});}}());(function(){var DomApi=Polymer.DomApi;var TreeApi=Polymer.TreeApi;Polymer.Base._addFeature({_prepShady:function(){this._useContent=this._useContent||Boolean(this._template);},_setupShady:function(){this.shadyRoot=null;if(!this.__domApi){this.__domApi=null;}
+if(!this.__dom){this.__dom=null;}
+if(!this._ownerShadyRoot){this._ownerShadyRoot=undefined;}},_poolContent:function(){if(this._useContent){TreeApi.Logical.saveChildNodes(this);}},_setupRoot:function(){if(this._useContent){this._createLocalRoot();if(!this.dataHost){upgradeLogicalChildren(TreeApi.Logical.getChildNodes(this));}}},_createLocalRoot:function(){this.shadyRoot=this.root;this.shadyRoot._distributionClean=false;this.shadyRoot._hasDistributed=false;this.shadyRoot._isShadyRoot=true;this.shadyRoot._dirtyRoots=[];var i$=this.shadyRoot._insertionPoints=!this._notes||this._notes._hasContent?this.shadyRoot.querySelectorAll('content'):[];TreeApi.Logical.saveChildNodes(this.shadyRoot);for(var i=0,c;i<i$.length;i++){c=i$[i];TreeApi.Logical.saveChildNodes(c);TreeApi.Logical.saveChildNodes(c.parentNode);}
+this.shadyRoot.host=this;},distributeContent:function(updateInsertionPoints){if(this.shadyRoot){this.shadyRoot._invalidInsertionPoints=this.shadyRoot._invalidInsertionPoints||updateInsertionPoints;var host=getTopDistributingHost(this);Polymer.dom(this)._lazyDistribute(host);}},_distributeContent:function(){if(this._useContent&&!this.shadyRoot._distributionClean){if(this.shadyRoot._invalidInsertionPoints){Polymer.dom(this)._updateInsertionPoints(this);this.shadyRoot._invalidInsertionPoints=false;}
+this._beginDistribute();this._distributeDirtyRoots();this._finishDistribute();}},_beginDistribute:function(){if(this._useContent&&DomApi.hasInsertionPoint(this.shadyRoot)){this._resetDistribution();this._distributePool(this.shadyRoot,this._collectPool());}},_distributeDirtyRoots:function(){var c$=this.shadyRoot._dirtyRoots;for(var i=0,l=c$.length,c;i<l&&(c=c$[i]);i++){c._distributeContent();}
+this.shadyRoot._dirtyRoots=[];},_finishDistribute:function(){if(this._useContent){this.shadyRoot._distributionClean=true;if(DomApi.hasInsertionPoint(this.shadyRoot)){this._composeTree();notifyContentObservers(this.shadyRoot);}else{if(!this.shadyRoot._hasDistributed){TreeApi.Composed.clearChildNodes(this);this.appendChild(this.shadyRoot);}else{var children=this._composeNode(this);this._updateChildNodes(this,children);}}
+if(!this.shadyRoot._hasDistributed){notifyInitialDistribution(this);}
+this.shadyRoot._hasDistributed=true;}},elementMatches:function(selector,node){node=node||this;return DomApi.matchesSelector.call(node,selector);},_resetDistribution:function(){var children=TreeApi.Logical.getChildNodes(this);for(var i=0;i<children.length;i++){var child=children[i];if(child._destinationInsertionPoints){child._destinationInsertionPoints=undefined;}
+if(isInsertionPoint(child)){clearDistributedDestinationInsertionPoints(child);}}
+var root=this.shadyRoot;var p$=root._insertionPoints;for(var j=0;j<p$.length;j++){p$[j]._distributedNodes=[];}},_collectPool:function(){var pool=[];var children=TreeApi.Logical.getChildNodes(this);for(var i=0;i<children.length;i++){var child=children[i];if(isInsertionPoint(child)){pool.push.apply(pool,child._distributedNodes);}else{pool.push(child);}}
+return pool;},_distributePool:function(node,pool){var p$=node._insertionPoints;for(var i=0,l=p$.length,p;i<l&&(p=p$[i]);i++){this._distributeInsertionPoint(p,pool);maybeRedistributeParent(p,this);}},_distributeInsertionPoint:function(content,pool){var anyDistributed=false;for(var i=0,l=pool.length,node;i<l;i++){node=pool[i];if(!node){continue;}
+if(this._matchesContentSelect(node,content)){distributeNodeInto(node,content);pool[i]=undefined;anyDistributed=true;}}
+if(!anyDistributed){var children=TreeApi.Logical.getChildNodes(content);for(var j=0;j<children.length;j++){distributeNodeInto(children[j],content);}}},_composeTree:function(){this._updateChildNodes(this,this._composeNode(this));var p$=this.shadyRoot._insertionPoints;for(var i=0,l=p$.length,p,parent;i<l&&(p=p$[i]);i++){parent=TreeApi.Logical.getParentNode(p);if(!parent._useContent&&parent!==this&&parent!==this.shadyRoot){this._updateChildNodes(parent,this._composeNode(parent));}}},_composeNode:function(node){var children=[];var c$=TreeApi.Logical.getChildNodes(node.shadyRoot||node);for(var i=0;i<c$.length;i++){var child=c$[i];if(isInsertionPoint(child)){var distributedNodes=child._distributedNodes;for(var j=0;j<distributedNodes.length;j++){var distributedNode=distributedNodes[j];if(isFinalDestination(child,distributedNode)){children.push(distributedNode);}}}else{children.push(child);}}
+return children;},_updateChildNodes:function(container,children){var composed=TreeApi.Composed.getChildNodes(container);var splices=Polymer.ArraySplice.calculateSplices(children,composed);for(var i=0,d=0,s;i<splices.length&&(s=splices[i]);i++){for(var j=0,n;j<s.removed.length&&(n=s.removed[j]);j++){if(TreeApi.Composed.getParentNode(n)===container){TreeApi.Composed.removeChild(container,n);}
+composed.splice(s.index+d,1);}
+d-=s.addedCount;}
+for(var i=0,s,next;i<splices.length&&(s=splices[i]);i++){next=composed[s.index];for(j=s.index,n;j<s.index+s.addedCount;j++){n=children[j];TreeApi.Composed.insertBefore(container,n,next);composed.splice(j,0,n);}}},_matchesContentSelect:function(node,contentElement){var select=contentElement.getAttribute('select');if(!select){return true;}
+select=select.trim();if(!select){return true;}
+if(!(node instanceof Element)){return false;}
+var validSelectors=/^(:not\()?[*.#[a-zA-Z_|]/;if(!validSelectors.test(select)){return false;}
+return this.elementMatches(select,node);},_elementAdd:function(){},_elementRemove:function(){}});var domHostDesc={get:function(){var root=Polymer.dom(this).getOwnerRoot();return root&&root.host;},configurable:true};Object.defineProperty(Polymer.Base,'domHost',domHostDesc);Polymer.BaseDescriptors.domHost=domHostDesc;function distributeNodeInto(child,insertionPoint){insertionPoint._distributedNodes.push(child);var points=child._destinationInsertionPoints;if(!points){child._destinationInsertionPoints=[insertionPoint];}else{points.push(insertionPoint);}}
+function clearDistributedDestinationInsertionPoints(content){var e$=content._distributedNodes;if(e$){for(var i=0;i<e$.length;i++){var d=e$[i]._destinationInsertionPoints;if(d){d.splice(d.indexOf(content)+1,d.length);}}}}
+function maybeRedistributeParent(content,host){var parent=TreeApi.Logical.getParentNode(content);if(parent&&parent.shadyRoot&&DomApi.hasInsertionPoint(parent.shadyRoot)&&parent.shadyRoot._distributionClean){parent.shadyRoot._distributionClean=false;host.shadyRoot._dirtyRoots.push(parent);}}
+function isFinalDestination(insertionPoint,node){var points=node._destinationInsertionPoints;return points&&points[points.length-1]===insertionPoint;}
+function isInsertionPoint(node){return node.localName=='content';}
+function getTopDistributingHost(host){while(host&&hostNeedsRedistribution(host)){host=host.domHost;}
+return host;}
+function hostNeedsRedistribution(host){var c$=TreeApi.Logical.getChildNodes(host);for(var i=0,c;i<c$.length;i++){c=c$[i];if(c.localName&&c.localName==='content'){return host.domHost;}}}
+function notifyContentObservers(root){for(var i=0,c;i<root._insertionPoints.length;i++){c=root._insertionPoints[i];if(DomApi.hasApi(c)){Polymer.dom(c).notifyObserver();}}}
+function notifyInitialDistribution(host){if(DomApi.hasApi(host)){Polymer.dom(host).notifyObserver();}}
+var needsUpgrade=window.CustomElements&&!CustomElements.useNative;function upgradeLogicalChildren(children){if(needsUpgrade&&children){for(var i=0;i<children.length;i++){CustomElements.upgrade(children[i]);}}}}());if(Polymer.Settings.useShadow){Polymer.Base._addFeature({_poolContent:function(){},_beginDistribute:function(){},distributeContent:function(){},_distributeContent:function(){},_finishDistribute:function(){},_createLocalRoot:function(){this.createShadowRoot();this.shadowRoot.appendChild(this.root);this.root=this.shadowRoot;}});}Polymer.Async={_currVal:0,_lastVal:0,_callbacks:[],_twiddleContent:0,_twiddle:document.createTextNode(''),run:function(callback,waitTime){if(waitTime>0){return~setTimeout(callback,waitTime);}else{this._twiddle.textContent=this._twiddleContent++;this._callbacks.push(callback);return this._currVal++;}},cancel:function(handle){if(handle<0){clearTimeout(~handle);}else{var idx=handle-this._lastVal;if(idx>=0){if(!this._callbacks[idx]){throw'invalid async handle: '+handle;}
+this._callbacks[idx]=null;}}},_atEndOfMicrotask:function(){var len=this._callbacks.length;for(var i=0;i<len;i++){var cb=this._callbacks[i];if(cb){try{cb();}catch(e){i++;this._callbacks.splice(0,i);this._lastVal+=i;this._twiddle.textContent=this._twiddleContent++;throw e;}}}
+this._callbacks.splice(0,len);this._lastVal+=len;}};new window.MutationObserver(function(){Polymer.Async._atEndOfMicrotask();}).observe(Polymer.Async._twiddle,{characterData:true});Polymer.Debounce=function(){var Async=Polymer.Async;var Debouncer=function(context){this.context=context;var self=this;this.boundComplete=function(){self.complete();};};Debouncer.prototype={go:function(callback,wait){var h;this.finish=function(){Async.cancel(h);};h=Async.run(this.boundComplete,wait);this.callback=callback;},stop:function(){if(this.finish){this.finish();this.finish=null;this.callback=null;}},complete:function(){if(this.finish){var callback=this.callback;this.stop();callback.call(this.context);}}};function debounce(debouncer,callback,wait){if(debouncer){debouncer.stop();}else{debouncer=new Debouncer(this);}
+debouncer.go(callback,wait);return debouncer;}
+return debounce;}();Polymer.Base._addFeature({_setupDebouncers:function(){this._debouncers={};},debounce:function(jobName,callback,wait){return this._debouncers[jobName]=Polymer.Debounce.call(this,this._debouncers[jobName],callback,wait);},isDebouncerActive:function(jobName){var debouncer=this._debouncers[jobName];return!!(debouncer&&debouncer.finish);},flushDebouncer:function(jobName){var debouncer=this._debouncers[jobName];if(debouncer){debouncer.complete();}},cancelDebouncer:function(jobName){var debouncer=this._debouncers[jobName];if(debouncer){debouncer.stop();}}});Polymer.DomModule=document.createElement('dom-module');Polymer.Base._addFeature({_registerFeatures:function(){this._prepIs();this._prepBehaviors();this._prepConstructor();this._prepTemplate();this._prepShady();this._prepPropertyInfo();},_prepBehavior:function(b){this._addHostAttributes(b.hostAttributes);},_initFeatures:function(){this._registerHost();if(this._template){this._poolContent();this._beginHosting();this._stampTemplate();this._endHosting();}
+this._marshalHostAttributes();this._setupDebouncers();this._marshalBehaviors();this._tryReady();},_marshalBehavior:function(b){}});(function(){Polymer.nar=[];var disableUpgradeEnabled=Polymer.Settings.disableUpgradeEnabled;Polymer.Annotations={parseAnnotations:function(template,stripWhiteSpace){var list=[];var content=template._content||template.content;this._parseNodeAnnotations(content,list,stripWhiteSpace||template.hasAttribute('strip-whitespace'));return list;},_parseNodeAnnotations:function(node,list,stripWhiteSpace){return node.nodeType===Node.TEXT_NODE?this._parseTextNodeAnnotation(node,list):this._parseElementAnnotations(node,list,stripWhiteSpace);},_bindingRegex:function(){var IDENT='(?:'+'[a-zA-Z_$][\\w.:$\\-*]*'+')';var NUMBER='(?:'+'[-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?'+')';var SQUOTE_STRING='(?:'+'\'(?:[^\'\\\\]|\\\\.)*\''+')';var DQUOTE_STRING='(?:'+'"(?:[^"\\\\]|\\\\.)*"'+')';var STRING='(?:'+SQUOTE_STRING+'|'+DQUOTE_STRING+')';var ARGUMENT='(?:'+IDENT+'|'+NUMBER+'|'+STRING+'\\s*'+')';var ARGUMENTS='(?:'+ARGUMENT+'(?:,\\s*'+ARGUMENT+')*'+')';var ARGUMENT_LIST='(?:'+'\\(\\s*'+'(?:'+ARGUMENTS+'?'+')'+'\\)\\s*'+')';var BINDING='('+IDENT+'\\s*'+ARGUMENT_LIST+'?'+')';var OPEN_BRACKET='(\\[\\[|{{)'+'\\s*';var CLOSE_BRACKET='(?:]]|}})';var NEGATE='(?:(!)\\s*)?';var EXPRESSION=OPEN_BRACKET+NEGATE+BINDING+CLOSE_BRACKET;return new RegExp(EXPRESSION,'g');}(),_parseBindings:function(text){var re=this._bindingRegex;var parts=[];var lastIndex=0;var m;while((m=re.exec(text))!==null){if(m.index>lastIndex){parts.push({literal:text.slice(lastIndex,m.index)});}
+var mode=m[1][0];var negate=Boolean(m[2]);var value=m[3].trim();var customEvent,notifyEvent,colon;if(mode=='{'&&(colon=value.indexOf('::'))>0){notifyEvent=value.substring(colon+2);value=value.substring(0,colon);customEvent=true;}
+parts.push({compoundIndex:parts.length,value:value,mode:mode,negate:negate,event:notifyEvent,customEvent:customEvent});lastIndex=re.lastIndex;}
+if(lastIndex&&lastIndex<text.length){var literal=text.substring(lastIndex);if(literal){parts.push({literal:literal});}}
+if(parts.length){return parts;}},_literalFromParts:function(parts){var s='';for(var i=0;i<parts.length;i++){var literal=parts[i].literal;s+=literal||'';}
+return s;},_parseTextNodeAnnotation:function(node,list){var parts=this._parseBindings(node.textContent);if(parts){node.textContent=this._literalFromParts(parts)||' ';var annote={bindings:[{kind:'text',name:'textContent',parts:parts,isCompound:parts.length!==1}]};list.push(annote);return annote;}},_parseElementAnnotations:function(element,list,stripWhiteSpace){var annote={bindings:[],events:[]};if(element.localName==='content'){list._hasContent=true;}
+this._parseChildNodesAnnotations(element,annote,list,stripWhiteSpace);if(element.attributes){this._parseNodeAttributeAnnotations(element,annote,list);if(this.prepElement){this.prepElement(element);}}
+if(annote.bindings.length||annote.events.length||annote.id){list.push(annote);}
+return annote;},_parseChildNodesAnnotations:function(root,annote,list,stripWhiteSpace){if(root.firstChild){var node=root.firstChild;var i=0;while(node){var next=node.nextSibling;if(node.localName==='template'&&!node.hasAttribute('preserve-content')){this._parseTemplate(node,i,list,annote,stripWhiteSpace);}
+if(node.localName=='slot'){node=this._replaceSlotWithContent(node);}
+if(node.nodeType===Node.TEXT_NODE){var n=next;while(n&&n.nodeType===Node.TEXT_NODE){node.textContent+=n.textContent;next=n.nextSibling;root.removeChild(n);n=next;}
+if(stripWhiteSpace&&!node.textContent.trim()){root.removeChild(node);i--;}}
+if(node.parentNode){var childAnnotation=this._parseNodeAnnotations(node,list,stripWhiteSpace);if(childAnnotation){childAnnotation.parent=annote;childAnnotation.index=i;}}
+node=next;i++;}}},_replaceSlotWithContent:function(slot){var content=slot.ownerDocument.createElement('content');while(slot.firstChild){content.appendChild(slot.firstChild);}
+var attrs=slot.attributes;for(var i=0;i<attrs.length;i++){var attr=attrs[i];content.setAttribute(attr.name,attr.value);}
+var name=slot.getAttribute('name');if(name){content.setAttribute('select','[slot=\''+name+'\']');}
+slot.parentNode.replaceChild(content,slot);return content;},_parseTemplate:function(node,index,list,parent,stripWhiteSpace){var content=document.createDocumentFragment();content._notes=this.parseAnnotations(node,stripWhiteSpace);content.appendChild(node.content);list.push({bindings:Polymer.nar,events:Polymer.nar,templateContent:content,parent:parent,index:index});},_parseNodeAttributeAnnotations:function(node,annotation){var attrs=Array.prototype.slice.call(node.attributes);for(var i=attrs.length-1,a;a=attrs[i];i--){var n=a.name;var v=a.value;var b;if(n.slice(0,3)==='on-'){node.removeAttribute(n);annotation.events.push({name:n.slice(3),value:v});}else if(b=this._parseNodeAttributeAnnotation(node,n,v)){annotation.bindings.push(b);}else if(n==='id'){annotation.id=v;}}},_parseNodeAttributeAnnotation:function(node,name,value){var parts=this._parseBindings(value);if(parts){var origName=name;var kind='property';if(name[name.length-1]=='$'){name=name.slice(0,-1);kind='attribute';}
+var literal=this._literalFromParts(parts);if(literal&&kind=='attribute'){node.setAttribute(name,literal);}
+if(node.localName==='input'&&origName==='value'){node.setAttribute(origName,'');}
+if(disableUpgradeEnabled&&origName==='disable-upgrade$'){node.setAttribute(name,'');}
+node.removeAttribute(origName);var propertyName=Polymer.CaseMap.dashToCamelCase(name);if(kind==='property'){name=propertyName;}
+return{kind:kind,name:name,propertyName:propertyName,parts:parts,literal:literal,isCompound:parts.length!==1};}},findAnnotatedNode:function(root,annote){var parent=annote.parent&&Polymer.Annotations.findAnnotatedNode(root,annote.parent);if(parent){for(var n=parent.firstChild,i=0;n;n=n.nextSibling){if(annote.index===i++){return n;}}}else{return root;}}};}());Polymer.Path={root:function(path){var dotIndex=path.indexOf('.');if(dotIndex===-1){return path;}
+return path.slice(0,dotIndex);},isDeep:function(path){return path.indexOf('.')!==-1;},isAncestor:function(base,path){return base.indexOf(path+'.')===0;},isDescendant:function(base,path){return path.indexOf(base+'.')===0;},translate:function(base,newBase,path){return newBase+path.slice(base.length);},matches:function(base,wildcard,path){return base===path||this.isAncestor(base,path)||Boolean(wildcard)&&this.isDescendant(base,path);}};Polymer.Base._addFeature({_prepAnnotations:function(){if(!this._template){this._notes=[];}else{var self=this;Polymer.Annotations.prepElement=function(element){self._prepElement(element);};if(this._template._content&&this._template._content._notes){this._notes=this._template._content._notes;}else{this._notes=Polymer.Annotations.parseAnnotations(this._template);this._processAnnotations(this._notes);}
+Polymer.Annotations.prepElement=null;}},_processAnnotations:function(notes){for(var i=0;i<notes.length;i++){var note=notes[i];for(var j=0;j<note.bindings.length;j++){var b=note.bindings[j];for(var k=0;k<b.parts.length;k++){var p=b.parts[k];if(!p.literal){var signature=this._parseMethod(p.value);if(signature){p.signature=signature;}else{p.model=Polymer.Path.root(p.value);}}}}
+if(note.templateContent){this._processAnnotations(note.templateContent._notes);var pp=note.templateContent._parentProps=this._discoverTemplateParentProps(note.templateContent._notes);var bindings=[];for(var prop in pp){var name='_parent_'+prop;bindings.push({index:note.index,kind:'property',name:name,propertyName:name,parts:[{mode:'{',model:prop,value:prop}]});}
+note.bindings=note.bindings.concat(bindings);}}},_discoverTemplateParentProps:function(notes){var pp={};for(var i=0,n;i<notes.length&&(n=notes[i]);i++){for(var j=0,b$=n.bindings,b;j<b$.length&&(b=b$[j]);j++){for(var k=0,p$=b.parts,p;k<p$.length&&(p=p$[k]);k++){if(p.signature){var args=p.signature.args;for(var kk=0;kk<args.length;kk++){var model=args[kk].model;if(model){pp[model]=true;}}
+if(p.signature.dynamicFn){pp[p.signature.method]=true;}}else{if(p.model){pp[p.model]=true;}}}}
+if(n.templateContent){var tpp=n.templateContent._parentProps;Polymer.Base.mixin(pp,tpp);}}
+return pp;},_prepElement:function(element){Polymer.ResolveUrl.resolveAttrs(element,this._template.ownerDocument);},_findAnnotatedNode:Polymer.Annotations.findAnnotatedNode,_marshalAnnotationReferences:function(){if(this._template){this._marshalIdNodes();this._marshalAnnotatedNodes();this._marshalAnnotatedListeners();}},_configureAnnotationReferences:function(){var notes=this._notes;var nodes=this._nodes;for(var i=0;i<notes.length;i++){var note=notes[i];var node=nodes[i];this._configureTemplateContent(note,node);this._configureCompoundBindings(note,node);}},_configureTemplateContent:function(note,node){if(note.templateContent){node._content=note.templateContent;}},_configureCompoundBindings:function(note,node){var bindings=note.bindings;for(var i=0;i<bindings.length;i++){var binding=bindings[i];if(binding.isCompound){var storage=node.__compoundStorage__||(node.__compoundStorage__={});var parts=binding.parts;var literals=new Array(parts.length);for(var j=0;j<parts.length;j++){literals[j]=parts[j].literal;}
+var name=binding.name;storage[name]=literals;if(binding.literal&&binding.kind=='property'){if(node._configValue){node._configValue(name,binding.literal);}else{node[name]=binding.literal;}}}}},_marshalIdNodes:function(){this.$={};for(var i=0,l=this._notes.length,a;i<l&&(a=this._notes[i]);i++){if(a.id){this.$[a.id]=this._findAnnotatedNode(this.root,a);}}},_marshalAnnotatedNodes:function(){if(this._notes&&this._notes.length){var r=new Array(this._notes.length);for(var i=0;i<this._notes.length;i++){r[i]=this._findAnnotatedNode(this.root,this._notes[i]);}
+this._nodes=r;}},_marshalAnnotatedListeners:function(){for(var i=0,l=this._notes.length,a;i<l&&(a=this._notes[i]);i++){if(a.events&&a.events.length){var node=this._findAnnotatedNode(this.root,a);for(var j=0,e$=a.events,e;j<e$.length&&(e=e$[j]);j++){this.listen(node,e.name,e.value);}}}}});Polymer.Base._addFeature({listeners:{},_listenListeners:function(listeners){var node,name,eventName;for(eventName in listeners){if(eventName.indexOf('.')<0){node=this;name=eventName;}else{name=eventName.split('.');node=this.$[name[0]];name=name[1];}
+this.listen(node,name,listeners[eventName]);}},listen:function(node,eventName,methodName){var handler=this._recallEventHandler(this,eventName,node,methodName);if(!handler){handler=this._createEventHandler(node,eventName,methodName);}
+if(handler._listening){return;}
+this._listen(node,eventName,handler);handler._listening=true;},_boundListenerKey:function(eventName,methodName){return eventName+':'+methodName;},_recordEventHandler:function(host,eventName,target,methodName,handler){var hbl=host.__boundListeners;if(!hbl){hbl=host.__boundListeners=new WeakMap();}
+var bl=hbl.get(target);if(!bl){bl={};if(!Polymer.Settings.isIE||target!=window){hbl.set(target,bl);}}
+var key=this._boundListenerKey(eventName,methodName);bl[key]=handler;},_recallEventHandler:function(host,eventName,target,methodName){var hbl=host.__boundListeners;if(!hbl){return;}
+var bl=hbl.get(target);if(!bl){return;}
+var key=this._boundListenerKey(eventName,methodName);return bl[key];},_createEventHandler:function(node,eventName,methodName){var host=this;var handler=function(e){if(host[methodName]){host[methodName](e,e.detail);}else{host._warn(host._logf('_createEventHandler','listener method `'+methodName+'` not defined'));}};handler._listening=false;this._recordEventHandler(host,eventName,node,methodName,handler);return handler;},unlisten:function(node,eventName,methodName){var handler=this._recallEventHandler(this,eventName,node,methodName);if(handler){this._unlisten(node,eventName,handler);handler._listening=false;}},_listen:function(node,eventName,handler){node.addEventListener(eventName,handler);},_unlisten:function(node,eventName,handler){node.removeEventListener(eventName,handler);}});(function(){'use strict';var wrap=Polymer.DomApi.wrap;var HAS_NATIVE_TA=typeof document.head.style.touchAction==='string';var GESTURE_KEY='__polymerGestures';var HANDLED_OBJ='__polymerGesturesHandled';var TOUCH_ACTION='__polymerGesturesTouchAction';var TAP_DISTANCE=25;var TRACK_DISTANCE=5;var TRACK_LENGTH=2;var MOUSE_TIMEOUT=2500;var MOUSE_EVENTS=['mousedown','mousemove','mouseup','click'];var MOUSE_WHICH_TO_BUTTONS=[0,1,4,2];var MOUSE_HAS_BUTTONS=function(){try{return new MouseEvent('test',{buttons:1}).buttons===1;}catch(e){return false;}}();function isMouseEvent(name){return MOUSE_EVENTS.indexOf(name)>-1;}
+var SUPPORTS_PASSIVE=false;(function(){try{var opts=Object.defineProperty({},'passive',{get:function(){SUPPORTS_PASSIVE=true;}});window.addEventListener('test',null,opts);window.removeEventListener('test',null,opts);}catch(e){}}());function PASSIVE_TOUCH(eventName){if(isMouseEvent(eventName)||eventName==='touchend'){return;}
+if(HAS_NATIVE_TA&&SUPPORTS_PASSIVE&&Polymer.Settings.passiveTouchGestures){return{passive:true};}}
+var IS_TOUCH_ONLY=navigator.userAgent.match(/iP(?:[oa]d|hone)|Android/);var mouseCanceller=function(mouseEvent){var sc=mouseEvent.sourceCapabilities;if(sc&&!sc.firesTouchEvents){return;}
+mouseEvent[HANDLED_OBJ]={skip:true};if(mouseEvent.type==='click'){var path=Polymer.dom(mouseEvent).path;if(path){for(var i=0;i<path.length;i++){if(path[i]===POINTERSTATE.mouse.target){return;}}}
+mouseEvent.preventDefault();mouseEvent.stopPropagation();}};function setupTeardownMouseCanceller(setup){var events=IS_TOUCH_ONLY?['click']:MOUSE_EVENTS;for(var i=0,en;i<events.length;i++){en=events[i];if(setup){document.addEventListener(en,mouseCanceller,true);}else{document.removeEventListener(en,mouseCanceller,true);}}}
+function ignoreMouse(ev){if(!POINTERSTATE.mouse.mouseIgnoreJob){setupTeardownMouseCanceller(true);}
+var unset=function(){setupTeardownMouseCanceller();POINTERSTATE.mouse.target=null;POINTERSTATE.mouse.mouseIgnoreJob=null;};POINTERSTATE.mouse.target=Polymer.dom(ev).rootTarget;POINTERSTATE.mouse.mouseIgnoreJob=Polymer.Debounce(POINTERSTATE.mouse.mouseIgnoreJob,unset,MOUSE_TIMEOUT);}
+function hasLeftMouseButton(ev){var type=ev.type;if(!isMouseEvent(type)){return false;}
+if(type==='mousemove'){var buttons=ev.buttons===undefined?1:ev.buttons;if(ev instanceof window.MouseEvent&&!MOUSE_HAS_BUTTONS){buttons=MOUSE_WHICH_TO_BUTTONS[ev.which]||0;}
+return Boolean(buttons&1);}else{var button=ev.button===undefined?0:ev.button;return button===0;}}
+function isSyntheticClick(ev){if(ev.type==='click'){if(ev.detail===0){return true;}
+var t=Gestures.findOriginalTarget(ev);var bcr=t.getBoundingClientRect();var x=ev.pageX,y=ev.pageY;return!(x>=bcr.left&&x<=bcr.right&&(y>=bcr.top&&y<=bcr.bottom));}
+return false;}
+var POINTERSTATE={mouse:{target:null,mouseIgnoreJob:null},touch:{x:0,y:0,id:-1,scrollDecided:false}};function firstTouchAction(ev){var path=Polymer.dom(ev).path;var ta='auto';for(var i=0,n;i<path.length;i++){n=path[i];if(n[TOUCH_ACTION]){ta=n[TOUCH_ACTION];break;}}
+return ta;}
+function trackDocument(stateObj,movefn,upfn){stateObj.movefn=movefn;stateObj.upfn=upfn;document.addEventListener('mousemove',movefn);document.addEventListener('mouseup',upfn);}
+function untrackDocument(stateObj){document.removeEventListener('mousemove',stateObj.movefn);document.removeEventListener('mouseup',stateObj.upfn);stateObj.movefn=null;stateObj.upfn=null;}
+document.addEventListener('touchend',ignoreMouse,SUPPORTS_PASSIVE?{passive:true}:false);var Gestures={gestures:{},recognizers:[],deepTargetFind:function(x,y){var node=document.elementFromPoint(x,y);var next=node;while(next&&next.shadowRoot){next=next.shadowRoot.elementFromPoint(x,y);if(next){node=next;}}
+return node;},findOriginalTarget:function(ev){if(ev.path){return ev.path[0];}
+return ev.target;},handleNative:function(ev){var handled;var type=ev.type;var node=wrap(ev.currentTarget);var gobj=node[GESTURE_KEY];if(!gobj){return;}
+var gs=gobj[type];if(!gs){return;}
+if(!ev[HANDLED_OBJ]){ev[HANDLED_OBJ]={};if(type.slice(0,5)==='touch'){var t=ev.changedTouches[0];if(type==='touchstart'){if(ev.touches.length===1){POINTERSTATE.touch.id=t.identifier;}}
+if(POINTERSTATE.touch.id!==t.identifier){return;}
+if(!HAS_NATIVE_TA){if(type==='touchstart'||type==='touchmove'){Gestures.handleTouchAction(ev);}}}}
+handled=ev[HANDLED_OBJ];if(handled.skip){return;}
+var recognizers=Gestures.recognizers;for(var i=0,r;i<recognizers.length;i++){r=recognizers[i];if(gs[r.name]&&!handled[r.name]){if(r.flow&&r.flow.start.indexOf(ev.type)>-1&&r.reset){r.reset();}}}
+for(i=0,r;i<recognizers.length;i++){r=recognizers[i];if(gs[r.name]&&!handled[r.name]){handled[r.name]=true;r[type](ev);}}},handleTouchAction:function(ev){var t=ev.changedTouches[0];var type=ev.type;if(type==='touchstart'){POINTERSTATE.touch.x=t.clientX;POINTERSTATE.touch.y=t.clientY;POINTERSTATE.touch.scrollDecided=false;}else if(type==='touchmove'){if(POINTERSTATE.touch.scrollDecided){return;}
+POINTERSTATE.touch.scrollDecided=true;var ta=firstTouchAction(ev);var prevent=false;var dx=Math.abs(POINTERSTATE.touch.x-t.clientX);var dy=Math.abs(POINTERSTATE.touch.y-t.clientY);if(!ev.cancelable){}else if(ta==='none'){prevent=true;}else if(ta==='pan-x'){prevent=dy>dx;}else if(ta==='pan-y'){prevent=dx>dy;}
+if(prevent){ev.preventDefault();}else{Gestures.prevent('track');}}},add:function(node,evType,handler){node=wrap(node);var recognizer=this.gestures[evType];var deps=recognizer.deps;var name=recognizer.name;var gobj=node[GESTURE_KEY];if(!gobj){node[GESTURE_KEY]=gobj={};}
+for(var i=0,dep,gd;i<deps.length;i++){dep=deps[i];if(IS_TOUCH_ONLY&&isMouseEvent(dep)&&dep!=='click'){continue;}
+gd=gobj[dep];if(!gd){gobj[dep]=gd={_count:0};}
+if(gd._count===0){node.addEventListener(dep,this.handleNative,PASSIVE_TOUCH(dep));}
+gd[name]=(gd[name]||0)+1;gd._count=(gd._count||0)+1;}
+node.addEventListener(evType,handler);if(recognizer.touchAction){this.setTouchAction(node,recognizer.touchAction);}},remove:function(node,evType,handler){node=wrap(node);var recognizer=this.gestures[evType];var deps=recognizer.deps;var name=recognizer.name;var gobj=node[GESTURE_KEY];if(gobj){for(var i=0,dep,gd;i<deps.length;i++){dep=deps[i];gd=gobj[dep];if(gd&&gd[name]){gd[name]=(gd[name]||1)-1;gd._count=(gd._count||1)-1;if(gd._count===0){node.removeEventListener(dep,this.handleNative,PASSIVE_TOUCH(dep));}}}}
+node.removeEventListener(evType,handler);},register:function(recog){this.recognizers.push(recog);for(var i=0;i<recog.emits.length;i++){this.gestures[recog.emits[i]]=recog;}},findRecognizerByEvent:function(evName){for(var i=0,r;i<this.recognizers.length;i++){r=this.recognizers[i];for(var j=0,n;j<r.emits.length;j++){n=r.emits[j];if(n===evName){return r;}}}
+return null;},setTouchAction:function(node,value){if(HAS_NATIVE_TA){node.style.touchAction=value;}
+node[TOUCH_ACTION]=value;},fire:function(target,type,detail){var ev=Polymer.Base.fire(type,detail,{node:target,bubbles:true,cancelable:true});if(ev.defaultPrevented){var preventer=detail.preventer||detail.sourceEvent;if(preventer&&preventer.preventDefault){preventer.preventDefault();}}},prevent:function(evName){var recognizer=this.findRecognizerByEvent(evName);if(recognizer.info){recognizer.info.prevent=true;}},resetMouseCanceller:function(){if(POINTERSTATE.mouse.mouseIgnoreJob){POINTERSTATE.mouse.mouseIgnoreJob.complete();}}};Gestures.register({name:'downup',deps:['mousedown','touchstart','touchend'],flow:{start:['mousedown','touchstart'],end:['mouseup','touchend']},emits:['down','up'],info:{movefn:null,upfn:null},reset:function(){untrackDocument(this.info);},mousedown:function(e){if(!hasLeftMouseButton(e)){return;}
+var t=Gestures.findOriginalTarget(e);var self=this;var movefn=function movefn(e){if(!hasLeftMouseButton(e)){self.fire('up',t,e);untrackDocument(self.info);}};var upfn=function upfn(e){if(hasLeftMouseButton(e)){self.fire('up',t,e);}
+untrackDocument(self.info);};trackDocument(this.info,movefn,upfn);this.fire('down',t,e);},touchstart:function(e){this.fire('down',Gestures.findOriginalTarget(e),e.changedTouches[0],e);},touchend:function(e){this.fire('up',Gestures.findOriginalTarget(e),e.changedTouches[0],e);},fire:function(type,target,event,preventer){Gestures.fire(target,type,{x:event.clientX,y:event.clientY,sourceEvent:event,preventer:preventer,prevent:function(e){return Gestures.prevent(e);}});}});Gestures.register({name:'track',touchAction:'none',deps:['mousedown','touchstart','touchmove','touchend'],flow:{start:['mousedown','touchstart'],end:['mouseup','touchend']},emits:['track'],info:{x:0,y:0,state:'start',started:false,moves:[],addMove:function(move){if(this.moves.length>TRACK_LENGTH){this.moves.shift();}
+this.moves.push(move);},movefn:null,upfn:null,prevent:false},reset:function(){this.info.state='start';this.info.started=false;this.info.moves=[];this.info.x=0;this.info.y=0;this.info.prevent=false;untrackDocument(this.info);},hasMovedEnough:function(x,y){if(this.info.prevent){return false;}
+if(this.info.started){return true;}
+var dx=Math.abs(this.info.x-x);var dy=Math.abs(this.info.y-y);return dx>=TRACK_DISTANCE||dy>=TRACK_DISTANCE;},mousedown:function(e){if(!hasLeftMouseButton(e)){return;}
+var t=Gestures.findOriginalTarget(e);var self=this;var movefn=function movefn(e){var x=e.clientX,y=e.clientY;if(self.hasMovedEnough(x,y)){self.info.state=self.info.started?e.type==='mouseup'?'end':'track':'start';if(self.info.state==='start'){Gestures.prevent('tap');}
+self.info.addMove({x:x,y:y});if(!hasLeftMouseButton(e)){self.info.state='end';untrackDocument(self.info);}
+self.fire(t,e);self.info.started=true;}};var upfn=function upfn(e){if(self.info.started){movefn(e);}
+untrackDocument(self.info);};trackDocument(this.info,movefn,upfn);this.info.x=e.clientX;this.info.y=e.clientY;},touchstart:function(e){var ct=e.changedTouches[0];this.info.x=ct.clientX;this.info.y=ct.clientY;},touchmove:function(e){var t=Gestures.findOriginalTarget(e);var ct=e.changedTouches[0];var x=ct.clientX,y=ct.clientY;if(this.hasMovedEnough(x,y)){if(this.info.state==='start'){Gestures.prevent('tap');}
+this.info.addMove({x:x,y:y});this.fire(t,ct);this.info.state='track';this.info.started=true;}},touchend:function(e){var t=Gestures.findOriginalTarget(e);var ct=e.changedTouches[0];if(this.info.started){this.info.state='end';this.info.addMove({x:ct.clientX,y:ct.clientY});this.fire(t,ct,e);}},fire:function(target,touch,preventer){var secondlast=this.info.moves[this.info.moves.length-2];var lastmove=this.info.moves[this.info.moves.length-1];var dx=lastmove.x-this.info.x;var dy=lastmove.y-this.info.y;var ddx,ddy=0;if(secondlast){ddx=lastmove.x-secondlast.x;ddy=lastmove.y-secondlast.y;}
+return Gestures.fire(target,'track',{state:this.info.state,x:touch.clientX,y:touch.clientY,dx:dx,dy:dy,ddx:ddx,ddy:ddy,sourceEvent:touch,preventer:preventer,hover:function(){return Gestures.deepTargetFind(touch.clientX,touch.clientY);}});}});Gestures.register({name:'tap',deps:['mousedown','click','touchstart','touchend'],flow:{start:['mousedown','touchstart'],end:['click','touchend']},emits:['tap'],info:{x:NaN,y:NaN,prevent:false},reset:function(){this.info.x=NaN;this.info.y=NaN;this.info.prevent=false;},save:function(e){this.info.x=e.clientX;this.info.y=e.clientY;},mousedown:function(e){if(hasLeftMouseButton(e)){this.save(e);}},click:function(e){if(hasLeftMouseButton(e)){this.forward(e);}},touchstart:function(e){this.save(e.changedTouches[0],e);},touchend:function(e){this.forward(e.changedTouches[0],e);},forward:function(e,preventer){var dx=Math.abs(e.clientX-this.info.x);var dy=Math.abs(e.clientY-this.info.y);var t=Gestures.findOriginalTarget(e);if(isNaN(dx)||isNaN(dy)||dx<=TAP_DISTANCE&&dy<=TAP_DISTANCE||isSyntheticClick(e)){if(!this.info.prevent){Gestures.fire(t,'tap',{x:e.clientX,y:e.clientY,sourceEvent:e,preventer:preventer});}}}});var DIRECTION_MAP={x:'pan-x',y:'pan-y',none:'none',all:'auto'};Polymer.Base._addFeature({_setupGestures:function(){this.__polymerGestures=null;},_listen:function(node,eventName,handler){if(Gestures.gestures[eventName]){Gestures.add(node,eventName,handler);}else{node.addEventListener(eventName,handler);}},_unlisten:function(node,eventName,handler){if(Gestures.gestures[eventName]){Gestures.remove(node,eventName,handler);}else{node.removeEventListener(eventName,handler);}},setScrollDirection:function(direction,node){node=node||this;Gestures.setTouchAction(node,DIRECTION_MAP[direction]||'auto');}});Polymer.Gestures=Gestures;}());(function(){'use strict';Polymer.Base._addFeature({$$:function(slctr){return Polymer.dom(this.root).querySelector(slctr);},toggleClass:function(name,bool,node){node=node||this;if(arguments.length==1){bool=!node.classList.contains(name);}
+if(bool){Polymer.dom(node).classList.add(name);}else{Polymer.dom(node).classList.remove(name);}},toggleAttribute:function(name,bool,node){node=node||this;if(arguments.length==1){bool=!node.hasAttribute(name);}
+if(bool){Polymer.dom(node).setAttribute(name,'');}else{Polymer.dom(node).removeAttribute(name);}},classFollows:function(name,toElement,fromElement){if(fromElement){Polymer.dom(fromElement).classList.remove(name);}
+if(toElement){Polymer.dom(toElement).classList.add(name);}},attributeFollows:function(name,toElement,fromElement){if(fromElement){Polymer.dom(fromElement).removeAttribute(name);}
+if(toElement){Polymer.dom(toElement).setAttribute(name,'');}},getEffectiveChildNodes:function(){return Polymer.dom(this).getEffectiveChildNodes();},getEffectiveChildren:function(){var list=Polymer.dom(this).getEffectiveChildNodes();return list.filter(function(n){return n.nodeType===Node.ELEMENT_NODE;});},getEffectiveTextContent:function(){var cn=this.getEffectiveChildNodes();var tc=[];for(var i=0,c;c=cn[i];i++){if(c.nodeType!==Node.COMMENT_NODE){tc.push(Polymer.dom(c).textContent);}}
+return tc.join('');},queryEffectiveChildren:function(slctr){var e$=Polymer.dom(this).queryDistributedElements(slctr);return e$&&e$[0];},queryAllEffectiveChildren:function(slctr){return Polymer.dom(this).queryDistributedElements(slctr);},getContentChildNodes:function(slctr){var content=Polymer.dom(this.root).querySelector(slctr||'content');return content?Polymer.dom(content).getDistributedNodes():[];},getContentChildren:function(slctr){return this.getContentChildNodes(slctr).filter(function(n){return n.nodeType===Node.ELEMENT_NODE;});},fire:function(type,detail,options){options=options||Polymer.nob;var node=options.node||this;detail=detail===null||detail===undefined?{}:detail;var bubbles=options.bubbles===undefined?true:options.bubbles;var cancelable=Boolean(options.cancelable);var useCache=options._useCache;var event=this._getEvent(type,bubbles,cancelable,useCache);event.detail=detail;if(useCache){this.__eventCache[type]=null;}
+node.dispatchEvent(event);if(useCache){this.__eventCache[type]=event;}
+return event;},__eventCache:{},_getEvent:function(type,bubbles,cancelable,useCache){var event=useCache&&this.__eventCache[type];if(!event||(event.bubbles!=bubbles||event.cancelable!=cancelable)){event=new Event(type,{bubbles:Boolean(bubbles),cancelable:cancelable});}
+return event;},async:function(callback,waitTime){var self=this;return Polymer.Async.run(function(){callback.call(self);},waitTime);},cancelAsync:function(handle){Polymer.Async.cancel(handle);},arrayDelete:function(path,item){var index;if(Array.isArray(path)){index=path.indexOf(item);if(index>=0){return path.splice(index,1);}}else{var arr=this._get(path);index=arr.indexOf(item);if(index>=0){return this.splice(path,index,1);}}},transform:function(transform,node){node=node||this;node.style.webkitTransform=transform;node.style.transform=transform;},translate3d:function(x,y,z,node){node=node||this;this.transform('translate3d('+x+','+y+','+z+')',node);},importHref:function(href,onload,onerror,optAsync){var link=document.createElement('link');link.rel='import';link.href=href;var list=Polymer.Base.importHref.imported=Polymer.Base.importHref.imported||{};var cached=list[link.href];var imprt=cached||link;var self=this;var loadListener=function(e){e.target.__firedLoad=true;e.target.removeEventListener('load',loadListener);e.target.removeEventListener('error',errorListener);return onload.call(self,e);};var errorListener=function(e){e.target.__firedError=true;e.target.removeEventListener('load',loadListener);e.target.removeEventListener('error',errorListener);return onerror.call(self,e);};if(onload){imprt.addEventListener('load',loadListener);}
+if(onerror){imprt.addEventListener('error',errorListener);}
+if(cached){if(cached.__firedLoad){cached.dispatchEvent(new Event('load'));}
+if(cached.__firedError){cached.dispatchEvent(new Event('error'));}}else{list[link.href]=link;optAsync=Boolean(optAsync);if(optAsync){link.setAttribute('async','');}
+document.head.appendChild(link);}
+return imprt;},create:function(tag,props){var elt=document.createElement(tag);if(props){for(var n in props){elt[n]=props[n];}}
+return elt;},isLightDescendant:function(node){return this!==node&&this.contains(node)&&Polymer.dom(this).getOwnerRoot()===Polymer.dom(node).getOwnerRoot();},isLocalDescendant:function(node){return this.root===Polymer.dom(node).getOwnerRoot();}});if(!Polymer.Settings.useNativeCustomElements){var importHref=Polymer.Base.importHref;Polymer.Base.importHref=function(href,onload,onerror,optAsync){CustomElements.ready=false;var loadFn=function(e){CustomElements.upgradeDocumentTree(document);CustomElements.ready=true;if(onload){return onload.call(this,e);}};return importHref.call(this,href,loadFn,onerror,optAsync);};}}());Polymer.Bind={prepareModel:function(model){Polymer.Base.mixin(model,this._modelApi);},_modelApi:{_notifyChange:function(source,event,value){value=value===undefined?this[source]:value;event=event||Polymer.CaseMap.camelToDashCase(source)+'-changed';this.fire(event,{value:value},{bubbles:false,cancelable:false,_useCache:Polymer.Settings.eventDataCache||!Polymer.Settings.isIE});},_propertySetter:function(property,value,effects,fromAbove){var old=this.__data__[property];if(old!==value&&(old===old||value===value)){this.__data__[property]=value;if(typeof value=='object'){this._clearPath(property);}
+if(this._propertyChanged){this._propertyChanged(property,value,old);}
+if(effects){this._effectEffects(property,value,effects,old,fromAbove);}}
+return old;},__setProperty:function(property,value,quiet,node){node=node||this;var effects=node._propertyEffects&&node._propertyEffects[property];if(effects){node._propertySetter(property,value,effects,quiet);}else if(node[property]!==value){node[property]=value;}},_effectEffects:function(property,value,effects,old,fromAbove){for(var i=0,l=effects.length,fx;i<l&&(fx=effects[i]);i++){fx.fn.call(this,property,this[property],fx.effect,old,fromAbove);}},_clearPath:function(path){for(var prop in this.__data__){if(Polymer.Path.isDescendant(path,prop)){this.__data__[prop]=undefined;}}}},ensurePropertyEffects:function(model,property){if(!model._propertyEffects){model._propertyEffects={};}
+var fx=model._propertyEffects[property];if(!fx){fx=model._propertyEffects[property]=[];}
+return fx;},addPropertyEffect:function(model,property,kind,effect){var fx=this.ensurePropertyEffects(model,property);var propEffect={kind:kind,effect:effect,fn:Polymer.Bind['_'+kind+'Effect']};fx.push(propEffect);return propEffect;},createBindings:function(model){var fx$=model._propertyEffects;if(fx$){for(var n in fx$){var fx=fx$[n];fx.sort(this._sortPropertyEffects);this._createAccessors(model,n,fx);}}},_sortPropertyEffects:function(){var EFFECT_ORDER={'compute':0,'annotation':1,'annotatedComputation':2,'reflect':3,'notify':4,'observer':5,'complexObserver':6,'function':7};return function(a,b){return EFFECT_ORDER[a.kind]-EFFECT_ORDER[b.kind];};}(),_createAccessors:function(model,property,effects){var defun={get:function(){return this.__data__[property];}};var setter=function(value){this._propertySetter(property,value,effects);};var info=model.getPropertyInfo&&model.getPropertyInfo(property);if(info&&info.readOnly){if(!info.computed){model['_set'+this.upper(property)]=setter;}}else{defun.set=setter;}
+Object.defineProperty(model,property,defun);},upper:function(name){return name[0].toUpperCase()+name.substring(1);},_addAnnotatedListener:function(model,index,property,path,event,negated){if(!model._bindListeners){model._bindListeners=[];}
+var fn=this._notedListenerFactory(property,path,Polymer.Path.isDeep(path),negated);var eventName=event||Polymer.CaseMap.camelToDashCase(property)+'-changed';model._bindListeners.push({index:index,property:property,path:path,changedFn:fn,event:eventName});},_isEventBogus:function(e,target){return e.path&&e.path[0]!==target;},_notedListenerFactory:function(property,path,isStructured,negated){return function(target,value,targetPath){if(targetPath){var newPath=Polymer.Path.translate(property,path,targetPath);this._notifyPath(newPath,value);}else{value=target[property];if(negated){value=!value;}
+if(!isStructured){this[path]=value;}else{if(this.__data__[path]!=value){this.set(path,value);}}}};},prepareInstance:function(inst){inst.__data__=Object.create(null);},setupBindListeners:function(inst){var b$=inst._bindListeners;for(var i=0,l=b$.length,info;i<l&&(info=b$[i]);i++){var node=inst._nodes[info.index];this._addNotifyListener(node,inst,info.event,info.changedFn);}},_addNotifyListener:function(element,context,event,changedFn){element.addEventListener(event,function(e){return context._notifyListener(changedFn,e);});}};Polymer.Base.mixin(Polymer.Bind,{_shouldAddListener:function(effect){return effect.name&&effect.kind!='attribute'&&effect.kind!='text'&&!effect.isCompound&&effect.parts[0].mode==='{';},_annotationEffect:function(source,value,effect){if(source!=effect.value){value=this._get(effect.value);this.__data__[effect.value]=value;}
+this._applyEffectValue(effect,value);},_reflectEffect:function(source,value,effect){this.reflectPropertyToAttribute(source,effect.attribute,value);},_notifyEffect:function(source,value,effect,old,fromAbove){if(!fromAbove){this._notifyChange(source,effect.event,value);}},_functionEffect:function(source,value,fn,old,fromAbove){fn.call(this,source,value,old,fromAbove);},_observerEffect:function(source,value,effect,old){var fn=this[effect.method];if(fn){fn.call(this,value,old);}else{this._warn(this._logf('_observerEffect','observer method `'+effect.method+'` not defined'));}},_complexObserverEffect:function(source,value,effect){var fn=this[effect.method];if(fn){var args=Polymer.Bind._marshalArgs(this.__data__,effect,source,value);if(args){fn.apply(this,args);}}else if(effect.dynamicFn){}else{this._warn(this._logf('_complexObserverEffect','observer method `'+effect.method+'` not defined'));}},_computeEffect:function(source,value,effect){var fn=this[effect.method];if(fn){var args=Polymer.Bind._marshalArgs(this.__data__,effect,source,value);if(args){var computedvalue=fn.apply(this,args);this.__setProperty(effect.name,computedvalue);}}else if(effect.dynamicFn){}else{this._warn(this._logf('_computeEffect','compute method `'+effect.method+'` not defined'));}},_annotatedComputationEffect:function(source,value,effect){var computedHost=this._rootDataHost||this;var fn=computedHost[effect.method];if(fn){var args=Polymer.Bind._marshalArgs(this.__data__,effect,source,value);if(args){var computedvalue=fn.apply(computedHost,args);this._applyEffectValue(effect,computedvalue);}}else if(effect.dynamicFn){}else{computedHost._warn(computedHost._logf('_annotatedComputationEffect','compute method `'+effect.method+'` not defined'));}},_marshalArgs:function(model,effect,path,value){var values=[];var args=effect.args;var bailoutEarly=args.length>1||effect.dynamicFn;for(var i=0,l=args.length;i<l;i++){var arg=args[i];var name=arg.name;var v;if(arg.literal){v=arg.value;}else if(path===name){v=value;}else{v=model[name];if(v===undefined&&arg.structured){v=Polymer.Base._get(name,model);}}
+if(bailoutEarly&&v===undefined){return;}
+if(arg.wildcard){var matches=Polymer.Path.isAncestor(path,name);values[i]={path:matches?path:name,value:matches?value:v,base:v};}else{values[i]=v;}}
+return values;}});Polymer.Base._addFeature({_addPropertyEffect:function(property,kind,effect){var prop=Polymer.Bind.addPropertyEffect(this,property,kind,effect);prop.pathFn=this['_'+prop.kind+'PathEffect'];},_prepEffects:function(){Polymer.Bind.prepareModel(this);this._addAnnotationEffects(this._notes);},_prepBindings:function(){Polymer.Bind.createBindings(this);},_addPropertyEffects:function(properties){if(properties){for(var p in properties){var prop=properties[p];if(prop.observer){this._addObserverEffect(p,prop.observer);}
+if(prop.computed){prop.readOnly=true;this._addComputedEffect(p,prop.computed);}
+if(prop.notify){this._addPropertyEffect(p,'notify',{event:Polymer.CaseMap.camelToDashCase(p)+'-changed'});}
+if(prop.reflectToAttribute){var attr=Polymer.CaseMap.camelToDashCase(p);if(attr[0]==='-'){this._warn(this._logf('_addPropertyEffects','Property '+p+' cannot be reflected to attribute '+attr+' because "-" is not a valid starting attribute name. Use a lowercase first letter for the property instead.'));}else{this._addPropertyEffect(p,'reflect',{attribute:attr});}}
+if(prop.readOnly){Polymer.Bind.ensurePropertyEffects(this,p);}}}},_addComputedEffect:function(name,expression){var sig=this._parseMethod(expression);var dynamicFn=sig.dynamicFn;for(var i=0,arg;i<sig.args.length&&(arg=sig.args[i]);i++){this._addPropertyEffect(arg.model,'compute',{method:sig.method,args:sig.args,trigger:arg,name:name,dynamicFn:dynamicFn});}
+if(dynamicFn){this._addPropertyEffect(sig.method,'compute',{method:sig.method,args:sig.args,trigger:null,name:name,dynamicFn:dynamicFn});}},_addObserverEffect:function(property,observer){this._addPropertyEffect(property,'observer',{method:observer,property:property});},_addComplexObserverEffects:function(observers){if(observers){for(var i=0,o;i<observers.length&&(o=observers[i]);i++){this._addComplexObserverEffect(o);}}},_addComplexObserverEffect:function(observer){var sig=this._parseMethod(observer);if(!sig){throw new Error('Malformed observer expression \''+observer+'\'');}
+var dynamicFn=sig.dynamicFn;for(var i=0,arg;i<sig.args.length&&(arg=sig.args[i]);i++){this._addPropertyEffect(arg.model,'complexObserver',{method:sig.method,args:sig.args,trigger:arg,dynamicFn:dynamicFn});}
+if(dynamicFn){this._addPropertyEffect(sig.method,'complexObserver',{method:sig.method,args:sig.args,trigger:null,dynamicFn:dynamicFn});}},_addAnnotationEffects:function(notes){for(var i=0,note;i<notes.length&&(note=notes[i]);i++){var b$=note.bindings;for(var j=0,binding;j<b$.length&&(binding=b$[j]);j++){this._addAnnotationEffect(binding,i);}}},_addAnnotationEffect:function(note,index){if(Polymer.Bind._shouldAddListener(note)){Polymer.Bind._addAnnotatedListener(this,index,note.name,note.parts[0].value,note.parts[0].event,note.parts[0].negate);}
+for(var i=0;i<note.parts.length;i++){var part=note.parts[i];if(part.signature){this._addAnnotatedComputationEffect(note,part,index);}else if(!part.literal){if(note.kind==='attribute'&&note.name[0]==='-'){this._warn(this._logf('_addAnnotationEffect','Cannot set attribute '+note.name+' because "-" is not a valid attribute starting character'));}else{this._addPropertyEffect(part.model,'annotation',{kind:note.kind,index:index,name:note.name,propertyName:note.propertyName,value:part.value,isCompound:note.isCompound,compoundIndex:part.compoundIndex,event:part.event,customEvent:part.customEvent,negate:part.negate});}}}},_addAnnotatedComputationEffect:function(note,part,index){var sig=part.signature;if(sig.static){this.__addAnnotatedComputationEffect('__static__',index,note,part,null);}else{for(var i=0,arg;i<sig.args.length&&(arg=sig.args[i]);i++){if(!arg.literal){this.__addAnnotatedComputationEffect(arg.model,index,note,part,arg);}}
+if(sig.dynamicFn){this.__addAnnotatedComputationEffect(sig.method,index,note,part,null);}}},__addAnnotatedComputationEffect:function(property,index,note,part,trigger){this._addPropertyEffect(property,'annotatedComputation',{index:index,isCompound:note.isCompound,compoundIndex:part.compoundIndex,kind:note.kind,name:note.name,negate:part.negate,method:part.signature.method,args:part.signature.args,trigger:trigger,dynamicFn:part.signature.dynamicFn});},_parseMethod:function(expression){var m=expression.match(/([^\s]+?)\(([\s\S]*)\)/);if(m){var sig={method:m[1],static:true};if(this.getPropertyInfo(sig.method)!==Polymer.nob){sig.static=false;sig.dynamicFn=true;}
+if(m[2].trim()){var args=m[2].replace(/\\,/g,'&comma;').split(',');return this._parseArgs(args,sig);}else{sig.args=Polymer.nar;return sig;}}},_parseArgs:function(argList,sig){sig.args=argList.map(function(rawArg){var arg=this._parseArg(rawArg);if(!arg.literal){sig.static=false;}
+return arg;},this);return sig;},_parseArg:function(rawArg){var arg=rawArg.trim().replace(/&comma;/g,',').replace(/\\(.)/g,'$1');var a={name:arg};var fc=arg[0];if(fc==='-'){fc=arg[1];}
+if(fc>='0'&&fc<='9'){fc='#';}
+switch(fc){case'\'':case'"':a.value=arg.slice(1,-1);a.literal=true;break;case'#':a.value=Number(arg);a.literal=true;break;}
+if(!a.literal){a.model=Polymer.Path.root(arg);a.structured=Polymer.Path.isDeep(arg);if(a.structured){a.wildcard=arg.slice(-2)=='.*';if(a.wildcard){a.name=arg.slice(0,-2);}}}
+return a;},_marshalInstanceEffects:function(){Polymer.Bind.prepareInstance(this);if(this._bindListeners){Polymer.Bind.setupBindListeners(this);}},_applyEffectValue:function(info,value){var node=this._nodes[info.index];var property=info.name;value=this._computeFinalAnnotationValue(node,property,value,info);if(info.kind=='attribute'){this.serializeValueToAttribute(value,property,node);}else{var pinfo=node._propertyInfo&&node._propertyInfo[property];if(pinfo&&pinfo.readOnly){return;}
+this.__setProperty(property,value,Polymer.Settings.suppressBindingNotifications,node);}},_computeFinalAnnotationValue:function(node,property,value,info){if(info.negate){value=!value;}
+if(info.isCompound){var storage=node.__compoundStorage__[property];storage[info.compoundIndex]=value;value=storage.join('');}
+if(info.kind!=='attribute'){if(property==='className'){value=this._scopeElementClass(node,value);}
+if(property==='textContent'||node.localName=='input'&&property=='value'){value=value==undefined?'':value;}}
+return value;},_executeStaticEffects:function(){if(this._propertyEffects&&this._propertyEffects.__static__){this._effectEffects('__static__',null,this._propertyEffects.__static__);}}});(function(){var usePolyfillProto=Polymer.Settings.usePolyfillProto;var avoidInstanceProperties=Boolean(Object.getOwnPropertyDescriptor(document.documentElement,'properties'));Polymer.Base._addFeature({_setupConfigure:function(initialConfig){this._config={};this._handlers=[];this._aboveConfig=null;if(initialConfig){for(var i in initialConfig){if(initialConfig[i]!==undefined){this._config[i]=initialConfig[i];}}}},_marshalAttributes:function(){this._takeAttributesToModel(this._config);},_attributeChangedImpl:function(name){var model=this._clientsReadied?this:this._config;this._setAttributeToProperty(model,name);},_configValue:function(name,value){var info=this._propertyInfo[name];if(!info||!info.readOnly){this._config[name]=value;}},_beforeClientsReady:function(){this._configure();},_configure:function(){this._configureAnnotationReferences();this._configureInstanceProperties();this._aboveConfig=this.mixin({},this._config);var config={};for(var i=0;i<this.behaviors.length;i++){this._configureProperties(this.behaviors[i].properties,config);}
+this._configureProperties(avoidInstanceProperties?this.__proto__.properties:this.properties,config);this.mixin(config,this._aboveConfig);this._config=config;if(this._clients&&this._clients.length){this._distributeConfig(this._config);}},_configureInstanceProperties:function(){for(var i in this._propertyEffects){if(!usePolyfillProto&&this.hasOwnProperty(i)){this._configValue(i,this[i]);delete this[i];}}},_configureProperties:function(properties,config){for(var i in properties){var c=properties[i];if(c.value!==undefined){var value=c.value;if(typeof value=='function'){value=value.call(this,this._config);}
+config[i]=value;}}},_distributeConfig:function(config){var fx$=this._propertyEffects;if(fx$){for(var p in config){var fx=fx$[p];if(fx){for(var i=0,l=fx.length,x;i<l&&(x=fx[i]);i++){if(x.kind==='annotation'){var node=this._nodes[x.effect.index];var name=x.effect.propertyName;var isAttr=x.effect.kind=='attribute';var hasEffect=node._propertyEffects&&node._propertyEffects[name];if(node._configValue&&(hasEffect||!isAttr)){var value=p===x.effect.value?config[p]:this._get(x.effect.value,config);value=this._computeFinalAnnotationValue(node,name,value,x.effect);if(isAttr){value=node.deserialize(this.serialize(value),node._propertyInfo[name].type);}
+node._configValue(name,value);}}}}}}},_afterClientsReady:function(){this.importPath=this._importPath;this.rootPath=Polymer.rootPath;this._executeStaticEffects();this._applyConfig(this._config,this._aboveConfig);this._flushHandlers();},_applyConfig:function(config,aboveConfig){for(var n in config){if(this[n]===undefined){this.__setProperty(n,config[n],n in aboveConfig);}}},_notifyListener:function(fn,e){if(!Polymer.Bind._isEventBogus(e,e.target)){var value,path;if(e.detail){value=e.detail.value;path=e.detail.path;}
+if(!this._clientsReadied){this._queueHandler([fn,e.target,value,path]);}else{return fn.call(this,e.target,value,path);}}},_queueHandler:function(args){this._handlers.push(args);},_flushHandlers:function(){var h$=this._handlers;for(var i=0,l=h$.length,h;i<l&&(h=h$[i]);i++){h[0].call(this,h[1],h[2],h[3]);}
+this._handlers=[];}});}());(function(){'use strict';var Path=Polymer.Path;Polymer.Base._addFeature({notifyPath:function(path,value,fromAbove){var info={};var v=this._get(path,this,info);if(arguments.length===1){value=v;}
+if(info.path){this._notifyPath(info.path,value,fromAbove);}},_notifyPath:function(path,value,fromAbove){var old=this._propertySetter(path,value);if(old!==value&&(old===old||value===value)){this._pathEffector(path,value);if(!fromAbove){this._notifyPathUp(path,value);}
+return true;}},_getPathParts:function(path){if(Array.isArray(path)){var parts=[];for(var i=0;i<path.length;i++){var args=path[i].toString().split('.');for(var j=0;j<args.length;j++){parts.push(args[j]);}}
+return parts;}else{return path.toString().split('.');}},set:function(path,value,root){var prop=root||this;var parts=this._getPathParts(path);var array;var last=parts[parts.length-1];if(parts.length>1){for(var i=0;i<parts.length-1;i++){var part=parts[i];if(array&&part[0]=='#'){prop=Polymer.Collection.get(array).getItem(part);}else{prop=prop[part];if(array&&parseInt(part,10)==part){parts[i]=Polymer.Collection.get(array).getKey(prop);}}
+if(!prop){return;}
+array=Array.isArray(prop)?prop:null;}
+if(array){var coll=Polymer.Collection.get(array);var old,key;if(last[0]=='#'){key=last;old=coll.getItem(key);last=array.indexOf(old);coll.setItem(key,value);}else if(parseInt(last,10)==last){old=prop[last];key=coll.getKey(old);parts[i]=key;coll.setItem(key,value);}}
+prop[last]=value;if(!root){this._notifyPath(parts.join('.'),value);}}else{prop[path]=value;}},get:function(path,root){return this._get(path,root);},_get:function(path,root,info){var prop=root||this;var parts=this._getPathParts(path);var array;for(var i=0;i<parts.length;i++){if(!prop){return;}
+var part=parts[i];if(array&&part[0]=='#'){prop=Polymer.Collection.get(array).getItem(part);}else{prop=prop[part];if(info&&array&&parseInt(part,10)==part){parts[i]=Polymer.Collection.get(array).getKey(prop);}}
+array=Array.isArray(prop)?prop:null;}
+if(info){info.path=parts.join('.');}
+return prop;},_pathEffector:function(path,value){var model=Path.root(path);var fx$=this._propertyEffects&&this._propertyEffects[model];if(fx$){for(var i=0,fx;i<fx$.length&&(fx=fx$[i]);i++){var fxFn=fx.pathFn;if(fxFn){fxFn.call(this,path,value,fx.effect);}}}
+if(this._boundPaths){this._notifyBoundPaths(path,value);}},_annotationPathEffect:function(path,value,effect){if(Path.matches(effect.value,false,path)){Polymer.Bind._annotationEffect.call(this,path,value,effect);}else if(!effect.negate&&Path.isDescendant(effect.value,path)){var node=this._nodes[effect.index];if(node&&node._notifyPath){var newPath=Path.translate(effect.value,effect.name,path);node._notifyPath(newPath,value,true);}}},_complexObserverPathEffect:function(path,value,effect){if(Path.matches(effect.trigger.name,effect.trigger.wildcard,path)){Polymer.Bind._complexObserverEffect.call(this,path,value,effect);}},_computePathEffect:function(path,value,effect){if(Path.matches(effect.trigger.name,effect.trigger.wildcard,path)){Polymer.Bind._computeEffect.call(this,path,value,effect);}},_annotatedComputationPathEffect:function(path,value,effect){if(Path.matches(effect.trigger.name,effect.trigger.wildcard,path)){Polymer.Bind._annotatedComputationEffect.call(this,path,value,effect);}},linkPaths:function(to,from){this._boundPaths=this._boundPaths||{};if(from){this._boundPaths[to]=from;}else{this.unlinkPaths(to);}},unlinkPaths:function(path){if(this._boundPaths){delete this._boundPaths[path];}},_notifyBoundPaths:function(path,value){for(var a in this._boundPaths){var b=this._boundPaths[a];if(Path.isDescendant(a,path)){this._notifyPath(Path.translate(a,b,path),value);}else if(Path.isDescendant(b,path)){this._notifyPath(Path.translate(b,a,path),value);}}},_notifyPathUp:function(path,value){var rootName=Path.root(path);var dashCaseName=Polymer.CaseMap.camelToDashCase(rootName);var eventName=dashCaseName+this._EVENT_CHANGED;this.fire(eventName,{path:path,value:value},{bubbles:false,_useCache:Polymer.Settings.eventDataCache||!Polymer.Settings.isIE});},_EVENT_CHANGED:'-changed',notifySplices:function(path,splices){var info={};var array=this._get(path,this,info);this._notifySplices(array,info.path,splices);},_notifySplices:function(array,path,splices){var change={keySplices:Polymer.Collection.applySplices(array,splices),indexSplices:splices};var splicesPath=path+'.splices';this._notifyPath(splicesPath,change);this._notifyPath(path+'.length',array.length);this.__data__[splicesPath]={keySplices:null,indexSplices:null};},_notifySplice:function(array,path,index,added,removed){this._notifySplices(array,path,[{index:index,addedCount:added,removed:removed,object:array,type:'splice'}]);},push:function(path){var info={};var array=this._get(path,this,info);var args=Array.prototype.slice.call(arguments,1);var len=array.length;var ret=array.push.apply(array,args);if(args.length){this._notifySplice(array,info.path,len,args.length,[]);}
+return ret;},pop:function(path){var info={};var array=this._get(path,this,info);var hadLength=Boolean(array.length);var args=Array.prototype.slice.call(arguments,1);var ret=array.pop.apply(array,args);if(hadLength){this._notifySplice(array,info.path,array.length,0,[ret]);}
+return ret;},splice:function(path,start){var info={};var array=this._get(path,this,info);if(start<0){start=array.length-Math.floor(-start);}else{start=Math.floor(start);}
+if(!start){start=0;}
+var args=Array.prototype.slice.call(arguments,1);var ret=array.splice.apply(array,args);var addedCount=Math.max(args.length-2,0);if(addedCount||ret.length){this._notifySplice(array,info.path,start,addedCount,ret);}
+return ret;},shift:function(path){var info={};var array=this._get(path,this,info);var hadLength=Boolean(array.length);var args=Array.prototype.slice.call(arguments,1);var ret=array.shift.apply(array,args);if(hadLength){this._notifySplice(array,info.path,0,0,[ret]);}
+return ret;},unshift:function(path){var info={};var array=this._get(path,this,info);var args=Array.prototype.slice.call(arguments,1);var ret=array.unshift.apply(array,args);if(args.length){this._notifySplice(array,info.path,0,args.length,[]);}
+return ret;},prepareModelNotifyPath:function(model){this.mixin(model,{fire:Polymer.Base.fire,_getEvent:Polymer.Base._getEvent,__eventCache:Polymer.Base.__eventCache,notifyPath:Polymer.Base.notifyPath,_get:Polymer.Base._get,_EVENT_CHANGED:Polymer.Base._EVENT_CHANGED,_notifyPath:Polymer.Base._notifyPath,_notifyPathUp:Polymer.Base._notifyPathUp,_pathEffector:Polymer.Base._pathEffector,_annotationPathEffect:Polymer.Base._annotationPathEffect,_complexObserverPathEffect:Polymer.Base._complexObserverPathEffect,_annotatedComputationPathEffect:Polymer.Base._annotatedComputationPathEffect,_computePathEffect:Polymer.Base._computePathEffect,_notifyBoundPaths:Polymer.Base._notifyBoundPaths,_getPathParts:Polymer.Base._getPathParts});}});}());Polymer.Base._addFeature({resolveUrl:function(url){return Polymer.ResolveUrl.resolveUrl(url,this._importPath);}});Polymer.CssParse=function(){return{parse:function(text){text=this._clean(text);return this._parseCss(this._lex(text),text);},_clean:function(cssText){return cssText.replace(this._rx.comments,'').replace(this._rx.port,'');},_lex:function(text){var root={start:0,end:text.length};var n=root;for(var i=0,l=text.length;i<l;i++){switch(text[i]){case this.OPEN_BRACE:if(!n.rules){n.rules=[];}
+var p=n;var previous=p.rules[p.rules.length-1];n={start:i+1,parent:p,previous:previous};p.rules.push(n);break;case this.CLOSE_BRACE:n.end=i+1;n=n.parent||root;break;}}
+return root;},_parseCss:function(node,text){var t=text.substring(node.start,node.end-1);node.parsedCssText=node.cssText=t.trim();if(node.parent){var ss=node.previous?node.previous.end:node.parent.start;t=text.substring(ss,node.start-1);t=this._expandUnicodeEscapes(t);t=t.replace(this._rx.multipleSpaces,' ');t=t.substring(t.lastIndexOf(';')+1);var s=node.parsedSelector=node.selector=t.trim();node.atRule=s.indexOf(this.AT_START)===0;if(node.atRule){if(s.indexOf(this.MEDIA_START)===0){node.type=this.types.MEDIA_RULE;}else if(s.match(this._rx.keyframesRule)){node.type=this.types.KEYFRAMES_RULE;node.keyframesName=node.selector.split(this._rx.multipleSpaces).pop();}}else{if(s.indexOf(this.VAR_START)===0){node.type=this.types.MIXIN_RULE;}else{node.type=this.types.STYLE_RULE;}}}
+var r$=node.rules;if(r$){for(var i=0,l=r$.length,r;i<l&&(r=r$[i]);i++){this._parseCss(r,text);}}
+return node;},_expandUnicodeEscapes:function(s){return s.replace(/\\([0-9a-f]{1,6})\s/gi,function(){var code=arguments[1],repeat=6-code.length;while(repeat--){code='0'+code;}
+return'\\'+code;});},stringify:function(node,preserveProperties,text){text=text||'';var cssText='';if(node.cssText||node.rules){var r$=node.rules;if(r$&&!this._hasMixinRules(r$)){for(var i=0,l=r$.length,r;i<l&&(r=r$[i]);i++){cssText=this.stringify(r,preserveProperties,cssText);}}else{cssText=preserveProperties?node.cssText:this.removeCustomProps(node.cssText);cssText=cssText.trim();if(cssText){cssText='  '+cssText+'\n';}}}
+if(cssText){if(node.selector){text+=node.selector+' '+this.OPEN_BRACE+'\n';}
+text+=cssText;if(node.selector){text+=this.CLOSE_BRACE+'\n\n';}}
+return text;},_hasMixinRules:function(rules){return rules[0].selector.indexOf(this.VAR_START)===0;},removeCustomProps:function(cssText){cssText=this.removeCustomPropAssignment(cssText);return this.removeCustomPropApply(cssText);},removeCustomPropAssignment:function(cssText){return cssText.replace(this._rx.customProp,'').replace(this._rx.mixinProp,'');},removeCustomPropApply:function(cssText){return cssText.replace(this._rx.mixinApply,'').replace(this._rx.varApply,'');},types:{STYLE_RULE:1,KEYFRAMES_RULE:7,MEDIA_RULE:4,MIXIN_RULE:1000},OPEN_BRACE:'{',CLOSE_BRACE:'}',_rx:{comments:/\/\*[^*]*\*+([^\/*][^*]*\*+)*\//gim,port:/@import[^;]*;/gim,customProp:/(?:^[^;\-\s}]+)?--[^;{}]*?:[^{};]*?(?:[;\n]|$)/gim,mixinProp:/(?:^[^;\-\s}]+)?--[^;{}]*?:[^{};]*?{[^}]*?}(?:[;\n]|$)?/gim,mixinApply:/@apply\s*\(?[^);]*\)?\s*(?:[;\n]|$)?/gim,varApply:/[^;:]*?:[^;]*?var\([^;]*\)(?:[;\n]|$)?/gim,keyframesRule:/^@[^\s]*keyframes/,multipleSpaces:/\s+/g},VAR_START:'--',MEDIA_START:'@media',AT_START:'@'};}();Polymer.StyleUtil=function(){var settings=Polymer.Settings;return{unscopedStyleImports:new WeakMap(),SHADY_UNSCOPED_ATTR:'shady-unscoped',NATIVE_VARIABLES:Polymer.Settings.useNativeCSSProperties,MODULE_STYLES_SELECTOR:'style, link[rel=import][type~=css], template',INCLUDE_ATTR:'include',toCssText:function(rules,callback){if(typeof rules==='string'){rules=this.parser.parse(rules);}
+if(callback){this.forEachRule(rules,callback);}
+return this.parser.stringify(rules,this.NATIVE_VARIABLES);},forRulesInStyles:function(styles,styleRuleCallback,keyframesRuleCallback){if(styles){for(var i=0,l=styles.length,s;i<l&&(s=styles[i]);i++){this.forEachRuleInStyle(s,styleRuleCallback,keyframesRuleCallback);}}},forActiveRulesInStyles:function(styles,styleRuleCallback,keyframesRuleCallback){if(styles){for(var i=0,l=styles.length,s;i<l&&(s=styles[i]);i++){this.forEachRuleInStyle(s,styleRuleCallback,keyframesRuleCallback,true);}}},rulesForStyle:function(style){if(!style.__cssRules&&style.textContent){style.__cssRules=this.parser.parse(style.textContent);}
+return style.__cssRules;},isKeyframesSelector:function(rule){return rule.parent&&rule.parent.type===this.ruleTypes.KEYFRAMES_RULE;},forEachRuleInStyle:function(style,styleRuleCallback,keyframesRuleCallback,onlyActiveRules){var rules=this.rulesForStyle(style);var styleCallback,keyframeCallback;if(styleRuleCallback){styleCallback=function(rule){styleRuleCallback(rule,style);};}
+if(keyframesRuleCallback){keyframeCallback=function(rule){keyframesRuleCallback(rule,style);};}
+this.forEachRule(rules,styleCallback,keyframeCallback,onlyActiveRules);},forEachRule:function(node,styleRuleCallback,keyframesRuleCallback,onlyActiveRules){if(!node){return;}
+var skipRules=false;if(onlyActiveRules){if(node.type===this.ruleTypes.MEDIA_RULE){var matchMedia=node.selector.match(this.rx.MEDIA_MATCH);if(matchMedia){if(!window.matchMedia(matchMedia[1]).matches){skipRules=true;}}}}
+if(node.type===this.ruleTypes.STYLE_RULE){styleRuleCallback(node);}else if(keyframesRuleCallback&&node.type===this.ruleTypes.KEYFRAMES_RULE){keyframesRuleCallback(node);}else if(node.type===this.ruleTypes.MIXIN_RULE){skipRules=true;}
+var r$=node.rules;if(r$&&!skipRules){for(var i=0,l=r$.length,r;i<l&&(r=r$[i]);i++){this.forEachRule(r,styleRuleCallback,keyframesRuleCallback,onlyActiveRules);}}},applyCss:function(cssText,moniker,target,contextNode){var style=this.createScopeStyle(cssText,moniker);return this.applyStyle(style,target,contextNode);},applyStyle:function(style,target,contextNode){target=target||document.head;var after=contextNode&&contextNode.nextSibling||target.firstChild;this.__lastHeadApplyNode=style;return target.insertBefore(style,after);},createScopeStyle:function(cssText,moniker){var style=document.createElement('style');if(moniker){style.setAttribute('scope',moniker);}
+style.textContent=cssText;return style;},__lastHeadApplyNode:null,applyStylePlaceHolder:function(moniker){var placeHolder=document.createComment(' Shady DOM styles for '+moniker+' ');var after=this.__lastHeadApplyNode?this.__lastHeadApplyNode.nextSibling:null;var scope=document.head;scope.insertBefore(placeHolder,after||scope.firstChild);this.__lastHeadApplyNode=placeHolder;return placeHolder;},cssFromModules:function(moduleIds,warnIfNotFound){var modules=moduleIds.trim().split(/\s+/);var cssText='';for(var i=0;i<modules.length;i++){cssText+=this.cssFromModule(modules[i],warnIfNotFound);}
+return cssText;},cssFromModule:function(moduleId,warnIfNotFound){var m=Polymer.DomModule.import(moduleId);if(m&&!m._cssText){m._cssText=this.cssFromElement(m);}
+if(!m&&warnIfNotFound){console.warn('Could not find style data in module named',moduleId);}
+return m&&m._cssText||'';},cssFromElement:function(element){var cssText='';var content=element.content||element;var e$=Polymer.TreeApi.arrayCopy(content.querySelectorAll(this.MODULE_STYLES_SELECTOR));for(var i=0,e;i<e$.length;i++){e=e$[i];if(e.localName==='template'){if(!e.hasAttribute('preserve-content')){cssText+=this.cssFromElement(e);}}else{if(e.localName==='style'){var include=e.getAttribute(this.INCLUDE_ATTR);if(include){cssText+=this.cssFromModules(include,true);}
+e=e.__appliedElement||e;e.parentNode.removeChild(e);var css=this.resolveCss(e.textContent,element.ownerDocument);if(!settings.useNativeShadow&&e.hasAttribute(this.SHADY_UNSCOPED_ATTR)){e.textContent=css;document.head.insertBefore(e,document.head.firstChild);}else{cssText+=css;}}else if(e.import&&e.import.body){var importCss=this.resolveCss(e.import.body.textContent,e.import);if(!settings.useNativeShadow&&e.hasAttribute(this.SHADY_UNSCOPED_ATTR)){if(!this.unscopedStyleImports.has(e.import)){this.unscopedStyleImports.set(e.import,true);var importStyle=document.createElement('style');importStyle.setAttribute(this.SHADY_UNSCOPED_ATTR,'');importStyle.textContent=importCss;document.head.insertBefore(importStyle,document.head.firstChild);}}else{cssText+=importCss;}}}}
+return cssText;},styleIncludesToTemplate:function(targetTemplate){var styles=targetTemplate.content.querySelectorAll('style[include]');for(var i=0,s;i<styles.length;i++){s=styles[i];s.parentNode.insertBefore(this._includesToFragment(s.getAttribute('include')),s);}},_includesToFragment:function(styleIncludes){var includeArray=styleIncludes.trim().split(' ');var frag=document.createDocumentFragment();for(var i=0;i<includeArray.length;i++){var t=Polymer.DomModule.import(includeArray[i],'template');if(t){this._addStylesToFragment(frag,t.content);}}
+return frag;},_addStylesToFragment:function(frag,source){var s$=source.querySelectorAll('style');for(var i=0,s;i<s$.length;i++){s=s$[i];var include=s.getAttribute('include');if(include){frag.appendChild(this._includesToFragment(include));}
+if(s.textContent){frag.appendChild(s.cloneNode(true));}}},isTargetedBuild:function(buildType){return settings.useNativeShadow?buildType==='shadow':buildType==='shady';},cssBuildTypeForModule:function(module){var dm=Polymer.DomModule.import(module);if(dm){return this.getCssBuildType(dm);}},getCssBuildType:function(element){return element.getAttribute('css-build');},_findMatchingParen:function(text,start){var level=0;for(var i=start,l=text.length;i<l;i++){switch(text[i]){case'(':level++;break;case')':if(--level===0){return i;}
+break;}}
+return-1;},processVariableAndFallback:function(str,callback){var start=str.indexOf('var(');if(start===-1){return callback(str,'','','');}
+var end=this._findMatchingParen(str,start+3);var inner=str.substring(start+4,end);var prefix=str.substring(0,start);var suffix=this.processVariableAndFallback(str.substring(end+1),callback);var comma=inner.indexOf(',');if(comma===-1){return callback(prefix,inner.trim(),'',suffix);}
+var value=inner.substring(0,comma).trim();var fallback=inner.substring(comma+1).trim();return callback(prefix,value,fallback,suffix);},rx:{VAR_ASSIGN:/(?:^|[;\s{]\s*)(--[\w-]*?)\s*:\s*(?:([^;{]*)|{([^}]*)})(?:(?=[;\s}])|$)/gi,MIXIN_MATCH:/(?:^|\W+)@apply\s*\(?([^);\n]*)\)?/gi,VAR_CONSUMED:/(--[\w-]+)\s*([:,;)]|$)/gi,ANIMATION_MATCH:/(animation\s*:)|(animation-name\s*:)/,MEDIA_MATCH:/@media[^(]*(\([^)]*\))/,IS_VAR:/^--/,BRACKETED:/\{[^}]*\}/g,HOST_PREFIX:'(?:^|[^.#[:])',HOST_SUFFIX:'($|[.:[\\s>+~])'},resolveCss:Polymer.ResolveUrl.resolveCss,parser:Polymer.CssParse,ruleTypes:Polymer.CssParse.types};}();Polymer.StyleTransformer=function(){var styleUtil=Polymer.StyleUtil;var settings=Polymer.Settings;var api={dom:function(node,scope,useAttr,shouldRemoveScope){this._transformDom(node,scope||'',useAttr,shouldRemoveScope);},_transformDom:function(node,selector,useAttr,shouldRemoveScope){if(node.setAttribute){this.element(node,selector,useAttr,shouldRemoveScope);}
+var c$=Polymer.dom(node).childNodes;for(var i=0;i<c$.length;i++){this._transformDom(c$[i],selector,useAttr,shouldRemoveScope);}},element:function(element,scope,useAttr,shouldRemoveScope){if(useAttr){if(shouldRemoveScope){element.removeAttribute(SCOPE_NAME);}else{element.setAttribute(SCOPE_NAME,scope);}}else{if(scope){if(element.classList){if(shouldRemoveScope){element.classList.remove(SCOPE_NAME);element.classList.remove(scope);}else{element.classList.add(SCOPE_NAME);element.classList.add(scope);}}else if(element.getAttribute){var c=element.getAttribute(CLASS);if(shouldRemoveScope){if(c){element.setAttribute(CLASS,c.replace(SCOPE_NAME,'').replace(scope,''));}}else{element.setAttribute(CLASS,(c?c+' ':'')+SCOPE_NAME+' '+scope);}}}}},elementStyles:function(element,callback){var styles=element._styles;var cssText='';var cssBuildType=element.__cssBuild;var passthrough=settings.useNativeShadow||cssBuildType==='shady';var cb;if(passthrough){var self=this;cb=function(rule){rule.selector=self._slottedToContent(rule.selector);rule.selector=rule.selector.replace(ROOT,':host > *');rule.selector=self._dirShadowTransform(rule.selector);if(callback){callback(rule);}};}
+for(var i=0,l=styles.length,s;i<l&&(s=styles[i]);i++){var rules=styleUtil.rulesForStyle(s);cssText+=passthrough?styleUtil.toCssText(rules,cb):this.css(rules,element.is,element.extends,callback,element._scopeCssViaAttr)+'\n\n';}
+return cssText.trim();},css:function(rules,scope,ext,callback,useAttr){var hostScope=this._calcHostScope(scope,ext);scope=this._calcElementScope(scope,useAttr);var self=this;return styleUtil.toCssText(rules,function(rule){if(!rule.isScoped){self.rule(rule,scope,hostScope);rule.isScoped=true;}
+if(callback){callback(rule,scope,hostScope);}});},_calcElementScope:function(scope,useAttr){if(scope){return useAttr?CSS_ATTR_PREFIX+scope+CSS_ATTR_SUFFIX:CSS_CLASS_PREFIX+scope;}else{return'';}},_calcHostScope:function(scope,ext){return ext?'[is='+scope+']':scope;},rule:function(rule,scope,hostScope){this._transformRule(rule,this._transformComplexSelector,scope,hostScope);},_transformRule:function(rule,transformer,scope,hostScope){rule.selector=rule.transformedSelector=this._transformRuleCss(rule,transformer,scope,hostScope);},_splitSelectorList:function(selector){var parts=[];var part='';for(var i=0;i>=0&&i<selector.length;i++){if(selector[i]==='('){var end=styleUtil._findMatchingParen(selector,i);part+=selector.slice(i,end+1);i=end;}else if(selector[i]===COMPLEX_SELECTOR_SEP){parts.push(part);part='';}else{part+=selector[i];}}
+if(part){parts.push(part);}
+if(parts.length===0){parts.push(selector);}
+return parts;},_transformRuleCss:function(rule,transformer,scope,hostScope){var p$=this._splitSelectorList(rule.selector);if(!styleUtil.isKeyframesSelector(rule)){for(var i=0,l=p$.length,p;i<l&&(p=p$[i]);i++){p$[i]=transformer.call(this,p,scope,hostScope);}}
+return p$.join(COMPLEX_SELECTOR_SEP);},_ensureScopedDir:function(s){var m=s.match(DIR_PAREN);if(m&&m[1]===''&&m[0].length===s.length){s='*'+s;}
+return s;},_additionalDirSelectors:function(dir,after,prefix){if(!dir||!after){return'';}
+prefix=prefix||'';return COMPLEX_SELECTOR_SEP+prefix+' '+dir+' '+after;},_transformComplexSelector:function(selector,scope,hostScope){var stop=false;var hostContext=false;var dir=false;var self=this;selector=selector.trim();selector=this._slottedToContent(selector);selector=selector.replace(ROOT,':host > *');selector=selector.replace(CONTENT_START,HOST+' $1');selector=this._ensureScopedDir(selector);selector=selector.replace(SIMPLE_SELECTOR_SEP,function(m,c,s){if(!stop){var info=self._transformCompoundSelector(s,c,scope,hostScope);stop=stop||info.stop;hostContext=hostContext||info.hostContext;dir=dir||info.dir;c=info.combinator;s=info.value;}else{s=s.replace(SCOPE_JUMP,' ');}
+return c+s;});if(hostContext){selector=selector.replace(HOST_CONTEXT_PAREN,function(m,pre,paren,post){var replacement=pre+paren+' '+hostScope+post+COMPLEX_SELECTOR_SEP+' '+pre+hostScope+paren+post;if(dir){replacement+=self._additionalDirSelectors(paren,post,hostScope);}
+return replacement;});}
+return selector;},_transformDir:function(s){s=s.replace(HOST_DIR,HOST_DIR_REPLACE);s=s.replace(DIR_PAREN,DIR_REPLACE);return s;},_transformCompoundSelector:function(selector,combinator,scope,hostScope){var jumpIndex=selector.search(SCOPE_JUMP);var hostContext=false;var dir=false;if(selector.match(DIR_PAREN)){selector=this._transformDir(selector);dir=true;}
+if(selector.indexOf(HOST_CONTEXT)>=0){hostContext=true;}else if(selector.indexOf(HOST)>=0){selector=this._transformHostSelector(selector,hostScope);}else if(jumpIndex!==0){selector=scope?this._transformSimpleSelector(selector,scope):selector;}
+if(selector.indexOf(CONTENT)>=0){combinator='';}
+var stop;if(jumpIndex>=0){selector=selector.replace(SCOPE_JUMP,' ');stop=true;}
+return{value:selector,combinator:combinator,stop:stop,hostContext:hostContext,dir:dir};},_transformSimpleSelector:function(selector,scope){var p$=selector.split(PSEUDO_PREFIX);p$[0]+=scope;return p$.join(PSEUDO_PREFIX);},_transformHostSelector:function(selector,hostScope){var m=selector.match(HOST_PAREN);var paren=m&&m[2].trim()||'';if(paren){if(!paren[0].match(SIMPLE_SELECTOR_PREFIX)){var typeSelector=paren.split(SIMPLE_SELECTOR_PREFIX)[0];if(typeSelector===hostScope){return paren;}else{return SELECTOR_NO_MATCH;}}else{return selector.replace(HOST_PAREN,function(m,host,paren){return hostScope+paren;});}}else{return selector.replace(HOST,hostScope);}},documentRule:function(rule){rule.selector=rule.parsedSelector;this.normalizeRootSelector(rule);if(!settings.useNativeShadow){this._transformRule(rule,this._transformDocumentSelector);}},normalizeRootSelector:function(rule){rule.selector=rule.selector.replace(ROOT,'html');var parts=this._splitSelectorList(rule.selector);parts=parts.filter(function(part){return!part.match(HOST_OR_HOST_GT_STAR);});rule.selector=parts.join(COMPLEX_SELECTOR_SEP);},_transformDocumentSelector:function(selector){return this._transformComplexSelector(selector,SCOPE_DOC_SELECTOR);},_slottedToContent:function(cssText){return cssText.replace(SLOTTED_PAREN,CONTENT+'> $1');},_dirShadowTransform:function(selector){if(!selector.match(/:dir\(/)){return selector;}
+return this._splitSelectorList(selector).map(function(s){s=this._ensureScopedDir(s);s=this._transformDir(s);var m=HOST_CONTEXT_PAREN.exec(s);if(m){s+=this._additionalDirSelectors(m[2],m[3],'');}
+return s;},this).join(COMPLEX_SELECTOR_SEP);},SCOPE_NAME:'style-scope'};var SCOPE_NAME=api.SCOPE_NAME;var SCOPE_DOC_SELECTOR=':not(['+SCOPE_NAME+'])'+':not(.'+SCOPE_NAME+')';var COMPLEX_SELECTOR_SEP=',';var SIMPLE_SELECTOR_SEP=/(^|[\s>+~]+)((?:\[.+?\]|[^\s>+~=\[])+)/g;var SIMPLE_SELECTOR_PREFIX=/[[.:#*]/;var HOST=':host';var ROOT=':root';var HOST_PAREN=/(:host)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/;var HOST_CONTEXT=':host-context';var HOST_CONTEXT_PAREN=/(.*)(?::host-context)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))(.*)/;var CONTENT='::content';var SCOPE_JUMP=/::content|::shadow|\/deep\//;var CSS_CLASS_PREFIX='.';var CSS_ATTR_PREFIX='['+SCOPE_NAME+'~=';var CSS_ATTR_SUFFIX=']';var PSEUDO_PREFIX=':';var CLASS='class';var CONTENT_START=new RegExp('^('+CONTENT+')');var SELECTOR_NO_MATCH='should_not_match';var SLOTTED_PAREN=/(?:::slotted)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/g;var HOST_OR_HOST_GT_STAR=/:host(?:\s*>\s*\*)?/;var DIR_PAREN=/(.*):dir\((ltr|rtl)\)/;var DIR_REPLACE=':host-context([dir="$2"]) $1';var HOST_DIR=/:host\(:dir\((rtl|ltr)\)\)/g;var HOST_DIR_REPLACE=':host-context([dir="$1"])';return api;}();Polymer.StyleExtends=function(){var styleUtil=Polymer.StyleUtil;return{hasExtends:function(cssText){return Boolean(cssText.match(this.rx.EXTEND));},transform:function(style){var rules=styleUtil.rulesForStyle(style);var self=this;styleUtil.forEachRule(rules,function(rule){self._mapRuleOntoParent(rule);if(rule.parent){var m;while(m=self.rx.EXTEND.exec(rule.cssText)){var extend=m[1];var extendor=self._findExtendor(extend,rule);if(extendor){self._extendRule(rule,extendor);}}}
+rule.cssText=rule.cssText.replace(self.rx.EXTEND,'');});return styleUtil.toCssText(rules,function(rule){if(rule.selector.match(self.rx.STRIP)){rule.cssText='';}},true);},_mapRuleOntoParent:function(rule){if(rule.parent){var map=rule.parent.map||(rule.parent.map={});var parts=rule.selector.split(',');for(var i=0,p;i<parts.length;i++){p=parts[i];map[p.trim()]=rule;}
+return map;}},_findExtendor:function(extend,rule){return rule.parent&&rule.parent.map&&rule.parent.map[extend]||this._findExtendor(extend,rule.parent);},_extendRule:function(target,source){if(target.parent!==source.parent){this._cloneAndAddRuleToParent(source,target.parent);}
+target.extends=target.extends||[];target.extends.push(source);source.selector=source.selector.replace(this.rx.STRIP,'');source.selector=(source.selector&&source.selector+',\n')+target.selector;if(source.extends){source.extends.forEach(function(e){this._extendRule(target,e);},this);}},_cloneAndAddRuleToParent:function(rule,parent){rule=Object.create(rule);rule.parent=parent;if(rule.extends){rule.extends=rule.extends.slice();}
+parent.rules.push(rule);},rx:{EXTEND:/@extends\(([^)]*)\)\s*?;/gim,STRIP:/%[^,]*$/}};}();Polymer.ApplyShim=function(){'use strict';var styleUtil=Polymer.StyleUtil;var MIXIN_MATCH=styleUtil.rx.MIXIN_MATCH;var VAR_ASSIGN=styleUtil.rx.VAR_ASSIGN;var BAD_VAR=/var\(\s*(--[^,]*),\s*(--[^)]*)\)/g;var APPLY_NAME_CLEAN=/;\s*/m;var INITIAL_INHERIT=/^\s*(initial)|(inherit)\s*$/;var MIXIN_VAR_SEP='_-_';var mixinMap={};function mapSet(name,props){name=name.trim();mixinMap[name]={properties:props,dependants:{}};}
+function mapGet(name){name=name.trim();return mixinMap[name];}
+function replaceInitialOrInherit(property,value){var match=INITIAL_INHERIT.exec(value);if(match){if(match[1]){value=ApplyShim._getInitialValueForProperty(property);}else{value='apply-shim-inherit';}}
+return value;}
+function cssTextToMap(text){var props=text.split(';');var property,value;var out={};for(var i=0,p,sp;i<props.length;i++){p=props[i];if(p){sp=p.split(':');if(sp.length>1){property=sp[0].trim();value=replaceInitialOrInherit(property,sp.slice(1).join(':'));out[property]=value;}}}
+return out;}
+function invalidateMixinEntry(mixinEntry){var currentProto=ApplyShim.__currentElementProto;var currentElementName=currentProto&&currentProto.is;for(var elementName in mixinEntry.dependants){if(elementName!==currentElementName){mixinEntry.dependants[elementName].__applyShimInvalid=true;}}}
+function produceCssProperties(matchText,propertyName,valueProperty,valueMixin){if(valueProperty){styleUtil.processVariableAndFallback(valueProperty,function(prefix,value){if(value&&mapGet(value)){valueMixin='@apply '+value+';';}});}
+if(!valueMixin){return matchText;}
+var mixinAsProperties=consumeCssProperties(valueMixin);var prefix=matchText.slice(0,matchText.indexOf('--'));var mixinValues=cssTextToMap(mixinAsProperties);var combinedProps=mixinValues;var mixinEntry=mapGet(propertyName);var oldProps=mixinEntry&&mixinEntry.properties;if(oldProps){combinedProps=Object.create(oldProps);combinedProps=Polymer.Base.mixin(combinedProps,mixinValues);}else{mapSet(propertyName,combinedProps);}
+var out=[];var p,v;var needToInvalidate=false;for(p in combinedProps){v=mixinValues[p];if(v===undefined){v='initial';}
+if(oldProps&&!(p in oldProps)){needToInvalidate=true;}
+out.push(propertyName+MIXIN_VAR_SEP+p+': '+v);}
+if(needToInvalidate){invalidateMixinEntry(mixinEntry);}
+if(mixinEntry){mixinEntry.properties=combinedProps;}
+if(valueProperty){prefix=matchText+';'+prefix;}
+return prefix+out.join('; ')+';';}
+function fixVars(matchText,varA,varB){return'var('+varA+','+'var('+varB+'))';}
+function atApplyToCssProperties(mixinName,fallbacks){mixinName=mixinName.replace(APPLY_NAME_CLEAN,'');var vars=[];var mixinEntry=mapGet(mixinName);if(!mixinEntry){mapSet(mixinName,{});mixinEntry=mapGet(mixinName);}
+if(mixinEntry){var currentProto=ApplyShim.__currentElementProto;if(currentProto){mixinEntry.dependants[currentProto.is]=currentProto;}
+var p,parts,f;for(p in mixinEntry.properties){f=fallbacks&&fallbacks[p];parts=[p,': var(',mixinName,MIXIN_VAR_SEP,p];if(f){parts.push(',',f);}
+parts.push(')');vars.push(parts.join(''));}}
+return vars.join('; ');}
+function consumeCssProperties(text){var m;while(m=MIXIN_MATCH.exec(text)){var matchText=m[0];var mixinName=m[1];var idx=m.index;var applyPos=idx+matchText.indexOf('@apply');var afterApplyPos=idx+matchText.length;var textBeforeApply=text.slice(0,applyPos);var textAfterApply=text.slice(afterApplyPos);var defaults=cssTextToMap(textBeforeApply);var replacement=atApplyToCssProperties(mixinName,defaults);text=[textBeforeApply,replacement,textAfterApply].join('');MIXIN_MATCH.lastIndex=idx+replacement.length;}
+return text;}
+var ApplyShim={_measureElement:null,_map:mixinMap,_separator:MIXIN_VAR_SEP,transform:function(styles,elementProto){this.__currentElementProto=elementProto;styleUtil.forRulesInStyles(styles,this._boundFindDefinitions);styleUtil.forRulesInStyles(styles,this._boundFindApplications);if(elementProto){elementProto.__applyShimInvalid=false;}
+this.__currentElementProto=null;},_findDefinitions:function(rule){var cssText=rule.parsedCssText;cssText=cssText.replace(BAD_VAR,fixVars);cssText=cssText.replace(VAR_ASSIGN,produceCssProperties);rule.cssText=cssText;if(rule.selector===':root'){rule.selector=':host > *';}},_findApplications:function(rule){rule.cssText=consumeCssProperties(rule.cssText);},transformRule:function(rule){this._findDefinitions(rule);this._findApplications(rule);},_getInitialValueForProperty:function(property){if(!this._measureElement){this._measureElement=document.createElement('meta');this._measureElement.style.all='initial';document.head.appendChild(this._measureElement);}
+return window.getComputedStyle(this._measureElement).getPropertyValue(property);}};ApplyShim._boundTransformRule=ApplyShim.transformRule.bind(ApplyShim);ApplyShim._boundFindDefinitions=ApplyShim._findDefinitions.bind(ApplyShim);ApplyShim._boundFindApplications=ApplyShim._findApplications.bind(ApplyShim);return ApplyShim;}();(function(){var prepElement=Polymer.Base._prepElement;var nativeShadow=Polymer.Settings.useNativeShadow;var styleUtil=Polymer.StyleUtil;var styleTransformer=Polymer.StyleTransformer;var styleExtends=Polymer.StyleExtends;var applyShim=Polymer.ApplyShim;var settings=Polymer.Settings;Polymer.Base._addFeature({_prepElement:function(element){if(this._encapsulateStyle&&this.__cssBuild!=='shady'){styleTransformer.element(element,this.is,this._scopeCssViaAttr);}
+prepElement.call(this,element);},_prepStyles:function(){if(this._encapsulateStyle===undefined){this._encapsulateStyle=!nativeShadow;}
+if(!nativeShadow){this._scopeStyle=styleUtil.applyStylePlaceHolder(this.is);}
+this.__cssBuild=styleUtil.cssBuildTypeForModule(this.is);},_prepShimStyles:function(){if(this._template){var hasTargetedCssBuild=styleUtil.isTargetedBuild(this.__cssBuild);if(settings.useNativeCSSProperties&&this.__cssBuild==='shadow'&&hasTargetedCssBuild){if(settings.preserveStyleIncludes){styleUtil.styleIncludesToTemplate(this._template);}
+return;}
+this._styles=this._styles||this._collectStyles();if(settings.useNativeCSSProperties&&!this.__cssBuild){applyShim.transform(this._styles,this);}
+var cssText=settings.useNativeCSSProperties&&hasTargetedCssBuild?this._styles.length&&this._styles[0].textContent.trim():styleTransformer.elementStyles(this);this._prepStyleProperties();if(!this._needsStyleProperties()&&cssText){styleUtil.applyCss(cssText,this.is,nativeShadow?this._template.content:null,this._scopeStyle);}}else{this._styles=[];}},_collectStyles:function(){var styles=[];var cssText='',m$=this.styleModules;if(m$){for(var i=0,l=m$.length,m;i<l&&(m=m$[i]);i++){cssText+=styleUtil.cssFromModule(m);}}
+cssText+=styleUtil.cssFromModule(this.is);var p=this._template&&this._template.parentNode;if(this._template&&(!p||p.id.toLowerCase()!==this.is)){cssText+=styleUtil.cssFromElement(this._template);}
+if(cssText){var style=document.createElement('style');style.textContent=cssText;if(styleExtends.hasExtends(style.textContent)){cssText=styleExtends.transform(style);}
+styles.push(style);}
+return styles;},_elementAdd:function(node){if(this._encapsulateStyle){if(node.__styleScoped){node.__styleScoped=false;}else{styleTransformer.dom(node,this.is,this._scopeCssViaAttr);}}},_elementRemove:function(node){if(this._encapsulateStyle){styleTransformer.dom(node,this.is,this._scopeCssViaAttr,true);}},scopeSubtree:function(container,shouldObserve){if(nativeShadow){return;}
+var self=this;var scopify=function(node){if(node.nodeType===Node.ELEMENT_NODE){var className=node.getAttribute('class');node.setAttribute('class',self._scopeElementClass(node,className));var n$=node.querySelectorAll('*');for(var i=0,n;i<n$.length&&(n=n$[i]);i++){className=n.getAttribute('class');n.setAttribute('class',self._scopeElementClass(n,className));}}};scopify(container);if(shouldObserve){var mo=new MutationObserver(function(mxns){for(var i=0,m;i<mxns.length&&(m=mxns[i]);i++){if(m.addedNodes){for(var j=0;j<m.addedNodes.length;j++){scopify(m.addedNodes[j]);}}}});mo.observe(container,{childList:true,subtree:true});return mo;}}});}());Polymer.StyleProperties=function(){'use strict';var matchesSelector=Polymer.DomApi.matchesSelector;var styleUtil=Polymer.StyleUtil;var styleTransformer=Polymer.StyleTransformer;var IS_IE=navigator.userAgent.match('Trident');var settings=Polymer.Settings;return{decorateStyles:function(styles,scope){var self=this,props={},keyframes=[],ruleIndex=0;var scopeSelector=styleTransformer._calcHostScope(scope.is,scope.extends);styleUtil.forRulesInStyles(styles,function(rule,style){self.decorateRule(rule);rule.index=ruleIndex++;self.whenHostOrRootRule(scope,rule,style,function(info){if(rule.parent.type===styleUtil.ruleTypes.MEDIA_RULE){scope.__notStyleScopeCacheable=true;}
+if(info.isHost){var hostContextOrFunction=info.selector.split(' ').some(function(s){return s.indexOf(scopeSelector)===0&&s.length!==scopeSelector.length;});scope.__notStyleScopeCacheable=scope.__notStyleScopeCacheable||hostContextOrFunction;}});self.collectPropertiesInCssText(rule.propertyInfo.cssText,props);},function onKeyframesRule(rule){keyframes.push(rule);});styles._keyframes=keyframes;var names=[];for(var i in props){names.push(i);}
+return names;},decorateRule:function(rule){if(rule.propertyInfo){return rule.propertyInfo;}
+var info={},properties={};var hasProperties=this.collectProperties(rule,properties);if(hasProperties){info.properties=properties;rule.rules=null;}
+info.cssText=this.collectCssText(rule);rule.propertyInfo=info;return info;},collectProperties:function(rule,properties){var info=rule.propertyInfo;if(info){if(info.properties){Polymer.Base.mixin(properties,info.properties);return true;}}else{var m,rx=this.rx.VAR_ASSIGN;var cssText=rule.parsedCssText;var value;var any;while(m=rx.exec(cssText)){value=(m[2]||m[3]).trim();if(value!=='inherit'){properties[m[1].trim()]=value;}
+any=true;}
+return any;}},collectCssText:function(rule){return this.collectConsumingCssText(rule.parsedCssText);},collectConsumingCssText:function(cssText){return cssText.replace(this.rx.BRACKETED,'').replace(this.rx.VAR_ASSIGN,'');},collectPropertiesInCssText:function(cssText,props){var m;while(m=this.rx.VAR_CONSUMED.exec(cssText)){var name=m[1];if(m[2]!==':'){props[name]=true;}}},reify:function(props){var names=Object.getOwnPropertyNames(props);for(var i=0,n;i<names.length;i++){n=names[i];props[n]=this.valueForProperty(props[n],props);}},valueForProperty:function(property,props){if(property){if(property.indexOf(';')>=0){property=this.valueForProperties(property,props);}else{var self=this;var fn=function(prefix,value,fallback,suffix){var propertyValue=self.valueForProperty(props[value],props);if(!propertyValue||propertyValue==='initial'){propertyValue=self.valueForProperty(props[fallback]||fallback,props)||fallback;}else if(propertyValue==='apply-shim-inherit'){propertyValue='inherit';}
+return prefix+(propertyValue||'')+suffix;};property=styleUtil.processVariableAndFallback(property,fn);}}
+return property&&property.trim()||'';},valueForProperties:function(property,props){var parts=property.split(';');for(var i=0,p,m;i<parts.length;i++){if(p=parts[i]){this.rx.MIXIN_MATCH.lastIndex=0;m=this.rx.MIXIN_MATCH.exec(p);if(m){p=this.valueForProperty(props[m[1]],props);}else{var colon=p.indexOf(':');if(colon!==-1){var pp=p.substring(colon);pp=pp.trim();pp=this.valueForProperty(pp,props)||pp;p=p.substring(0,colon)+pp;}}
+parts[i]=p&&p.lastIndexOf(';')===p.length-1?p.slice(0,-1):p||'';}}
+return parts.join(';');},applyProperties:function(rule,props){var output='';if(!rule.propertyInfo){this.decorateRule(rule);}
+if(rule.propertyInfo.cssText){output=this.valueForProperties(rule.propertyInfo.cssText,props);}
+rule.cssText=output;},applyKeyframeTransforms:function(rule,keyframeTransforms){var input=rule.cssText;var output=rule.cssText;if(rule.hasAnimations==null){rule.hasAnimations=this.rx.ANIMATION_MATCH.test(input);}
+if(rule.hasAnimations){var transform;if(rule.keyframeNamesToTransform==null){rule.keyframeNamesToTransform=[];for(var keyframe in keyframeTransforms){transform=keyframeTransforms[keyframe];output=transform(input);if(input!==output){input=output;rule.keyframeNamesToTransform.push(keyframe);}}}else{for(var i=0;i<rule.keyframeNamesToTransform.length;++i){transform=keyframeTransforms[rule.keyframeNamesToTransform[i]];input=transform(input);}
+output=input;}}
+rule.cssText=output;},propertyDataFromStyles:function(styles,element){var props={},self=this;var o=[];styleUtil.forActiveRulesInStyles(styles,function(rule){if(!rule.propertyInfo){self.decorateRule(rule);}
+var selectorToMatch=rule.transformedSelector||rule.parsedSelector;if(element&&rule.propertyInfo.properties&&selectorToMatch){if(matchesSelector.call(element,selectorToMatch)){self.collectProperties(rule,props);addToBitMask(rule.index,o);}}});return{properties:props,key:o};},_rootSelector:/:root|:host\s*>\s*\*/,_checkRoot:function(hostScope,selector){return Boolean(selector.match(this._rootSelector))||hostScope==='html'&&selector.indexOf('html')>-1;},whenHostOrRootRule:function(scope,rule,style,callback){if(!rule.propertyInfo){self.decorateRule(rule);}
+if(!rule.propertyInfo.properties){return;}
+var hostScope=scope.is?styleTransformer._calcHostScope(scope.is,scope.extends):'html';var parsedSelector=rule.parsedSelector;var isRoot=this._checkRoot(hostScope,parsedSelector);var isHost=!isRoot&&parsedSelector.indexOf(':host')===0;var cssBuild=scope.__cssBuild||style.__cssBuild;if(cssBuild==='shady'){isRoot=parsedSelector===hostScope+' > *.'+hostScope||parsedSelector.indexOf('html')>-1;isHost=!isRoot&&parsedSelector.indexOf(hostScope)===0;}
+if(!isRoot&&!isHost){return;}
+var selectorToMatch=hostScope;if(isHost){if(settings.useNativeShadow&&!rule.transformedSelector){rule.transformedSelector=styleTransformer._transformRuleCss(rule,styleTransformer._transformComplexSelector,scope.is,hostScope);}
+selectorToMatch=rule.transformedSelector||rule.parsedSelector;}
+if(isRoot&&hostScope==='html'){selectorToMatch=rule.transformedSelector||rule.parsedSelector;}
+callback({selector:selectorToMatch,isHost:isHost,isRoot:isRoot});},hostAndRootPropertiesForScope:function(scope){var hostProps={},rootProps={},self=this;styleUtil.forActiveRulesInStyles(scope._styles,function(rule,style){self.whenHostOrRootRule(scope,rule,style,function(info){var element=scope._element||scope;if(matchesSelector.call(element,info.selector)){if(info.isHost){self.collectProperties(rule,hostProps);}else{self.collectProperties(rule,rootProps);}}});});return{rootProps:rootProps,hostProps:hostProps};},transformStyles:function(element,properties,scopeSelector){var self=this;var hostSelector=styleTransformer._calcHostScope(element.is,element.extends);var rxHostSelector=element.extends?'\\'+hostSelector.slice(0,-1)+'\\]':hostSelector;var hostRx=new RegExp(this.rx.HOST_PREFIX+rxHostSelector+this.rx.HOST_SUFFIX);var keyframeTransforms=this._elementKeyframeTransforms(element,scopeSelector);return styleTransformer.elementStyles(element,function(rule){self.applyProperties(rule,properties);if(!settings.useNativeShadow&&!Polymer.StyleUtil.isKeyframesSelector(rule)&&rule.cssText){self.applyKeyframeTransforms(rule,keyframeTransforms);self._scopeSelector(rule,hostRx,hostSelector,element._scopeCssViaAttr,scopeSelector);}});},_elementKeyframeTransforms:function(element,scopeSelector){var keyframesRules=element._styles._keyframes;var keyframeTransforms={};if(!settings.useNativeShadow&&keyframesRules){for(var i=0,keyframesRule=keyframesRules[i];i<keyframesRules.length;keyframesRule=keyframesRules[++i]){this._scopeKeyframes(keyframesRule,scopeSelector);keyframeTransforms[keyframesRule.keyframesName]=this._keyframesRuleTransformer(keyframesRule);}}
+return keyframeTransforms;},_keyframesRuleTransformer:function(keyframesRule){return function(cssText){return cssText.replace(keyframesRule.keyframesNameRx,keyframesRule.transformedKeyframesName);};},_scopeKeyframes:function(rule,scopeId){rule.keyframesNameRx=new RegExp('\\b'+rule.keyframesName+'(?!\\B|-)','g');rule.transformedKeyframesName=rule.keyframesName+'-'+scopeId;rule.transformedSelector=rule.transformedSelector||rule.selector;rule.selector=rule.transformedSelector.replace(rule.keyframesName,rule.transformedKeyframesName);},_hasDirOrHostContext:function(parsedSelector){return/:host-context|:dir/.test(parsedSelector);},_scopeSelector:function(rule,hostRx,hostSelector,viaAttr,scopeId){rule.transformedSelector=rule.transformedSelector||rule.selector;var selector=rule.transformedSelector;var scope=styleTransformer._calcElementScope(scopeId,viaAttr);var hostScope=styleTransformer._calcElementScope(hostSelector,viaAttr);var parts=selector.split(',');var isDirOrHostContextSelector=this._hasDirOrHostContext(rule.parsedSelector);for(var i=0,l=parts.length,p;i<l&&(p=parts[i]);i++){parts[i]=p.match(hostRx)?p.replace(hostSelector,scope):isDirOrHostContextSelector?p.replace(hostScope,scope+' '+hostScope):scope+' '+p;}
+rule.selector=parts.join(',');},applyElementScopeSelector:function(element,selector,old,viaAttr){var c=viaAttr?element.getAttribute(styleTransformer.SCOPE_NAME):element.getAttribute('class')||'';var v=old?c.replace(old,selector):(c?c+' ':'')+this.XSCOPE_NAME+' '+selector;if(c!==v){if(viaAttr){element.setAttribute(styleTransformer.SCOPE_NAME,v);}else{element.setAttribute('class',v);}}},applyElementStyle:function(element,properties,selector,style){var cssText=style?style.textContent||'':this.transformStyles(element,properties,selector);var s=element._customStyle;if(s&&!settings.useNativeShadow&&s!==style){s._useCount--;if(s._useCount<=0&&s.parentNode){s.parentNode.removeChild(s);}}
+if(settings.useNativeShadow){if(element._customStyle){element._customStyle.textContent=cssText;style=element._customStyle;}else if(cssText){style=styleUtil.applyCss(cssText,selector,element.root,element._scopeStyle);}}else{if(!style){if(cssText){style=styleUtil.applyCss(cssText,selector,null,element._scopeStyle);}}else if(!style.parentNode){if(IS_IE&&cssText.indexOf('@media')>-1){style.textContent=cssText;}
+styleUtil.applyStyle(style,null,element._scopeStyle);}}
+if(style){style._useCount=style._useCount||0;if(element._customStyle!=style){style._useCount++;}
+element._customStyle=style;}
+return style;},mixinCustomStyle:function(props,customStyle){var v;for(var i in customStyle){v=customStyle[i];if(v||v===0){props[i]=v;}}},updateNativeStyleProperties:function(element,properties){var oldPropertyNames=element.__customStyleProperties;if(oldPropertyNames){for(var i=0;i<oldPropertyNames.length;i++){element.style.removeProperty(oldPropertyNames[i]);}}
+var propertyNames=[];for(var p in properties){if(properties[p]!==null){element.style.setProperty(p,properties[p]);propertyNames.push(p);}}
+element.__customStyleProperties=propertyNames;},rx:styleUtil.rx,XSCOPE_NAME:'x-scope'};function addToBitMask(n,bits){var o=parseInt(n/32);var v=1<<n%32;bits[o]=(bits[o]||0)|v;}}();(function(){Polymer.StyleCache=function(){this.cache={};};Polymer.StyleCache.prototype={MAX:100,store:function(is,data,keyValues,keyStyles){data.keyValues=keyValues;data.styles=keyStyles;var s$=this.cache[is]=this.cache[is]||[];s$.push(data);if(s$.length>this.MAX){s$.shift();}},retrieve:function(is,keyValues,keyStyles){var cache=this.cache[is];if(cache){for(var i=cache.length-1,data;i>=0;i--){data=cache[i];if(keyStyles===data.styles&&this._objectsEqual(keyValues,data.keyValues)){return data;}}}},clear:function(){this.cache={};},_objectsEqual:function(target,source){var t,s;for(var i in target){t=target[i],s=source[i];if(!(typeof t==='object'&&t?this._objectsStrictlyEqual(t,s):t===s)){return false;}}
+if(Array.isArray(target)){return target.length===source.length;}
+return true;},_objectsStrictlyEqual:function(target,source){return this._objectsEqual(target,source)&&this._objectsEqual(source,target);}};}());Polymer.StyleDefaults=function(){var styleProperties=Polymer.StyleProperties;var StyleCache=Polymer.StyleCache;var nativeVariables=Polymer.Settings.useNativeCSSProperties;var api={_styles:[],_properties:null,customStyle:{},_styleCache:new StyleCache(),_element:Polymer.DomApi.wrap(document.documentElement),addStyle:function(style){this._styles.push(style);this._properties=null;},get _styleProperties(){if(!this._properties){styleProperties.decorateStyles(this._styles,this);this._styles._scopeStyleProperties=null;this._properties=styleProperties.hostAndRootPropertiesForScope(this).rootProps;styleProperties.mixinCustomStyle(this._properties,this.customStyle);styleProperties.reify(this._properties);}
+return this._properties;},hasStyleProperties:function(){return Boolean(this._properties);},_needsStyleProperties:function(){},_computeStyleProperties:function(){return this._styleProperties;},updateStyles:function(properties){this._properties=null;if(properties){Polymer.Base.mixin(this.customStyle,properties);}
+this._styleCache.clear();for(var i=0,s;i<this._styles.length;i++){s=this._styles[i];s=s.__importElement||s;s._apply();}
+if(nativeVariables){styleProperties.updateNativeStyleProperties(document.documentElement,this.customStyle);}}};return api;}();(function(){'use strict';var serializeValueToAttribute=Polymer.Base.serializeValueToAttribute;var propertyUtils=Polymer.StyleProperties;var styleTransformer=Polymer.StyleTransformer;var styleDefaults=Polymer.StyleDefaults;var nativeShadow=Polymer.Settings.useNativeShadow;var nativeVariables=Polymer.Settings.useNativeCSSProperties;Polymer.Base._addFeature({_prepStyleProperties:function(){if(!nativeVariables){this._ownStylePropertyNames=this._styles&&this._styles.length?propertyUtils.decorateStyles(this._styles,this):null;}},customStyle:null,getComputedStyleValue:function(property){if(!nativeVariables&&!this._styleProperties){this._computeStyleProperties();}
+return!nativeVariables&&this._styleProperties&&this._styleProperties[property]||getComputedStyle(this).getPropertyValue(property);},_setupStyleProperties:function(){this.customStyle={};this._styleCache=null;this._styleProperties=null;this._scopeSelector=null;this._ownStyleProperties=null;this._customStyle=null;},_needsStyleProperties:function(){return Boolean(!nativeVariables&&this._ownStylePropertyNames&&this._ownStylePropertyNames.length);},_validateApplyShim:function(){if(this.__applyShimInvalid){Polymer.ApplyShim.transform(this._styles,this.__proto__);var cssText=styleTransformer.elementStyles(this);if(nativeShadow){var templateStyle=this._template.content.querySelector('style');if(templateStyle){templateStyle.textContent=cssText;}}else{var shadyStyle=this._scopeStyle&&this._scopeStyle.nextSibling;if(shadyStyle){shadyStyle.textContent=cssText;}}}},_beforeAttached:function(){if((!this._scopeSelector||this.__stylePropertiesInvalid)&&this._needsStyleProperties()){this.__stylePropertiesInvalid=false;this._updateStyleProperties();}},_findStyleHost:function(){var e=this,root;while(root=Polymer.dom(e).getOwnerRoot()){if(Polymer.isInstance(root.host)){return root.host;}
+e=root.host;}
+return styleDefaults;},_updateStyleProperties:function(){var info,scope=this._findStyleHost();if(!scope._styleProperties){scope._computeStyleProperties();}
+if(!scope._styleCache){scope._styleCache=new Polymer.StyleCache();}
+var scopeData=propertyUtils.propertyDataFromStyles(scope._styles,this);var scopeCacheable=!this.__notStyleScopeCacheable;if(scopeCacheable){scopeData.key.customStyle=this.customStyle;info=scope._styleCache.retrieve(this.is,scopeData.key,this._styles);}
+var scopeCached=Boolean(info);if(scopeCached){this._styleProperties=info._styleProperties;}else{this._computeStyleProperties(scopeData.properties);}
+this._computeOwnStyleProperties();if(!scopeCached){info=styleCache.retrieve(this.is,this._ownStyleProperties,this._styles);}
+var globalCached=Boolean(info)&&!scopeCached;var style=this._applyStyleProperties(info);if(!scopeCached){style=style&&nativeShadow?style.cloneNode(true):style;info={style:style,_scopeSelector:this._scopeSelector,_styleProperties:this._styleProperties};if(scopeCacheable){scopeData.key.customStyle={};this.mixin(scopeData.key.customStyle,this.customStyle);scope._styleCache.store(this.is,info,scopeData.key,this._styles);}
+if(!globalCached){styleCache.store(this.is,Object.create(info),this._ownStyleProperties,this._styles);}}},_computeStyleProperties:function(scopeProps){var scope=this._findStyleHost();if(!scope._styleProperties){scope._computeStyleProperties();}
+var props=Object.create(scope._styleProperties);var hostAndRootProps=propertyUtils.hostAndRootPropertiesForScope(this);this.mixin(props,hostAndRootProps.hostProps);scopeProps=scopeProps||propertyUtils.propertyDataFromStyles(scope._styles,this).properties;this.mixin(props,scopeProps);this.mixin(props,hostAndRootProps.rootProps);propertyUtils.mixinCustomStyle(props,this.customStyle);propertyUtils.reify(props);this._styleProperties=props;},_computeOwnStyleProperties:function(){var props={};for(var i=0,n;i<this._ownStylePropertyNames.length;i++){n=this._ownStylePropertyNames[i];props[n]=this._styleProperties[n];}
+this._ownStyleProperties=props;},_scopeCount:0,_applyStyleProperties:function(info){var oldScopeSelector=this._scopeSelector;this._scopeSelector=info?info._scopeSelector:this.is+'-'+this.__proto__._scopeCount++;var style=propertyUtils.applyElementStyle(this,this._styleProperties,this._scopeSelector,info&&info.style);if(!nativeShadow){propertyUtils.applyElementScopeSelector(this,this._scopeSelector,oldScopeSelector,this._scopeCssViaAttr);}
+return style;},serializeValueToAttribute:function(value,attribute,node){node=node||this;if(attribute==='class'&&!nativeShadow){var host=node===this?this.domHost||this.dataHost:this;if(host){value=host._scopeElementClass(node,value);}}
+node=this.shadyRoot&&this.shadyRoot._hasDistributed?Polymer.dom(node):node;serializeValueToAttribute.call(this,value,attribute,node);},_scopeElementClass:function(element,selector){if(!nativeShadow&&!this._scopeCssViaAttr){selector=(selector?selector+' ':'')+SCOPE_NAME+' '+this.is+(element._scopeSelector?' '+XSCOPE_NAME+' '+element._scopeSelector:'');}
+return selector;},updateStyles:function(properties){if(properties){this.mixin(this.customStyle,properties);}
+if(nativeVariables){propertyUtils.updateNativeStyleProperties(this,this.customStyle);}else{if(this.isAttached){if(this._needsStyleProperties()){this._updateStyleProperties();}else{this._styleProperties=null;}}else{this.__stylePropertiesInvalid=true;}
+if(this._styleCache){this._styleCache.clear();}
+this._updateRootStyles();}},_updateRootStyles:function(root){root=root||this.root;var c$=Polymer.dom(root)._query(function(e){return e.shadyRoot||e.shadowRoot;});for(var i=0,l=c$.length,c;i<l&&(c=c$[i]);i++){if(c.updateStyles){c.updateStyles();}}}});Polymer.updateStyles=function(properties){styleDefaults.updateStyles(properties);Polymer.Base._updateRootStyles(document);};var styleCache=new Polymer.StyleCache();Polymer.customStyleCache=styleCache;var SCOPE_NAME=styleTransformer.SCOPE_NAME;var XSCOPE_NAME=propertyUtils.XSCOPE_NAME;}());Polymer.Base._addFeature({_registerFeatures:function(){this._prepIs();if(this.factoryImpl){this._prepConstructor();}
+this._prepStyles();},_finishRegisterFeatures:function(){this._prepTemplate();this._prepShimStyles();this._prepAnnotations();this._prepEffects();this._prepBehaviors();this._prepPropertyInfo();this._prepBindings();this._prepShady();},_prepBehavior:function(b){this._addPropertyEffects(b.properties);this._addComplexObserverEffects(b.observers);this._addHostAttributes(b.hostAttributes);},_initFeatures:function(){this._setupGestures();this._setupConfigure(this.__data__);this._setupStyleProperties();this._setupDebouncers();this._setupShady();this._registerHost();if(this._template){this._validateApplyShim();this._poolContent();this._beginHosting();this._stampTemplate();this._endHosting();this._marshalAnnotationReferences();}
+this._marshalInstanceEffects();this._marshalBehaviors();this._marshalHostAttributes();this._marshalAttributes();this._tryReady();},_marshalBehavior:function(b){if(b.listeners){this._listenListeners(b.listeners);}}});(function(){var propertyUtils=Polymer.StyleProperties;var styleUtil=Polymer.StyleUtil;var cssParse=Polymer.CssParse;var styleDefaults=Polymer.StyleDefaults;var styleTransformer=Polymer.StyleTransformer;var applyShim=Polymer.ApplyShim;var debounce=Polymer.Debounce;var settings=Polymer.Settings;var updateDebouncer;Polymer({is:'custom-style',extends:'style',_template:null,properties:{include:String},ready:function(){this.__appliedElement=this.__appliedElement||this;this.__cssBuild=styleUtil.getCssBuildType(this);if(this.__appliedElement!==this){this.__appliedElement.__cssBuild=this.__cssBuild;}
+if(this.ownerDocument!==window.document&&this.__appliedElement===this){document.head.appendChild(this);}
+this._tryApply();},attached:function(){this._tryApply();},_tryApply:function(){if(!this._appliesToDocument){if(this.parentNode&&this.parentNode.localName!=='dom-module'){this._appliesToDocument=true;var e=this.__appliedElement;if(!settings.useNativeCSSProperties){this.__needsUpdateStyles=styleDefaults.hasStyleProperties();styleDefaults.addStyle(e);}
+if(e.textContent||this.include){this._apply(true);}else{var self=this;var observer=new MutationObserver(function(){observer.disconnect();self._apply(true);});observer.observe(e,{childList:true});}}}},_updateStyles:function(){Polymer.updateStyles();},_apply:function(initialApply){var e=this.__appliedElement;if(this.include){e.textContent=styleUtil.cssFromModules(this.include,true)+e.textContent;}
+if(!e.textContent){return;}
+var buildType=this.__cssBuild;var targetedBuild=styleUtil.isTargetedBuild(buildType);if(settings.useNativeCSSProperties&&targetedBuild){return;}
+var styleRules=styleUtil.rulesForStyle(e);if(!targetedBuild){styleUtil.forEachRule(styleRules,function(rule){styleTransformer.documentRule(rule);});if(settings.useNativeCSSProperties&&!buildType){applyShim.transform([e]);}}
+if(settings.useNativeCSSProperties){e.textContent=styleUtil.toCssText(styleRules);}else{var self=this;var fn=function fn(){self._flushCustomProperties();};if(initialApply){Polymer.RenderStatus.whenReady(fn);}else{fn();}}},_flushCustomProperties:function(){if(this.__needsUpdateStyles){this.__needsUpdateStyles=false;updateDebouncer=debounce(updateDebouncer,this._updateStyles);}else{this._applyCustomProperties();}},_applyCustomProperties:function(){var element=this.__appliedElement;this._computeStyleProperties();var props=this._styleProperties;var rules=styleUtil.rulesForStyle(element);if(!rules){return;}
+element.textContent=styleUtil.toCssText(rules,function(rule){var css=rule.cssText=rule.parsedCssText;if(rule.propertyInfo&&rule.propertyInfo.cssText){css=cssParse.removeCustomPropAssignment(css);rule.cssText=propertyUtils.valueForProperties(css,props);}});}});}());Polymer.Templatizer={properties:{__hideTemplateChildren__:{observer:'_showHideChildren'}},_instanceProps:Polymer.nob,_parentPropPrefix:'_parent_',templatize:function(template){this._templatized=template;if(!template._content){template._content=template.content;}
+if(template._content._ctor){this.ctor=template._content._ctor;this._prepParentProperties(this.ctor.prototype,template);return;}
+var archetype=Object.create(Polymer.Base);this._customPrepAnnotations(archetype,template);this._prepParentProperties(archetype,template);archetype._prepEffects();this._customPrepEffects(archetype);archetype._prepBehaviors();archetype._prepPropertyInfo();archetype._prepBindings();archetype._notifyPathUp=this._notifyPathUpImpl;archetype._scopeElementClass=this._scopeElementClassImpl;archetype.listen=this._listenImpl;archetype._showHideChildren=this._showHideChildrenImpl;archetype.__setPropertyOrig=this.__setProperty;archetype.__setProperty=this.__setPropertyImpl;var _constructor=this._constructorImpl;var ctor=function TemplateInstance(model,host){_constructor.call(this,model,host);};ctor.prototype=archetype;archetype.constructor=ctor;template._content._ctor=ctor;this.ctor=ctor;},_getRootDataHost:function(){return this.dataHost&&this.dataHost._rootDataHost||this.dataHost;},_showHideChildrenImpl:function(hide){var c=this._children;for(var i=0;i<c.length;i++){var n=c[i];if(Boolean(hide)!=Boolean(n.__hideTemplateChildren__)){if(n.nodeType===Node.TEXT_NODE){if(hide){n.__polymerTextContent__=n.textContent;n.textContent='';}else{n.textContent=n.__polymerTextContent__;}}else if(n.style){if(hide){n.__polymerDisplay__=n.style.display;n.style.display='none';}else{n.style.display=n.__polymerDisplay__;}}}
+n.__hideTemplateChildren__=hide;}},__setPropertyImpl:function(property,value,fromAbove,node){if(node&&node.__hideTemplateChildren__&&property=='textContent'){property='__polymerTextContent__';}
+this.__setPropertyOrig(property,value,fromAbove,node);},_debounceTemplate:function(fn){Polymer.dom.addDebouncer(this.debounce('_debounceTemplate',fn));},_flushTemplates:function(){Polymer.dom.flush();},_customPrepEffects:function(archetype){var parentProps=archetype._parentProps;for(var prop in parentProps){archetype._addPropertyEffect(prop,'function',this._createHostPropEffector(prop));}
+for(prop in this._instanceProps){archetype._addPropertyEffect(prop,'function',this._createInstancePropEffector(prop));}},_customPrepAnnotations:function(archetype,template){var t=archetype._template=document.createElement('template');var c=t._content=template._content;if(!c._notes){var rootDataHost=archetype._rootDataHost;if(rootDataHost){Polymer.Annotations.prepElement=function(){rootDataHost._prepElement();};}
+c._notes=Polymer.Annotations.parseAnnotations(template);Polymer.Annotations.prepElement=null;this._processAnnotations(c._notes);}
+archetype._notes=c._notes;archetype._parentProps=c._parentProps;},_prepParentProperties:function(archetype,template){var parentProps=this._parentProps=archetype._parentProps;if(this._forwardParentProp&&parentProps){var proto=archetype._parentPropProto;var prop;if(!proto){for(prop in this._instanceProps){delete parentProps[prop];}
+proto=archetype._parentPropProto=Object.create(null);if(template!=this){Polymer.Bind.prepareModel(proto);Polymer.Base.prepareModelNotifyPath(proto);}
+for(prop in parentProps){var parentProp=this._parentPropPrefix+prop;var effects=[{kind:'function',effect:this._createForwardPropEffector(prop),fn:Polymer.Bind._functionEffect},{kind:'notify',fn:Polymer.Bind._notifyEffect,effect:{event:Polymer.CaseMap.camelToDashCase(parentProp)+'-changed'}}];proto._propertyEffects=proto._propertyEffects||{};proto._propertyEffects[parentProp]=effects;Polymer.Bind._createAccessors(proto,parentProp,effects);}}
+var self=this;if(template!=this){Polymer.Bind.prepareInstance(template);template._forwardParentProp=function(source,value){self._forwardParentProp(source,value);};}
+this._extendTemplate(template,proto);template._pathEffector=function(path,value,fromAbove){return self._pathEffectorImpl(path,value,fromAbove);};}},_createForwardPropEffector:function(prop){return function(source,value){this._forwardParentProp(prop,value);};},_createHostPropEffector:function(prop){var prefix=this._parentPropPrefix;return function(source,value){this.dataHost._templatized[prefix+prop]=value;};},_createInstancePropEffector:function(prop){return function(source,value,old,fromAbove){if(!fromAbove){this.dataHost._forwardInstanceProp(this,prop,value);}};},_extendTemplate:function(template,proto){var n$=Object.getOwnPropertyNames(proto);if(proto._propertySetter){template._propertySetter=proto._propertySetter;}
+for(var i=0,n;i<n$.length&&(n=n$[i]);i++){var val=template[n];if(val&&n=='_propertyEffects'){var pe=Polymer.Base.mixin({},val);template._propertyEffects=Polymer.Base.mixin(pe,proto._propertyEffects);}else{var pd=Object.getOwnPropertyDescriptor(proto,n);Object.defineProperty(template,n,pd);if(val!==undefined){template._propertySetter(n,val);}}}},_showHideChildren:function(hidden){},_forwardInstancePath:function(inst,path,value){},_forwardInstanceProp:function(inst,prop,value){},_notifyPathUpImpl:function(path,value){var dataHost=this.dataHost;var root=Polymer.Path.root(path);dataHost._forwardInstancePath.call(dataHost,this,path,value);if(root in dataHost._parentProps){dataHost._templatized._notifyPath(dataHost._parentPropPrefix+path,value);}},_pathEffectorImpl:function(path,value,fromAbove){if(this._forwardParentPath){if(path.indexOf(this._parentPropPrefix)===0){var subPath=path.substring(this._parentPropPrefix.length);var model=Polymer.Path.root(subPath);if(model in this._parentProps){this._forwardParentPath(subPath,value);}}}
+Polymer.Base._pathEffector.call(this._templatized,path,value,fromAbove);},_constructorImpl:function(model,host){this._rootDataHost=host._getRootDataHost();this._setupConfigure(model);this._registerHost(host);this._beginHosting();this.root=this.instanceTemplate(this._template);this.root.__noContent=!this._notes._hasContent;this.root.__styleScoped=true;this._endHosting();this._marshalAnnotatedNodes();this._marshalInstanceEffects();this._marshalAnnotatedListeners();var children=[];for(var n=this.root.firstChild;n;n=n.nextSibling){children.push(n);n._templateInstance=this;}
+this._children=children;if(host.__hideTemplateChildren__){this._showHideChildren(true);}
+this._tryReady();},_listenImpl:function(node,eventName,methodName){var model=this;var host=this._rootDataHost;var handler=host._createEventHandler(node,eventName,methodName);var decorated=function(e){e.model=model;handler(e);};host._listen(node,eventName,decorated);},_scopeElementClassImpl:function(node,value){var host=this._rootDataHost;if(host){return host._scopeElementClass(node,value);}
+return value;},stamp:function(model){model=model||{};if(this._parentProps){var templatized=this._templatized;for(var prop in this._parentProps){if(model[prop]===undefined){model[prop]=templatized[this._parentPropPrefix+prop];}}}
+return new this.ctor(model,this);},modelForElement:function(el){var model;while(el){if(model=el._templateInstance){if(model.dataHost!=this){el=model.dataHost;}else{return model;}}else{el=el.parentNode;}}}};Polymer({is:'dom-template',extends:'template',_template:null,behaviors:[Polymer.Templatizer],ready:function(){this.templatize(this);}});Polymer._collections=new WeakMap();Polymer.Collection=function(userArray){Polymer._collections.set(userArray,this);this.userArray=userArray;this.store=userArray.slice();this.initMap();};Polymer.Collection.prototype={constructor:Polymer.Collection,initMap:function(){var omap=this.omap=new WeakMap();var pmap=this.pmap={};var s=this.store;for(var i=0;i<s.length;i++){var item=s[i];if(item&&typeof item=='object'){omap.set(item,i);}else{pmap[item]=i;}}},add:function(item){var key=this.store.push(item)-1;if(item&&typeof item=='object'){this.omap.set(item,key);}else{this.pmap[item]=key;}
+return'#'+key;},removeKey:function(key){if(key=this._parseKey(key)){this._removeFromMap(this.store[key]);delete this.store[key];}},_removeFromMap:function(item){if(item&&typeof item=='object'){this.omap.delete(item);}else{delete this.pmap[item];}},remove:function(item){var key=this.getKey(item);this.removeKey(key);return key;},getKey:function(item){var key;if(item&&typeof item=='object'){key=this.omap.get(item);}else{key=this.pmap[item];}
+if(key!=undefined){return'#'+key;}},getKeys:function(){return Object.keys(this.store).map(function(key){return'#'+key;});},_parseKey:function(key){if(key&&key[0]=='#'){return key.slice(1);}},setItem:function(key,item){if(key=this._parseKey(key)){var old=this.store[key];if(old){this._removeFromMap(old);}
+if(item&&typeof item=='object'){this.omap.set(item,key);}else{this.pmap[item]=key;}
+this.store[key]=item;}},getItem:function(key){if(key=this._parseKey(key)){return this.store[key];}},getItems:function(){var items=[],store=this.store;for(var key in store){items.push(store[key]);}
+return items;},_applySplices:function(splices){var keyMap={},key;for(var i=0,s;i<splices.length&&(s=splices[i]);i++){s.addedKeys=[];for(var j=0;j<s.removed.length;j++){key=this.getKey(s.removed[j]);keyMap[key]=keyMap[key]?null:-1;}
+for(j=0;j<s.addedCount;j++){var item=this.userArray[s.index+j];key=this.getKey(item);key=key===undefined?this.add(item):key;keyMap[key]=keyMap[key]?null:1;s.addedKeys.push(key);}}
+var removed=[];var added=[];for(key in keyMap){if(keyMap[key]<0){this.removeKey(key);removed.push(key);}
+if(keyMap[key]>0){added.push(key);}}
+return[{removed:removed,added:added}];}};Polymer.Collection.get=function(userArray){return Polymer._collections.get(userArray)||new Polymer.Collection(userArray);};Polymer.Collection.applySplices=function(userArray,splices){var coll=Polymer._collections.get(userArray);return coll?coll._applySplices(splices):null;};Polymer({is:'dom-repeat',extends:'template',_template:null,properties:{items:{type:Array},as:{type:String,value:'item'},indexAs:{type:String,value:'index'},sort:{type:Function,observer:'_sortChanged'},filter:{type:Function,observer:'_filterChanged'},observe:{type:String,observer:'_observeChanged'},delay:Number,renderedItemCount:{type:Number,notify:!Polymer.Settings.suppressTemplateNotifications,readOnly:true},initialCount:{type:Number,observer:'_initializeChunking'},targetFramerate:{type:Number,value:20},notifyDomChange:{type:Boolean},_targetFrameTime:{type:Number,computed:'_computeFrameTime(targetFramerate)'}},behaviors:[Polymer.Templatizer],observers:['_itemsChanged(items.*)'],created:function(){this._instances=[];this._pool=[];this._limit=Infinity;var self=this;this._boundRenderChunk=function(){self._renderChunk();};},detached:function(){this.__isDetached=true;for(var i=0;i<this._instances.length;i++){this._detachInstance(i);}},attached:function(){if(this.__isDetached){this.__isDetached=false;var refNode;var parentNode=Polymer.dom(this).parentNode;if(parentNode.localName==this.is){refNode=parentNode;parentNode=Polymer.dom(parentNode).parentNode;}else{refNode=this;}
+var parent=Polymer.dom(parentNode);for(var i=0;i<this._instances.length;i++){this._attachInstance(i,parent,refNode);}}},ready:function(){this._instanceProps={__key__:true};this._instanceProps[this.as]=true;this._instanceProps[this.indexAs]=true;if(!this.ctor){this.templatize(this);}},_sortChanged:function(sort){var dataHost=this._getRootDataHost();this._sortFn=sort&&(typeof sort=='function'?sort:function(){return dataHost[sort].apply(dataHost,arguments);});this._needFullRefresh=true;if(this.items){this._debounceTemplate(this._render);}},_filterChanged:function(filter){var dataHost=this._getRootDataHost();this._filterFn=filter&&(typeof filter=='function'?filter:function(){return dataHost[filter].apply(dataHost,arguments);});this._needFullRefresh=true;if(this.items){this._debounceTemplate(this._render);}},_computeFrameTime:function(rate){return Math.ceil(1000/rate);},_initializeChunking:function(){if(this.initialCount){this._limit=this.initialCount;this._chunkCount=this.initialCount;this._lastChunkTime=performance.now();}},_tryRenderChunk:function(){if(this.items&&this._limit<this.items.length){this.debounce('renderChunk',this._requestRenderChunk);}},_requestRenderChunk:function(){requestAnimationFrame(this._boundRenderChunk);},_renderChunk:function(){var currChunkTime=performance.now();var ratio=this._targetFrameTime/(currChunkTime-this._lastChunkTime);this._chunkCount=Math.round(this._chunkCount*ratio)||1;this._limit+=this._chunkCount;this._lastChunkTime=currChunkTime;this._debounceTemplate(this._render);},_observeChanged:function(){this._observePaths=this.observe&&this.observe.replace('.*','.').split(' ');},_itemsChanged:function(change){if(change.path=='items'){if(Array.isArray(this.items)){this.collection=Polymer.Collection.get(this.items);}else if(!this.items){this.collection=null;}else{this._error(this._logf('dom-repeat','expected array for `items`,'+' found',this.items));}
+this._keySplices=[];this._indexSplices=[];this._needFullRefresh=true;this._initializeChunking();this._debounceTemplate(this._render);}else if(change.path=='items.splices'){this._keySplices=this._keySplices.concat(change.value.keySplices);this._indexSplices=this._indexSplices.concat(change.value.indexSplices);this._debounceTemplate(this._render);}else{var subpath=change.path.slice(6);this._forwardItemPath(subpath,change.value);this._checkObservedPaths(subpath);}},_checkObservedPaths:function(path){if(this._observePaths){path=path.substring(path.indexOf('.')+1);var paths=this._observePaths;for(var i=0;i<paths.length;i++){if(path.indexOf(paths[i])===0){this._needFullRefresh=true;if(this.delay){this.debounce('render',this._render,this.delay);}else{this._debounceTemplate(this._render);}
+return;}}}},render:function(){this._needFullRefresh=true;this._debounceTemplate(this._render);this._flushTemplates();},_render:function(){if(this._needFullRefresh){this._applyFullRefresh();this._needFullRefresh=false;}else if(this._keySplices.length){if(this._sortFn){this._applySplicesUserSort(this._keySplices);}else{if(this._filterFn){this._applyFullRefresh();}else{this._applySplicesArrayOrder(this._indexSplices);}}}else{}
+this._keySplices=[];this._indexSplices=[];var keyToIdx=this._keyToInstIdx={};for(var i=this._instances.length-1;i>=0;i--){var inst=this._instances[i];if(inst.isPlaceholder&&i<this._limit){inst=this._insertInstance(i,inst.__key__);}else if(!inst.isPlaceholder&&i>=this._limit){inst=this._downgradeInstance(i,inst.__key__);}
+keyToIdx[inst.__key__]=i;if(!inst.isPlaceholder){inst.__setProperty(this.indexAs,i,true);}}
+this._pool.length=0;this._setRenderedItemCount(this._instances.length);if(!Polymer.Settings.suppressTemplateNotifications||this.notifyDomChange){this.fire('dom-change');}
+this._tryRenderChunk();},_applyFullRefresh:function(){var c=this.collection;var keys;if(this._sortFn){keys=c?c.getKeys():[];}else{keys=[];var items=this.items;if(items){for(var i=0;i<items.length;i++){keys.push(c.getKey(items[i]));}}}
+var self=this;if(this._filterFn){keys=keys.filter(function(a){return self._filterFn(c.getItem(a));});}
+if(this._sortFn){keys.sort(function(a,b){return self._sortFn(c.getItem(a),c.getItem(b));});}
+for(i=0;i<keys.length;i++){var key=keys[i];var inst=this._instances[i];if(inst){inst.__key__=key;if(!inst.isPlaceholder&&i<this._limit){inst.__setProperty(this.as,c.getItem(key),true);}}else if(i<this._limit){this._insertInstance(i,key);}else{this._insertPlaceholder(i,key);}}
+for(var j=this._instances.length-1;j>=i;j--){this._detachAndRemoveInstance(j);}},_numericSort:function(a,b){return a-b;},_applySplicesUserSort:function(splices){var c=this.collection;var keyMap={};var key;for(var i=0,s;i<splices.length&&(s=splices[i]);i++){for(var j=0;j<s.removed.length;j++){key=s.removed[j];keyMap[key]=keyMap[key]?null:-1;}
+for(j=0;j<s.added.length;j++){key=s.added[j];keyMap[key]=keyMap[key]?null:1;}}
+var removedIdxs=[];var addedKeys=[];for(key in keyMap){if(keyMap[key]===-1){removedIdxs.push(this._keyToInstIdx[key]);}
+if(keyMap[key]===1){addedKeys.push(key);}}
+if(removedIdxs.length){removedIdxs.sort(this._numericSort);for(i=removedIdxs.length-1;i>=0;i--){var idx=removedIdxs[i];if(idx!==undefined){this._detachAndRemoveInstance(idx);}}}
+var self=this;if(addedKeys.length){if(this._filterFn){addedKeys=addedKeys.filter(function(a){return self._filterFn(c.getItem(a));});}
+addedKeys.sort(function(a,b){return self._sortFn(c.getItem(a),c.getItem(b));});var start=0;for(i=0;i<addedKeys.length;i++){start=this._insertRowUserSort(start,addedKeys[i]);}}},_insertRowUserSort:function(start,key){var c=this.collection;var item=c.getItem(key);var end=this._instances.length-1;var idx=-1;while(start<=end){var mid=start+end>>1;var midKey=this._instances[mid].__key__;var cmp=this._sortFn(c.getItem(midKey),item);if(cmp<0){start=mid+1;}else if(cmp>0){end=mid-1;}else{idx=mid;break;}}
+if(idx<0){idx=end+1;}
+this._insertPlaceholder(idx,key);return idx;},_applySplicesArrayOrder:function(splices){for(var i=0,s;i<splices.length&&(s=splices[i]);i++){for(var j=0;j<s.removed.length;j++){this._detachAndRemoveInstance(s.index);}
+for(j=0;j<s.addedKeys.length;j++){this._insertPlaceholder(s.index+j,s.addedKeys[j]);}}},_detachInstance:function(idx){var inst=this._instances[idx];if(!inst.isPlaceholder){for(var i=0;i<inst._children.length;i++){var el=inst._children[i];Polymer.dom(inst.root).appendChild(el);}
+return inst;}},_attachInstance:function(idx,parent,refNode){var inst=this._instances[idx];if(!inst.isPlaceholder){parent.insertBefore(inst.root,refNode);}},_detachAndRemoveInstance:function(idx){var inst=this._detachInstance(idx);if(inst){this._pool.push(inst);}
+this._instances.splice(idx,1);},_insertPlaceholder:function(idx,key){this._instances.splice(idx,0,{isPlaceholder:true,__key__:key});},_stampInstance:function(idx,key){var model={__key__:key};model[this.as]=this.collection.getItem(key);model[this.indexAs]=idx;return this.stamp(model);},_insertInstance:function(idx,key){var inst=this._pool.pop();if(inst){inst.__setProperty(this.as,this.collection.getItem(key),true);inst.__setProperty('__key__',key,true);}else{inst=this._stampInstance(idx,key);}
+var beforeRow=this._instances[idx+1];var beforeNode=beforeRow&&!beforeRow.isPlaceholder?beforeRow._children[0]:this;var parentNode=Polymer.dom(this).parentNode;if(parentNode.localName==this.is){if(beforeNode==this){beforeNode=parentNode;}
+parentNode=Polymer.dom(parentNode).parentNode;}
+Polymer.dom(parentNode).insertBefore(inst.root,beforeNode);this._instances[idx]=inst;return inst;},_downgradeInstance:function(idx,key){var inst=this._detachInstance(idx);if(inst){this._pool.push(inst);}
+inst={isPlaceholder:true,__key__:key};this._instances[idx]=inst;return inst;},_showHideChildren:function(hidden){for(var i=0;i<this._instances.length;i++){if(!this._instances[i].isPlaceholder)
+this._instances[i]._showHideChildren(hidden);}},_forwardInstanceProp:function(inst,prop,value){if(prop==this.as){var idx;if(this._sortFn||this._filterFn){idx=this.items.indexOf(this.collection.getItem(inst.__key__));}else{idx=inst[this.indexAs];}
+this.set('items.'+idx,value);}},_forwardInstancePath:function(inst,path,value){if(path.indexOf(this.as+'.')===0){this._notifyPath('items.'+inst.__key__+'.'+path.slice(this.as.length+1),value);}},_forwardParentProp:function(prop,value){var i$=this._instances;for(var i=0,inst;i<i$.length&&(inst=i$[i]);i++){if(!inst.isPlaceholder){inst.__setProperty(prop,value,true);}}},_forwardParentPath:function(path,value){var i$=this._instances;for(var i=0,inst;i<i$.length&&(inst=i$[i]);i++){if(!inst.isPlaceholder){inst._notifyPath(path,value,true);}}},_forwardItemPath:function(path,value){if(this._keyToInstIdx){var dot=path.indexOf('.');var key=path.substring(0,dot<0?path.length:dot);var idx=this._keyToInstIdx[key];var inst=this._instances[idx];if(inst&&!inst.isPlaceholder){if(dot>=0){path=this.as+'.'+path.substring(dot+1);inst._notifyPath(path,value,true);}else{inst.__setProperty(this.as,value,true);}}}},itemForElement:function(el){var instance=this.modelForElement(el);return instance&&instance[this.as];},keyForElement:function(el){var instance=this.modelForElement(el);return instance&&instance.__key__;},indexForElement:function(el){var instance=this.modelForElement(el);return instance&&instance[this.indexAs];}});Polymer({is:'array-selector',_template:null,properties:{items:{type:Array,observer:'clearSelection'},multi:{type:Boolean,value:false,observer:'clearSelection'},selected:{type:Object,notify:true},selectedItem:{type:Object,notify:true},toggle:{type:Boolean,value:false}},clearSelection:function(){if(Array.isArray(this.selected)){for(var i=0;i<this.selected.length;i++){this.unlinkPaths('selected.'+i);}}else{this.unlinkPaths('selected');this.unlinkPaths('selectedItem');}
+if(this.multi){if(!this.selected||this.selected.length){this.selected=[];this._selectedColl=Polymer.Collection.get(this.selected);}}else{this.selected=null;this._selectedColl=null;}
+this.selectedItem=null;},isSelected:function(item){if(this.multi){return this._selectedColl.getKey(item)!==undefined;}else{return this.selected==item;}},deselect:function(item){if(this.multi){if(this.isSelected(item)){var skey=this._selectedColl.getKey(item);this.arrayDelete('selected',item);this.unlinkPaths('selected.'+skey);}}else{this.selected=null;this.selectedItem=null;this.unlinkPaths('selected');this.unlinkPaths('selectedItem');}},select:function(item){var icol=Polymer.Collection.get(this.items);var key=icol.getKey(item);if(this.multi){if(this.isSelected(item)){if(this.toggle){this.deselect(item);}}else{this.push('selected',item);var skey=this._selectedColl.getKey(item);this.linkPaths('selected.'+skey,'items.'+key);}}else{if(this.toggle&&item==this.selected){this.deselect();}else{this.selected=item;this.selectedItem=item;this.linkPaths('selected','items.'+key);this.linkPaths('selectedItem','items.'+key);}}}});Polymer({is:'dom-if',extends:'template',_template:null,properties:{'if':{type:Boolean,value:false,observer:'_queueRender'},restamp:{type:Boolean,value:false,observer:'_queueRender'},notifyDomChange:{type:Boolean}},behaviors:[Polymer.Templatizer],_queueRender:function(){this._debounceTemplate(this._render);},detached:function(){var parentNode=this.parentNode;if(parentNode&&parentNode.localName==this.is){parentNode=Polymer.dom(parentNode).parentNode;}
+if(!parentNode||parentNode.nodeType==Node.DOCUMENT_FRAGMENT_NODE&&(!Polymer.Settings.hasShadow||!(parentNode instanceof ShadowRoot))){this._teardownInstance();}},attached:function(){if(this.if&&this.ctor){this.async(this._ensureInstance);}},render:function(){this._flushTemplates();},_render:function(){if(this.if){if(!this.ctor){this.templatize(this);}
+this._ensureInstance();this._showHideChildren();}else if(this.restamp){this._teardownInstance();}
+if(!this.restamp&&this._instance){this._showHideChildren();}
+if(this.if!=this._lastIf){if(!Polymer.Settings.suppressTemplateNotifications||this.notifyDomChange){this.fire('dom-change');}
+this._lastIf=this.if;}},_ensureInstance:function(){var refNode;var parentNode=Polymer.dom(this).parentNode;if(parentNode&&parentNode.localName==this.is){refNode=parentNode;parentNode=Polymer.dom(parentNode).parentNode;}else{refNode=this;}
+if(parentNode){if(!this._instance){this._instance=this.stamp();var root=this._instance.root;Polymer.dom(parentNode).insertBefore(root,refNode);}else{var c$=this._instance._children;if(c$&&c$.length){var lastChild=Polymer.dom(refNode).previousSibling;if(lastChild!==c$[c$.length-1]){for(var i=0,n;i<c$.length&&(n=c$[i]);i++){Polymer.dom(parentNode).insertBefore(n,refNode);}}}}}},_teardownInstance:function(){if(this._instance){var c$=this._instance._children;if(c$&&c$.length){var parent=Polymer.dom(Polymer.dom(c$[0]).parentNode);for(var i=0,n;i<c$.length&&(n=c$[i]);i++){parent.removeChild(n);}}
+this._instance=null;}},_showHideChildren:function(){var hidden=this.__hideTemplateChildren__||!this.if;if(this._instance){this._instance._showHideChildren(hidden);}},_forwardParentProp:function(prop,value){if(this._instance){this._instance.__setProperty(prop,value,true);}},_forwardParentPath:function(path,value){if(this._instance){this._instance._notifyPath(path,value,true);}}});Polymer({is:'dom-bind',properties:{notifyDomChange:{type:Boolean}},extends:'template',_template:null,created:function(){var self=this;Polymer.RenderStatus.whenReady(function(){if(document.readyState=='loading'){document.addEventListener('DOMContentLoaded',function(){self._markImportsReady();});}else{self._markImportsReady();}});},_ensureReady:function(){if(!this._readied){this._readySelf();}},_markImportsReady:function(){this._importsReady=true;this._ensureReady();},_registerFeatures:function(){this._prepConstructor();},_insertChildren:function(){var refNode;var parentNode=Polymer.dom(this).parentNode;if(parentNode.localName==this.is){refNode=parentNode;parentNode=Polymer.dom(parentNode).parentNode;}else{refNode=this;}
+Polymer.dom(parentNode).insertBefore(this.root,refNode);},_removeChildren:function(){if(this._children){for(var i=0;i<this._children.length;i++){this.root.appendChild(this._children[i]);}}},_initFeatures:function(){},_scopeElementClass:function(element,selector){if(this.dataHost){return this.dataHost._scopeElementClass(element,selector);}else{return selector;}},_configureInstanceProperties:function(){},_prepConfigure:function(){var config={};for(var prop in this._propertyEffects){config[prop]=this[prop];}
+var setupConfigure=this._setupConfigure;this._setupConfigure=function(){setupConfigure.call(this,config);};},attached:function(){if(this._importsReady){this.render();}},detached:function(){this._removeChildren();},render:function(){this._ensureReady();if(!this._children){this._template=this;this._prepAnnotations();this._prepEffects();this._prepBehaviors();this._prepConfigure();this._prepBindings();this._prepPropertyInfo();Polymer.Base._initFeatures.call(this);this._children=Polymer.TreeApi.arrayCopyChildNodes(this.root);}
+this._insertChildren();if(!Polymer.Settings.suppressTemplateNotifications||this.notifyDomChange){this.fire('dom-change');}}});'use strict';if(!Polymer.Settings.useNativeShadow){tr.showPanic('Polymer error','base only works in shadow mode');}'use strict';const global=this.window||this.global;this.tr=(function(){if(global.tr)return global.tr;function exportPath(name){const parts=name.split('.');let cur=global;for(let part;parts.length&&(part=parts.shift());){if(part in cur){cur=cur[part];}else{cur=cur[part]={};}}
+return cur;}
+function isExported(name){const parts=name.split('.');let cur=global;for(let part;parts.length&&(part=parts.shift());){if(part in cur){cur=cur[part];}else{return false;}}
 return true;}
-function isDefined(name){var parts=name.split('.');var curObject=global;for(var i=0;i<parts.length;i++){var partName=parts[i];var nextObject=curObject[partName];if(nextObject===undefined)
-return false;curObject=nextObject;}
+function isDefined(name){const parts=name.split('.');let curObject=global;for(let i=0;i<parts.length;i++){const partName=parts[i];const nextObject=curObject[partName];if(nextObject===undefined)return false;curObject=nextObject;}
 return true;}
-var panicElement=undefined;var rawPanicMessages=[];function showPanicElementIfNeeded(){if(panicElement)
-return;var panicOverlay=document.createElement('div');panicOverlay.style.backgroundColor='white';panicOverlay.style.border='3px solid red';panicOverlay.style.boxSizing='border-box';panicOverlay.style.color='black';panicOverlay.style.display='-webkit-flex';panicOverlay.style.height='100%';panicOverlay.style.left=0;panicOverlay.style.padding='8px';panicOverlay.style.position='fixed';panicOverlay.style.top=0;panicOverlay.style.webkitFlexDirection='column';panicOverlay.style.width='100%';panicElement=document.createElement('div');panicElement.style.webkitFlex='1 1 auto';panicElement.style.overflow='auto';panicOverlay.appendChild(panicElement);if(!document.body){setTimeout(function(){document.body.appendChild(panicOverlay);},150);}else{document.body.appendChild(panicOverlay);}}
-function showPanic(panicTitle,panicDetails){if(tr.isHeadless){if(panicDetails instanceof Error)
-throw panicDetails;throw new Error('Panic: '+panicTitle+':\n'+panicDetails);}
-if(panicDetails instanceof Error)
-panicDetails=panicDetails.stack;showPanicElementIfNeeded();var panicMessageEl=document.createElement('div');panicMessageEl.innerHTML='<h2 id="message"></h2>'+'<pre id="details"></pre>';panicMessageEl.querySelector('#message').textContent=panicTitle;panicMessageEl.querySelector('#details').textContent=panicDetails;panicElement.appendChild(panicMessageEl);rawPanicMessages.push({title:panicTitle,details:panicDetails});}
+let panicElement=undefined;const rawPanicMessages=[];function showPanicElementIfNeeded(){if(panicElement)return;const panicOverlay=document.createElement('div');panicOverlay.style.backgroundColor='white';panicOverlay.style.border='3px solid red';panicOverlay.style.boxSizing='border-box';panicOverlay.style.color='black';panicOverlay.style.display='flex';panicOverlay.style.height='100%';panicOverlay.style.left=0;panicOverlay.style.padding='8px';panicOverlay.style.position='fixed';panicOverlay.style.top=0;panicOverlay.style.webkitFlexDirection='column';panicOverlay.style.width='100%';panicElement=document.createElement('div');panicElement.style.webkitFlex='1 1 auto';panicElement.style.overflow='auto';panicOverlay.appendChild(panicElement);if(!document.body){setTimeout(function(){document.body.appendChild(panicOverlay);},150);}else{document.body.appendChild(panicOverlay);}}
+function showPanic(panicTitle,panicDetails){if(tr.isHeadless){if(panicDetails instanceof Error)throw panicDetails;throw new Error('Panic: '+panicTitle+':\n'+panicDetails);}
+if(panicDetails instanceof Error){panicDetails=panicDetails.stack;}
+showPanicElementIfNeeded();const panicMessageEl=document.createElement('div');panicMessageEl.innerHTML='<h2 id="message"></h2>'+'<pre id="details"></pre>';panicMessageEl.querySelector('#message').textContent=panicTitle;panicMessageEl.querySelector('#details').textContent=panicDetails;panicElement.appendChild(panicMessageEl);rawPanicMessages.push({title:panicTitle,details:panicDetails});}
 function hasPanic(){return rawPanicMessages.length!==0;}
 function getPanicText(){return rawPanicMessages.map(function(msg){return msg.title;}).join(', ');}
-function exportTo(namespace,fn){var obj=exportPath(namespace);var exports=fn();for(var propertyName in exports){var propertyDescriptor=Object.getOwnPropertyDescriptor(exports,propertyName);if(propertyDescriptor)
-Object.defineProperty(obj,propertyName,propertyDescriptor);}};function initialize(){if(global.isVinn){tr.isVinn=true;}else if(global.process&&global.process.versions.node){tr.isNode=true;}else{tr.isVinn=false;tr.isNode=false;tr.doc=document;tr.isMac=/Mac/.test(navigator.platform);tr.isWindows=/Win/.test(navigator.platform);tr.isChromeOS=/CrOS/.test(navigator.userAgent);tr.isLinux=/Linux/.test(navigator.userAgent);}
+function exportTo(namespace,fn){const obj=exportPath(namespace);const exports=fn();for(const propertyName in exports){const propertyDescriptor=Object.getOwnPropertyDescriptor(exports,propertyName);if(propertyDescriptor){Object.defineProperty(obj,propertyName,propertyDescriptor);}}}
+function initialize(){if(global.isVinn){tr.isVinn=true;}else if(global.process&&global.process.versions.node){tr.isNode=true;}else{tr.isVinn=false;tr.isNode=false;tr.doc=document;tr.isMac=/Mac/.test(navigator.platform);tr.isWindows=/Win/.test(navigator.platform);tr.isChromeOS=/CrOS/.test(navigator.userAgent);tr.isLinux=/Linux/.test(navigator.userAgent);}
 tr.isHeadless=tr.isVinn||tr.isNode;}
-return{initialize:initialize,exportTo:exportTo,isExported:isExported,isDefined:isDefined,showPanic:showPanic,hasPanic:hasPanic,getPanicText:getPanicText};})();tr.initialize();'use strict';tr.exportTo('tr.b',function(){function asArray(arrayish){var values=[];for(var i=0;i<arrayish.length;i++)
-values.push(arrayish[i]);return values;}
-function compareArrays(x,y,elementCmp){var minLength=Math.min(x.length,y.length);for(var i=0;i<minLength;i++){var tmp=elementCmp(x[i],y[i]);if(tmp)
-return tmp;}
-if(x.length==y.length)
-return 0;if(x[i]===undefined)
-return-1;return 1;}
-function comparePossiblyUndefinedValues(x,y,cmp,opt_this){if(x!==undefined&&y!==undefined)
-return cmp.call(opt_this,x,y);if(x!==undefined)
-return-1;if(y!==undefined)
-return 1;return 0;}
-function compareNumericWithNaNs(x,y){if(!isNaN(x)&&!isNaN(y))
-return x-y;if(isNaN(x))
-return 1;if(isNaN(y))
-return-1;return 0;}
-function concatenateArrays(){var values=[];for(var i=0;i<arguments.length;i++){if(!(arguments[i]instanceof Array))
-throw new Error('Arguments '+i+'is not an array');values.push.apply(values,arguments[i]);}
-return values;}
-function concatenateObjects(){var result={};for(var i=0;i<arguments.length;i++){var object=arguments[i];for(var j in object){result[j]=object[j];}}
-return result;}
-function dictionaryKeys(dict){var keys=[];for(var key in dict)
-keys.push(key);return keys;}
-function dictionaryValues(dict){var values=[];for(var key in dict)
-values.push(dict[key]);return values;}
-function dictionaryLength(dict){var n=0;for(var key in dict)
-n++;return n;}
-function dictionaryContainsValue(dict,value){for(var key in dict)
-if(dict[key]===value)
-return true;return false;}
-function group(ary,fn){return ary.reduce(function(accumulator,curr){var key=fn(curr);if(key in accumulator)
-accumulator[key].push(curr);else
-accumulator[key]=[curr];return accumulator;},{});}
-function iterItems(dict,fn,opt_this){opt_this=opt_this||this;var keys=Object.keys(dict);for(var i=0;i<keys.length;i++){var key=keys[i];fn.call(opt_this,key,dict[key]);}}
-function mapItems(dict,fn,opt_this){opt_this=opt_this||this;var result={};var keys=Object.keys(dict);for(var i=0;i<keys.length;i++){var key=keys[i];result[key]=fn.call(opt_this,key,dict[key]);}
-return result;}
-function filterItems(dict,predicate,opt_this){opt_this=opt_this||this;var result={};var keys=Object.keys(dict);for(var i=0;i<keys.length;i++){var key=keys[i];var value=dict[key];if(predicate.call(opt_this,key,value))
-result[key]=value;}
-return result;}
-function iterObjectFieldsRecursively(object,func){if(!(object instanceof Object))
-return;if(object instanceof Array){for(var i=0;i<object.length;i++){func(object,i,object[i]);iterObjectFieldsRecursively(object[i],func);}
-return;}
-for(var key in object){var value=object[key];func(object,key,value);iterObjectFieldsRecursively(value,func);}}
-function invertArrayOfDicts(array,opt_dictGetter,opt_this){opt_this=opt_this||this;var result={};for(var i=0;i<array.length;i++){var item=array[i];if(item===undefined)
-continue;var dict=opt_dictGetter?opt_dictGetter.call(opt_this,item):item;if(dict===undefined)
-continue;for(var key in dict){var valueList=result[key];if(valueList===undefined)
-result[key]=valueList=new Array(array.length);valueList[i]=dict[key];}}
-return result;}
-function arrayToDict(array,valueToKeyFn,opt_this){opt_this=opt_this||this;var result={};var length=array.length;for(var i=0;i<length;i++){var value=array[i];var key=valueToKeyFn.call(opt_this,value);result[key]=value;}
-return result;}
-function identity(d){return d;}
-function findFirstIndexInArray(ary,opt_func,opt_this){var func=opt_func||identity;for(var i=0;i<ary.length;i++){if(func.call(opt_this,ary[i],i))
-return i;}
-return-1;}
-function findFirstInArray(ary,opt_func,opt_this){var i=findFirstIndexInArray(ary,opt_func,opt_func);if(i===-1)
-return undefined;return ary[i];}
-function findFirstKeyInDictMatching(dict,opt_func,opt_this){var func=opt_func||identity;for(var key in dict){if(func.call(opt_this,key,dict[key]))
-return key;}
-return undefined;}
-function mapValues(map){var values=[];for(var value of map.values())
-values.push(value);return values;}
-function iterMapItems(map,fn,opt_this){opt_this=opt_this||this;for(var key of map.keys())
-fn.call(opt_this,key,map.get(key));}
-return{asArray:asArray,concatenateArrays:concatenateArrays,concatenateObjects:concatenateObjects,compareArrays:compareArrays,comparePossiblyUndefinedValues:comparePossiblyUndefinedValues,compareNumericWithNaNs:compareNumericWithNaNs,dictionaryLength:dictionaryLength,dictionaryKeys:dictionaryKeys,dictionaryValues:dictionaryValues,dictionaryContainsValue:dictionaryContainsValue,group:group,iterItems:iterItems,mapItems:mapItems,filterItems:filterItems,iterObjectFieldsRecursively:iterObjectFieldsRecursively,invertArrayOfDicts:invertArrayOfDicts,arrayToDict:arrayToDict,identity:identity,findFirstIndexInArray:findFirstIndexInArray,findFirstInArray:findFirstInArray,findFirstKeyInDictMatching:findFirstKeyInDictMatching,mapValues:mapValues,iterMapItems:iterMapItems};});'use strict';tr.exportTo('tr.b',function(){function EventTarget(){}
-EventTarget.decorate=function(target){for(var k in EventTarget.prototype){if(k=='decorate')
-continue;var v=EventTarget.prototype[k];if(typeof v!=='function')
-continue;target[k]=v;}};EventTarget.prototype={addEventListener:function(type,handler){if(!this.listeners_)
-this.listeners_=Object.create(null);if(!(type in this.listeners_)){this.listeners_[type]=[handler];}else{var handlers=this.listeners_[type];if(handlers.indexOf(handler)<0)
-handlers.push(handler);}},removeEventListener:function(type,handler){if(!this.listeners_)
-return;if(type in this.listeners_){var handlers=this.listeners_[type];var index=handlers.indexOf(handler);if(index>=0){if(handlers.length==1)
-delete this.listeners_[type];else
-handlers.splice(index,1);}}},dispatchEvent:function(event){if(!this.listeners_)
-return true;var self=this;event.__defineGetter__('target',function(){return self;});var realPreventDefault=event.preventDefault;event.preventDefault=function(){realPreventDefault.call(this);this.rawReturnValue=false;};var type=event.type;var prevented=0;if(type in this.listeners_){var handlers=this.listeners_[type].concat();for(var i=0,handler;handler=handlers[i];i++){if(handler.handleEvent)
-prevented|=handler.handleEvent.call(handler,event)===false;else
-prevented|=handler.call(this,event)===false;}}
-return!prevented&&event.rawReturnValue;},hasEventListener:function(type){return this.listeners_[type]!==undefined;}};var EventTargetHelper={decorate:function(target){for(var k in EventTargetHelper){if(k=='decorate')
-continue;var v=EventTargetHelper[k];if(typeof v!=='function')
-continue;target[k]=v;}
-target.listenerCounts_={};},addEventListener:function(type,listener,useCapture){this.__proto__.addEventListener.call(this,type,listener,useCapture);if(this.listenerCounts_[type]===undefined)
-this.listenerCounts_[type]=0;this.listenerCounts_[type]++;},removeEventListener:function(type,listener,useCapture){this.__proto__.removeEventListener.call(this,type,listener,useCapture);this.listenerCounts_[type]--;},hasEventListener:function(type){return this.listenerCounts_[type]>0;}};return{EventTarget:EventTarget,EventTargetHelper:EventTargetHelper};});'use strict';tr.exportTo('tr.b',function(){var Event;if(tr.isHeadless){function HeadlessEvent(type,opt_bubbles,opt_preventable){this.type=type;this.bubbles=(opt_bubbles!==undefined?!!opt_bubbles:false);this.cancelable=(opt_preventable!==undefined?!!opt_preventable:false);this.defaultPrevented=false;this.cancelBubble=false;};HeadlessEvent.prototype={preventDefault:function(){this.defaultPrevented=true;},stopPropagation:function(){this.cancelBubble=true;}};Event=HeadlessEvent;}else{function TrEvent(type,opt_bubbles,opt_preventable){var e=tr.doc.createEvent('Event');e.initEvent(type,!!opt_bubbles,!!opt_preventable);e.__proto__=global.Event.prototype;return e;};TrEvent.prototype={__proto__:global.Event.prototype};Event=TrEvent;}
-function dispatchSimpleEvent(target,type,opt_bubbles,opt_cancelable){var e=new tr.b.Event(type,opt_bubbles,opt_cancelable);return target.dispatchEvent(e);}
-return{Event:Event,dispatchSimpleEvent:dispatchSimpleEvent};});'use strict';tr.exportTo('tr.b',function(){function RegisteredTypeInfo(constructor,metadata){this.constructor=constructor;this.metadata=metadata;};var BASIC_REGISTRY_MODE='BASIC_REGISTRY_MODE';var TYPE_BASED_REGISTRY_MODE='TYPE_BASED_REGISTRY_MODE';var ALL_MODES={BASIC_REGISTRY_MODE:true,TYPE_BASED_REGISTRY_MODE:true};function ExtensionRegistryOptions(mode){if(mode===undefined)
-throw new Error('Mode is required');if(!ALL_MODES[mode])
-throw new Error('Not a mode.');this.mode_=mode;this.defaultMetadata_={};this.defaultConstructor_=undefined;this.mandatoryBaseClass_=undefined;this.defaultTypeInfo_=undefined;this.frozen_=false;}
-ExtensionRegistryOptions.prototype={freeze:function(){if(this.frozen_)
-throw new Error('Frozen');this.frozen_=true;},get mode(){return this.mode_;},get defaultMetadata(){return this.defaultMetadata_;},set defaultMetadata(defaultMetadata){if(this.frozen_)
-throw new Error('Frozen');this.defaultMetadata_=defaultMetadata;this.defaultTypeInfo_=undefined;},get defaultConstructor(){return this.defaultConstructor_;},set defaultConstructor(defaultConstructor){if(this.frozen_)
-throw new Error('Frozen');this.defaultConstructor_=defaultConstructor;this.defaultTypeInfo_=undefined;},get defaultTypeInfo(){if(this.defaultTypeInfo_===undefined&&this.defaultConstructor_){this.defaultTypeInfo_=new RegisteredTypeInfo(this.defaultConstructor,this.defaultMetadata);}
-return this.defaultTypeInfo_;},validateConstructor:function(constructor){if(!this.mandatoryBaseClass)
-return;var curProto=constructor.prototype.__proto__;var ok=false;while(curProto){if(curProto===this.mandatoryBaseClass.prototype){ok=true;break;}
+return{initialize,exportTo,isExported,isDefined,showPanic,hasPanic,getPanicText,};})();tr.initialize();'use strict';tr.exportTo('tr.b',function(){function EventTarget(){}
+EventTarget.decorate=function(target){for(const k in EventTarget.prototype){if(k==='decorate')continue;const v=EventTarget.prototype[k];if(typeof v!=='function')continue;target[k]=v;}};EventTarget.prototype={addEventListener(type,handler){if(!this.listeners_){this.listeners_=Object.create(null);}
+if(!(type in this.listeners_)){this.listeners_[type]=[handler];}else{const handlers=this.listeners_[type];if(handlers.indexOf(handler)<0){handlers.push(handler);}}},removeEventListener(type,handler){if(!this.listeners_)return;if(type in this.listeners_){const handlers=this.listeners_[type];const index=handlers.indexOf(handler);if(index>=0){if(handlers.length===1){delete this.listeners_[type];}else{handlers.splice(index,1);}}}},dispatchEvent(event){if(!this.listeners_)return true;event.__defineGetter__('target',()=>this);const realPreventDefault=event.preventDefault;event.preventDefault=function(){realPreventDefault.call(this);this.rawReturnValue=false;};const type=event.type;let prevented=0;if(type in this.listeners_){const handlers=this.listeners_[type].concat();for(let i=0,handler;handler=handlers[i];i++){if(handler.handleEvent){prevented|=handler.handleEvent.call(handler,event)===false;}else{prevented|=handler.call(this,event)===false;}}}
+return!prevented&&event.rawReturnValue;},async dispatchAsync(event){if(!this.listeners_)return true;const listeners=this.listeners_[event.type];if(listeners===undefined)return;await Promise.all(listeners.slice().map(listener=>{if(listener.handleEvent){return listener.handleEvent.call(listener,event);}
+return listener.call(this,event);}));},hasEventListener(type){return(this.listeners_!==undefined&&this.listeners_[type]!==undefined);}};return{EventTarget,};});'use strict';tr.exportTo('tr.b',function(){function RegisteredTypeInfo(constructor,metadata){this.constructor=constructor;this.metadata=metadata;}
+const BASIC_REGISTRY_MODE='BASIC_REGISTRY_MODE';const TYPE_BASED_REGISTRY_MODE='TYPE_BASED_REGISTRY_MODE';const ALL_MODES={BASIC_REGISTRY_MODE:true,TYPE_BASED_REGISTRY_MODE:true};function ExtensionRegistryOptions(mode){if(mode===undefined){throw new Error('Mode is required');}
+if(!ALL_MODES[mode]){throw new Error('Not a mode.');}
+this.mode_=mode;this.defaultMetadata_={};this.defaultConstructor_=undefined;this.defaultTypeInfo_=undefined;this.frozen_=false;}
+ExtensionRegistryOptions.prototype={freeze(){if(this.frozen_){throw new Error('Frozen');}
+this.frozen_=true;},get mode(){return this.mode_;},get defaultMetadata(){return this.defaultMetadata_;},set defaultMetadata(defaultMetadata){if(this.frozen_){throw new Error('Frozen');}
+this.defaultMetadata_=defaultMetadata;this.defaultTypeInfo_=undefined;},get defaultConstructor(){return this.defaultConstructor_;},set defaultConstructor(defaultConstructor){if(this.frozen_){throw new Error('Frozen');}
+this.defaultConstructor_=defaultConstructor;this.defaultTypeInfo_=undefined;},get defaultTypeInfo(){if(this.defaultTypeInfo_===undefined&&this.defaultConstructor_){this.defaultTypeInfo_=new RegisteredTypeInfo(this.defaultConstructor,this.defaultMetadata);}
+return this.defaultTypeInfo_;},validateConstructor(constructor){if(!this.mandatoryBaseClass)return;let curProto=constructor.prototype.__proto__;let ok=false;while(curProto){if(curProto===this.mandatoryBaseClass.prototype){ok=true;break;}
 curProto=curProto.__proto__;}
-if(!ok)
-throw new Error(constructor+'must be subclass of '+registry);}};return{BASIC_REGISTRY_MODE:BASIC_REGISTRY_MODE,TYPE_BASED_REGISTRY_MODE:TYPE_BASED_REGISTRY_MODE,ExtensionRegistryOptions:ExtensionRegistryOptions,RegisteredTypeInfo:RegisteredTypeInfo};});'use strict';tr.exportTo('tr.b',function(){var RegisteredTypeInfo=tr.b.RegisteredTypeInfo;var ExtensionRegistryOptions=tr.b.ExtensionRegistryOptions;function decorateBasicExtensionRegistry(registry,extensionRegistryOptions){var savedStateStack=[];registry.registeredTypeInfos_=[];registry.register=function(constructor,opt_metadata){if(registry.findIndexOfRegisteredConstructor(constructor)!==undefined)
-throw new Error('Handler already registered for '+constructor);extensionRegistryOptions.validateConstructor(constructor);var metadata={};for(var k in extensionRegistryOptions.defaultMetadata)
-metadata[k]=extensionRegistryOptions.defaultMetadata[k];if(opt_metadata){for(var k in opt_metadata)
-metadata[k]=opt_metadata[k];}
-var typeInfo=new RegisteredTypeInfo(constructor,metadata);var e=new tr.b.Event('will-register');e.typeInfo=typeInfo;registry.dispatchEvent(e);registry.registeredTypeInfos_.push(typeInfo);e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.pushCleanStateBeforeTest=function(){savedStateStack.push(registry.registeredTypeInfos_);registry.registeredTypeInfos_=[];var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.popCleanStateAfterTest=function(){registry.registeredTypeInfos_=savedStateStack[0];savedStateStack.splice(0,1);var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.findIndexOfRegisteredConstructor=function(constructor){for(var i=0;i<registry.registeredTypeInfos_.length;i++)
-if(registry.registeredTypeInfos_[i].constructor==constructor)
-return i;return undefined;};registry.unregister=function(constructor){var foundIndex=registry.findIndexOfRegisteredConstructor(constructor);if(foundIndex===undefined)
-throw new Error(constructor+' not registered');registry.registeredTypeInfos_.splice(foundIndex,1);var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.getAllRegisteredTypeInfos=function(){return registry.registeredTypeInfos_;};registry.findTypeInfo=function(constructor){var foundIndex=this.findIndexOfRegisteredConstructor(constructor);if(foundIndex!==undefined)
-return this.registeredTypeInfos_[foundIndex];return undefined;};registry.findTypeInfoMatching=function(predicate,opt_this){opt_this=opt_this?opt_this:undefined;for(var i=0;i<registry.registeredTypeInfos_.length;++i){var typeInfo=registry.registeredTypeInfos_[i];if(predicate.call(opt_this,typeInfo))
-return typeInfo;}
-return extensionRegistryOptions.defaultTypeInfo;};registry.findTypeInfoWithName=function(name){if(typeof(name)!=='string')
-throw new Error('Name is not a string.');var typeInfo=registry.findTypeInfoMatching(function(ti){return ti.constructor.name===name;});if(typeInfo)
-return typeInfo;return undefined;};}
-return{_decorateBasicExtensionRegistry:decorateBasicExtensionRegistry};});'use strict';tr.exportTo('tr.b',function(){var categoryPartsFor={};function getCategoryParts(category){var parts=categoryPartsFor[category];if(parts!==undefined)
-return parts;parts=category.split(',');categoryPartsFor[category]=parts;return parts;}
-return{getCategoryParts:getCategoryParts};});'use strict';tr.exportTo('tr.b',function(){var getCategoryParts=tr.b.getCategoryParts;var RegisteredTypeInfo=tr.b.RegisteredTypeInfo;var ExtensionRegistryOptions=tr.b.ExtensionRegistryOptions;function decorateTypeBasedExtensionRegistry(registry,extensionRegistryOptions){var savedStateStack=[];registry.registeredTypeInfos_=[];registry.categoryPartToTypeInfoMap_={};registry.typeNameToTypeInfoMap_={};registry.register=function(constructor,metadata){extensionRegistryOptions.validateConstructor(constructor);var typeInfo=new RegisteredTypeInfo(constructor,metadata||extensionRegistryOptions.defaultMetadata);typeInfo.typeNames=[];typeInfo.categoryParts=[];if(metadata&&metadata.typeName)
-typeInfo.typeNames.push(metadata.typeName);if(metadata&&metadata.typeNames){typeInfo.typeNames.push.apply(typeInfo.typeNames,metadata.typeNames);}
+if(!ok){throw new Error(constructor+'must be subclass of '+registry);}}};return{BASIC_REGISTRY_MODE,TYPE_BASED_REGISTRY_MODE,ExtensionRegistryOptions,RegisteredTypeInfo,};});'use strict';tr.exportTo('tr.b',function(){let Event;if(tr.isHeadless){function HeadlessEvent(type,opt_bubbles,opt_preventable){this.type=type;this.bubbles=(opt_bubbles!==undefined?!!opt_bubbles:false);this.cancelable=(opt_preventable!==undefined?!!opt_preventable:false);this.defaultPrevented=false;this.cancelBubble=false;}
+HeadlessEvent.prototype={preventDefault(){this.defaultPrevented=true;},stopPropagation(){this.cancelBubble=true;}};Event=HeadlessEvent;}else{function TrEvent(type,opt_bubbles,opt_preventable){const e=tr.doc.createEvent('Event');e.initEvent(type,!!opt_bubbles,!!opt_preventable);e.__proto__=global.Event.prototype;return e;}
+TrEvent.prototype={__proto__:global.Event.prototype};Event=TrEvent;}
+function dispatchSimpleEvent(target,type,opt_bubbles,opt_cancelable,opt_fields){const e=new tr.b.Event(type,opt_bubbles,opt_cancelable);Object.assign(e,opt_fields);return target.dispatchEvent(e);}
+async function dispatchSimpleEventAsync(target,type,opt_fields){const e=new tr.b.Event(type,false,false);Object.assign(e,opt_fields);return await target.dispatchAsync(e);}
+return{Event,dispatchSimpleEvent,dispatchSimpleEventAsync,};});'use strict';tr.exportTo('tr.b',function(){const RegisteredTypeInfo=tr.b.RegisteredTypeInfo;const ExtensionRegistryOptions=tr.b.ExtensionRegistryOptions;function decorateBasicExtensionRegistry(registry,extensionRegistryOptions){const savedStateStack=[];registry.registeredTypeInfos_=[];registry.register=function(constructor,opt_metadata){if(registry.findIndexOfRegisteredConstructor(constructor)!==undefined){throw new Error('Handler already registered for '+constructor);}
+extensionRegistryOptions.validateConstructor(constructor);const metadata={};for(const k in extensionRegistryOptions.defaultMetadata){metadata[k]=extensionRegistryOptions.defaultMetadata[k];}
+if(opt_metadata){for(const k in opt_metadata){metadata[k]=opt_metadata[k];}}
+const typeInfo=new RegisteredTypeInfo(constructor,metadata);let e=new tr.b.Event('will-register');e.typeInfo=typeInfo;registry.dispatchEvent(e);registry.registeredTypeInfos_.push(typeInfo);e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.pushCleanStateBeforeTest=function(){savedStateStack.push(registry.registeredTypeInfos_);registry.registeredTypeInfos_=[];const e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.popCleanStateAfterTest=function(){registry.registeredTypeInfos_=savedStateStack[0];savedStateStack.splice(0,1);const e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.findIndexOfRegisteredConstructor=function(constructor){for(let i=0;i<registry.registeredTypeInfos_.length;i++){if(registry.registeredTypeInfos_[i].constructor===constructor){return i;}}
+return undefined;};registry.unregister=function(constructor){const foundIndex=registry.findIndexOfRegisteredConstructor(constructor);if(foundIndex===undefined){throw new Error(constructor+' not registered');}
+registry.registeredTypeInfos_.splice(foundIndex,1);const e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.getAllRegisteredTypeInfos=function(){return registry.registeredTypeInfos_;};registry.findTypeInfo=function(constructor){const foundIndex=this.findIndexOfRegisteredConstructor(constructor);if(foundIndex!==undefined){return this.registeredTypeInfos_[foundIndex];}
+return undefined;};registry.findTypeInfoMatching=function(predicate,opt_this){opt_this=opt_this?opt_this:undefined;for(let i=0;i<registry.registeredTypeInfos_.length;++i){const typeInfo=registry.registeredTypeInfos_[i];if(predicate.call(opt_this,typeInfo)){return typeInfo;}}
+return extensionRegistryOptions.defaultTypeInfo;};registry.findTypeInfoWithName=function(name){if(typeof(name)!=='string'){throw new Error('Name is not a string.');}
+const typeInfo=registry.findTypeInfoMatching(function(ti){return ti.constructor.name===name;});if(typeInfo)return typeInfo;return undefined;};}
+return{_decorateBasicExtensionRegistry:decorateBasicExtensionRegistry};});'use strict';tr.exportTo('tr.b',function(){const categoryPartsFor={};function getCategoryParts(category){let parts=categoryPartsFor[category];if(parts!==undefined)return parts;parts=category.split(',');categoryPartsFor[category]=parts;return parts;}
+return{getCategoryParts,};});'use strict';tr.exportTo('tr.b',function(){const getCategoryParts=tr.b.getCategoryParts;const RegisteredTypeInfo=tr.b.RegisteredTypeInfo;const ExtensionRegistryOptions=tr.b.ExtensionRegistryOptions;function decorateTypeBasedExtensionRegistry(registry,extensionRegistryOptions){const savedStateStack=[];registry.registeredTypeInfos_=[];registry.categoryPartToTypeInfoMap_=new Map();registry.typeNameToTypeInfoMap_=new Map();registry.register=function(constructor,metadata){extensionRegistryOptions.validateConstructor(constructor);const typeInfo=new RegisteredTypeInfo(constructor,metadata||extensionRegistryOptions.defaultMetadata);typeInfo.typeNames=[];typeInfo.categoryParts=[];if(metadata&&metadata.typeName){typeInfo.typeNames.push(metadata.typeName);}
+if(metadata&&metadata.typeNames){typeInfo.typeNames.push.apply(typeInfo.typeNames,metadata.typeNames);}
 if(metadata&&metadata.categoryParts){typeInfo.categoryParts.push.apply(typeInfo.categoryParts,metadata.categoryParts);}
-if(typeInfo.typeNames.length===0&&typeInfo.categoryParts.length===0)
-throw new Error('typeName or typeNames must be provided');typeInfo.typeNames.forEach(function(typeName){if(registry.typeNameToTypeInfoMap_[typeName])
-throw new Error('typeName '+typeName+' already registered');});typeInfo.categoryParts.forEach(function(categoryPart){if(registry.categoryPartToTypeInfoMap_[categoryPart]){throw new Error('categoryPart '+categoryPart+' already registered');}});var e=new tr.b.Event('will-register');e.typeInfo=typeInfo;registry.dispatchEvent(e);typeInfo.typeNames.forEach(function(typeName){registry.typeNameToTypeInfoMap_[typeName]=typeInfo;});typeInfo.categoryParts.forEach(function(categoryPart){registry.categoryPartToTypeInfoMap_[categoryPart]=typeInfo;});registry.registeredTypeInfos_.push(typeInfo);var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.pushCleanStateBeforeTest=function(){savedStateStack.push({registeredTypeInfos:registry.registeredTypeInfos_,typeNameToTypeInfoMap:registry.typeNameToTypeInfoMap_,categoryPartToTypeInfoMap:registry.categoryPartToTypeInfoMap_});registry.registeredTypeInfos_=[];registry.typeNameToTypeInfoMap_={};registry.categoryPartToTypeInfoMap_={};var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.popCleanStateAfterTest=function(){var state=savedStateStack[0];savedStateStack.splice(0,1);registry.registeredTypeInfos_=state.registeredTypeInfos;registry.typeNameToTypeInfoMap_=state.typeNameToTypeInfoMap;registry.categoryPartToTypeInfoMap_=state.categoryPartToTypeInfoMap;var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.unregister=function(constructor){var typeInfoIndex=-1;for(var i=0;i<registry.registeredTypeInfos_.length;i++){if(registry.registeredTypeInfos_[i].constructor==constructor){typeInfoIndex=i;break;}}
-if(typeInfoIndex===-1)
-throw new Error(constructor+' not registered');var typeInfo=registry.registeredTypeInfos_[typeInfoIndex];registry.registeredTypeInfos_.splice(typeInfoIndex,1);typeInfo.typeNames.forEach(function(typeName){delete registry.typeNameToTypeInfoMap_[typeName];});typeInfo.categoryParts.forEach(function(categoryPart){delete registry.categoryPartToTypeInfoMap_[categoryPart];});var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.getTypeInfo=function(category,typeName){if(category){var categoryParts=getCategoryParts(category);for(var i=0;i<categoryParts.length;i++){var categoryPart=categoryParts[i];if(registry.categoryPartToTypeInfoMap_[categoryPart])
-return registry.categoryPartToTypeInfoMap_[categoryPart];}}
-if(registry.typeNameToTypeInfoMap_[typeName])
-return registry.typeNameToTypeInfoMap_[typeName];return extensionRegistryOptions.defaultTypeInfo;};registry.getConstructor=function(category,typeName){var typeInfo=registry.getTypeInfo(category,typeName);if(typeInfo)
-return typeInfo.constructor;return undefined;};}
-return{_decorateTypeBasedExtensionRegistry:decorateTypeBasedExtensionRegistry};});'use strict';tr.exportTo('tr.b',function(){function decorateExtensionRegistry(registry,registryOptions){if(registry.register)
-throw new Error('Already has registry');registryOptions.freeze();if(registryOptions.mode==tr.b.BASIC_REGISTRY_MODE){tr.b._decorateBasicExtensionRegistry(registry,registryOptions);}else if(registryOptions.mode==tr.b.TYPE_BASED_REGISTRY_MODE){tr.b._decorateTypeBasedExtensionRegistry(registry,registryOptions);}else{throw new Error('Unrecognized mode');}
-if(registry.addEventListener===undefined)
-tr.b.EventTarget.decorate(registry);}
-return{decorateExtensionRegistry:decorateExtensionRegistry};});'use strict';tr.exportTo('tr.importer',function(){function Importer(){}
-Importer.prototype={__proto__:Object.prototype,get importerName(){return'Importer';},isTraceDataContainer:function(){return false;},extractSubtraces:function(){return[];},importClockSyncMarkers:function(){},importEvents:function(){},importSampleData:function(){},finalizeImport:function(){}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Importer;tr.b.decorateExtensionRegistry(Importer,options);Importer.findImporterFor=function(eventData){var typeInfo=Importer.findTypeInfoMatching(function(ti){return ti.constructor.canImport(eventData);});if(typeInfo)
-return typeInfo.constructor;return undefined;};return{Importer:Importer};});'use strict';tr.exportTo('tr.e.importer.gcloud_trace',function(){function GcloudTraceImporter(model,eventData){this.importPriority=2;this.eventData_=eventData;}
-GcloudTraceImporter.canImport=function(eventData){if(typeof(eventData)!=='string'&&!(eventData instanceof String))
-return false;var normalizedEventData=eventData.slice(0,20).replace(/\s/g,'');if(normalizedEventData.length<14)
-return false;return normalizedEventData.slice(0,14)=='{"projectId":"';};GcloudTraceImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'GcloudTraceImporter';},extractSubtraces:function(){var traceEvents=this.createEventsForTrace();return traceEvents?[traceEvents]:[];},createEventsForTrace:function(){var events=[];var trace=JSON.parse(this.eventData_);var spanLength=trace.spans.length;for(var i=0;i<spanLength;i++){events.push(this.createEventForSpan(trace.traceId,trace.spans[i]));}
-return{'traceEvents':events};},createEventForSpan:function(traceId,span){var newArgs={};if(span.labels){newArgs=JSON.parse(JSON.stringify(span.labels));}
+if(typeInfo.typeNames.length===0&&typeInfo.categoryParts.length===0){throw new Error('typeName or typeNames must be provided');}
+typeInfo.typeNames.forEach(function(typeName){if(registry.typeNameToTypeInfoMap_.has(typeName)){throw new Error('typeName '+typeName+' already registered');}});typeInfo.categoryParts.forEach(function(categoryPart){if(registry.categoryPartToTypeInfoMap_.has(categoryPart)){throw new Error('categoryPart '+categoryPart+' already registered');}});let e=new tr.b.Event('will-register');e.typeInfo=typeInfo;registry.dispatchEvent(e);typeInfo.typeNames.forEach(function(typeName){registry.typeNameToTypeInfoMap_.set(typeName,typeInfo);});typeInfo.categoryParts.forEach(function(categoryPart){registry.categoryPartToTypeInfoMap_.set(categoryPart,typeInfo);});registry.registeredTypeInfos_.push(typeInfo);e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.pushCleanStateBeforeTest=function(){savedStateStack.push({registeredTypeInfos:registry.registeredTypeInfos_,typeNameToTypeInfoMap:registry.typeNameToTypeInfoMap_,categoryPartToTypeInfoMap:registry.categoryPartToTypeInfoMap_});registry.registeredTypeInfos_=[];registry.typeNameToTypeInfoMap_=new Map();registry.categoryPartToTypeInfoMap_=new Map();const e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.popCleanStateAfterTest=function(){const state=savedStateStack[0];savedStateStack.splice(0,1);registry.registeredTypeInfos_=state.registeredTypeInfos;registry.typeNameToTypeInfoMap_=state.typeNameToTypeInfoMap;registry.categoryPartToTypeInfoMap_=state.categoryPartToTypeInfoMap;const e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.unregister=function(constructor){let typeInfoIndex=-1;for(let i=0;i<registry.registeredTypeInfos_.length;i++){if(registry.registeredTypeInfos_[i].constructor===constructor){typeInfoIndex=i;break;}}
+if(typeInfoIndex===-1){throw new Error(constructor+' not registered');}
+const typeInfo=registry.registeredTypeInfos_[typeInfoIndex];registry.registeredTypeInfos_.splice(typeInfoIndex,1);typeInfo.typeNames.forEach(function(typeName){registry.typeNameToTypeInfoMap_.delete(typeName);});typeInfo.categoryParts.forEach(function(categoryPart){registry.categoryPartToTypeInfoMap_.delete(categoryPart);});const e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.getTypeInfo=function(category,typeName){if(category){const categoryParts=getCategoryParts(category);for(let i=0;i<categoryParts.length;i++){const categoryPart=categoryParts[i];const typeInfo=registry.categoryPartToTypeInfoMap_.get(categoryPart);if(typeInfo!==undefined)return typeInfo;}}
+const typeInfo=registry.typeNameToTypeInfoMap_.get(typeName);if(typeInfo!==undefined)return typeInfo;return extensionRegistryOptions.defaultTypeInfo;};registry.getConstructor=function(category,typeName){const typeInfo=registry.getTypeInfo(category,typeName);if(typeInfo)return typeInfo.constructor;return undefined;};}
+return{_decorateTypeBasedExtensionRegistry:decorateTypeBasedExtensionRegistry};});'use strict';tr.exportTo('tr.b',function(){const URL_REGEX=/^(https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b|file:\/\/)([-a-zA-Z0-9@:%_\+.~#?&//=]*)$/;function deepCopy(value){if(!(value instanceof Object)){if(value===undefined||value===null)return value;if(typeof value==='string')return value.substring();if(typeof value==='boolean')return value;if(typeof value==='number')return value;throw new Error('Unrecognized: '+typeof value);}
+const object=value;if(object instanceof Array){const res=new Array(object.length);for(let i=0;i<object.length;i++){res[i]=deepCopy(object[i]);}
+return res;}
+if(object.__proto__!==Object.prototype){throw new Error('Can only clone simple types');}
+const res={};for(const key in object){res[key]=deepCopy(object[key]);}
+return res;}
+function normalizeException(e){if(e===undefined||e===null){return{typeName:'UndefinedError',message:'Unknown: null or undefined exception',stack:'Unknown'};}
+if(typeof(e)==='string'){return{typeName:'StringError',message:e,stack:[e]};}
+let typeName;if(e.name){typeName=e.name;}else if(e.constructor){if(e.constructor.name){typeName=e.constructor.name;}else{typeName='AnonymousError';}}else{typeName='ErrorWithNoConstructor';}
+const msg=e.message?e.message:'Unknown';return{typeName,message:msg,stack:e.stack?e.stack:[msg]};}
+function stackTraceAsString(){return new Error().stack+'';}
+function stackTrace(){let stack=stackTraceAsString();stack=stack.split('\n');return stack.slice(2);}
+function getUsingPath(path,fromDict){const parts=path.split('.');let cur=fromDict;for(let part;parts.length&&(part=parts.shift());){if(!parts.length){return cur[part];}else if(part in cur){cur=cur[part];}else{return undefined;}}
+return undefined;}
+function formatDate(date){return date.toISOString().replace('T',' ').slice(0,19);}
+function numberToJson(n){if(isNaN(n))return'NaN';if(n===Infinity)return'Infinity';if(n===-Infinity)return'-Infinity';return n;}
+function numberFromJson(n){if(n==='NaN'||n===null)return NaN;if(n==='Infinity')return Infinity;if(n==='-Infinity')return-Infinity;return n;}
+function runLengthEncoding(ary){const encodedArray=[];for(const element of ary){if(encodedArray.length===0||encodedArray[encodedArray.length-1].value!==element){encodedArray.push({value:element,count:1,});}else{encodedArray[encodedArray.length-1].count+=1;}}
+return encodedArray;}
+function isUrl(s){return typeof(s)==='string'&&s.match(URL_REGEX)!==null;}
+function getOnlyElement(iterable){const iterator=iterable[Symbol.iterator]();const firstIteration=iterator.next();if(firstIteration.done){throw new Error('getOnlyElement was passed an empty iterable.');}
+const secondIteration=iterator.next();if(!secondIteration.done){throw new Error('getOnlyElement was passed an iterable with multiple elements.');}
+return firstIteration.value;}
+function getFirstElement(iterable){const iterator=iterable[Symbol.iterator]();const result=iterator.next();if(result.done){throw new Error('getFirstElement was passed an empty iterable.');}
+return result.value;}
+function compareArrays(x,y,elementCmp){const minLength=Math.min(x.length,y.length);let i;for(i=0;i<minLength;i++){const tmp=elementCmp(x[i],y[i]);if(tmp)return tmp;}
+if(x.length===y.length)return 0;if(x[i]===undefined)return-1;return 1;}
+function groupIntoMap(ary,callback,opt_this,opt_arrayConstructor){const arrayConstructor=opt_arrayConstructor||Array;const results=new Map();for(const element of ary){const key=callback.call(opt_this,element);let items=results.get(key);if(items===undefined){items=new arrayConstructor();results.set(key,items);}
+items.push(element);}
+return results;}
+function inPlaceFilter(array,predicate,opt_this){opt_this=opt_this||this;let nextPosition=0;for(let i=0;i<array.length;i++){if(!predicate.call(opt_this,array[i],i))continue;if(nextPosition<i){array[nextPosition]=array[i];}
+nextPosition++;}
+if(nextPosition<array.length){array.length=nextPosition;}}
+function invertArrayOfDicts(array,opt_dictGetter,opt_this){opt_this=opt_this||this;const result={};for(let i=0;i<array.length;i++){const item=array[i];if(item===undefined)continue;const dict=opt_dictGetter?opt_dictGetter.call(opt_this,item):item;if(dict===undefined)continue;for(const key in dict){let valueList=result[key];if(valueList===undefined){result[key]=valueList=new Array(array.length);}
+valueList[i]=dict[key];}}
+return result;}
+function setsEqual(a,b){if(!(a instanceof Set)||!(b instanceof Set))return false;if(a.size!==b.size)return false;for(const x of a){if(!b.has(x))return false;}
+return true;}
+function findLowIndexInSortedArray(ary,mapFn,loVal){if(ary.length===0)return 1;let low=0;let high=ary.length-1;let i;let comparison;let hitPos=-1;while(low<=high){i=Math.floor((low+high)/2);comparison=mapFn(ary[i])-loVal;if(comparison<0){low=i+1;continue;}else if(comparison>0){high=i-1;continue;}else{hitPos=i;high=i-1;}}
+return hitPos!==-1?hitPos:low;}
+function findIndexInSortedIntervals(ary,mapLoFn,mapWidthFn,loVal){const first=findLowIndexInSortedArray(ary,mapLoFn,loVal);if(first===0){if(loVal>=mapLoFn(ary[0])&&loVal<mapLoFn(ary[0])+mapWidthFn(ary[0],0)){return 0;}
+return-1;}
+if(first<ary.length){if(loVal>=mapLoFn(ary[first])&&loVal<mapLoFn(ary[first])+mapWidthFn(ary[first],first)){return first;}
+if(loVal>=mapLoFn(ary[first-1])&&loVal<mapLoFn(ary[first-1])+
+mapWidthFn(ary[first-1],first-1)){return first-1;}
+return ary.length;}
+if(first===ary.length){if(loVal>=mapLoFn(ary[first-1])&&loVal<mapLoFn(ary[first-1])+
+mapWidthFn(ary[first-1],first-1)){return first-1;}
+return ary.length;}
+return ary.length;}
+function findIndexInSortedClosedIntervals(ary,mapLoFn,mapHiFn,val){const i=findLowIndexInSortedArray(ary,mapLoFn,val);if(i===0){if(val>=mapLoFn(ary[0],0)&&val<=mapHiFn(ary[0],0)){return 0;}
+return-1;}
+if(i<ary.length){if(val>=mapLoFn(ary[i-1],i-1)&&val<=mapHiFn(ary[i-1],i-1)){return i-1;}
+if(val>=mapLoFn(ary[i],i)&&val<=mapHiFn(ary[i],i)){return i;}
+return ary.length;}
+if(i===ary.length){if(val>=mapLoFn(ary[i-1],i-1)&&val<=mapHiFn(ary[i-1],i-1)){return i-1;}
+return ary.length;}
+return ary.length;}
+function iterateOverIntersectingIntervals(ary,mapLoFn,mapWidthFn,loVal,hiVal,cb){if(ary.length===0)return;if(loVal>hiVal)return;let i=findLowIndexInSortedArray(ary,mapLoFn,loVal);if(i===-1){return;}
+if(i>0){const hi=mapLoFn(ary[i-1])+mapWidthFn(ary[i-1],i-1);if(hi>=loVal){cb(ary[i-1],i-1);}}
+if(i===ary.length){return;}
+for(let n=ary.length;i<n;i++){const lo=mapLoFn(ary[i]);if(lo>=hiVal)break;cb(ary[i],i);}}
+function findClosestElementInSortedArray(ary,mapFn,val,maxDiff){if(ary.length===0)return null;let aftIdx=findLowIndexInSortedArray(ary,mapFn,val);const befIdx=aftIdx>0?aftIdx-1:0;if(aftIdx===ary.length)aftIdx-=1;const befDiff=Math.abs(val-mapFn(ary[befIdx]));const aftDiff=Math.abs(val-mapFn(ary[aftIdx]));if(befDiff>maxDiff&&aftDiff>maxDiff)return null;const idx=befDiff<aftDiff?befIdx:aftIdx;return ary[idx];}
+function findClosestIntervalInSortedIntervals(ary,mapLoFn,mapHiFn,val,maxDiff){if(ary.length===0)return null;let idx=findLowIndexInSortedArray(ary,mapLoFn,val);if(idx>0)idx-=1;const hiInt=ary[idx];let loInt=hiInt;if(val>mapHiFn(hiInt)&&idx+1<ary.length){loInt=ary[idx+1];}
+const loDiff=Math.abs(val-mapLoFn(loInt));const hiDiff=Math.abs(val-mapHiFn(hiInt));if(loDiff>maxDiff&&hiDiff>maxDiff)return null;if(loDiff<hiDiff)return loInt;return hiInt;}
+function findFirstTrueIndexInSortedArray(array,test){let i0=0;let i1=array.length;while(i0<i1){const i=Math.trunc((i0+i1)/2);if(test(array[i])){i1=i;}else{i0=i+1;}}
+return i1;}
+return{compareArrays,deepCopy,findClosestElementInSortedArray,findClosestIntervalInSortedIntervals,findFirstTrueIndexInSortedArray,findIndexInSortedClosedIntervals,findIndexInSortedIntervals,findLowIndexInSortedArray,formatDate,getFirstElement,getOnlyElement,getUsingPath,groupIntoMap,inPlaceFilter,invertArrayOfDicts,isUrl,iterateOverIntersectingIntervals,normalizeException,numberFromJson,numberToJson,runLengthEncoding,setsEqual,stackTrace,stackTraceAsString,};});'use strict';tr.exportTo('tr.b',function(){function decorateExtensionRegistry(registry,registryOptions){if(registry.register){throw new Error('Already has registry');}
+registryOptions.freeze();if(registryOptions.mode===tr.b.BASIC_REGISTRY_MODE){tr.b._decorateBasicExtensionRegistry(registry,registryOptions);}else if(registryOptions.mode===tr.b.TYPE_BASED_REGISTRY_MODE){tr.b._decorateTypeBasedExtensionRegistry(registry,registryOptions);}else{throw new Error('Unrecognized mode');}
+if(registry.addEventListener===undefined){tr.b.EventTarget.decorate(registry);}}
+return{decorateExtensionRegistry,};});'use strict';tr.exportTo('tr.importer',function(){function Importer(){}
+Importer.prototype={__proto__:Object.prototype,get importerName(){return'Importer';},isTraceDataContainer(){return false;},extractSubtraces(){return[];},importClockSyncMarkers(){},importEvents(){},importSampleData(){},finalizeImport(){}};const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Importer;tr.b.decorateExtensionRegistry(Importer,options);Importer.findImporterFor=function(eventData){const typeInfo=Importer.findTypeInfoMatching(function(ti){return ti.constructor.canImport(eventData);});if(typeInfo){return typeInfo.constructor;}
+return undefined;};return{Importer,};});'use strict';tr.exportTo('tr.e.importer.gcloud_trace',function(){function GcloudTraceImporter(model,eventData){this.importPriority=2;this.eventData_=eventData;}
+GcloudTraceImporter.canImport=function(eventData){if(typeof(eventData)!=='string'&&!(eventData instanceof String)){return false;}
+const normalizedEventData=eventData.slice(0,20).replace(/\s/g,'');if(normalizedEventData.length<14)return false;return normalizedEventData.slice(0,14)==='{"projectId":"';};GcloudTraceImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'GcloudTraceImporter';},extractSubtraces(){const traceEvents=this.createEventsForTrace();return traceEvents?[traceEvents]:[];},createEventsForTrace(){const events=[];const trace=JSON.parse(this.eventData_);const spanLength=trace.spans.length;for(let i=0;i<spanLength;i++){events.push(this.createEventForSpan(trace.traceId,trace.spans[i]));}
+return{'traceEvents':events};},createEventForSpan(traceId,span){let newArgs={};if(span.labels){newArgs=JSON.parse(JSON.stringify(span.labels));}
 newArgs['Span ID']=span.spanId;newArgs['Start Time']=span.startTime;newArgs['End Time']=span.endTime;if(span.parentSpanId){newArgs['Parent Span ID']=span.parentSpanId;}
-return{name:span.name,args:newArgs,pid:traceId,ts:Date.parse(span.startTime)*1000,dur:(Date.parse(span.endTime)-Date.parse(span.startTime))*1000,cat:'tracespan',tid:traceId,ph:'X'};}};tr.importer.Importer.register(GcloudTraceImporter);return{GcloudTraceImporter:GcloudTraceImporter};});'use strict';tr.exportTo('tr.b',function(){function convertEventsToRanges(events){return events.map(function(event){return tr.b.Range.fromExplicitRange(event.start,event.end);});}
-function mergeRanges(inRanges,mergeThreshold,mergeFunction){var remainingEvents=inRanges.slice();remainingEvents.sort(function(x,y){return x.min-y.min;});if(remainingEvents.length<=1){var merged=[];if(remainingEvents.length==1){merged.push(mergeFunction(remainingEvents));}
+return{name:span.name,args:newArgs,pid:traceId,ts:Date.parse(span.startTime)*1000,dur:(Date.parse(span.endTime)-Date.parse(span.startTime))*1000,cat:'tracespan',tid:traceId,ph:'X'};}};tr.importer.Importer.register(GcloudTraceImporter);return{GcloudTraceImporter,};});'use strict';tr.exportTo('tr.b.math',function(){function convertEventsToRanges(events){return events.map(function(event){return tr.b.math.Range.fromExplicitRange(event.start,event.end);});}
+function mergeRanges(inRanges,mergeThreshold,mergeFunction){const remainingEvents=inRanges.slice();remainingEvents.sort(function(x,y){return x.min-y.min;});if(remainingEvents.length<=1){const merged=[];if(remainingEvents.length===1){merged.push(mergeFunction(remainingEvents));}
 return merged;}
-var mergedEvents=[];var currentMergeBuffer=[];var rightEdge;function beginMerging(){currentMergeBuffer.push(remainingEvents[0]);remainingEvents.splice(0,1);rightEdge=currentMergeBuffer[0].max;}
-function flushCurrentMergeBuffer(){if(currentMergeBuffer.length==0)
-return;mergedEvents.push(mergeFunction(currentMergeBuffer));currentMergeBuffer=[];if(remainingEvents.length!=0)
-beginMerging();}
-beginMerging();while(remainingEvents.length){var currentEvent=remainingEvents[0];var distanceFromRightEdge=currentEvent.min-rightEdge;if(distanceFromRightEdge<mergeThreshold){rightEdge=Math.max(rightEdge,currentEvent.max);remainingEvents.splice(0,1);currentMergeBuffer.push(currentEvent);continue;}
+const mergedEvents=[];let currentMergeBuffer=[];let rightEdge;function beginMerging(){currentMergeBuffer.push(remainingEvents[0]);remainingEvents.splice(0,1);rightEdge=currentMergeBuffer[0].max;}
+function flushCurrentMergeBuffer(){if(currentMergeBuffer.length===0)return;mergedEvents.push(mergeFunction(currentMergeBuffer));currentMergeBuffer=[];if(remainingEvents.length!==0)beginMerging();}
+beginMerging();while(remainingEvents.length){const currentEvent=remainingEvents[0];const distanceFromRightEdge=currentEvent.min-rightEdge;if(distanceFromRightEdge<mergeThreshold){rightEdge=Math.max(rightEdge,currentEvent.max);remainingEvents.splice(0,1);currentMergeBuffer.push(currentEvent);continue;}
 flushCurrentMergeBuffer();}
 flushCurrentMergeBuffer();return mergedEvents;}
-function findEmptyRangesBetweenRanges(inRanges,opt_totalRange){if(opt_totalRange&&opt_totalRange.isEmpty)
-opt_totalRange=undefined;var emptyRanges=[];if(!inRanges.length){if(opt_totalRange)
-emptyRanges.push(opt_totalRange);return emptyRanges;}
-inRanges=inRanges.slice();inRanges.sort(function(x,y){return x.min-y.min;});if(opt_totalRange&&(opt_totalRange.min<inRanges[0].min)){emptyRanges.push(tr.b.Range.fromExplicitRange(opt_totalRange.min,inRanges[0].min));}
-inRanges.forEach(function(range,index){for(var otherIndex=0;otherIndex<inRanges.length;++otherIndex){if(index===otherIndex)
-continue;var other=inRanges[otherIndex];if(other.min>range.max){emptyRanges.push(tr.b.Range.fromExplicitRange(range.max,other.min));return;}
+function findEmptyRangesBetweenRanges(inRanges,opt_totalRange){if(opt_totalRange&&opt_totalRange.isEmpty)opt_totalRange=undefined;const emptyRanges=[];if(!inRanges.length){if(opt_totalRange)emptyRanges.push(opt_totalRange);return emptyRanges;}
+inRanges=inRanges.slice();inRanges.sort(function(x,y){return x.min-y.min;});if(opt_totalRange&&(opt_totalRange.min<inRanges[0].min)){emptyRanges.push(tr.b.math.Range.fromExplicitRange(opt_totalRange.min,inRanges[0].min));}
+inRanges.forEach(function(range,index){for(let otherIndex=0;otherIndex<inRanges.length;++otherIndex){if(index===otherIndex)continue;const other=inRanges[otherIndex];if(other.min>range.max){emptyRanges.push(tr.b.math.Range.fromExplicitRange(range.max,other.min));return;}
 if(other.max>range.max){return;}}
-if(opt_totalRange&&(range.max<opt_totalRange.max)){emptyRanges.push(tr.b.Range.fromExplicitRange(range.max,opt_totalRange.max));}});return emptyRanges;}
-return{convertEventsToRanges:convertEventsToRanges,findEmptyRangesBetweenRanges:findEmptyRangesBetweenRanges,mergeRanges:mergeRanges};});'use strict';tr.exportTo('tr.b',function(){function Range(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;};Range.prototype={__proto__:Object.prototype,reset:function(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;},get isEmpty(){return this.isEmpty_;},addRange:function(range){if(range.isEmpty)
-return;this.addValue(range.min);this.addValue(range.max);},addValue:function(value){if(this.isEmpty_){this.max_=value;this.min_=value;this.isEmpty_=false;return;}
-this.max_=Math.max(this.max_,value);this.min_=Math.min(this.min_,value);},set min(min){this.isEmpty_=false;this.min_=min;},get min(){if(this.isEmpty_)
-return undefined;return this.min_;},get max(){if(this.isEmpty_)
-return undefined;return this.max_;},set max(max){this.isEmpty_=false;this.max_=max;},get range(){if(this.isEmpty_)
-return undefined;return this.max_-this.min_;},get center(){return(this.min_+this.max_)*0.5;},get duration(){if(this.isEmpty_)
-return 0;return this.max_-this.min_;},equals:function(that){if(this.isEmpty&&that.isEmpty)
-return true;if(this.isEmpty!=that.isEmpty)
-return false;return this.min===that.min&&this.max===that.max;},containsExplicitRangeInclusive:function(min,max){if(this.isEmpty)
-return false;return this.min_<=min&&max<=this.max_;},containsExplicitRangeExclusive:function(min,max){if(this.isEmpty)
-return false;return this.min_<min&&max<this.max_;},intersectsExplicitRangeInclusive:function(min,max){if(this.isEmpty)
-return false;return this.min_<=max&&min<=this.max_;},intersectsExplicitRangeExclusive:function(min,max){if(this.isEmpty)
-return false;return this.min_<max&&min<this.max_;},containsRangeInclusive:function(range){if(range.isEmpty)
-return false;return this.containsExplicitRangeInclusive(range.min_,range.max_);},containsRangeExclusive:function(range){if(range.isEmpty)
-return false;return this.containsExplicitRangeExclusive(range.min_,range.max_);},intersectsRangeInclusive:function(range){if(range.isEmpty)
-return false;return this.intersectsExplicitRangeInclusive(range.min_,range.max_);},intersectsRangeExclusive:function(range){if(range.isEmpty)
-return false;return this.intersectsExplicitRangeExclusive(range.min_,range.max_);},findIntersection:function(range){if(this.isEmpty||range.isEmpty)
-return new Range();var min=Math.max(this.min,range.min);var max=Math.min(this.max,range.max);if(max<min)
-return new Range();return Range.fromExplicitRange(min,max);},toJSON:function(){if(this.isEmpty_)
-return{isEmpty:true};return{isEmpty:false,max:this.max,min:this.min};},filterArray:function(array,opt_keyFunc,opt_this){if(this.isEmpty_)
-return[];function binSearch(test){var i0=0;var i1=array.length;while(i0<i1){var i=Math.trunc((i0+i1)/2);if(test(i))
-i1=i;else
-i0=i+1;}
-return i1;}
-var keyFunc=opt_keyFunc||tr.b.identity;function getValue(index){return keyFunc.call(opt_this,array[index]);}
-var first=binSearch(function(i){return this.min_===undefined||this.min_<=getValue(i);}.bind(this));var last=binSearch(function(i){return this.max_!==undefined&&this.max_<getValue(i);}.bind(this));return array.slice(first,last);}};Range.fromDict=function(d){if(d.isEmpty===true){return new Range();}else if(d.isEmpty===false){var range=new Range();range.min=d.min;range.max=d.max;return range;}else{throw new Error('Not a range');}};Range.fromExplicitRange=function(min,max){var range=new Range();range.min=min;range.max=max;return range;};Range.compareByMinTimes=function(a,b){if(!a.isEmpty&&!b.isEmpty)
-return a.min_-b.min_;if(a.isEmpty&&!b.isEmpty)
-return-1;if(!a.isEmpty&&b.isEmpty)
-return 1;return 0;};return{Range:Range};});'use strict';tr.exportTo('tr.b',function(){function identity(d){return d;}
-function Statistics(){}
-Statistics.divideIfPossibleOrZero=function(numerator,denominator){if(denominator===0)
-return 0;return numerator/denominator;};Statistics.sum=function(ary,opt_func,opt_this){var func=opt_func||identity;var ret=0;for(var i=0;i<ary.length;i++)
-ret+=func.call(opt_this,ary[i],i);return ret;};Statistics.mean=function(ary,opt_func,opt_this){return Statistics.sum(ary,opt_func,opt_this)/ary.length;};Statistics.weightedMean=function(ary,weightCallback,opt_valueCallback,opt_this){var valueCallback=opt_valueCallback||identity;var numerator=0;var denominator=0;for(var i=0;i<ary.length;i++){var value=valueCallback.call(opt_this,ary[i],i);if(value===undefined)
-continue;var weight=weightCallback.call(opt_this,ary[i],i,value);numerator+=weight*value;denominator+=weight;}
-if(denominator===0)
-return undefined;return numerator/denominator;};Statistics.variance=function(ary,opt_func,opt_this){var func=opt_func||identity;var mean=Statistics.mean(ary,func,opt_this);var sumOfSquaredDistances=Statistics.sum(ary,function(d,i){var v=func.call(this,d,i)-mean;return v*v;},opt_this);return sumOfSquaredDistances/(ary.length-1);};Statistics.stddev=function(ary,opt_func,opt_this){return Math.sqrt(Statistics.variance(ary,opt_func,opt_this));};Statistics.max=function(ary,opt_func,opt_this){var func=opt_func||identity;var ret=-Infinity;for(var i=0;i<ary.length;i++)
-ret=Math.max(ret,func.call(opt_this,ary[i],i));return ret;};Statistics.min=function(ary,opt_func,opt_this){var func=opt_func||identity;var ret=Infinity;for(var i=0;i<ary.length;i++)
-ret=Math.min(ret,func.call(opt_this,ary[i],i));return ret;};Statistics.range=function(ary,opt_func,opt_this){var func=opt_func||identity;var ret=new tr.b.Range();for(var i=0;i<ary.length;i++)
-ret.addValue(func.call(opt_this,ary[i],i));return ret;};Statistics.percentile=function(ary,percent,opt_func,opt_this){if(!(percent>=0&&percent<=1))
-throw new Error('percent must be [0,1]');var func=opt_func||identity;var tmp=new Array(ary.length);for(var i=0;i<ary.length;i++)
-tmp[i]=func.call(opt_this,ary[i],i);tmp.sort();var idx=Math.floor((ary.length-1)*percent);return tmp[idx];};Statistics.clamp=function(value,opt_low,opt_high){opt_low=opt_low||0.0;opt_high=opt_high||1.0;return Math.min(Math.max(value,opt_low),opt_high);};Statistics.normalizeSamples=function(samples){if(samples.length===0){return{normalized_samples:samples,scale:1.0};}
-samples=samples.slice().sort(function(a,b){return a-b;});var low=Math.min.apply(null,samples);var high=Math.max.apply(null,samples);var new_low=0.5/samples.length;var new_high=(samples.length-0.5)/samples.length;if(high-low===0.0){samples=Array.apply(null,new Array(samples.length)).map(function(){return 0.5;});return{normalized_samples:samples,scale:1.0};}
-var scale=(new_high-new_low)/(high-low);for(var i=0;i<samples.length;i++){samples[i]=(samples[i]-low)*scale+new_low;}
-return{normalized_samples:samples,scale:scale};};Statistics.discrepancy=function(samples,opt_location_count){if(samples.length===0)
-return 0.0;var max_local_discrepancy=0;var inv_sample_count=1.0/samples.length;var locations=[];var count_less=[];var count_less_equal=[];if(opt_location_count!==undefined){var sample_index=0;for(var i=0;i<opt_location_count;i++){var location=i/(opt_location_count-1);locations.push(location);while(sample_index<samples.length&&samples[sample_index]<location){sample_index+=1;}
-count_less.push(sample_index);while(sample_index<samples.length&&samples[sample_index]<=location){sample_index+=1;}
-count_less_equal.push(sample_index);}}else{if(samples[0]>0.0){locations.push(0.0);count_less.push(0);count_less_equal.push(0);}
-for(var i=0;i<samples.length;i++){locations.push(samples[i]);count_less.push(i);count_less_equal.push(i+1);}
-if(samples[-1]<1.0){locations.push(1.0);count_less.push(samples.length);count_less_equal.push(samples.length);}}
-for(var i=0;i<locations.length;i++){for(var j=i+1;j<locations.length;j++){var length=locations[j]-locations[i];var count_closed=count_less_equal[j]-count_less[i];var local_discrepancy_closed=Math.abs(count_closed*inv_sample_count-length);var max_local_discrepancy=Math.max(local_discrepancy_closed,max_local_discrepancy);var count_open=count_less[j]-count_less_equal[i];var local_discrepancy_open=Math.abs(count_open*inv_sample_count-length);var max_local_discrepancy=Math.max(local_discrepancy_open,max_local_discrepancy);}}
-return max_local_discrepancy;};Statistics.timestampsDiscrepancy=function(timestamps,opt_absolute,opt_location_count){if(timestamps.length===0)
-return 0.0;if(opt_absolute===undefined)
-opt_absolute=true;if(Array.isArray(timestamps[0])){var range_discrepancies=timestamps.map(function(r){return Statistics.timestampsDiscrepancy(r);});return Math.max.apply(null,range_discrepancies);}
-var s=Statistics.normalizeSamples(timestamps);var samples=s.normalized_samples;var sample_scale=s.scale;var discrepancy=Statistics.discrepancy(samples,opt_location_count);var inv_sample_count=1.0/samples.length;if(opt_absolute===true){discrepancy/=sample_scale;}else{discrepancy=Statistics.clamp((discrepancy-inv_sample_count)/(1.0-inv_sample_count));}
-return discrepancy;};Statistics.durationsDiscrepancy=function(durations,opt_absolute,opt_location_count){if(durations.length===0)
-return 0.0;var timestamps=durations.reduce(function(prev,curr,index,array){prev.push(prev[prev.length-1]+curr);return prev;},[0]);return Statistics.timestampsDiscrepancy(timestamps,opt_absolute,opt_location_count);};Statistics.uniformlySampleStream=function(samples,streamLength,newElement,numSamples){if(streamLength<=numSamples){if(samples.length>=streamLength)
-samples[streamLength-1]=newElement;else
-samples.push(newElement);return;}
-var probToKeep=numSamples/streamLength;if(Math.random()>probToKeep)
-return;var index=Math.floor(Math.random()*numSamples);samples[index]=newElement;};Statistics.mergeSampledStreams=function(samplesA,streamLengthA,samplesB,streamLengthB,numSamples){if(streamLengthB<numSamples){var nbElements=Math.min(streamLengthB,samplesB.length);for(var i=0;i<nbElements;++i){Statistics.uniformlySampleStream(samplesA,streamLengthA+i+1,samplesB[i],numSamples);}
-return;}
-if(streamLengthA<numSamples){var nbElements=Math.min(streamLengthA,samplesA.length);var tempSamples=samplesB.slice();for(var i=0;i<nbElements;++i){Statistics.uniformlySampleStream(tempSamples,streamLengthB+i+1,samplesA[i],numSamples);}
-for(var i=0;i<tempSamples.length;++i){samplesA[i]=tempSamples[i];}
-return;}
-var nbElements=Math.min(numSamples,samplesB.length);var probOfSwapping=streamLengthB/(streamLengthA+streamLengthB);for(var i=0;i<nbElements;++i){if(Math.random()<probOfSwapping){samplesA[i]=samplesB[i];}}};return{Statistics:Statistics};});'use strict';tr.exportTo('tr.c',function(){function Auditor(model){this.model_=model;}
-Auditor.prototype={__proto__:Object.prototype,get model(){return this.model_;},runAnnotate:function(){},installUserFriendlyCategoryDriverIfNeeded:function(){},runAudit:function(){}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Auditor;tr.b.decorateExtensionRegistry(Auditor,options);return{Auditor:Auditor};});'use strict';tr.exportTo('tr.b',function(){function clamp01(value){return Math.max(0,Math.min(1,value));}
-function Color(opt_r,opt_g,opt_b,opt_a){this.r=Math.floor(opt_r)||0;this.g=Math.floor(opt_g)||0;this.b=Math.floor(opt_b)||0;this.a=opt_a;}
-Color.fromString=function(str){var tmp;var values;if(str.substr(0,4)=='rgb('){tmp=str.substr(4,str.length-5);values=tmp.split(',').map(function(v){return v.replace(/^\s+/,'','g');});if(values.length!=3)
-throw new Error('Malformatted rgb-expression');return new Color(parseInt(values[0]),parseInt(values[1]),parseInt(values[2]));}else if(str.substr(0,5)=='rgba('){tmp=str.substr(5,str.length-6);values=tmp.split(',').map(function(v){return v.replace(/^\s+/,'','g');});if(values.length!=4)
-throw new Error('Malformatted rgb-expression');return new Color(parseInt(values[0]),parseInt(values[1]),parseInt(values[2]),parseFloat(values[3]));}else if(str[0]=='#'&&str.length==7){return new Color(parseInt(str.substr(1,2),16),parseInt(str.substr(3,2),16),parseInt(str.substr(5,2),16));}else{throw new Error('Unrecognized string format.');}};Color.lerp=function(a,b,percent){if(a.a!==undefined&&b.a!==undefined)
-return Color.lerpRGBA(a,b,percent);return Color.lerpRGB(a,b,percent);};Color.lerpRGB=function(a,b,percent){return new Color(((b.r-a.r)*percent)+a.r,((b.g-a.g)*percent)+a.g,((b.b-a.b)*percent)+a.b);};Color.lerpRGBA=function(a,b,percent){return new Color(((b.r-a.r)*percent)+a.r,((b.g-a.g)*percent)+a.g,((b.b-a.b)*percent)+a.b,((b.a-a.a)*percent)+a.a);};Color.fromDict=function(dict){return new Color(dict.r,dict.g,dict.b,dict.a);};Color.fromHSLExplicit=function(h,s,l,a){var r,g,b;function hue2rgb(p,q,t){if(t<0)t+=1;if(t>1)t-=1;if(t<1/6)return p+(q-p)*6*t;if(t<1/2)return q;if(t<2/3)return p+(q-p)*(2/3-t)*6;return p;}
-if(s===0){r=g=b=l;}else{var q=l<0.5?l*(1+s):l+s-l*s;var p=2*l-q;r=hue2rgb(p,q,h+1/3);g=hue2rgb(p,q,h);b=hue2rgb(p,q,h-1/3);}
-return new Color(Math.floor(r*255),Math.floor(g*255),Math.floor(b*255),a);}
-Color.fromHSL=function(hsl){return Color.fromHSLExplicit(hsl.h,hsl.s,hsl.l,hsl.a);}
-Color.prototype={clone:function(){var c=new Color();c.r=this.r;c.g=this.g;c.b=this.b;c.a=this.a;return c;},blendOver:function(bgColor){var oneMinusThisAlpha=1-this.a;var outA=this.a+bgColor.a*oneMinusThisAlpha;var bgBlend=(bgColor.a*oneMinusThisAlpha)/bgColor.a;return new Color(this.r*this.a+bgColor.r*bgBlend,this.g*this.a+bgColor.g*bgBlend,this.b*this.a+bgColor.b*bgBlend,outA);},brighten:function(opt_k){var k;k=opt_k||0.45;return new Color(Math.min(255,this.r+Math.floor(this.r*k)),Math.min(255,this.g+Math.floor(this.g*k)),Math.min(255,this.b+Math.floor(this.b*k)),this.a);},lighten:function(k,opt_max_l){var max_l=opt_max_l!==undefined?opt_max_l:1.0;var hsl=this.toHSL();hsl.l=clamp01(hsl.l+k);return Color.fromHSL(hsl);},darken:function(opt_k){var k;if(opt_k!==undefined)
-k=opt_k;else
-k=0.45;return new Color(Math.min(255,this.r-Math.floor(this.r*k)),Math.min(255,this.g-Math.floor(this.g*k)),Math.min(255,this.b-Math.floor(this.b*k)),this.a);},desaturate:function(opt_desaturateFactor){var desaturateFactor;if(opt_desaturateFactor!==undefined)
-desaturateFactor=opt_desaturateFactor;else
-desaturateFactor=1;var hsl=this.toHSL();hsl.s=clamp01(hsl.s*(1-desaturateFactor));return Color.fromHSL(hsl);},withAlpha:function(a){return new Color(this.r,this.g,this.b,a);},toString:function(){if(this.a!==undefined){return'rgba('+
-this.r+','+this.g+','+
-this.b+','+this.a+')';}
-return'rgb('+this.r+','+this.g+','+this.b+')';},toHSL:function(){var r=this.r/255;var g=this.g/255;var b=this.b/255;var max=Math.max(r,g,b);var min=Math.min(r,g,b);var h,s;var l=(max+min)/2;if(min===max){h=0;s=0;}else{var delta=max-min;if(l>0.5)
-s=delta/(2-max-min);else
-s=delta/(max+min);if(r===max){h=(g-b)/delta;if(g<b)
-h+=6;}else if(g===max){h=2+((b-r)/delta);}else{h=4+((r-g)/delta);}
-h/=6;}
-return{h:h,s:s,l:l,a:this.a};},toStringWithAlphaOverride:function(alpha){return'rgba('+
-this.r+','+this.g+','+
-this.b+','+alpha+')';}};return{Color:Color};});'use strict';tr.exportTo('tr.b',function(){var generalPurposeColors=[new tr.b.Color(122,98,135),new tr.b.Color(150,83,105),new tr.b.Color(44,56,189),new tr.b.Color(99,86,147),new tr.b.Color(104,129,107),new tr.b.Color(130,178,55),new tr.b.Color(87,109,147),new tr.b.Color(111,145,88),new tr.b.Color(81,152,131),new tr.b.Color(142,91,111),new tr.b.Color(81,163,70),new tr.b.Color(148,94,86),new tr.b.Color(144,89,118),new tr.b.Color(83,150,97),new tr.b.Color(105,94,139),new tr.b.Color(89,144,122),new tr.b.Color(105,119,128),new tr.b.Color(96,128,137),new tr.b.Color(145,88,145),new tr.b.Color(88,145,144),new tr.b.Color(90,100,143),new tr.b.Color(121,97,136),new tr.b.Color(111,160,73),new tr.b.Color(112,91,142),new tr.b.Color(86,147,86),new tr.b.Color(63,100,170),new tr.b.Color(81,152,107),new tr.b.Color(60,164,173),new tr.b.Color(143,72,161),new tr.b.Color(159,74,86)];var reservedColorsByName={thread_state_uninterruptible:new tr.b.Color(182,125,143),thread_state_iowait:new tr.b.Color(255,140,0),thread_state_running:new tr.b.Color(126,200,148),thread_state_runnable:new tr.b.Color(133,160,210),thread_state_sleeping:new tr.b.Color(240,240,240),thread_state_unknown:new tr.b.Color(199,155,125),light_memory_dump:new tr.b.Color(0,0,180),detailed_memory_dump:new tr.b.Color(180,0,180),generic_work:new tr.b.Color(125,125,125),good:new tr.b.Color(0,125,0),bad:new tr.b.Color(180,125,0),terrible:new tr.b.Color(180,0,0),black:new tr.b.Color(0,0,0),rail_response:new tr.b.Color(67,135,253),rail_animation:new tr.b.Color(244,74,63),rail_idle:new tr.b.Color(238,142,0),rail_load:new tr.b.Color(13,168,97),used_memory_column:new tr.b.Color(0,0,255),older_used_memory_column:new tr.b.Color(153,204,255),tracing_memory_column:new tr.b.Color(153,153,153),heap_dump_stack_frame:new tr.b.Color(128,128,128),heap_dump_object_type:new tr.b.Color(0,0,255),cq_build_running:new tr.b.Color(255,255,119),cq_build_passed:new tr.b.Color(153,238,102),cq_build_failed:new tr.b.Color(238,136,136),cq_build_abandoned:new tr.b.Color(187,187,187),cq_build_attempt_runnig:new tr.b.Color(222,222,75),cq_build_attempt_passed:new tr.b.Color(103,218,35),cq_build_attempt_failed:new tr.b.Color(197,81,81)};var numGeneralPurposeColorIds=generalPurposeColors.length;var numReservedColorIds=tr.b.dictionaryLength(reservedColorsByName);var numColorsPerVariant=numGeneralPurposeColorIds+numReservedColorIds;function ColorScheme(){}
-var paletteBase=[];paletteBase.push.apply(paletteBase,generalPurposeColors);paletteBase.push.apply(paletteBase,tr.b.dictionaryValues(reservedColorsByName));ColorScheme.colors=[];ColorScheme.properties={};ColorScheme.properties={numColorsPerVariant:numColorsPerVariant};function pushVariant(func){var variantColors=paletteBase.map(func);ColorScheme.colors.push.apply(ColorScheme.colors,variantColors);}
-pushVariant(function(c){return c;});ColorScheme.properties.brightenedOffsets=[];ColorScheme.properties.brightenedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.lighten(0.3,0.9);});ColorScheme.properties.brightenedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.lighten(0.48,0.9);});ColorScheme.properties.brightenedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.lighten(0.65,0.9);});ColorScheme.properties.dimmedOffsets=[];ColorScheme.properties.dimmedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.desaturate();});ColorScheme.properties.dimmedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.desaturate(0.5);});ColorScheme.properties.dimmedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.desaturate(0.3);});ColorScheme.colorsAsStrings=ColorScheme.colors.map(function(c){return c.toString();});var reservedColorNameToIdMap=(function(){var m={};var i=generalPurposeColors.length;tr.b.iterItems(reservedColorsByName,function(key,value){m[key]=i++;});return m;})();ColorScheme.getColorIdForReservedName=function(name){var id=reservedColorNameToIdMap[name];if(id===undefined)
-throw new Error('Unrecognized color ')+name;return id;};ColorScheme.getColorForReservedNameAsString=function(reservedName){var id=ColorScheme.getColorIdForReservedName(reservedName);return ColorScheme.colorsAsStrings[id];};ColorScheme.getStringHash=function(name){var hash=0;for(var i=0;i<name.length;++i)
-hash=(hash+37*hash+11*name.charCodeAt(i))%0xFFFFFFFF;return hash;};var stringColorIdCache={};ColorScheme.getColorIdForGeneralPurposeString=function(string){if(stringColorIdCache[string]===undefined){var hash=ColorScheme.getStringHash(string);stringColorIdCache[string]=hash%numGeneralPurposeColorIds;}
-return stringColorIdCache[string];};return{ColorScheme:ColorScheme};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;function EventInfo(title,description,docLinks){this.title=title;this.description=description;this.docLinks=docLinks;this.colorId=ColorScheme.getColorIdForGeneralPurposeString(title);}
-return{EventInfo:EventInfo};});'use strict';tr.exportTo('tr.b',function(){var nextGUID=1;var GUID={allocate:function(){return nextGUID++;},getLastGuid:function(){return nextGUID-1;}};return{GUID:GUID};});'use strict';tr.exportTo('tr.model',function(){function EventRegistry(){}
-var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(EventRegistry,options);EventRegistry.addEventListener('will-register',function(e){var metadata=e.typeInfo.metadata;if(metadata.name===undefined)
-throw new Error('Registered events must provide name metadata');var i=tr.b.findFirstInArray(EventRegistry.getAllRegisteredTypeInfos(),function(x){return x.metadata.name===metadata.name;});if(i!==undefined)
-throw new Error('Event type with that name already registered');if(metadata.pluralName===undefined)
-throw new Error('Registered events must provide pluralName metadata');if(metadata.singleViewElementName===undefined){throw new Error('Registered events must provide '+'singleViewElementName metadata');}
-if(metadata.multiViewElementName===undefined){throw new Error('Registered events must provide '+'multiViewElementName metadata');}});var eventsByTypeName=undefined;EventRegistry.getEventTypeInfoByTypeName=function(typeName){if(eventsByTypeName===undefined){eventsByTypeName={};EventRegistry.getAllRegisteredTypeInfos().forEach(function(typeInfo){eventsByTypeName[typeInfo.metadata.name]=typeInfo;});}
-return eventsByTypeName[typeName];}
-EventRegistry.addEventListener('registry-changed',function(){eventsByTypeName=undefined;});function convertCamelCaseToTitleCase(name){var result=name.replace(/[A-Z]/g,' $&');result=result.charAt(0).toUpperCase()+result.slice(1);return result;}
-EventRegistry.getUserFriendlySingularName=function(typeName){var typeInfo=EventRegistry.getEventTypeInfoByTypeName(typeName);var str=typeInfo.metadata.name;return convertCamelCaseToTitleCase(str);};EventRegistry.getUserFriendlyPluralName=function(typeName){var typeInfo=EventRegistry.getEventTypeInfoByTypeName(typeName);var str=typeInfo.metadata.pluralName;return convertCamelCaseToTitleCase(str);};return{EventRegistry:EventRegistry};});'use strict';tr.exportTo('tr.model',function(){var EventRegistry=tr.model.EventRegistry;var RequestSelectionChangeEvent=tr.b.Event.bind(undefined,'requestSelectionChange',true,false);function EventSet(opt_events){this.bounds_dirty_=true;this.bounds_=new tr.b.Range();this.length_=0;this.guid_=tr.b.GUID.allocate();this.pushed_guids_={};if(opt_events){if(opt_events instanceof Array){for(var i=0;i<opt_events.length;i++)
-this.push(opt_events[i]);}else if(opt_events instanceof EventSet){this.addEventSet(opt_events);}else{this.push(opt_events);}}}
-EventSet.prototype={__proto__:Object.prototype,get bounds(){if(this.bounds_dirty_)
-this.resolveBounds_();return this.bounds_;},get duration(){if(this.bounds_.isEmpty)
-return 0;return this.bounds_.max-this.bounds_.min;},get length(){return this.length_;},get guid(){return this.guid_;},clear:function(){for(var i=0;i<this.length_;++i)
-delete this[i];this.length_=0;this.bounds_dirty_=true;},resolveBounds_:function(){this.bounds_.reset();for(var i=0;i<this.length_;i++)
-this[i].addBoundsToRange(this.bounds_);this.bounds_dirty_=false;},push:function(event){if(event.guid==undefined)
-throw new Error('Event must have a GUID');if(this.contains(event))
-return event;this.pushed_guids_[event.guid]=true;this[this.length_++]=event;this.bounds_dirty_=true;return event;},contains:function(event){return this.pushed_guids_[event.guid];},indexOf:function(event){for(var i=0;i<this.length;i++){if(this[i].guid===event.guid)
-return i;}
-return-1;},addEventSet:function(eventSet){for(var i=0;i<eventSet.length;i++)
-this.push(eventSet[i]);},subEventSet:function(index,count){count=count||1;var eventSet=new EventSet();eventSet.bounds_dirty_=true;if(index<0||index+count>this.length_)
-throw new Error('Index out of bounds');for(var i=index;i<index+count;i++)
-eventSet.push(this[i]);return eventSet;},intersectionIsEmpty:function(otherEventSet){return!this.some(function(event){return otherEventSet.contains(event);});},equals:function(that){if(this.length!==that.length)
-return false;for(var i=0;i<this.length;i++){var event=this[i];if(that.pushed_guids_[event.guid]===undefined)
-return false;}
-return true;},getEventsOrganizedByBaseType:function(opt_pruneEmpty){var allTypeInfos=EventRegistry.getAllRegisteredTypeInfos();var events=this.getEventsOrganizedByCallback(function(event){var maxEventIndex=-1;var maxEventTypeInfo=undefined;allTypeInfos.forEach(function(eventTypeInfo,eventIndex){if(!(event instanceof eventTypeInfo.constructor))
-return;if(eventIndex>maxEventIndex){maxEventIndex=eventIndex;maxEventTypeInfo=eventTypeInfo;}});if(maxEventIndex==-1){console.log(event);throw new Error('Unrecognized event type');}
-return maxEventTypeInfo.metadata.name;});if(!opt_pruneEmpty){allTypeInfos.forEach(function(eventTypeInfo){if(events[eventTypeInfo.metadata.name]===undefined)
-events[eventTypeInfo.metadata.name]=new EventSet();});}
-return events;},getEventsOrganizedByTitle:function(){return this.getEventsOrganizedByCallback(function(event){if(event.title===undefined)
-throw new Error('An event didn\'t have a title!');return event.title;});},getEventsOrganizedByCallback:function(cb){var eventsByCallback={};for(var i=0;i<this.length;i++){var event=this[i];var key=cb(event);if(key===undefined)
-throw new Error('An event could not be organized');if(eventsByCallback[key]===undefined)
-eventsByCallback[key]=new EventSet();eventsByCallback[key].push(event);}
-return eventsByCallback;},enumEventsOfType:function(type,func){for(var i=0;i<this.length_;i++)
-if(this[i]instanceof type)
-func(this[i]);},get userFriendlyName(){if(this.length===0){throw new Error('Empty event set');}
-var eventsByBaseType=this.getEventsOrganizedByBaseType(true);var eventTypeName=tr.b.dictionaryKeys(eventsByBaseType)[0];if(this.length===1){var tmp=EventRegistry.getUserFriendlySingularName(eventTypeName);return this[0].userFriendlyName;}
-var numEventTypes=tr.b.dictionaryLength(eventsByBaseType);if(numEventTypes!==1){return this.length+' events of various types';}
-var tmp=EventRegistry.getUserFriendlyPluralName(eventTypeName);return this.length+' '+tmp;},filter:function(fn,opt_this){var res=new EventSet();this.forEach(function(slice){if(fn.call(this,slice))
-res.push(slice);},opt_this);return res;},toArray:function(){var ary=[];for(var i=0;i<this.length;i++)
-ary.push(this[i]);return ary;},forEach:function(fn,opt_this){for(var i=0;i<this.length;i++)
-fn.call(opt_this,this[i],i);},map:function(fn,opt_this){var res=[];for(var i=0;i<this.length;i++)
-res.push(fn.call(opt_this,this[i],i));return res;},every:function(fn,opt_this){for(var i=0;i<this.length;i++)
-if(!fn.call(opt_this,this[i],i))
-return false;return true;},some:function(fn,opt_this){for(var i=0;i<this.length;i++)
-if(fn.call(opt_this,this[i],i))
-return true;return false;},asDict:function(){var stable_ids=[];this.forEach(function(event){stable_ids.push(event.stableId);});return{'events':stable_ids};}};EventSet.IMMUTABLE_EMPTY_SET=(function(){var s=new EventSet();s.resolveBounds_();s.push=function(){throw new Error('Cannot push to an immutable event set');};s.addEventSet=function(){throw new Error('Cannot add to an immutable event set');};Object.freeze(s);return s;})();return{EventSet:EventSet,RequestSelectionChangeEvent:RequestSelectionChangeEvent};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;var SelectionState={NONE:0,SELECTED:ColorScheme.properties.brightenedOffsets[0],HIGHLIGHTED:ColorScheme.properties.brightenedOffsets[1],DIMMED:ColorScheme.properties.dimmedOffsets[0],BRIGHTENED0:ColorScheme.properties.brightenedOffsets[0],BRIGHTENED1:ColorScheme.properties.brightenedOffsets[1],BRIGHTENED2:ColorScheme.properties.brightenedOffsets[2],DIMMED0:ColorScheme.properties.dimmedOffsets[0],DIMMED1:ColorScheme.properties.dimmedOffsets[1],DIMMED2:ColorScheme.properties.dimmedOffsets[2]};var brighteningLevels=[SelectionState.NONE,SelectionState.BRIGHTENED0,SelectionState.BRIGHTENED1,SelectionState.BRIGHTENED2];SelectionState.getFromBrighteningLevel=function(level){return brighteningLevels[level];}
-var dimmingLevels=[SelectionState.DIMMED0,SelectionState.DIMMED1,SelectionState.DIMMED2];SelectionState.getFromDimmingLevel=function(level){return dimmingLevels[level];}
-return{SelectionState:SelectionState};});'use strict';tr.exportTo('tr.model',function(){var SelectionState=tr.model.SelectionState;function SelectableItem(modelItem){this.modelItem_=modelItem;}
-SelectableItem.prototype={get modelItem(){return this.modelItem_;},get selected(){return this.selectionState===SelectionState.SELECTED;},addToSelection:function(selection){var modelItem=this.modelItem_;if(!modelItem)
-return;selection.push(modelItem);},addToTrackMap:function(eventToTrackMap,track){var modelItem=this.modelItem_;if(!modelItem)
-return;eventToTrackMap.addEvent(modelItem,track);}};return{SelectableItem:SelectableItem};});'use strict';tr.exportTo('tr.model',function(){var SelectableItem=tr.model.SelectableItem;var SelectionState=tr.model.SelectionState;var IMMUTABLE_EMPTY_SET=tr.model.EventSet.IMMUTABLE_EMPTY_SET;function Event(){SelectableItem.call(this,this);this.guid_=tr.b.GUID.allocate();this.selectionState=SelectionState.NONE;this.info=undefined;}
-Event.prototype={__proto__:SelectableItem.prototype,get guid(){return this.guid_;},get stableId(){return undefined;},associatedAlerts:IMMUTABLE_EMPTY_SET,addAssociatedAlert:function(alert){if(this.associatedAlerts===IMMUTABLE_EMPTY_SET)
-this.associatedAlerts=new tr.model.EventSet();this.associatedAlerts.push(alert);},addBoundsToRange:function(range){throw new Error('Not implemented');}};return{Event:Event};});'use strict';tr.exportTo('tr.v',function(){var msDisplayMode={scale:1e-3,suffix:'ms',roundedLess:function(a,b){return Math.round(a*1000)<Math.round(b*1000);},format:function(ts){return new Number(ts).toLocaleString(undefined,{minimumFractionDigits:3})+' ms';}};var nsDisplayMode={scale:1e-9,suffix:'ns',roundedLess:function(a,b){return Math.round(a*1000000)<Math.round(b*1000000);},format:function(ts){return new Number(ts*1000000).toLocaleString(undefined,{maximumFractionDigits:0})+' ns';}};var TimeDisplayModes={ns:nsDisplayMode,ms:msDisplayMode};return{TimeDisplayModes:TimeDisplayModes};});'use strict';tr.exportTo('tr.model',function(){function TimedEvent(start){tr.model.Event.call(this);this.start=start;this.duration=0;this.cpuStart=undefined;this.cpuDuration=undefined;}
-TimedEvent.prototype={__proto__:tr.model.Event.prototype,get end(){return this.start+this.duration;},addBoundsToRange:function(range){range.addValue(this.start);range.addValue(this.end);},bounds:function(that,opt_precisionUnit){if(opt_precisionUnit===undefined)
-opt_precisionUnit=tr.v.TimeDisplayModes.ms;var startsBefore=opt_precisionUnit.roundedLess(that.start,this.start);var endsAfter=opt_precisionUnit.roundedLess(this.end,that.end);return!startsBefore&&!endsAfter;}};return{TimedEvent:TimedEvent};});'use strict';tr.exportTo('tr.v',function(){var TimeDisplayModes=tr.v.TimeDisplayModes;var BINARY_PREFIXES=['','Ki','Mi','Gi','Ti'];var PLUS_MINUS_SIGN=String.fromCharCode(177);function max(a,b){if(a===undefined)
-return b;if(b===undefined)
-return a;return a.scale>b.scale?a:b;}
-var ImprovementDirection={DONT_CARE:0,BIGGER_IS_BETTER:1,SMALLER_IS_BETTER:2};function Unit(unitName,jsonName,isDelta,improvementDirection,formatValue){this.unitName=unitName;this.jsonName=jsonName;this.isDelta=isDelta;this.improvementDirection=improvementDirection;this.formatValue_=formatValue;this.correspondingDeltaUnit=undefined;}
-Unit.prototype={asJSON:function(){return this.jsonName;},format:function(value){var formattedValue=this.formatValue_(value);if(!this.isDelta||value<0)
-return formattedValue;if(value===0)
-return PLUS_MINUS_SIGN+formattedValue;else
-return'+'+formattedValue;}};Unit.reset=function(){Unit.currentTimeDisplayMode=TimeDisplayModes.ms;};Unit.timestampFromUs=function(us){return us/1000;};Unit.maybeTimestampFromUs=function(us){return us===undefined?undefined:us/1000;};Object.defineProperty(Unit,'currentTimeDisplayMode',{get:function(){return Unit.currentTimeDisplayMode_;},set:function(value){if(Unit.currentTimeDisplayMode_===value)
-return;Unit.currentTimeDisplayMode_=value;Unit.dispatchEvent(new tr.b.Event('display-mode-changed'));}});Unit.didPreferredTimeDisplayUnitChange=function(){var largest=undefined;var els=tr.b.findDeepElementsMatching(document.body,'tr-v-ui-preferred-display-unit');els.forEach(function(el){largest=max(largest,el.preferredTimeDisplayMode);});Unit.currentDisplayUnit=largest===undefined?TimeDisplayModes.ms:largest;};Unit.byName={};Unit.byJSONName={};Unit.fromJSON=function(object){var u=Unit.byJSONName[object];if(u){return u;}
-throw new Error('Unrecognized unit');};Unit.define=function(params){tr.b.iterItems(ImprovementDirection,function(_,improvementDirection){var regularUnit=Unit.defineUnitVariant_(params,false,improvementDirection);var deltaUnit=Unit.defineUnitVariant_(params,true,improvementDirection);regularUnit.correspondingDeltaUnit=deltaUnit;deltaUnit.correspondingDeltaUnit=deltaUnit;});};Unit.defineUnitVariant_=function(params,isDelta,improvementDirection){var nameSuffix=isDelta?'Delta':'';switch(improvementDirection){case ImprovementDirection.DONT_CARE:break;case ImprovementDirection.BIGGER_IS_BETTER:nameSuffix+='_biggerIsBetter';break;case ImprovementDirection.SMALLER_IS_BETTER:nameSuffix+='_smallerIsBetter';break;default:throw new Error('Unknown improvement direction: '+improvementDirection);}
-var unitName=params.baseUnitName+nameSuffix;var jsonName=params.baseJsonName+nameSuffix;if(Unit.byName[unitName]!==undefined)
-throw new Error('Unit \''+unitName+'\' already exists');if(Unit.byJSONName[jsonName]!==undefined)
-throw new Error('JSON unit \''+jsonName+'\' alread exists');var unit=new Unit(unitName,jsonName,isDelta,improvementDirection,params.formatValue);Unit.byName[unitName]=unit;Unit.byJSONName[jsonName]=unit;return unit;};tr.b.EventTarget.decorate(Unit);Unit.reset();Unit.define({baseUnitName:'timeDurationInMs',baseJsonName:'ms',formatValue:function(value){return Unit.currentTimeDisplayMode_.format(value);}});Unit.define({baseUnitName:'timeStampInMs',baseJsonName:'tsMs',formatValue:function(value){return Unit.currentTimeDisplayMode_.format(value);}});Unit.define({baseUnitName:'normalizedPercentage',baseJsonName:'n%',formatValue:function(value){var tmp=new Number(Math.round(value*100000)/1000);return tmp.toLocaleString(undefined,{minimumFractionDigits:3})+'%';}});Unit.define({baseUnitName:'sizeInBytes',baseJsonName:'sizeInBytes',formatValue:function(value){var signPrefix='';if(value<0){signPrefix='-';value=-value;}
-var i=0;while(value>=1024&&i<BINARY_PREFIXES.length-1){value/=1024;i++;}
-return signPrefix+value.toFixed(1)+' '+BINARY_PREFIXES[i]+'B';}});Unit.define({baseUnitName:'energyInJoules',baseJsonName:'J',formatValue:function(value){return value.toLocaleString(undefined,{minimumFractionDigits:3})+' J';}});Unit.define({baseUnitName:'powerInWatts',baseJsonName:'W',formatValue:function(value){return value.toLocaleString(undefined,{minimumFractionDigits:3})+' W';}});Unit.define({baseUnitName:'unitlessNumber',baseJsonName:'unitless',formatValue:function(value){return value.toLocaleString(undefined,{minimumFractionDigits:3,maximumFractionDigits:3});}});return{ImprovementDirection:ImprovementDirection,Unit:Unit};});'use strict';tr.exportTo('tr.model',function(){function Alert(info,start,opt_associatedEvents,opt_args){tr.model.TimedEvent.call(this,start);this.info=info;this.args=opt_args||{};this.associatedEvents=new tr.model.EventSet(opt_associatedEvents);this.associatedEvents.forEach(function(event){event.addAssociatedAlert(this);},this);}
-Alert.prototype={__proto__:tr.model.TimedEvent.prototype,get title(){return this.info.title;},get colorId(){return this.info.colorId;},get userFriendlyName(){return'Alert '+this.title+' at '+
-tr.v.Unit.byName.timeStampInMs.format(this.start);}};tr.model.EventRegistry.register(Alert,{name:'alert',pluralName:'alerts',singleViewElementName:'tr-ui-a-alert-sub-view',multiViewElementName:'tr-ui-a-alert-sub-view'});return{Alert:Alert};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;var Statistics=tr.b.Statistics;var FRAME_PERF_CLASS={GOOD:'good',BAD:'bad',TERRIBLE:'terrible',NEUTRAL:'generic_work'};function Frame(associatedEvents,threadTimeRanges,opt_args){tr.model.Event.call(this);this.threadTimeRanges=threadTimeRanges;this.associatedEvents=new tr.model.EventSet(associatedEvents);this.args=opt_args||{};this.title='Frame';this.start=Statistics.min(threadTimeRanges,function(x){return x.start;});this.end=Statistics.max(threadTimeRanges,function(x){return x.end;});this.totalDuration=Statistics.sum(threadTimeRanges,function(x){return x.end-x.start;});this.perfClass=FRAME_PERF_CLASS.NEUTRAL;};Frame.prototype={__proto__:tr.model.Event.prototype,set perfClass(perfClass){this.colorId=ColorScheme.getColorIdForReservedName(perfClass);this.perfClass_=perfClass;},get perfClass(){return this.perfClass_;},shiftTimestampsForward:function(amount){this.start+=amount;this.end+=amount;for(var i=0;i<this.threadTimeRanges.length;i++){this.threadTimeRanges[i].start+=amount;this.threadTimeRanges[i].end+=amount;}},addBoundsToRange:function(range){range.addValue(this.start);range.addValue(this.end);}};tr.model.EventRegistry.register(Frame,{name:'frame',pluralName:'frames',singleViewElementName:'tr-ui-a-single-frame-sub-view',multiViewElementName:'tr-ui-a-multi-frame-sub-view'});return{Frame:Frame,FRAME_PERF_CLASS:FRAME_PERF_CLASS};});'use strict';tr.exportTo('tr.b',function(){function findLowIndexInSortedArray(ary,mapFn,loVal){if(ary.length==0)
-return 1;var low=0;var high=ary.length-1;var i,comparison;var hitPos=-1;while(low<=high){i=Math.floor((low+high)/2);comparison=mapFn(ary[i])-loVal;if(comparison<0){low=i+1;continue;}else if(comparison>0){high=i-1;continue;}else{hitPos=i;high=i-1;}}
-return hitPos!=-1?hitPos:low;}
-function findHighIndexInSortedArray(ary,mapFn,loVal,hiVal){var lo=loVal||0;var hi=hiVal!==undefined?hiVal:ary.length;while(lo<hi){var mid=(lo+hi)>>1;if(mapFn(ary[mid])>=0)
-lo=mid+1;else
-hi=mid;}
-return hi;}
-function findIndexInSortedIntervals(ary,mapLoFn,mapWidthFn,loVal){var first=findLowIndexInSortedArray(ary,mapLoFn,loVal);if(first==0){if(loVal>=mapLoFn(ary[0])&&loVal<mapLoFn(ary[0])+mapWidthFn(ary[0],0)){return 0;}else{return-1;}}else if(first<ary.length){if(loVal>=mapLoFn(ary[first])&&loVal<mapLoFn(ary[first])+mapWidthFn(ary[first],first)){return first;}else if(loVal>=mapLoFn(ary[first-1])&&loVal<mapLoFn(ary[first-1])+
-mapWidthFn(ary[first-1],first-1)){return first-1;}else{return ary.length;}}else if(first==ary.length){if(loVal>=mapLoFn(ary[first-1])&&loVal<mapLoFn(ary[first-1])+
-mapWidthFn(ary[first-1],first-1)){return first-1;}else{return ary.length;}}else{return ary.length;}}
-function findIndexInSortedClosedIntervals(ary,mapLoFn,mapHiFn,val){var i=findLowIndexInSortedArray(ary,mapLoFn,val);if(i===0){if(val>=mapLoFn(ary[0],0)&&val<=mapHiFn(ary[0],0)){return 0;}else{return-1;}}else if(i<ary.length){if(val>=mapLoFn(ary[i-1],i-1)&&val<=mapHiFn(ary[i-1],i-1)){return i-1;}else if(val>=mapLoFn(ary[i],i)&&val<=mapHiFn(ary[i],i)){return i;}else{return ary.length;}}else if(i==ary.length){if(val>=mapLoFn(ary[i-1],i-1)&&val<=mapHiFn(ary[i-1],i-1)){return i-1;}else{return ary.length;}}else{return ary.length;}}
-function iterateOverIntersectingIntervals(ary,mapLoFn,mapWidthFn,loVal,hiVal,cb){if(ary.length==0)
-return;if(loVal>hiVal)return;var i=findLowIndexInSortedArray(ary,mapLoFn,loVal);if(i==-1){return;}
-if(i>0){var hi=mapLoFn(ary[i-1])+mapWidthFn(ary[i-1],i-1);if(hi>=loVal){cb(ary[i-1],i-1);}}
-if(i==ary.length){return;}
-for(var n=ary.length;i<n;i++){var lo=mapLoFn(ary[i]);if(lo>=hiVal)
-break;cb(ary[i],i);}}
-function getIntersectingIntervals(ary,mapLoFn,mapWidthFn,loVal,hiVal){var tmp=[];iterateOverIntersectingIntervals(ary,mapLoFn,mapWidthFn,loVal,hiVal,function(d){tmp.push(d);});return tmp;}
-function findClosestElementInSortedArray(ary,mapFn,val,maxDiff){if(ary.length===0)
-return null;var aftIdx=findLowIndexInSortedArray(ary,mapFn,val);var befIdx=aftIdx>0?aftIdx-1:0;if(aftIdx===ary.length)
-aftIdx-=1;var befDiff=Math.abs(val-mapFn(ary[befIdx]));var aftDiff=Math.abs(val-mapFn(ary[aftIdx]));if(befDiff>maxDiff&&aftDiff>maxDiff)
-return null;var idx=befDiff<aftDiff?befIdx:aftIdx;return ary[idx];}
-function findClosestIntervalInSortedIntervals(ary,mapLoFn,mapHiFn,val,maxDiff){if(ary.length===0)
-return null;var idx=findLowIndexInSortedArray(ary,mapLoFn,val);if(idx>0)
-idx-=1;var hiInt=ary[idx];var loInt=hiInt;if(val>mapHiFn(hiInt)&&idx+1<ary.length)
-loInt=ary[idx+1];var loDiff=Math.abs(val-mapLoFn(loInt));var hiDiff=Math.abs(val-mapHiFn(hiInt));if(loDiff>maxDiff&&hiDiff>maxDiff)
-return null;if(loDiff<hiDiff)
-return loInt;else
-return hiInt;}
-return{findLowIndexInSortedArray:findLowIndexInSortedArray,findHighIndexInSortedArray:findHighIndexInSortedArray,findIndexInSortedIntervals:findIndexInSortedIntervals,findIndexInSortedClosedIntervals:findIndexInSortedClosedIntervals,iterateOverIntersectingIntervals:iterateOverIntersectingIntervals,getIntersectingIntervals:getIntersectingIntervals,findClosestElementInSortedArray:findClosestElementInSortedArray,findClosestIntervalInSortedIntervals:findClosestIntervalInSortedIntervals};});'use strict';tr.exportTo('tr.model.helpers',function(){var Frame=tr.model.Frame;var Statistics=tr.b.Statistics;var UI_DRAW_TYPE={NONE:'none',LEGACY:'legacy',MARSHMALLOW:'marshmallow'};var UI_THREAD_DRAW_NAMES={'performTraversals':UI_DRAW_TYPE.LEGACY,'Choreographer#doFrame':UI_DRAW_TYPE.MARSHMALLOW};var RENDER_THREAD_DRAW_NAME='DrawFrame';var RENDER_THREAD_INDEP_DRAW_NAME='doFrame';var THREAD_SYNC_NAME='syncFrameState';function getSlicesForThreadTimeRanges(threadTimeRanges){var ret=[];threadTimeRanges.forEach(function(threadTimeRange){var slices=[];threadTimeRange.thread.sliceGroup.iterSlicesInTimeRange(function(slice){slices.push(slice);},threadTimeRange.start,threadTimeRange.end);ret.push.apply(ret,slices);});return ret;}
-function makeFrame(threadTimeRanges,surfaceFlinger){var args={};if(surfaceFlinger&&surfaceFlinger.hasVsyncs){var start=Statistics.min(threadTimeRanges,function(threadTimeRanges){return threadTimeRanges.start;});args['deadline']=surfaceFlinger.getFrameDeadline(start);args['frameKickoff']=surfaceFlinger.getFrameKickoff(start);}
-var events=getSlicesForThreadTimeRanges(threadTimeRanges);return new Frame(events,threadTimeRanges,args);}
-function findOverlappingDrawFrame(renderThread,time){if(!renderThread)
-return undefined;var slices=renderThread.sliceGroup.slices;for(var i=0;i<slices.length;i++){var slice=slices[i];if(slice.title==RENDER_THREAD_DRAW_NAME&&slice.start<=time&&time<=slice.end){return slice;}}
-return undefined;}
-function getPreTraversalWorkRanges(uiThread){if(!uiThread)
-return[];var preFrameEvents=[];uiThread.sliceGroup.slices.forEach(function(slice){if(slice.title=='obtainView'||slice.title=='setupListItem'||slice.title=='deliverInputEvent'||slice.title=='RV Scroll')
-preFrameEvents.push(slice);});uiThread.asyncSliceGroup.slices.forEach(function(slice){if(slice.title=='deliverInputEvent')
-preFrameEvents.push(slice);});return tr.b.mergeRanges(tr.b.convertEventsToRanges(preFrameEvents),3,function(events){return{start:events[0].min,end:events[events.length-1].max};});}
-function getFrameStartTime(traversalStart,preTraversalWorkRanges){var preTraversalWorkRange=tr.b.findClosestIntervalInSortedIntervals(preTraversalWorkRanges,function(range){return range.start},function(range){return range.end},traversalStart,3);if(preTraversalWorkRange)
-return preTraversalWorkRange.start;return traversalStart;}
-function getUiThreadDrivenFrames(app){if(!app.uiThread)
-return[];var preTraversalWorkRanges=[];if(app.uiDrawType==UI_DRAW_TYPE.LEGACY)
-preTraversalWorkRanges=getPreTraversalWorkRanges(app.uiThread);var frames=[];app.uiThread.sliceGroup.slices.forEach(function(slice){if(!(slice.title in UI_THREAD_DRAW_NAMES)){return;}
-var threadTimeRanges=[];var uiThreadTimeRange={thread:app.uiThread,start:getFrameStartTime(slice.start,preTraversalWorkRanges),end:slice.end};threadTimeRanges.push(uiThreadTimeRange);var rtDrawSlice=findOverlappingDrawFrame(app.renderThread,slice.end);if(rtDrawSlice){var rtSyncSlice=rtDrawSlice.findDescendentSlice(THREAD_SYNC_NAME);if(rtSyncSlice){uiThreadTimeRange.end=Math.min(uiThreadTimeRange.end,rtSyncSlice.start);}
-threadTimeRanges.push({thread:app.renderThread,start:rtDrawSlice.start,end:rtDrawSlice.end});}
-frames.push(makeFrame(threadTimeRanges,app.surfaceFlinger));});return frames;}
-function getRenderThreadDrivenFrames(app){if(!app.renderThread)
-return[];var frames=[];app.renderThread.sliceGroup.getSlicesOfName(RENDER_THREAD_INDEP_DRAW_NAME).forEach(function(slice){var threadTimeRanges=[{thread:app.renderThread,start:slice.start,end:slice.end}];frames.push(makeFrame(threadTimeRanges,app.surfaceFlinger));});return frames;}
-function getUiDrawType(uiThread){if(!uiThread)
-return UI_DRAW_TYPE.NONE;var slices=uiThread.sliceGroup.slices;for(var i=0;i<slices.length;i++){if(slices[i].title in UI_THREAD_DRAW_NAMES){return UI_THREAD_DRAW_NAMES[slices[i].title];}}
-return UI_DRAW_TYPE.NONE;}
-function getInputSamples(process){var samples=undefined;for(var counterName in process.counters){if(/^android\.aq\:pending/.test(counterName)&&process.counters[counterName].numSeries==1){samples=process.counters[counterName].series[0].samples;break;}}
-if(!samples)
-return[];var inputSamples=[];var lastValue=0;samples.forEach(function(sample){if(sample.value>lastValue){inputSamples.push(sample);}
-lastValue=sample.value;});return inputSamples;}
-function getAnimationAsyncSlices(uiThread){if(!uiThread)
-return[];var slices=[];uiThread.asyncSliceGroup.iterateAllEvents(function(slice){if(/^animator\:/.test(slice.title))
-slices.push(slice);});return slices;}
-function AndroidApp(process,uiThread,renderThread,surfaceFlinger,uiDrawType){this.process=process;this.uiThread=uiThread;this.renderThread=renderThread;this.surfaceFlinger=surfaceFlinger;this.uiDrawType=uiDrawType;this.frames_=undefined;this.inputs_=undefined;};AndroidApp.createForProcessIfPossible=function(process,surfaceFlinger){var uiThread=process.getThread(process.pid);var uiDrawType=getUiDrawType(uiThread);if(uiDrawType==UI_DRAW_TYPE.NONE){uiThread=undefined;}
-var renderThreads=process.findAllThreadsNamed('RenderThread');var renderThread=renderThreads.length==1?renderThreads[0]:undefined;if(uiThread||renderThread){return new AndroidApp(process,uiThread,renderThread,surfaceFlinger,uiDrawType);}};AndroidApp.prototype={getFrames:function(){if(!this.frames_){var uiFrames=getUiThreadDrivenFrames(this);var rtFrames=getRenderThreadDrivenFrames(this);this.frames_=uiFrames.concat(rtFrames);this.frames_.sort(function(a,b){a.end-b.end});}
-return this.frames_;},getInputSamples:function(){if(!this.inputs_){this.inputs_=getInputSamples(this.process);}
-return this.inputs_;},getAnimationAsyncSlices:function(){if(!this.animations_){this.animations_=getAnimationAsyncSlices(this.uiThread);}
-return this.animations_;}};return{AndroidApp:AndroidApp};});'use strict';tr.exportTo('tr.model.helpers',function(){var findLowIndexInSortedArray=tr.b.findLowIndexInSortedArray;var VSYNC_SF_NAME='android.VSYNC-sf';var VSYNC_APP_NAME='android.VSYNC-app';var VSYNC_FALLBACK_NAME='android.VSYNC';var TIMESTAMP_FUDGE_MS=0.01;function getVsyncTimestamps(process,counterName){var vsync=process.counters[counterName];if(!vsync)
-vsync=process.counters[VSYNC_FALLBACK_NAME];if(vsync&&vsync.numSeries==1&&vsync.numSamples>1)
-return vsync.series[0].timestamps;return undefined;}
-function AndroidSurfaceFlinger(process,thread){this.process=process;this.thread=thread;this.appVsync_=undefined;this.sfVsync_=undefined;this.appVsyncTimestamps_=getVsyncTimestamps(process,VSYNC_APP_NAME);this.sfVsyncTimestamps_=getVsyncTimestamps(process,VSYNC_SF_NAME);};AndroidSurfaceFlinger.createForProcessIfPossible=function(process){var mainThread=process.getThread(process.pid);if(mainThread&&mainThread.name&&/surfaceflinger/.test(mainThread.name))
-return new AndroidSurfaceFlinger(process,mainThread);var primaryThreads=process.findAllThreadsNamed('SurfaceFlinger');if(primaryThreads.length==1)
-return new AndroidSurfaceFlinger(process,primaryThreads[0]);return undefined;};AndroidSurfaceFlinger.prototype={get hasVsyncs(){return!!this.appVsyncTimestamps_&&!!this.sfVsyncTimestamps_;},getFrameKickoff:function(timestamp){if(!this.hasVsyncs)
-throw new Error('cannot query vsync info without vsyncs');var firstGreaterIndex=findLowIndexInSortedArray(this.appVsyncTimestamps_,function(x){return x;},timestamp+TIMESTAMP_FUDGE_MS);if(firstGreaterIndex<1)
-return undefined;return this.appVsyncTimestamps_[firstGreaterIndex-1];},getFrameDeadline:function(timestamp){if(!this.hasVsyncs)
-throw new Error('cannot query vsync info without vsyncs');var firstGreaterIndex=findLowIndexInSortedArray(this.sfVsyncTimestamps_,function(x){return x;},timestamp+TIMESTAMP_FUDGE_MS);if(firstGreaterIndex>=this.sfVsyncTimestamps_.length)
-return undefined;return this.sfVsyncTimestamps_[firstGreaterIndex];}};return{AndroidSurfaceFlinger:AndroidSurfaceFlinger};});'use strict';tr.exportTo('tr.model.helpers',function(){var AndroidApp=tr.model.helpers.AndroidApp;var AndroidSurfaceFlinger=tr.model.helpers.AndroidSurfaceFlinger;var IMPORTANT_SURFACE_FLINGER_SLICES={'doComposition':true,'updateTexImage':true,'postFramebuffer':true};var IMPORTANT_UI_THREAD_SLICES={'Choreographer#doFrame':true,'performTraversals':true,'deliverInputEvent':true};var IMPORTANT_RENDER_THREAD_SLICES={'doFrame':true};function iterateImportantThreadSlices(thread,important,callback){if(!thread)
-return;thread.sliceGroup.slices.forEach(function(slice){if(slice.title in important)
-callback(slice);});}
-function AndroidModelHelper(model){this.model=model;this.apps=[];this.surfaceFlinger=undefined;var processes=model.getAllProcesses();for(var i=0;i<processes.length&&!this.surfaceFlinger;i++){this.surfaceFlinger=AndroidSurfaceFlinger.createForProcessIfPossible(processes[i]);}
-model.getAllProcesses().forEach(function(process){var app=AndroidApp.createForProcessIfPossible(process,this.surfaceFlinger);if(app)
-this.apps.push(app);},this);};AndroidModelHelper.guid=tr.b.GUID.allocate();AndroidModelHelper.supportsModel=function(model){return true;};AndroidModelHelper.prototype={iterateImportantSlices:function(callback){if(this.surfaceFlinger){iterateImportantThreadSlices(this.surfaceFlinger.thread,IMPORTANT_SURFACE_FLINGER_SLICES,callback);}
-this.apps.forEach(function(app){iterateImportantThreadSlices(app.uiThread,IMPORTANT_UI_THREAD_SLICES,callback);iterateImportantThreadSlices(app.renderThread,IMPORTANT_RENDER_THREAD_SLICES,callback);});}};return{AndroidModelHelper:AndroidModelHelper};});'use strict';tr.exportTo('tr.model',function(){function Slice(category,title,colorId,start,args,opt_duration,opt_cpuStart,opt_cpuDuration,opt_argsStripped,opt_bind_id){tr.model.TimedEvent.call(this,start);this.category=category||'';this.title=title;this.colorId=colorId;this.args=args;this.startStackFrame=undefined;this.endStackFrame=undefined;this.didNotFinish=false;this.inFlowEvents=[];this.outFlowEvents=[];this.subSlices=[];this.selfTime=undefined;this.cpuSelfTime=undefined;this.important=false;this.parentContainer=undefined;this.argsStripped=false;this.bind_id_=opt_bind_id;this.parentSlice=undefined;this.isTopLevel=false;if(opt_duration!==undefined)
-this.duration=opt_duration;if(opt_cpuStart!==undefined)
-this.cpuStart=opt_cpuStart;if(opt_cpuDuration!==undefined)
-this.cpuDuration=opt_cpuDuration;if(opt_argsStripped!==undefined)
-this.argsStripped=true;}
-Slice.prototype={__proto__:tr.model.TimedEvent.prototype,get analysisTypeName(){return this.title;},get userFriendlyName(){return'Slice '+this.title+' at '+
-tr.v.Unit.byName.timeStampInMs.format(this.start);},get stableId(){var parentSliceGroup=this.parentContainer.sliceGroup;return parentSliceGroup.stableId+'.'+
-parentSliceGroup.slices.indexOf(this);},findDescendentSlice:function(targetTitle){if(!this.subSlices)
-return undefined;for(var i=0;i<this.subSlices.length;i++){if(this.subSlices[i].title==targetTitle)
-return this.subSlices[i];var slice=this.subSlices[i].findDescendentSlice(targetTitle);if(slice)return slice;}
-return undefined;},get mostTopLevelSlice(){var curSlice=this;while(curSlice.parentSlice)
-curSlice=curSlice.parentSlice;return curSlice;},getProcess:function(){var thread=this.parentContainer;if(thread&&thread.getProcess)
-return thread.getProcess();return undefined;},get model(){var process=this.getProcess();if(process!==undefined)
-return this.getProcess().model;return undefined;},iterateAllSubsequentSlices:function(callback,opt_this){var parentStack=[];var started=false;var topmostSlice=this.mostTopLevelSlice;parentStack.push(topmostSlice);while(parentStack.length!==0){var curSlice=parentStack.pop();if(started)
-callback.call(opt_this,curSlice);else
-started=(curSlice.guid===this.guid);for(var i=curSlice.subSlices.length-1;i>=0;i--){parentStack.push(curSlice.subSlices[i]);}}},get subsequentSlices(){var res=[];this.iterateAllSubsequentSlices(function(subseqSlice){res.push(subseqSlice);});return res;},iterateAllAncestors:function(callback,opt_this){var curSlice=this;while(curSlice.parentSlice){curSlice=curSlice.parentSlice;callback.call(opt_this,curSlice);}},get ancestorSlices(){var res=[];this.iterateAllAncestors(function(ancestor){res.push(ancestor);});return res;},iterateEntireHierarchy:function(callback,opt_this){var mostTopLevelSlice=this.mostTopLevelSlice;callback.call(opt_this,mostTopLevelSlice);mostTopLevelSlice.iterateAllSubsequentSlices(callback,opt_this);},get entireHierarchy(){var res=[];this.iterateEntireHierarchy(function(slice){res.push(slice);});return res;},get ancestorAndSubsequentSlices(){var res=[];res.push(this);this.iterateAllAncestors(function(aSlice){res.push(aSlice);});this.iterateAllSubsequentSlices(function(sSlice){res.push(sSlice);});return res;},iterateAllDescendents:function(callback,opt_this){this.subSlices.forEach(callback,opt_this);this.subSlices.forEach(function(subSlice){subSlice.iterateAllDescendents(callback,opt_this);},opt_this);},get descendentSlices(){var res=[];this.iterateAllDescendents(function(des){res.push(des);});return res;}};return{Slice:Slice};});'use strict';tr.exportTo('tr.model',function(){var Slice=tr.model.Slice;var SCHEDULING_STATE={DEBUG:'Debug',EXIT_DEAD:'Exit Dead',RUNNABLE:'Runnable',RUNNING:'Running',SLEEPING:'Sleeping',STOPPED:'Stopped',TASK_DEAD:'Task Dead',UNINTR_SLEEP:'Uninterruptible Sleep',UNINTR_SLEEP_WAKE_KILL:'Uninterruptible Sleep | WakeKill',UNINTR_SLEEP_WAKING:'Uninterruptible Sleep | Waking',UNINTR_SLEEP_IO:'Uninterruptible Sleep - Block I/O',UNINTR_SLEEP_WAKE_KILL_IO:'Uninterruptible Sleep | WakeKill - Block I/O',UNINTR_SLEEP_WAKING_IO:'Uninterruptible Sleep | Waking - Block I/O',UNKNOWN:'UNKNOWN',WAKE_KILL:'Wakekill',WAKING:'Waking',ZOMBIE:'Zombie'};function ThreadTimeSlice(thread,schedulingState,cat,start,args,opt_duration){Slice.call(this,cat,schedulingState,this.getColorForState_(schedulingState),start,args,opt_duration);this.thread=thread;this.schedulingState=schedulingState;this.cpuOnWhichThreadWasRunning=undefined;}
-ThreadTimeSlice.prototype={__proto__:Slice.prototype,getColorForState_:function(state){var getColorIdForReservedName=tr.b.ColorScheme.getColorIdForReservedName;switch(state){case SCHEDULING_STATE.RUNNABLE:return getColorIdForReservedName('thread_state_runnable');case SCHEDULING_STATE.RUNNING:return getColorIdForReservedName('thread_state_running');case SCHEDULING_STATE.SLEEPING:return getColorIdForReservedName('thread_state_sleeping');case SCHEDULING_STATE.DEBUG:case SCHEDULING_STATE.EXIT_DEAD:case SCHEDULING_STATE.STOPPED:case SCHEDULING_STATE.TASK_DEAD:case SCHEDULING_STATE.UNINTR_SLEEP:case SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL:case SCHEDULING_STATE.UNINTR_SLEEP_WAKING:case SCHEDULING_STATE.UNKNOWN:case SCHEDULING_STATE.WAKE_KILL:case SCHEDULING_STATE.WAKING:case SCHEDULING_STATE.ZOMBIE:return getColorIdForReservedName('thread_state_uninterruptible');case SCHEDULING_STATE.UNINTR_SLEEP_IO:case SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL_IO:case SCHEDULING_STATE.UNINTR_SLEEP_WAKING_IO:return getColorIdForReservedName('thread_state_iowait');default:return getColorIdForReservedName('thread_state_unknown');}},get analysisTypeName(){return'tr.ui.analysis.ThreadTimeSlice';},getAssociatedCpuSlice:function(){if(!this.cpuOnWhichThreadWasRunning)
-return undefined;var cpuSlices=this.cpuOnWhichThreadWasRunning.slices;for(var i=0;i<cpuSlices.length;i++){var cpuSlice=cpuSlices[i];if(cpuSlice.start!==this.start)
-continue;if(cpuSlice.duration!==this.duration)
-continue;return cpuSlice;}
-return undefined;},getCpuSliceThatTookCpu:function(){if(this.cpuOnWhichThreadWasRunning)
-return undefined;var curIndex=this.thread.indexOfTimeSlice(this);var cpuSliceWhenLastRunning;while(curIndex>=0){var curSlice=this.thread.timeSlices[curIndex];if(!curSlice.cpuOnWhichThreadWasRunning){curIndex--;continue;}
-cpuSliceWhenLastRunning=curSlice.getAssociatedCpuSlice();break;}
-if(!cpuSliceWhenLastRunning)
-return undefined;var cpu=cpuSliceWhenLastRunning.cpu;var indexOfSliceOnCpuWhenLastRunning=cpu.indexOf(cpuSliceWhenLastRunning);var nextRunningSlice=cpu.slices[indexOfSliceOnCpuWhenLastRunning+1];if(!nextRunningSlice)
-return undefined;if(Math.abs(nextRunningSlice.start-cpuSliceWhenLastRunning.end)<0.00001)
-return nextRunningSlice;return undefined;}};tr.model.EventRegistry.register(ThreadTimeSlice,{name:'threadTimeSlice',pluralName:'threadTimeSlices',singleViewElementName:'tr-ui-a-single-thread-time-slice-sub-view',multiViewElementName:'tr-ui-a-multi-thread-time-slice-sub-view'});return{ThreadTimeSlice:ThreadTimeSlice,SCHEDULING_STATE:SCHEDULING_STATE};});'use strict';tr.exportTo('tr.model',function(){var CompoundEventSelectionState={NOT_SELECTED:0,EVENT_SELECTED:0x1,SOME_ASSOCIATED_EVENTS_SELECTED:0x2,ALL_ASSOCIATED_EVENTS_SELECTED:0x4,EVENT_AND_SOME_ASSOCIATED_SELECTED:0x1|0x2,EVENT_AND_ALL_ASSOCIATED_SELECTED:0x1|0x4};return{CompoundEventSelectionState:CompoundEventSelectionState};});'use strict';tr.exportTo('tr.model.um',function(){var CompoundEventSelectionState=tr.model.CompoundEventSelectionState;function UserExpectation(parentModel,initiatorTitle,start,duration){tr.model.TimedEvent.call(this,start);this.associatedEvents=new tr.model.EventSet();this.duration=duration;this.initiatorTitle_=initiatorTitle;this.parentModel=parentModel;this.typeInfo_=undefined;this.sourceEvents=new tr.model.EventSet();}
-UserExpectation.prototype={__proto__:tr.model.TimedEvent.prototype,computeCompoundEvenSelectionState:function(selection){var cess=CompoundEventSelectionState.NOT_SELECTED;if(selection.contains(this))
-cess|=CompoundEventSelectionState.EVENT_SELECTED;if(this.associatedEvents.intersectionIsEmpty(selection))
-return cess;var allContained=this.associatedEvents.every(function(event){return selection.contains(event);});if(allContained)
-cess|=CompoundEventSelectionState.ALL_ASSOCIATED_EVENTS_SELECTED;else
-cess|=CompoundEventSelectionState.SOME_ASSOCIATED_EVENTS_SELECTED;return cess;},get userFriendlyName(){return this.title+' User Expectation at '+
-tr.v.Unit.byName.timeStampInMs.format(this.start);},get stableId(){return('UserExpectation.'+
-this.parentModel.userModel.expectations.indexOf(this));},get typeInfo(){if(!this.typeInfo_)
-this.typeInfo_=UserExpectation.findTypeInfo(this.constructor);if(!this.typeInfo_)
-throw new Error('Unregistered UserExpectation');return this.typeInfo_;},get colorId(){return this.typeInfo.metadata.colorId;},get stageTitle(){return this.typeInfo.metadata.stageTitle;},get initiatorTitle(){return this.initiatorTitle_;},get title(){if(!this.initiatorTitle)
-return this.stageTitle;return this.initiatorTitle+' '+this.stageTitle;},get totalCpuMs(){var cpuMs=0;this.associatedEvents.forEach(function(event){if(event.cpuSelfTime)
-cpuMs+=event.cpuSelfTime;});return cpuMs;}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(UserExpectation,options);UserExpectation.addEventListener('will-register',function(e){var metadata=e.typeInfo.metadata;if(metadata.stageTitle===undefined){throw new Error('Registered UserExpectations must provide '+'stageTitle');}
-if(metadata.colorId===undefined){throw new Error('Registered UserExpectations must provide '+'colorId');}});tr.model.EventRegistry.register(UserExpectation,{name:'user-expectation',pluralName:'user-expectations',singleViewElementName:'tr-ui-a-single-user-expectation-sub-view',multiViewElementName:'tr-ui-a-multi-user-expectation-sub-view'});return{UserExpectation:UserExpectation};});'use strict';tr.exportTo('tr.model.um',function(){function ResponseExpectation(parentModel,initiatorTitle,start,duration,opt_isAnimationBegin){tr.model.um.UserExpectation.call(this,parentModel,initiatorTitle,start,duration);this.isAnimationBegin=opt_isAnimationBegin||false;}
-ResponseExpectation.prototype={__proto__:tr.model.um.UserExpectation.prototype,constructor:ResponseExpectation};tr.model.um.UserExpectation.register(ResponseExpectation,{stageTitle:'Response',colorId:tr.b.ColorScheme.getColorIdForReservedName('rail_response')});return{ResponseExpectation:ResponseExpectation};});'use strict';tr.exportTo('tr.v',function(){var Range=tr.b.Range;var MAX_SOURCE_INFOS=16;function NumericBase(unit){if(!(unit instanceof tr.v.Unit))
-throw new Error('Expected provided unit to be instance of Unit');this.unit=unit;}
-NumericBase.prototype={asDict:function(){var d={unit:this.unit.asJSON()};this.asDictInto_(d);return d;}};NumericBase.fromDict=function(d){if(d.type==='scalar')
-return ScalarNumeric.fromDict(d);throw new Error('Not implemented');};function NumericBin(parentNumeric,opt_range){this.parentNumeric=parentNumeric;this.range=opt_range||(new tr.b.Range());this.count=0;this.sourceInfos=[];}
-NumericBin.fromDict=function(parentNumeric,d){var n=new NumericBin(parentNumeric);n.range.min=d.min;n.range.max=d.max;n.count=d.count;n.sourceInfos=d.sourceInfos;return n;};NumericBin.prototype={add:function(value,sourceInfo){this.count+=1;tr.b.Statistics.uniformlySampleStream(this.sourceInfos,this.count,sourceInfo,MAX_SOURCE_INFOS);},addBin:function(other){if(!this.range.equals(other.range))
-throw new Error('Merging incompatible Numeric bins.');tr.b.Statistics.mergeSampledStreams(this.sourceInfos,this.count,other.sourceInfos,other.count,MAX_SOURCE_INFOS);this.count+=other.count;},asDict:function(){return{min:this.range.min,max:this.range.max,count:this.count,sourceInfos:this.sourceInfos.slice(0)};},asJSON:function(){return this.asDict();}};function Numeric(unit,range,binInfo){NumericBase.call(this,unit);this.range=range;this.numNans=0;this.nanSourceInfos=[];this.runningSum=0;this.maxCount_=0;this.underflowBin=binInfo.underflowBin;this.centralBins=binInfo.centralBins;this.centralBinWidth=binInfo.centralBinWidth;this.overflowBin=binInfo.overflowBin;this.allBins=[];this.allBins.push(this.underflowBin);this.allBins.push.apply(this.allBins,this.centralBins);this.allBins.push(this.overflowBin);this.allBins.forEach(function(bin){if(bin.count>this.maxCount_)
-this.maxCount_=bin.count;},this);}
-Numeric.fromDict=function(d){var range=Range.fromExplicitRange(d.min,d.max);var binInfo={};binInfo.underflowBin=NumericBin.fromDict(undefined,d.underflowBin);binInfo.centralBins=d.centralBins.map(function(binAsDict){return NumericBin.fromDict(undefined,binAsDict);});binInfo.centralBinWidth=d.centralBinWidth;binInfo.overflowBin=NumericBin.fromDict(undefined,d.overflowBin);var n=new Numeric(tr.v.Unit.fromJSON(d.unit),range,binInfo);n.allBins.forEach(function(bin){bin.parentNumeric=n;});n.runningSum=d.runningSum;n.numNans=d.numNans;n.nanSourceInfos=d.nanSourceInfos;return n;};Numeric.createLinear=function(unit,range,numBins){if(range.isEmpty)
-throw new Error('Nope');var binInfo={};binInfo.underflowBin=new NumericBin(this,Range.fromExplicitRange(-Number.MAX_VALUE,range.min));binInfo.overflowBin=new NumericBin(this,Range.fromExplicitRange(range.max,Number.MAX_VALUE));binInfo.centralBins=[];binInfo.centralBinWidth=range.range/numBins;for(var i=0;i<numBins;i++){var lo=range.min+(binInfo.centralBinWidth*i);var hi=lo+binInfo.centralBinWidth;binInfo.centralBins.push(new NumericBin(undefined,Range.fromExplicitRange(lo,hi)));}
-var n=new Numeric(unit,range,binInfo);n.allBins.forEach(function(bin){bin.parentNumeric=n;});return n;};Numeric.prototype={__proto__:NumericBase.prototype,get numValues(){return tr.b.Statistics.sum(this.allBins,function(e){return e.count;});},get average(){return this.runningSum/this.numValues;},get maxCount(){return this.maxCount_;},getInterpolatedCountAt:function(value){var bin=this.getBinForValue(value);var idx=this.centralBins.indexOf(bin);if(idx<0){return bin.count;}
-var lesserBin=bin;var greaterBin=bin;var lesserBinCenter=undefined;var greaterBinCenter=undefined;if(value<greaterBin.range.center){if(idx>0){lesserBin=this.centralBins[idx-1];}else{lesserBin=this.underflowBin;lesserBinCenter=lesserBin.range.max;}}else{if(idx<(this.centralBins.length-1)){greaterBin=this.centralBins[idx+1];}else{greaterBin=this.overflowBin;greaterBinCenter=greaterBin.range.min;}}
-if(greaterBinCenter===undefined)
-greaterBinCenter=greaterBin.range.center;if(lesserBinCenter===undefined)
-lesserBinCenter=lesserBin.range.center;value=tr.b.normalize(value,lesserBinCenter,greaterBinCenter);return tr.b.lerp(value,lesserBin.count,greaterBin.count);},getBinForValue:function(value){if(value<this.range.min)
-return this.underflowBin;if(value>=this.range.max)
-return this.overflowBin;var binIdx=Math.floor((value-this.range.min)/this.centralBinWidth);return this.centralBins[binIdx];},add:function(value,sourceInfo){if(typeof(value)!=='number'||isNaN(value)){this.numNans++;tr.b.Statistics.uniformlySampleStream(this.nanSourceInfos,this.numNans,sourceInfo,MAX_SOURCE_INFOS);return;}
-var bin=this.getBinForValue(value);bin.add(value,sourceInfo);this.runningSum+=value;if(bin.count>this.maxCount_)
-this.maxCount_=bin.count;},addNumeric:function(other){if(!this.range.equals(other.range)||!this.unit===other.unit||this.allBins.length!==other.allBins.length){throw new Error('Merging incompatible Numerics.');}
-tr.b.Statistics.mergeSampledStreams(this.nanSourceInfos,this.numNans,other.nanSourceInfos,other.numNans,MAX_SOURCE_INFOS);this.numNans+=other.numNans;this.runningSum+=other.runningSum;for(var i=0;i<this.allBins.length;++i){this.allBins[i].addBin(other.allBins[i]);}},clone:function(){return Numeric.fromDict(this.asDict());},asDict:function(){var d={unit:this.unit.asJSON(),min:this.range.min,max:this.range.max,numNans:this.numNans,nanSourceInfos:this.nanSourceInfos,runningSum:this.runningSum,underflowBin:this.underflowBin.asDict(),centralBins:this.centralBins.map(function(bin){return bin.asDict();}),centralBinWidth:this.centralBinWidth,overflowBin:this.overflowBin.asDict()};return d;},asJSON:function(){return this.asDict();}};function ScalarNumeric(unit,value){if(!(typeof(value)=='number'))
-throw new Error('Expected value to be number');NumericBase.call(this,unit);this.value=value;}
-ScalarNumeric.prototype={__proto__:NumericBase.prototype,asDictInto_:function(d){d.type='scalar';d.value=this.value;},toString:function(){return this.unit.format(this.value);}};ScalarNumeric.fromDict=function(d){return new ScalarNumeric(tr.v.Unit.fromJSON(d.unit),d.value);};return{NumericBase:NumericBase,NumericBin:NumericBin,Numeric:Numeric,ScalarNumeric:ScalarNumeric};});'use strict';tr.exportTo('tr.e.audits',function(){var SCHEDULING_STATE=tr.model.SCHEDULING_STATE;var Auditor=tr.c.Auditor;var AndroidModelHelper=tr.model.helpers.AndroidModelHelper;var ColorScheme=tr.b.ColorScheme;var Statistics=tr.b.Statistics;var FRAME_PERF_CLASS=tr.model.FRAME_PERF_CLASS;var Alert=tr.model.Alert;var EventInfo=tr.model.EventInfo;var ScalarNumeric=tr.v.ScalarNumeric;var timeDurationInMs=tr.v.Unit.byName.timeDurationInMs;var EXPECTED_FRAME_TIME_MS=16.67;function getStart(e){return e.start;}
-function getDuration(e){return e.duration;}
-function getCpuDuration(e){return(e.cpuDuration!==undefined)?e.cpuDuration:e.duration;}
-function frameIsActivityStart(frame){for(var i=0;i<frame.associatedEvents.length;i++){if(frame.associatedEvents[i].title=='activityStart')
-return true;}
-return false;}
-function frameMissedDeadline(frame){return frame.args['deadline']&&frame.args['deadline']<frame.end;}
-function DocLinkBuilder(){this.docLinks=[];}
-DocLinkBuilder.prototype={addAppVideo:function(name,videoId){this.docLinks.push({label:'Video Link',textContent:('Android Performance Patterns: '+name),href:'https://www.youtube.com/watch?list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE&v='+videoId});return this;},addDacRef:function(name,link){this.docLinks.push({label:'Doc Link',textContent:(name+' documentation'),href:'https://developer.android.com/reference/'+link});return this;},build:function(){return this.docLinks;}};function AndroidAuditor(model){Auditor.call(this,model);var helper=model.getOrCreateHelper(AndroidModelHelper);if(helper.apps.length||helper.surfaceFlinger)
-this.helper=helper;};AndroidAuditor.viewAlphaAlertInfo_=new EventInfo('Inefficient View alpha usage','Setting an alpha between 0 and 1 has significant performance costs, if one of the fast alpha paths is not used.',new DocLinkBuilder().addAppVideo('Hidden Cost of Transparency','wIy8g8yNhNk').addDacRef('View#setAlpha()','android/view/View.html#setAlpha(float)').build());AndroidAuditor.saveLayerAlertInfo_=new EventInfo('Expensive rendering with Canvas#saveLayer()','Canvas#saveLayer() incurs extremely high rendering cost. They disrupt the rendering pipeline when drawn, forcing a flush of drawing content. Instead use View hardware layers, or static Bitmaps. This enables the offscreen buffers to be reused in between frames, and avoids the disruptive render target switch.',new DocLinkBuilder().addAppVideo('Hidden Cost of Transparency','wIy8g8yNhNk').addDacRef('Canvas#saveLayerAlpha()','android/graphics/Canvas.html#saveLayerAlpha(android.graphics.RectF, int, int)').build());AndroidAuditor.getSaveLayerAlerts_=function(frame){var badAlphaRegEx=/^(.+) alpha caused (unclipped )?saveLayer (\d+)x(\d+)$/;var saveLayerRegEx=/^(unclipped )?saveLayer (\d+)x(\d+)$/;var ret=[];var events=[];frame.associatedEvents.forEach(function(slice){var match=badAlphaRegEx.exec(slice.title);if(match){var args={'view name':match[1],width:parseInt(match[3]),height:parseInt(match[4])};ret.push(new Alert(AndroidAuditor.viewAlphaAlertInfo_,slice.start,[slice],args));}else if(saveLayerRegEx.test(slice.title))
-events.push(slice);},this);if(events.length>ret.length){var unclippedSeen=Statistics.sum(events,function(slice){return saveLayerRegEx.exec(slice.title)[1]?1:0;});var clippedSeen=events.length-unclippedSeen;var earliestStart=Statistics.min(events,function(slice){return slice.start;});var args={'Unclipped saveLayer count (especially bad!)':unclippedSeen,'Clipped saveLayer count':clippedSeen};events.push(frame);ret.push(new Alert(AndroidAuditor.saveLayerAlertInfo_,earliestStart,events,args));}
-return ret;};AndroidAuditor.pathAlertInfo_=new EventInfo('Path texture churn','Paths are drawn with a mask texture, so when a path is modified / newly drawn, that texture must be generated and uploaded to the GPU. Ensure that you cache paths between frames and do not unnecessarily call Path#reset(). You can cut down on this cost by sharing Path object instances between drawables/views.');AndroidAuditor.getPathAlert_=function(frame){var uploadRegEx=/^Generate Path Texture$/;var events=frame.associatedEvents.filter(function(event){return event.title=='Generate Path Texture';});var start=Statistics.min(events,getStart);var duration=Statistics.sum(events,getDuration);if(duration<3)
-return undefined;events.push(frame);return new Alert(AndroidAuditor.pathAlertInfo_,start,events,{'Time spent':new ScalarNumeric(timeDurationInMs,duration)});};AndroidAuditor.uploadAlertInfo_=new EventInfo('Expensive Bitmap uploads','Bitmaps that have been modified / newly drawn must be uploaded to the GPU. Since this is expensive if the total number of pixels uploaded is large, reduce the amount of Bitmap churn in this animation/context, per frame.');AndroidAuditor.getUploadAlert_=function(frame){var uploadRegEx=/^Upload (\d+)x(\d+) Texture$/;var events=[];var start=Number.POSITIVE_INFINITY;var duration=0;var pixelsUploaded=0;frame.associatedEvents.forEach(function(event){var match=uploadRegEx.exec(event.title);if(match){events.push(event);start=Math.min(start,event.start);duration+=event.duration;pixelsUploaded+=parseInt(match[1])*parseInt(match[2]);}});if(events.length==0||duration<3)
-return undefined;var mPixels=(pixelsUploaded/1000000).toFixed(2)+' million';var args={'Pixels uploaded':mPixels,'Time spent':new ScalarNumeric(timeDurationInMs,duration)};events.push(frame);return new Alert(AndroidAuditor.uploadAlertInfo_,start,events,args);};AndroidAuditor.ListViewInflateAlertInfo_=new EventInfo('Inflation during ListView recycling','ListView item recycling involved inflating views. Ensure your Adapter#getView() recycles the incoming View, instead of constructing a new one.');AndroidAuditor.ListViewBindAlertInfo_=new EventInfo('Inefficient ListView recycling/rebinding','ListView recycling taking too much time per frame. Ensure your Adapter#getView() binds data efficiently.');AndroidAuditor.getListViewAlert_=function(frame){var events=frame.associatedEvents.filter(function(event){return event.title=='obtainView'||event.title=='setupListItem';});var duration=Statistics.sum(events,getCpuDuration);if(events.length==0||duration<3)
-return undefined;var hasInflation=false;for(var i=0;i<events.length;i++){if(events[i]instanceof tr.model.Slice&&events[i].findDescendentSlice('inflate')){hasInflation=true;break;}}
-var start=Statistics.min(events,getStart);var args={'Time spent':new ScalarNumeric(timeDurationInMs,duration)};args['ListView items '+(hasInflation?'inflated':'rebound')]=events.length/2;var eventInfo=hasInflation?AndroidAuditor.ListViewInflateAlertInfo_:AndroidAuditor.ListViewBindAlertInfo_;events.push(frame);return new Alert(eventInfo,start,events,args);};AndroidAuditor.measureLayoutAlertInfo_=new EventInfo('Expensive measure/layout pass','Measure/Layout took a significant time, contributing to jank. Avoid triggering layout during animations.',new DocLinkBuilder().addAppVideo('Invalidations, Layouts, and Performance','we6poP0kw6E').build());AndroidAuditor.getMeasureLayoutAlert_=function(frame){var events=frame.associatedEvents.filter(function(event){return event.title=='measure'||event.title=='layout';});var duration=Statistics.sum(events,getCpuDuration);if(events.length==0||duration<3)
-return undefined;var start=Statistics.min(events,getStart);events.push(frame);return new Alert(AndroidAuditor.measureLayoutAlertInfo_,start,events,{'Time spent':new ScalarNumeric(timeDurationInMs,duration)});};AndroidAuditor.viewDrawAlertInfo_=new EventInfo('Long View#draw()','Recording the drawing commands of invalidated Views took a long time. Avoid significant work in View or Drawable custom drawing, especially allocations or drawing to Bitmaps.',new DocLinkBuilder().addAppVideo('Invalidations, Layouts, and Performance','we6poP0kw6E').addAppVideo('Avoiding Allocations in onDraw()','HAK5acHQ53E').build());AndroidAuditor.getViewDrawAlert_=function(frame){var slice=undefined;for(var i=0;i<frame.associatedEvents.length;i++){if(frame.associatedEvents[i].title=='getDisplayList'||frame.associatedEvents[i].title=='Record View#draw()'){slice=frame.associatedEvents[i];break;}}
-if(!slice||getCpuDuration(slice)<3)
-return undefined;return new Alert(AndroidAuditor.viewDrawAlertInfo_,slice.start,[slice,frame],{'Time spent':new ScalarNumeric(timeDurationInMs,getCpuDuration(slice))});};AndroidAuditor.blockingGcAlertInfo_=new EventInfo('Blocking Garbage Collection','Blocking GCs are caused by object churn, and made worse by having large numbers of objects in the heap. Avoid allocating objects during animations/scrolling, and recycle Bitmaps to avoid triggering garbage collection.',new DocLinkBuilder().addAppVideo('Garbage Collection in Android','pzfzz50W5Uo').addAppVideo('Avoiding Allocations in onDraw()','HAK5acHQ53E').build());AndroidAuditor.getBlockingGcAlert_=function(frame){var events=frame.associatedEvents.filter(function(event){return event.title=='DVM Suspend'||event.title=='GC: Wait For Concurrent';});var blockedDuration=Statistics.sum(events,getDuration);if(blockedDuration<3)
-return undefined;var start=Statistics.min(events,getStart);events.push(frame);return new Alert(AndroidAuditor.blockingGcAlertInfo_,start,events,{'Blocked duration':new ScalarNumeric(timeDurationInMs,blockedDuration)});};AndroidAuditor.lockContentionAlertInfo_=new EventInfo('Lock contention','UI thread lock contention is caused when another thread holds a lock that the UI thread is trying to use. UI thread progress is blocked until the lock is released. Inspect locking done within the UI thread, and ensure critical sections are short.');AndroidAuditor.getLockContentionAlert_=function(frame){var events=frame.associatedEvents.filter(function(event){return/^Lock Contention on /.test(event.title);});var blockedDuration=Statistics.sum(events,getDuration);if(blockedDuration<1)
-return undefined;var start=Statistics.min(events,getStart);events.push(frame);return new Alert(AndroidAuditor.lockContentionAlertInfo_,start,events,{'Blocked duration':new ScalarNumeric(timeDurationInMs,blockedDuration)});};AndroidAuditor.schedulingAlertInfo_=new EventInfo('Scheduling delay','Work to produce this frame was descheduled for several milliseconds, contributing to jank. Ensure that code on the UI thread doesn\'t block on work being done on other threads, and that background threads (doing e.g. network or bitmap loading) are running at android.os.Process#THREAD_PRIORITY_BACKGROUND or lower so they are less likely to interrupt the UI thread. These background threads should show up with a priority number of 130 or higher in the scheduling section under the Kernel process.');AndroidAuditor.getSchedulingAlert_=function(frame){var totalDuration=0;var totalStats={};frame.threadTimeRanges.forEach(function(ttr){var stats=ttr.thread.getSchedulingStatsForRange(ttr.start,ttr.end);tr.b.iterItems(stats,function(key,value){if(!(key in totalStats))
-totalStats[key]=0;totalStats[key]+=value;totalDuration+=value;});});if(!(SCHEDULING_STATE.RUNNING in totalStats)||totalDuration==0||totalDuration-totalStats[SCHEDULING_STATE.RUNNING]<3)
-return;var args={};tr.b.iterItems(totalStats,function(key,value){if(key===SCHEDULING_STATE.RUNNABLE)
-key='Not scheduled, but runnable';else if(key===SCHEDULING_STATE.UNINTR_SLEEP)
-key='Blocking I/O delay';args[key]=new ScalarNumeric(timeDurationInMs,value);});return new Alert(AndroidAuditor.schedulingAlertInfo_,frame.start,[frame],args);};AndroidAuditor.prototype={__proto__:Auditor.prototype,renameAndSort_:function(){this.model.kernel.important=false;this.model.getAllProcesses().forEach(function(process){if(this.helper.surfaceFlinger&&process==this.helper.surfaceFlinger.process){if(!process.name)
-process.name='SurfaceFlinger';process.sortIndex=Number.NEGATIVE_INFINITY;process.important=false;return;}
-var uiThread=process.getThread(process.pid);if(!process.name&&uiThread&&uiThread.name){if(/^ndroid\./.test(uiThread.name))
-uiThread.name='a'+uiThread.name;process.name=uiThread.name;uiThread.name='UI Thread';}
-process.sortIndex=0;for(var tid in process.threads){process.sortIndex-=process.threads[tid].sliceGroup.slices.length;}},this);this.model.getAllThreads().forEach(function(thread){if(thread.tid==thread.parent.pid)
-thread.sortIndex=-3;if(thread.name=='RenderThread')
-thread.sortIndex=-2;if(/^hwuiTask/.test(thread.name))
-thread.sortIndex=-1;});},pushFramesAndJudgeJank_:function(){var badFramesObserved=0;var framesObserved=0;var surfaceFlinger=this.helper.surfaceFlinger;this.helper.apps.forEach(function(app){app.process.frames=app.getFrames();app.process.frames.forEach(function(frame){if(frame.totalDuration>EXPECTED_FRAME_TIME_MS*2){badFramesObserved+=2;frame.perfClass=FRAME_PERF_CLASS.TERRIBLE;}else if(frame.totalDuration>EXPECTED_FRAME_TIME_MS||frameMissedDeadline(frame)){badFramesObserved++;frame.perfClass=FRAME_PERF_CLASS.BAD;}else{frame.perfClass=FRAME_PERF_CLASS.GOOD;}});framesObserved+=app.process.frames.length;});if(framesObserved){var portionBad=badFramesObserved/framesObserved;if(portionBad>0.3)
-this.model.faviconHue='red';else if(portionBad>0.05)
-this.model.faviconHue='yellow';else
-this.model.faviconHue='green';}},pushEventInfo_:function(){var appAnnotator=new AppAnnotator();this.helper.apps.forEach(function(app){if(app.uiThread)
-appAnnotator.applyEventInfos(app.uiThread.sliceGroup);if(app.renderThread)
-appAnnotator.applyEventInfos(app.renderThread.sliceGroup);});},runAnnotate:function(){if(!this.helper)
-return;this.renameAndSort_();this.pushFramesAndJudgeJank_();this.pushEventInfo_();this.helper.iterateImportantSlices(function(slice){slice.important=true;});},runAudit:function(){if(!this.helper)
-return;var alerts=this.model.alerts;this.helper.apps.forEach(function(app){app.getFrames().forEach(function(frame){alerts.push.apply(alerts,AndroidAuditor.getSaveLayerAlerts_(frame));if(frame.perfClass==FRAME_PERF_CLASS.NEUTRAL||frame.perfClass==FRAME_PERF_CLASS.GOOD)
-return;var alert=AndroidAuditor.getPathAlert_(frame);if(alert)
-alerts.push(alert);var alert=AndroidAuditor.getUploadAlert_(frame);if(alert)
-alerts.push(alert);var alert=AndroidAuditor.getListViewAlert_(frame);if(alert)
-alerts.push(alert);var alert=AndroidAuditor.getMeasureLayoutAlert_(frame);if(alert)
-alerts.push(alert);var alert=AndroidAuditor.getViewDrawAlert_(frame);if(alert)
-alerts.push(alert);var alert=AndroidAuditor.getBlockingGcAlert_(frame);if(alert)
-alerts.push(alert);var alert=AndroidAuditor.getLockContentionAlert_(frame);if(alert)
-alerts.push(alert);var alert=AndroidAuditor.getSchedulingAlert_(frame);if(alert)
-alerts.push(alert);});},this);this.addRenderingInteractionRecords();this.addInputInteractionRecords();},addRenderingInteractionRecords:function(){var events=[];this.helper.apps.forEach(function(app){events.push.apply(events,app.getAnimationAsyncSlices());events.push.apply(events,app.getFrames());});var mergerFunction=function(events){var ir=new tr.model.um.ResponseExpectation(this.model,'Rendering',events[0].min,events[events.length-1].max-events[0].min);this.model.userModel.expectations.push(ir);}.bind(this);tr.b.mergeRanges(tr.b.convertEventsToRanges(events),30,mergerFunction);},addInputInteractionRecords:function(){var inputSamples=[];this.helper.apps.forEach(function(app){inputSamples.push.apply(inputSamples,app.getInputSamples());});var mergerFunction=function(events){var ir=new tr.model.um.ResponseExpectation(this.model,'Input',events[0].min,events[events.length-1].max-events[0].min);this.model.userModel.expectations.push(ir);}.bind(this);var inputRanges=inputSamples.map(function(sample){return tr.b.Range.fromExplicitRange(sample.timestamp,sample.timestamp);});tr.b.mergeRanges(inputRanges,30,mergerFunction);}};Auditor.register(AndroidAuditor);function AppAnnotator(){this.titleInfoLookup={};this.titleParentLookup={};this.build_();}
-AppAnnotator.prototype={build_:function(){var registerEventInfo=function(dict){this.titleInfoLookup[dict.title]=new EventInfo(dict.title,dict.description,dict.docLinks);if(dict.parents)
-this.titleParentLookup[dict.title]=dict.parents;}.bind(this);registerEventInfo({title:'inflate',description:'Constructing a View hierarchy from pre-processed XML via LayoutInflater#layout. This includes constructing all of the View objects in the hierarchy, and applying styled attributes.'});registerEventInfo({title:'obtainView',description:'Adapter#getView() called to bind content to a recycled View that is being presented.'});registerEventInfo({title:'setupListItem',description:'Attached a newly-bound, recycled View to its parent ListView.'});registerEventInfo({title:'setupGridItem',description:'Attached a newly-bound, recycled View to its parent GridView.'});var choreographerLinks=new DocLinkBuilder().addDacRef('Choreographer','android/view/Choreographer.html').build();registerEventInfo({title:'Choreographer#doFrame',docLinks:choreographerLinks,description:'Choreographer executes frame callbacks for inputs, animations, and rendering traversals. When this work is done, a frame will be presented to the user.'});registerEventInfo({title:'input',parents:['Choreographer#doFrame'],docLinks:choreographerLinks,description:'Input callbacks are processed. This generally encompasses dispatching input to Views, as well as any work the Views do to process this input/gesture.'});registerEventInfo({title:'animation',parents:['Choreographer#doFrame'],docLinks:choreographerLinks,description:'Animation callbacks are processed. This is generally minimal work, as animations determine progress for the frame, and push new state to animated objects (such as setting View properties).'});registerEventInfo({title:'traversals',parents:['Choreographer#doFrame'],docLinks:choreographerLinks,description:'Primary draw traversals. This is the primary traversal of the View hierarchy, including layout and draw passes.'});var traversalParents=['Choreographer#doFrame','performTraversals'];var layoutLinks=new DocLinkBuilder().addDacRef('View#Layout','android/view/View.html#Layout').build();registerEventInfo({title:'performTraversals',description:'A drawing traversal of the View hierarchy, comprised of all layout and drawing needed to produce the frame.'});registerEventInfo({title:'measure',parents:traversalParents,docLinks:layoutLinks,description:'First of two phases in view hierarchy layout. Views are asked to size themselves according to constraints supplied by their parent. Some ViewGroups may measure a child more than once to help satisfy their own constraints. Nesting ViewGroups that measure children more than once can lead to excessive and repeated work.'});registerEventInfo({title:'layout',parents:traversalParents,docLinks:layoutLinks,description:'Second of two phases in view hierarchy layout, repositioning content and child Views into their new locations.'});var drawString='Draw pass over the View hierarchy. Every invalidated View will have its drawing commands recorded. On Android versions prior to Lollipop, this would also include the issuing of draw commands to the GPU. Starting with Lollipop, it only includes the recording of commands, and syncing that information to the RenderThread.';registerEventInfo({title:'draw',parents:traversalParents,description:drawString});var recordString='Every invalidated View\'s drawing commands are recorded. Each will have View#draw() called, and is passed a Canvas that will record and store its drawing commands until it is next invalidated/rerecorded.';registerEventInfo({title:'getDisplayList',parents:['draw'],description:recordString});registerEventInfo({title:'Record View#draw()',parents:['draw'],description:recordString});registerEventInfo({title:'drawDisplayList',parents:['draw'],description:'Execution of recorded draw commands to generate a frame. This represents the actual formation and issuing of drawing commands to the GPU. On Android L and higher devices, this work is done on a dedicated RenderThread, instead of on the UI Thread.'});registerEventInfo({title:'DrawFrame',description:'RenderThread portion of the standard UI/RenderThread split frame. This represents the actual formation and issuing of drawing commands to the GPU.'});registerEventInfo({title:'doFrame',description:'RenderThread animation frame. Represents drawing work done by the RenderThread on a frame where the UI thread did not produce new drawing content.'});registerEventInfo({title:'syncFrameState',description:'Sync stage between the UI thread and the RenderThread, where the UI thread hands off a frame (including information about modified Views). Time in this method primarily consists of uploading modified Bitmaps to the GPU. After this sync is completed, the UI thread is unblocked, and the RenderThread starts to render the frame.'});registerEventInfo({title:'flush drawing commands',description:'Issuing the now complete drawing commands to the GPU.'});registerEventInfo({title:'eglSwapBuffers',description:'Complete GPU rendering of the frame.'});registerEventInfo({title:'RV Scroll',description:'RecyclerView is calculating a scroll. If there are too many of these in Systrace, some Views inside RecyclerView might be causing it. Try to avoid using EditText, focusable views or handle them with care.'});registerEventInfo({title:'RV OnLayout',description:'OnLayout has been called by the View system. If this shows up too many times in Systrace, make sure the children of RecyclerView do not update themselves directly. This will cause a full re-layout but when it happens via the Adapter notifyItemChanged, RecyclerView can avoid full layout calculation.'});registerEventInfo({title:'RV FullInvalidate',description:'NotifyDataSetChanged or equal has been called. If this is taking a long time, try sending granular notify adapter changes instead of just calling notifyDataSetChanged or setAdapter / swapAdapter. Adding stable ids to your adapter might help.'});registerEventInfo({title:'RV PartialInvalidate',description:'RecyclerView is rebinding a View. If this is taking a lot of time, consider optimizing your layout or make sure you are not doing extra operations in onBindViewHolder call.'});registerEventInfo({title:'RV OnBindView',description:'RecyclerView is rebinding a View. If this is taking a lot of time, consider optimizing your layout or make sure you are not doing extra operations in onBindViewHolder call.'});registerEventInfo({title:'RV CreateView',description:'RecyclerView is creating a new View. If too many of these are present: 1) There might be a problem in Recycling (e.g. custom Animations that set transient state and prevent recycling or ItemAnimator not implementing the contract properly. See Adapter#onFailedToRecycleView(ViewHolder). 2) There may be too many item view types. Try merging them. 3) There might be too many itemChange animations and not enough space in RecyclerPool. Try increasing your pool size and item cache size.'});registerEventInfo({title:'eglSwapBuffers',description:'The CPU has finished producing drawing commands, and is flushing drawing work to the GPU, and posting that buffer to the consumer (which is often SurfaceFlinger window composition). Once this is completed, the GPU can produce the frame content without any involvement from the CPU.'});},applyEventInfosRecursive_:function(parentNames,slice){var checkExpectedParentNames=function(expectedParentNames){if(!expectedParentNames)
-return true;return expectedParentNames.some(function(name){return name in parentNames;});};if(slice.title in this.titleInfoLookup){if(checkExpectedParentNames(this.titleParentLookup[slice.title]))
-slice.info=this.titleInfoLookup[slice.title];}
-if(slice.subSlices.length>0){if(!(slice.title in parentNames))
-parentNames[slice.title]=0;parentNames[slice.title]++;slice.subSlices.forEach(function(subSlice){this.applyEventInfosRecursive_(parentNames,subSlice);},this);parentNames[slice.title]--;if(parentNames[slice.title]==0)
-delete parentNames[slice.title];}},applyEventInfos:function(sliceGroup){sliceGroup.topLevelSlices.forEach(function(slice){this.applyEventInfosRecursive_({},slice);},this);}};return{AndroidAuditor:AndroidAuditor};});'use strict';tr.exportTo('tr.model.helpers',function(){var MAIN_FRAMETIME_TYPE='main_frametime_type';var IMPL_FRAMETIME_TYPE='impl_frametime_type';var MAIN_RENDERING_STATS='BenchmarkInstrumentation::MainThreadRenderingStats';var IMPL_RENDERING_STATS='BenchmarkInstrumentation::ImplThreadRenderingStats';function getSlicesIntersectingRange(rangeOfInterest,slices){var slicesInFilterRange=[];for(var i=0;i<slices.length;i++){var slice=slices[i];if(rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end))
-slicesInFilterRange.push(slice);}
-return slicesInFilterRange;}
-function ChromeProcessHelper(modelHelper,process){this.modelHelper=modelHelper;this.process=process;}
-ChromeProcessHelper.prototype={get pid(){return this.process.pid;},getFrameEventsInRange:function(frametimeType,range){var titleToGet;if(frametimeType==MAIN_FRAMETIME_TYPE)
-titleToGet=MAIN_RENDERING_STATS;else
-titleToGet=IMPL_RENDERING_STATS;var frameEvents=[];this.process.iterateAllEvents(function(event){if(event.title!==titleToGet)
-return;if(range.intersectsExplicitRangeInclusive(event.start,event.end))
-frameEvents.push(event);});frameEvents.sort(function(a,b){return a.start-b.start});return frameEvents;}};function getFrametimeDataFromEvents(frameEvents){var frametimeData=[];for(var i=1;i<frameEvents.length;i++){var diff=frameEvents[i].start-frameEvents[i-1].start;frametimeData.push({'x':frameEvents[i].start,'frametime':diff});}
-return frametimeData;}
-return{ChromeProcessHelper:ChromeProcessHelper,MAIN_FRAMETIME_TYPE:MAIN_FRAMETIME_TYPE,IMPL_FRAMETIME_TYPE:IMPL_FRAMETIME_TYPE,MAIN_RENDERING_STATS:MAIN_RENDERING_STATS,IMPL_RENDERING_STATS:IMPL_RENDERING_STATS,getSlicesIntersectingRange:getSlicesIntersectingRange,getFrametimeDataFromEvents:getFrametimeDataFromEvents};});'use strict';tr.exportTo('tr.model.helpers',function(){function ChromeBrowserHelper(modelHelper,process){tr.model.helpers.ChromeProcessHelper.call(this,modelHelper,process);this.mainThread_=process.findAtMostOneThreadNamed('CrBrowserMain');}
-ChromeBrowserHelper.isBrowserProcess=function(process){return!!process.findAtMostOneThreadNamed('CrBrowserMain');};ChromeBrowserHelper.prototype={__proto__:tr.model.helpers.ChromeProcessHelper.prototype,get rendererHelpers(){return this.modelHelper.rendererHelpers;},getLoadingEventsInRange:function(rangeOfInterest){return this.getAllAsyncSlicesMatching(function(slice){return slice.title.indexOf('WebContentsImpl Loading')===0&&rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end);});},getCommitProvisionalLoadEventsInRange:function(rangeOfInterest){return this.getAllAsyncSlicesMatching(function(slice){return slice.title==='RenderFrameImpl::didCommitProvisionalLoad'&&rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end);});},get hasLatencyEvents(){var hasLatency=false;this.modelHelper.model.getAllThreads().some(function(thread){thread.iterateAllEvents(function(event){if(!event.isTopLevel)
-return;if(!(event instanceof tr.e.cc.InputLatencyAsyncSlice))
-return;hasLatency=true;});return hasLatency;});return hasLatency;},getLatencyEventsInRange:function(rangeOfInterest){return this.getAllAsyncSlicesMatching(function(slice){return(slice.title.indexOf('InputLatency')===0)&&rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end);});},getAllAsyncSlicesMatching:function(pred,opt_this){var events=[];this.iterAllThreads(function(thread){thread.iterateAllEvents(function(slice){if(pred.call(opt_this,slice))
-events.push(slice);});});return events;},getAllNetworkEventsInRange:function(rangeOfInterest){var networkEvents=[];this.modelHelper.model.getAllThreads().forEach(function(thread){thread.asyncSliceGroup.slices.forEach(function(slice){var match=false;if(slice.category=='net'||slice.category=='disabled-by-default-netlog'||slice.category=='netlog'){match=true;}
-if(!match)
-return;if(rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end))
-networkEvents.push(slice);});});return networkEvents;},iterAllThreads:function(func,opt_this){tr.b.iterItems(this.process.threads,function(tid,thread){func.call(opt_this,thread);});tr.b.iterItems(this.rendererHelpers,function(pid,rendererHelper){var rendererProcess=rendererHelper.process;tr.b.iterItems(rendererProcess.threads,function(tid,thread){func.call(opt_this,thread);});},this);}};return{ChromeBrowserHelper:ChromeBrowserHelper};});'use strict';tr.exportTo('tr.model.helpers',function(){function ChromeGpuHelper(modelHelper,process){tr.model.helpers.ChromeProcessHelper.call(this,modelHelper,process);this.mainThread_=process.findAtMostOneThreadNamed('CrGpuMain');};ChromeGpuHelper.isGpuProcess=function(process){if(process.findAtMostOneThreadNamed('CrBrowserMain')||process.findAtMostOneThreadNamed('CrRendererMain'))
-return false;return process.findAtMostOneThreadNamed('CrGpuMain');};ChromeGpuHelper.prototype={__proto__:tr.model.helpers.ChromeProcessHelper.prototype,get mainThread(){return this.mainThread_;}};return{ChromeGpuHelper:ChromeGpuHelper};});'use strict';tr.exportTo('tr.model.helpers',function(){function ChromeRendererHelper(modelHelper,process){tr.model.helpers.ChromeProcessHelper.call(this,modelHelper,process);this.mainThread_=process.findAtMostOneThreadNamed('CrRendererMain');this.compositorThread_=process.findAtMostOneThreadNamed('Compositor');this.rasterWorkerThreads_=process.findAllThreadsMatching(function(t){if(t.name===undefined)
-return false;if(t.name.indexOf('CompositorTileWorker')===0)
-return true;if(t.name.indexOf('CompositorRasterWorker')===0)
-return true;return false;});};ChromeRendererHelper.isRenderProcess=function(process){if(!process.findAtMostOneThreadNamed('CrRendererMain'))
-return false;if(!process.findAtMostOneThreadNamed('Compositor'))
-return false;return true;};ChromeRendererHelper.prototype={__proto__:tr.model.helpers.ChromeProcessHelper.prototype,get mainThread(){return this.mainThread_;},get compositorThread(){return this.compositorThread_;},get rasterWorkerThreads(){return this.rasterWorkerThreads_;}};return{ChromeRendererHelper:ChromeRendererHelper};});'use strict';tr.exportTo('tr.model.helpers',function(){function findChromeBrowserProcess(model){var browserProcesses=[];model.getAllProcesses().forEach(function(process){if(!tr.model.helpers.ChromeBrowserHelper.isBrowserProcess(process))
-return;browserProcesses.push(process);},this);if(browserProcesses.length===0)
-return undefined;if(browserProcesses.length>1)
-return undefined;return browserProcesses[0];}
-function findChromeRenderProcesses(model){var rendererProcesses=[];model.getAllProcesses().forEach(function(process){if(!tr.model.helpers.ChromeRendererHelper.isRenderProcess(process))
-return;rendererProcesses.push(process);});return rendererProcesses;}
-function findChromeGpuProcess(model){var gpuProcesses=model.getAllProcesses().filter(tr.model.helpers.ChromeGpuHelper.isGpuProcess);if(gpuProcesses.length!=1)
-return undefined;return gpuProcesses[0];}
-function ChromeModelHelper(model){this.model_=model;this.browserProcess_=findChromeBrowserProcess(model);if(this.browserProcess_){this.browserHelper_=new tr.model.helpers.ChromeBrowserHelper(this,this.browserProcess_);}else{this.browserHelper_=undefined;}
-var gpuProcess=findChromeGpuProcess(model);if(gpuProcess){this.gpuHelper_=new tr.model.helpers.ChromeGpuHelper(this,gpuProcess);}else{this.gpuHelper_=undefined;}
-var rendererProcesses_=findChromeRenderProcesses(model);this.rendererHelpers_={};rendererProcesses_.forEach(function(renderProcess){var rendererHelper=new tr.model.helpers.ChromeRendererHelper(this,renderProcess);this.rendererHelpers_[rendererHelper.pid]=rendererHelper;},this);}
-ChromeModelHelper.guid=tr.b.GUID.allocate();ChromeModelHelper.supportsModel=function(model){if(findChromeBrowserProcess(model)!==undefined)
-return true;if(findChromeRenderProcesses(model).length)
-return true;return false;};ChromeModelHelper.prototype={get pid(){throw new Error('woah');},get process(){throw new Error('woah');},get model(){return this.model_;},get browserProcess(){return this.browserProcess_;},get browserHelper(){return this.browserHelper_;},get gpuHelper(){return this.gpuHelper_;},get rendererHelpers(){return this.rendererHelpers_;}};return{ChromeModelHelper:ChromeModelHelper};});'use strict';tr.exportTo('tr.model',function(){function AsyncSlice(category,title,colorId,start,args,duration,opt_isTopLevel,opt_cpuStart,opt_cpuDuration,opt_argsStripped){tr.model.TimedEvent.call(this,start);this.category=category||'';this.originalTitle=title;this.title=title;this.colorId=colorId;this.args=args;this.startStackFrame=undefined;this.endStackFrame=undefined;this.didNotFinish=false;this.important=false;this.subSlices=[];this.parentContainer_=undefined;this.id=undefined;this.startThread=undefined;this.endThread=undefined;this.cpuStart=undefined;this.cpuDuration=undefined;this.argsStripped=false;this.startStackFrame=undefined;this.endStackFrame=undefined;this.duration=duration;this.isTopLevel=(opt_isTopLevel===true);if(opt_cpuStart!==undefined)
-this.cpuStart=opt_cpuStart;if(opt_cpuDuration!==undefined)
-this.cpuDuration=opt_cpuDuration;if(opt_argsStripped!==undefined)
-this.argsStripped=opt_argsStripped;};AsyncSlice.prototype={__proto__:tr.model.TimedEvent.prototype,get analysisTypeName(){return this.title;},get parentContainer(){return this.parentContainer_;},set parentContainer(parentContainer){this.parentContainer_=parentContainer;for(var i=0;i<this.subSlices.length;i++){var subSlice=this.subSlices[i];if(subSlice.parentContainer===undefined)
-subSlice.parentContainer=parentContainer;}},get viewSubGroupTitle(){return this.title;},get userFriendlyName(){return'Async slice '+this.title+' at '+
-tr.v.Unit.byName.timeStampInMs.format(this.start);},get stableId(){var parentAsyncSliceGroup=this.parentContainer.asyncSliceGroup;return parentAsyncSliceGroup.stableId+'.'+
-parentAsyncSliceGroup.slices.indexOf(this);},findDescendentSlice:function(targetTitle){if(!this.subSlices)
-return undefined;for(var i=0;i<this.subSlices.length;i++){if(this.subSlices[i].title==targetTitle)
-return this.subSlices[i];var slice=this.subSlices[i].findDescendentSlice(targetTitle);if(slice)return slice;}
-return undefined;},iterateAllDescendents:function(callback,opt_this){this.subSlices.forEach(callback,opt_this);this.subSlices.forEach(function(subSlice){subSlice.iterateAllDescendents(callback,opt_this);},opt_this);},compareTo:function(that){return this.title.localeCompare(that.title);}};tr.model.EventRegistry.register(AsyncSlice,{name:'asyncSlice',pluralName:'asyncSlices',singleViewElementName:'tr-ui-a-single-async-slice-sub-view',multiViewElementName:'tr-ui-a-multi-async-slice-sub-view'});var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=AsyncSlice;options.defaultConstructor=AsyncSlice;tr.b.decorateExtensionRegistry(AsyncSlice,options);return{AsyncSlice:AsyncSlice};});'use strict';tr.exportTo('tr.e.cc',function(){var AsyncSlice=tr.model.AsyncSlice;var EventSet=tr.model.EventSet;var UI_COMP_NAME='INPUT_EVENT_LATENCY_UI_COMPONENT';var ORIGINAL_COMP_NAME='INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT';var BEGIN_COMP_NAME='INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT';var END_COMP_NAME='INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT';var MAIN_RENDERER_THREAD_NAME='CrRendererMain';var COMPOSITOR_THREAD_NAME='Compositor';var POSTTASK_FLOW_EVENT='disabled-by-default-toplevel.flow';var IPC_FLOW_EVENT='disabled-by-default-ipc.flow';var INPUT_EVENT_TYPE_NAMES={CHAR:'Char',CLICK:'GestureClick',CONTEXT_MENU:'ContextMenu',FLING_CANCEL:'GestureFlingCancel',FLING_START:'GestureFlingStart',KEY_DOWN:'KeyDown',KEY_DOWN_RAW:'RawKeyDown',KEY_UP:'KeyUp',LATENCY_SCROLL_UPDATE:'ScrollUpdate',MOUSE_DOWN:'MouseDown',MOUSE_ENTER:'MouseEnter',MOUSE_LEAVE:'MouseLeave',MOUSE_MOVE:'MouseMove',MOUSE_UP:'MouseUp',MOUSE_WHEEL:'MouseWheel',PINCH_BEGIN:'GesturePinchBegin',PINCH_END:'GesturePinchEnd',PINCH_UPDATE:'GesturePinchUpdate',SCROLL_BEGIN:'GestureScrollBegin',SCROLL_END:'GestureScrollEnd',SCROLL_UPDATE:'GestureScrollUpdate',SCROLL_UPDATE_RENDERER:'ScrollUpdate',SHOW_PRESS:'GestureShowPress',TAP:'GestureTap',TAP_CANCEL:'GestureTapCancel',TAP_DOWN:'GestureTapDown',TOUCH_CANCEL:'TouchCancel',TOUCH_END:'TouchEnd',TOUCH_MOVE:'TouchMove',TOUCH_START:'TouchStart',UNKNOWN:'UNKNOWN'};function InputLatencyAsyncSlice(){AsyncSlice.apply(this,arguments);this.associatedEvents_=new EventSet();this.typeName_=undefined;if(!this.isLegacyEvent)
-this.determineModernTypeName_();}
-InputLatencyAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get isLegacyEvent(){return this.title==='InputLatency';},get typeName(){if(!this.typeName_)
-this.determineLegacyTypeName_();return this.typeName_;},checkTypeName_:function(){if(!this.typeName_)
-throw'Unable to determine typeName';var found=false;for(var type_name in INPUT_EVENT_TYPE_NAMES){if(this.typeName===INPUT_EVENT_TYPE_NAMES[type_name]){found=true;break;}}
-if(!found)
-this.typeName_=INPUT_EVENT_TYPE_NAMES.UNKNOWN;},determineModernTypeName_:function(){var lastColonIndex=this.title.lastIndexOf(':');if(lastColonIndex<0)
-return;var characterAfterLastColonIndex=lastColonIndex+1;this.typeName_=this.title.slice(characterAfterLastColonIndex);this.checkTypeName_();},determineLegacyTypeName_:function(){this.iterateAllDescendents(function(subSlice){var subSliceIsAInputLatencyAsyncSlice=(subSlice instanceof InputLatencyAsyncSlice);if(!subSliceIsAInputLatencyAsyncSlice)
-return;if(!subSlice.typeName)
-return;if(this.typeName_&&subSlice.typeName_){var subSliceHasDifferentTypeName=(this.typeName_!==subSlice.typeName_);if(subSliceHasDifferentTypeName){throw'InputLatencyAsyncSlice.determineLegacyTypeName_() '+' found multiple typeNames';}}
-this.typeName_=subSlice.typeName_;},this);if(!this.typeName_)
-throw'InputLatencyAsyncSlice.determineLegacyTypeName_() failed';this.checkTypeName_();},getRendererHelper:function(sourceSlices){var traceModel=this.startThread.parent.model;var modelHelper=traceModel.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(!modelHelper)
-return undefined;var mainThread=undefined;var compositorThread=undefined;for(var i in sourceSlices){if(sourceSlices[i].parentContainer.name===MAIN_RENDERER_THREAD_NAME)
-mainThread=sourceSlices[i].parentContainer;else if(sourceSlices[i].parentContainer.name===COMPOSITOR_THREAD_NAME)
-compositorThread=sourceSlices[i].parentContainer;if(mainThread&&compositorThread)
-break;}
-var rendererHelpers=modelHelper.rendererHelpers;var pids=Object.keys(rendererHelpers);for(var i=0;i<pids.length;i++){var pid=pids[i];var rendererHelper=rendererHelpers[pid];if(rendererHelper.mainThread===mainThread||rendererHelper.compositorThread===compositorThread)
-return rendererHelper;}
-return undefined;},addEntireSliceHierarchy:function(slice){this.associatedEvents_.push(slice);slice.iterateAllSubsequentSlices(function(subsequentSlice){this.associatedEvents_.push(subsequentSlice);},this);},addDirectlyAssociatedEvents:function(flowEvents){var slices=[];flowEvents.forEach(function(flowEvent){this.associatedEvents_.push(flowEvent);var newSource=flowEvent.startSlice.mostTopLevelSlice;if(slices.indexOf(newSource)===-1)
-slices.push(newSource);},this);var lastFlowEvent=flowEvents[flowEvents.length-1];var lastSource=lastFlowEvent.endSlice.mostTopLevelSlice;if(slices.indexOf(lastSource)===-1)
-slices.push(lastSource);return slices;},addScrollUpdateEvents:function(rendererHelper){if(!rendererHelper||!rendererHelper.compositorThread)
-return;var compositorThread=rendererHelper.compositorThread;var gestureScrollUpdateStart=this.start;var gestureScrollUpdateEnd=this.end;var allCompositorAsyncSlices=compositorThread.asyncSliceGroup.slices;for(var i in allCompositorAsyncSlices){var slice=allCompositorAsyncSlices[i];if(slice.title!=='Latency::ScrollUpdate')
-continue;var parentId=slice.args.data.INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT.sequence_number;if(parentId===undefined){if(slice.start<gestureScrollUpdateStart||slice.start>=gestureScrollUpdateEnd)
-continue;}else{if(parseInt(parentId)!==parseInt(this.id))
-continue;}
-slice.associatedEvents.forEach(function(event){this.associatedEvents_.push(event);},this);break;}},belongToOtherInputs:function(slice,flowEvents){var fromOtherInputs=false;slice.iterateEntireHierarchy(function(subsequentSlice){if(fromOtherInputs)
-return;subsequentSlice.inFlowEvents.forEach(function(inflow){if(fromOtherInputs)
-return;if(inflow.category.indexOf('input')>-1){if(flowEvents.indexOf(inflow)===-1)
-fromOtherInputs=true;}},this);},this);return fromOtherInputs;},triggerOtherInputs:function(event,flowEvents){if(event.outFlowEvents===undefined||event.outFlowEvents.length===0)
-return false;var flow=event.outFlowEvents[0];if(flow.category!==POSTTASK_FLOW_EVENT||!flow.endSlice)
-return false;var endSlice=flow.endSlice;if(this.belongToOtherInputs(endSlice.mostTopLevelSlice,flowEvents))
-return true;return false;},followSubsequentSlices:function(event,queue,visited,flowEvents){var stopFollowing=false;var inputAck=false;event.iterateAllSubsequentSlices(function(slice){if(stopFollowing)
-return;if(slice.title==='TaskQueueManager::RunTask')
-return;if(slice.title==='ThreadProxy::ScheduledActionSendBeginMainFrame')
-return;if(slice.title==='Scheduler::ScheduleBeginImplFrameDeadline'){if(this.triggerOtherInputs(slice,flowEvents))
-return;}
-if(slice.title==='CompositorImpl::PostComposite'){if(this.triggerOtherInputs(slice,flowEvents))
-return;}
-if(slice.title==='InputRouterImpl::ProcessInputEventAck')
-inputAck=true;if(inputAck&&slice.title==='InputRouterImpl::FilterAndSendWebInputEvent')
-stopFollowing=true;this.followCurrentSlice(slice,queue,visited);},this);},followCurrentSlice:function(event,queue,visited){event.outFlowEvents.forEach(function(outflow){if((outflow.category===POSTTASK_FLOW_EVENT||outflow.category===IPC_FLOW_EVENT)&&outflow.endSlice){this.associatedEvents_.push(outflow);var nextEvent=outflow.endSlice.mostTopLevelSlice;if(!visited.contains(nextEvent)){visited.push(nextEvent);queue.push(nextEvent);}}},this);},backtraceFromDraw:function(beginImplFrame,visited){var pendingEventQueue=[];pendingEventQueue.push(beginImplFrame.mostTopLevelSlice);while(pendingEventQueue.length!==0){var event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);event.inFlowEvents.forEach(function(inflow){if(inflow.category===POSTTASK_FLOW_EVENT&&inflow.startSlice){var nextEvent=inflow.startSlice.mostTopLevelSlice;if(!visited.contains(nextEvent)){visited.push(nextEvent);pendingEventQueue.push(nextEvent);}}},this);}},sortRasterizerSlices:function(rasterWorkerThreads,sortedRasterizerSlices){rasterWorkerThreads.forEach(function(rasterizer){Array.prototype.push.apply(sortedRasterizerSlices,rasterizer.sliceGroup.slices);},this);sortedRasterizerSlices.sort(function(a,b){if(a.start!==b.start)
-return a.start-b.start;return a.guid-b.guid;});},addRasterizationEvents:function(prepareTiles,rendererHelper,visited,flowEvents,sortedRasterizerSlices){if(!prepareTiles.args.prepare_tiles_id)
-return;if(!rendererHelper||!rendererHelper.rasterWorkerThreads)
-return;var rasterWorkerThreads=rendererHelper.rasterWorkerThreads;var prepare_tile_id=prepareTiles.args.prepare_tiles_id;var pendingEventQueue=[];if(sortedRasterizerSlices.length===0)
-this.sortRasterizerSlices(rasterWorkerThreads,sortedRasterizerSlices);var numFinishedTasks=0;var RASTER_TASK_TITLE='RasterizerTaskImpl::RunOnWorkerThread';var IMAGEDECODE_TASK_TITLE='ImageDecodeTaskImpl::RunOnWorkerThread';var FINISHED_TASK_TITLE='TaskSetFinishedTaskImpl::RunOnWorkerThread';for(var i=0;i<sortedRasterizerSlices.length;i++){var task=sortedRasterizerSlices[i];if(task.title===RASTER_TASK_TITLE||task.title===IMAGEDECODE_TASK_TITLE){if(task.args.source_prepare_tiles_id===prepare_tile_id)
-this.addEntireSliceHierarchy(task.mostTopLevelSlice);}else if(task.title===FINISHED_TASK_TITLE){if(task.start>prepareTiles.start){pendingEventQueue.push(task.mostTopLevelSlice);if(++numFinishedTasks===3)
-break;}}}
-while(pendingEventQueue.length!=0){var event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);this.followSubsequentSlices(event,pendingEventQueue,visited,flowEvents);}},addOtherCausallyRelatedEvents:function(rendererHelper,sourceSlices,flowEvents,sortedRasterizerSlices){var pendingEventQueue=[];var visitedEvents=new EventSet();var beginImplFrame=undefined;var prepareTiles=undefined;var sortedRasterizerSlices=[];sourceSlices.forEach(function(sourceSlice){if(!visitedEvents.contains(sourceSlice)){visitedEvents.push(sourceSlice);pendingEventQueue.push(sourceSlice);}},this);while(pendingEventQueue.length!=0){var event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);this.followCurrentSlice(event,pendingEventQueue,visitedEvents);this.followSubsequentSlices(event,pendingEventQueue,visitedEvents,flowEvents);var COMPOSITOR_PREPARE_TILES='TileManager::PrepareTiles';prepareTiles=event.findDescendentSlice(COMPOSITOR_PREPARE_TILES);if(prepareTiles)
-this.addRasterizationEvents(prepareTiles,rendererHelper,visitedEvents,flowEvents,sortedRasterizerSlices);var COMPOSITOR_ON_BIFD='Scheduler::OnBeginImplFrameDeadline';beginImplFrame=event.findDescendentSlice(COMPOSITOR_ON_BIFD);if(beginImplFrame)
-this.backtraceFromDraw(beginImplFrame,visitedEvents);}
-var INPUT_GSU='InputLatency::GestureScrollUpdate';if(this.title===INPUT_GSU)
-this.addScrollUpdateEvents(rendererHelper);},get associatedEvents(){if(this.associatedEvents_.length!==0)
-return this.associatedEvents_;var modelIndices=this.startThread.parent.model.modelIndices;var flowEvents=modelIndices.getFlowEventsWithId(this.id);if(flowEvents.length===0)
-return this.associatedEvents_;var sourceSlices=this.addDirectlyAssociatedEvents(flowEvents);var rendererHelper=this.getRendererHelper(sourceSlices);this.addOtherCausallyRelatedEvents(rendererHelper,sourceSlices,flowEvents);return this.associatedEvents_;},get inputLatency(){if(!('data'in this.args))
-return undefined;var data=this.args.data;if(!(END_COMP_NAME in data))
-return undefined;var latency=0;var endTime=data[END_COMP_NAME].time;if(ORIGINAL_COMP_NAME in data){latency=endTime-data[ORIGINAL_COMP_NAME].time;}else if(UI_COMP_NAME in data){latency=endTime-data[UI_COMP_NAME].time;}else if(BEGIN_COMP_NAME in data){latency=endTime-data[BEGIN_COMP_NAME].time;}else{throw new Error('No valid begin latency component');}
-return latency;}};var eventTypeNames=['Char','ContextMenu','GestureClick','GestureFlingCancel','GestureFlingStart','GestureScrollBegin','GestureScrollEnd','GestureScrollUpdate','GestureShowPress','GestureTap','GestureTapCancel','GestureTapDown','GesturePinchBegin','GesturePinchEnd','GesturePinchUpdate','KeyDown','KeyUp','MouseDown','MouseEnter','MouseLeave','MouseMove','MouseUp','MouseWheel','RawKeyDown','ScrollUpdate','TouchCancel','TouchEnd','TouchMove','TouchStart'];var allTypeNames=['InputLatency'];eventTypeNames.forEach(function(eventTypeName){allTypeNames.push('InputLatency:'+eventTypeName);allTypeNames.push('InputLatency::'+eventTypeName);});AsyncSlice.register(InputLatencyAsyncSlice,{typeNames:allTypeNames,categoryParts:['latencyInfo']});return{InputLatencyAsyncSlice:InputLatencyAsyncSlice,INPUT_EVENT_TYPE_NAMES:INPUT_EVENT_TYPE_NAMES};});'use strict';tr.exportTo('tr.e.chrome',function(){var SAME_AS_PARENT='same-as-parent';var TITLES_FOR_USER_FRIENDLY_CATEGORY={composite:['CompositingInputsUpdater::update','ThreadProxy::SetNeedsUpdateLayers','LayerTreeHost::UpdateLayers::CalcDrawProps','UpdateLayerTree'],gc:['minorGC','majorGC','MajorGC','MinorGC','V8.GCScavenger','V8.GCIncrementalMarking','V8.GCIdleNotification','V8.GCContext','V8.GCCompactor','V8GCController::traceDOMWrappers'],iframe_creation:['WebLocalFrameImpl::createChildframe'],imageDecode:['Decode Image','ImageFrameGenerator::decode','ImageFrameGenerator::decodeAndScale'],input:['HitTest','ScrollableArea::scrollPositionChanged','EventHandler::handleMouseMoveEvent'],layout:['FrameView::invalidateTree','FrameView::layout','FrameView::performLayout','FrameView::performPostLayoutTasks','FrameView::performPreLayoutTasks','Layer::updateLayerPositionsAfterLayout','Layout','LayoutView::hitTest','ResourceLoadPriorityOptimizer::updateAllImageResourcePriorities','WebViewImpl::layout'],parseHTML:['ParseHTML','HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser','HTMLDocumentParser::processParsedChunkFromBackgroundParser'],raster:['DisplayListRasterSource::PerformSolidColorAnalysis','Picture::Raster','RasterBufferImpl::Playback','RasterTask','RasterizerTaskImpl::RunOnWorkerThread','SkCanvas::drawImageRect()','SkCanvas::drawPicture()','SkCanvas::drawTextBlob()','TileTaskWorkerPool::PlaybackToMemory'],record:['ContentLayerDelegate::paintContents','DeprecatedPaintLayerCompositor::updateIfNeededRecursive','DeprecatedPaintLayerCompositor::updateLayerPositionsAfterLayout','Paint','Picture::Record','PictureLayer::Update','RenderLayer::updateLayerPositionsAfterLayout'],script:['EvaluateScript','FunctionCall','ScheduledAction::execute','Script','V8.Execute','v8.run','v8.callModuleMethod','v8.callFunction','WindowProxy::initialize'],style:['CSSParserImpl::parseStyleSheet.parse','CSSParserImpl::parseStyleSheet.tokenize','Document::updateStyle','Document::updateStyleInvalidationIfNeeded','ParseAuthorStyleSheet','RuleSet::addRulesFromSheet','StyleElement::processStyleSheet','StyleEngine::createResolver','StyleSheetContents::parseAuthorStyleSheet','UpdateLayoutTree'],script_parse_and_compile:['V8.RecompileSynchronous','V8.RecompileConcurrent','V8.PreParseMicroSeconds','v8.parseOnBackground','V8.ParseMicroSeconds','V8.ParseLazyMicroSeconds','V8.CompileScriptMicroSeconds','V8.CompileMicroSeconds','V8.CompileFullCode','V8.CompileEvalMicroSeconds','v8.compile'],script_parse:['V8Test.ParseScript','V8Test.ParseFunction',],script_compile:['V8Test.Compile','V8Test.CompileFullCode',],resource_loading:['ResourceFetcher::requestResource','ResourceDispatcher::OnReceivedData','ResourceDispatcher::OnRequestComplete','ResourceDispatcher::OnReceivedResponse','Resource::appendData'],renderer_misc:['DecodeFont','ThreadState::completeSweep'],[SAME_AS_PARENT]:['SyncChannel::Send']};var USER_FRIENDLY_CATEGORY_FOR_TITLE={};for(var category in TITLES_FOR_USER_FRIENDLY_CATEGORY){TITLES_FOR_USER_FRIENDLY_CATEGORY[category].forEach(function(title){USER_FRIENDLY_CATEGORY_FOR_TITLE[title]=category;});}
-var USER_FRIENDLY_CATEGORY_FOR_EVENT_CATEGORY={netlog:'net',overhead:'overhead',startup:'startup',gpu:'gpu'};function ChromeUserFriendlyCategoryDriver(){}
-ChromeUserFriendlyCategoryDriver.fromEvent=function(event){var userFriendlyCategory=USER_FRIENDLY_CATEGORY_FOR_TITLE[event.title];if(userFriendlyCategory){if(userFriendlyCategory==SAME_AS_PARENT){if(event.parentSlice)
-return ChromeUserFriendlyCategoryDriver.fromEvent(event.parentSlice);}else{return userFriendlyCategory;}}
-var eventCategoryParts=tr.b.getCategoryParts(event.category);for(var i=0;i<eventCategoryParts.length;++i){var eventCategory=eventCategoryParts[i];userFriendlyCategory=USER_FRIENDLY_CATEGORY_FOR_EVENT_CATEGORY[eventCategory];if(userFriendlyCategory)
-return userFriendlyCategory;}
-return undefined;};return{ChromeUserFriendlyCategoryDriver:ChromeUserFriendlyCategoryDriver};});'use strict';tr.exportTo('tr.model',function(){return{BROWSER_PROCESS_PID_REF:-1,OBJECT_DEFAULT_SCOPE:'ptr'};});'use strict';tr.exportTo('tr.e.audits',function(){var Auditor=tr.c.Auditor;function ChromeAuditor(model){Auditor.call(this,model);var modelHelper=this.model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(modelHelper&&modelHelper.browserHelper){this.modelHelper=modelHelper;}else{this.modelHelper=undefined;}};ChromeAuditor.prototype={__proto__:Auditor.prototype,runAnnotate:function(){if(!this.modelHelper)
-return;this.model.getAllProcesses().forEach(function(process){if(process.labels!==undefined&&process.labels.length==1&&process.labels[0]=='chrome://tracing')
-process.important=false;});},installUserFriendlyCategoryDriverIfNeeded:function(){this.model.addUserFriendlyCategoryDriver(tr.e.chrome.ChromeUserFriendlyCategoryDriver);},runAudit:function(){if(!this.modelHelper)
-return;this.model.replacePIDRefsInPatchups(tr.model.BROWSER_PROCESS_PID_REF,this.modelHelper.browserProcess.pid);this.model.applyObjectRefPatchups();}};Auditor.register(ChromeAuditor);return{ChromeAuditor:ChromeAuditor};});'use strict';tr.exportTo('tr.model',function(){function ObjectSnapshot(objectInstance,ts,args){tr.model.Event.call(this);this.objectInstance=objectInstance;this.ts=ts;this.args=args;}
-ObjectSnapshot.prototype={__proto__:tr.model.Event.prototype,preInitialize:function(){},initialize:function(){},addBoundsToRange:function(range){range.addValue(this.ts);},get userFriendlyName(){return'Snapshot of '+
-this.objectInstance.typeName+' '+
-this.objectInstance.id+' @ '+
-tr.v.Unit.byName.timeStampInMs.format(this.ts);}};tr.model.EventRegistry.register(ObjectSnapshot,{name:'objectSnapshot',pluralName:'objectSnapshots',singleViewElementName:'tr-ui-a-single-object-snapshot-sub-view',multiViewElementName:'tr-ui-a-multi-object-sub-view'});var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectSnapshot;options.defaultConstructor=ObjectSnapshot;tr.b.decorateExtensionRegistry(ObjectSnapshot,options);return{ObjectSnapshot:ObjectSnapshot};});'use strict';tr.exportTo('tr.model',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function ObjectInstance(parent,scopedId,category,name,creationTs,opt_baseTypeName){tr.model.Event.call(this);this.parent=parent;this.scopedId=scopedId;this.category=category;this.baseTypeName=opt_baseTypeName?opt_baseTypeName:name;this.name=name;this.creationTs=creationTs;this.creationTsWasExplicit=false;this.deletionTs=Number.MAX_VALUE;this.deletionTsWasExplicit=false;this.colorId=0;this.bounds=new tr.b.Range();this.snapshots=[];this.hasImplicitSnapshots=false;}
-ObjectInstance.prototype={__proto__:tr.model.Event.prototype,get typeName(){return this.name;},addBoundsToRange:function(range){range.addRange(this.bounds);},addSnapshot:function(ts,args,opt_name,opt_baseTypeName){if(ts<this.creationTs)
-throw new Error('Snapshots must be >= instance.creationTs');if(ts>=this.deletionTs)
-throw new Error('Snapshots cannot be added after '+'an objects deletion timestamp.');var lastSnapshot;if(this.snapshots.length>0){lastSnapshot=this.snapshots[this.snapshots.length-1];if(lastSnapshot.ts==ts)
-throw new Error('Snapshots already exists at this time!');if(ts<lastSnapshot.ts){throw new Error('Snapshots must be added in increasing timestamp order');}}
-if(opt_name&&(this.name!=opt_name)){if(!opt_baseTypeName)
-throw new Error('Must provide base type name for name update');if(this.baseTypeName!=opt_baseTypeName)
-throw new Error('Cannot update type name: base types dont match');this.name=opt_name;}
-var snapshotConstructor=tr.model.ObjectSnapshot.getConstructor(this.category,this.name);var snapshot=new snapshotConstructor(this,ts,args);this.snapshots.push(snapshot);return snapshot;},wasDeleted:function(ts){var lastSnapshot;if(this.snapshots.length>0){lastSnapshot=this.snapshots[this.snapshots.length-1];if(lastSnapshot.ts>ts)
-throw new Error('Instance cannot be deleted at ts='+
-ts+'. A snapshot exists that is older.');}
-this.deletionTs=ts;this.deletionTsWasExplicit=true;},preInitialize:function(){for(var i=0;i<this.snapshots.length;i++)
-this.snapshots[i].preInitialize();},initialize:function(){for(var i=0;i<this.snapshots.length;i++)
-this.snapshots[i].initialize();},getSnapshotAt:function(ts){if(ts<this.creationTs){if(this.creationTsWasExplicit)
-throw new Error('ts must be within lifetime of this instance');return this.snapshots[0];}
-if(ts>this.deletionTs)
-throw new Error('ts must be within lifetime of this instance');var snapshots=this.snapshots;var i=tr.b.findIndexInSortedIntervals(snapshots,function(snapshot){return snapshot.ts;},function(snapshot,i){if(i==snapshots.length-1)
-return snapshots[i].objectInstance.deletionTs;return snapshots[i+1].ts-snapshots[i].ts;},ts);if(i<0){return this.snapshots[0];}
-if(i>=this.snapshots.length)
-return this.snapshots[this.snapshots.length-1];return this.snapshots[i];},updateBounds:function(){this.bounds.reset();this.bounds.addValue(this.creationTs);if(this.deletionTs!=Number.MAX_VALUE)
-this.bounds.addValue(this.deletionTs);else if(this.snapshots.length>0)
-this.bounds.addValue(this.snapshots[this.snapshots.length-1].ts);},shiftTimestampsForward:function(amount){this.creationTs+=amount;if(this.deletionTs!=Number.MAX_VALUE)
-this.deletionTs+=amount;this.snapshots.forEach(function(snapshot){snapshot.ts+=amount;});},get userFriendlyName(){return this.typeName+' object '+this.scopedId;}};tr.model.EventRegistry.register(ObjectInstance,{name:'objectInstance',pluralName:'objectInstances',singleViewElementName:'tr-ui-a-single-object-instance-sub-view',multiViewElementName:'tr-ui-a-multi-object-sub-view'});var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectInstance;options.defaultConstructor=ObjectInstance;tr.b.decorateExtensionRegistry(ObjectInstance,options);return{ObjectInstance:ObjectInstance};});'use strict';tr.exportTo('tr.e.chrome',function(){var constants=tr.e.cc.constants;var ObjectSnapshot=tr.model.ObjectSnapshot;var ObjectInstance=tr.model.ObjectInstance;function FrameTreeNodeSnapshot(){ObjectSnapshot.apply(this,arguments);}
-FrameTreeNodeSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){},initialize:function(){},get userFriendlyName(){return'FrameTreeNode';}};ObjectSnapshot.register(FrameTreeNodeSnapshot,{typeName:'FrameTreeNode'});function FrameTreeNodeInstance(){ObjectInstance.apply(this,arguments);}
-FrameTreeNodeInstance.prototype={__proto__:ObjectInstance.prototype};ObjectInstance.register(FrameTreeNodeInstance,{typeName:'FrameTreeNode'});return{FrameTreeNodeSnapshot:FrameTreeNodeSnapshot,FrameTreeNodeInstance:FrameTreeNodeInstance};});'use strict';tr.exportTo('tr.e.chrome',function(){var KNOWN_PROPERTIES={absX:1,absY:1,address:1,anonymous:1,childNeeds:1,children:1,classNames:1,col:1,colSpan:1,float:1,height:1,htmlId:1,name:1,posChildNeeds:1,positioned:1,positionedMovement:1,relX:1,relY:1,relativePositioned:1,row:1,rowSpan:1,selfNeeds:1,stickyPositioned:1,tag:1,width:1};function LayoutObject(snapshot,args){this.snapshot_=snapshot;this.id_=args.address;this.name_=args.name;this.childLayoutObjects_=[];this.otherProperties_={};this.tag_=args.tag;this.relativeRect_=tr.b.Rect.fromXYWH(args.relX,args.relY,args.width,args.height);this.absoluteRect_=tr.b.Rect.fromXYWH(args.absX,args.absY,args.width,args.height);this.isFloat_=args.float;this.isStickyPositioned_=args.stickyPositioned;this.isPositioned_=args.positioned;this.isRelativePositioned_=args.relativePositioned;this.isAnonymous_=args.anonymous;this.htmlId_=args.htmlId;this.classNames_=args.classNames;this.needsLayoutReasons_=[];if(args.selfNeeds)
-this.needsLayoutReasons_.push('self');if(args.childNeeds)
-this.needsLayoutReasons_.push('child');if(args.posChildNeeds)
-this.needsLayoutReasons_.push('positionedChild');if(args.positionedMovement)
-this.needsLayoutReasons_.push('positionedMovement');this.tableRow_=args.row;this.tableCol_=args.col;this.tableRowSpan_=args.rowSpan;this.tableColSpan_=args.colSpan;if(args.children){args.children.forEach(function(child){this.childLayoutObjects_.push(new LayoutObject(snapshot,child));}.bind(this));}
-for(var property in args){if(!KNOWN_PROPERTIES[property])
-this.otherProperties_[property]=args[property];}}
-LayoutObject.prototype={get snapshot(){return this.snapshot_;},get id(){return this.id_;},get name(){return this.name_;},get tag(){return this.tag_;},get relativeRect(){return this.relativeRect_;},get absoluteRect(){return this.absoluteRect_;},get isPositioned(){return this.isPositioned_;},get isFloat(){return this.isFloat_;},get isStickyPositioned(){return this.isStickyPositioned_;},get isRelativePositioned(){return this.isRelativePositioned_;},get isAnonymous(){return this.isAnonymous_;},get tableRow(){return this.tableRow_;},get tableCol(){return this.tableCol_;},get tableRowSpan(){return this.tableRowSpan_;},get tableColSpan(){return this.tableColSpan_;},get htmlId(){return this.htmlId_;},get classNames(){return this.classNames_;},get needsLayoutReasons(){return this.needsLayoutReasons_;},get hasChildLayoutObjects(){return this.childLayoutObjects_.length>0;},get childLayoutObjects(){return this.childLayoutObjects_;},traverseTree:function(cb,opt_this){cb.call(opt_this,this);if(!this.hasChildLayoutObjects)
-return;this.childLayoutObjects.forEach(function(child){child.traverseTree(cb,opt_this);});},get otherPropertyNames(){var names=[];for(var name in this.otherProperties_){names.push(name);}
-return names;},getProperty:function(name){return this.otherProperties_[name];},get previousSnapshotLayoutObject(){if(!this.snapshot.previousSnapshot)
-return undefined;return this.snapshot.previousSnapshot.getLayoutObjectById(this.id);},get nextSnapshotLayoutObject(){if(!this.snapshot.nextSnapshot)
-return undefined;return this.snapshot.nextSnapshot.getLayoutObjectById(this.id);}};return{LayoutObject:LayoutObject};});'use strict';tr.exportTo('tr.e.chrome',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;var ObjectInstance=tr.model.ObjectInstance;function LayoutTreeInstance(){ObjectInstance.apply(this,arguments);}
-LayoutTreeInstance.prototype={__proto__:ObjectInstance.prototype,};ObjectInstance.register(LayoutTreeInstance,{typeName:'LayoutTree'});function LayoutTreeSnapshot(){ObjectSnapshot.apply(this,arguments);this.rootLayoutObject=new tr.e.chrome.LayoutObject(this,this.args);}
-LayoutTreeSnapshot.prototype={__proto__:ObjectSnapshot.prototype,};ObjectSnapshot.register(LayoutTreeSnapshot,{typeName:'LayoutTree'});tr.model.EventRegistry.register(LayoutTreeSnapshot,{name:'layoutTree',pluralName:'layoutTrees',singleViewElementName:'tr-ui-a-layout-tree-sub-view',multiViewElementName:'tr-ui-a-layout-tree-sub-view'});return{LayoutTreeInstance:LayoutTreeInstance,LayoutTreeSnapshot:LayoutTreeSnapshot};});'use strict';tr.exportTo('tr.e.chrome',function(){var constants=tr.e.cc.constants;var ObjectSnapshot=tr.model.ObjectSnapshot;var ObjectInstance=tr.model.ObjectInstance;function RenderFrameSnapshot(){ObjectSnapshot.apply(this,arguments);}
-RenderFrameSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){},initialize:function(){},get userFriendlyName(){return'RenderFrame';}};ObjectSnapshot.register(RenderFrameSnapshot,{typeName:'RenderFrame'});function RenderFrameInstance(){ObjectInstance.apply(this,arguments);}
-RenderFrameInstance.prototype={__proto__:ObjectInstance.prototype};ObjectInstance.register(RenderFrameInstance,{typeName:'RenderFrame'});return{RenderFrameSnapshot:RenderFrameSnapshot,RenderFrameInstance:RenderFrameInstance};});'use strict';tr.exportTo('tr.b',function(){function Base64(){}
-function b64ToUint6(nChr){if(nChr>64&&nChr<91)
-return nChr-65;if(nChr>96&&nChr<123)
-return nChr-71;if(nChr>47&&nChr<58)
-return nChr+4;if(nChr===43)
-return 62;if(nChr===47)
-return 63;return 0;}
-Base64.getDecodedBufferLength=function(input){return input.length*3+1>>2;};Base64.EncodeArrayBufferToString=function(input){var binary='';var bytes=new Uint8Array(input);var len=bytes.byteLength;for(var i=0;i<len;i++)
-binary+=String.fromCharCode(bytes[i]);return btoa(binary);};Base64.DecodeToTypedArray=function(input,output){var nInLen=input.length;var nOutLen=nInLen*3+1>>2;var nMod3=0;var nMod4=0;var nUint24=0;var nOutIdx=0;if(nOutLen>output.byteLength)
-throw new Error('Output buffer too small to decode.');for(var nInIdx=0;nInIdx<nInLen;nInIdx++){nMod4=nInIdx&3;nUint24|=b64ToUint6(input.charCodeAt(nInIdx))<<18-6*nMod4;if(nMod4===3||nInLen-nInIdx===1){for(nMod3=0;nMod3<3&&nOutIdx<nOutLen;nMod3++,nOutIdx++){output.setUint8(nOutIdx,nUint24>>>(16>>>nMod3&24)&255);}
-nUint24=0;}}
-return nOutIdx-1;};Base64.btoa=function(input){return btoa(input);};Base64.atob=function(input){return atob(input);};return{Base64:Base64};});'use strict';tr.exportTo('tr.e.importer.etw',function(){function Parser(importer){this.importer=importer;this.model=importer.model;}
-Parser.prototype={__proto__:Object.prototype};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.mandatoryBaseClass=Parser;tr.b.decorateExtensionRegistry(Parser,options);return{Parser:Parser};});'use strict';tr.exportTo('tr.e.importer.etw',function(){var Parser=tr.e.importer.etw.Parser;var guid='68FDD900-4A3E-11D1-84F4-0000F80464E3';var kEventTraceHeaderOpcode=0;function EventTraceParser(importer){Parser.call(this,importer);importer.registerEventHandler(guid,kEventTraceHeaderOpcode,EventTraceParser.prototype.decodeHeader.bind(this));}
-EventTraceParser.prototype={__proto__:Parser.prototype,decodeFields:function(header,decoder){if(header.version!=2)
-throw new Error('Incompatible EventTrace event version.');var bufferSize=decoder.decodeUInt32();var version=decoder.decodeUInt32();var providerVersion=decoder.decodeUInt32();var numberOfProcessors=decoder.decodeUInt32();var endTime=decoder.decodeUInt64ToString();var timerResolution=decoder.decodeUInt32();var maxFileSize=decoder.decodeUInt32();var logFileMode=decoder.decodeUInt32();var buffersWritten=decoder.decodeUInt32();var startBuffers=decoder.decodeUInt32();var pointerSize=decoder.decodeUInt32();var eventsLost=decoder.decodeUInt32();var cpuSpeed=decoder.decodeUInt32();var loggerName=decoder.decodeUInteger(header.is64);var logFileName=decoder.decodeUInteger(header.is64);var timeZoneInformation=decoder.decodeTimeZoneInformation();var padding=decoder.decodeUInt32();var bootTime=decoder.decodeUInt64ToString();var perfFreq=decoder.decodeUInt64ToString();var startTime=decoder.decodeUInt64ToString();var reservedFlags=decoder.decodeUInt32();var buffersLost=decoder.decodeUInt32();var sessionNameString=decoder.decodeW16String();var logFileNameString=decoder.decodeW16String();return{bufferSize:bufferSize,version:version,providerVersion:providerVersion,numberOfProcessors:numberOfProcessors,endTime:endTime,timerResolution:timerResolution,maxFileSize:maxFileSize,logFileMode:logFileMode,buffersWritten:buffersWritten,startBuffers:startBuffers,pointerSize:pointerSize,eventsLost:eventsLost,cpuSpeed:cpuSpeed,loggerName:loggerName,logFileName:logFileName,timeZoneInformation:timeZoneInformation,bootTime:bootTime,perfFreq:perfFreq,startTime:startTime,reservedFlags:reservedFlags,buffersLost:buffersLost,sessionNameString:sessionNameString,logFileNameString:logFileNameString};},decodeHeader:function(header,decoder){var fields=this.decodeFields(header,decoder);return true;}};Parser.register(EventTraceParser);return{EventTraceParser:EventTraceParser};});'use strict';tr.exportTo('tr.e.importer.etw',function(){var Parser=tr.e.importer.etw.Parser;var guid='3D6FA8D0-FE05-11D0-9DDA-00C04FD7BA7C';var kProcessStartOpcode=1;var kProcessEndOpcode=2;var kProcessDCStartOpcode=3;var kProcessDCEndOpcode=4;var kProcessDefunctOpcode=39;function ProcessParser(importer){Parser.call(this,importer);importer.registerEventHandler(guid,kProcessStartOpcode,ProcessParser.prototype.decodeStart.bind(this));importer.registerEventHandler(guid,kProcessEndOpcode,ProcessParser.prototype.decodeEnd.bind(this));importer.registerEventHandler(guid,kProcessDCStartOpcode,ProcessParser.prototype.decodeDCStart.bind(this));importer.registerEventHandler(guid,kProcessDCEndOpcode,ProcessParser.prototype.decodeDCEnd.bind(this));importer.registerEventHandler(guid,kProcessDefunctOpcode,ProcessParser.prototype.decodeDefunct.bind(this));}
-ProcessParser.prototype={__proto__:Parser.prototype,decodeFields:function(header,decoder){if(header.version>5)
-throw new Error('Incompatible Process event version.');var pageDirectoryBase;if(header.version==1)
-pageDirectoryBase=decoder.decodeUInteger(header.is64);var uniqueProcessKey;if(header.version>=2)
-uniqueProcessKey=decoder.decodeUInteger(header.is64);var processId=decoder.decodeUInt32();var parentId=decoder.decodeUInt32();var sessionId;var exitStatus;if(header.version>=1){sessionId=decoder.decodeUInt32();exitStatus=decoder.decodeInt32();}
-var directoryTableBase;if(header.version>=3)
-directoryTableBase=decoder.decodeUInteger(header.is64);var flags;if(header.version>=4)
-flags=decoder.decodeUInt32();var userSID=decoder.decodeSID(header.is64);var imageFileName;if(header.version>=1)
-imageFileName=decoder.decodeString();var commandLine;if(header.version>=2)
-commandLine=decoder.decodeW16String();var packageFullName;var applicationId;if(header.version>=4){packageFullName=decoder.decodeW16String();applicationId=decoder.decodeW16String();}
-var exitTime;if(header.version==5&&header.opcode==kProcessDefunctOpcode)
-exitTime=decoder.decodeUInt64ToString();return{pageDirectoryBase:pageDirectoryBase,uniqueProcessKey:uniqueProcessKey,processId:processId,parentId:parentId,sessionId:sessionId,exitStatus:exitStatus,directoryTableBase:directoryTableBase,flags:flags,userSID:userSID,imageFileName:imageFileName,commandLine:commandLine,packageFullName:packageFullName,applicationId:applicationId,exitTime:exitTime};},decodeStart:function(header,decoder){var fields=this.decodeFields(header,decoder);var process=this.model.getOrCreateProcess(fields.processId);if(process.hasOwnProperty('has_ended')){throw new Error('Process clash detected.');}
-process.name=fields.imageFileName;return true;},decodeEnd:function(header,decoder){var fields=this.decodeFields(header,decoder);var process=this.model.getOrCreateProcess(fields.processId);process.has_ended=true;return true;},decodeDCStart:function(header,decoder){var fields=this.decodeFields(header,decoder);var process=this.model.getOrCreateProcess(fields.processId);if(process.hasOwnProperty('has_ended'))
-throw new Error('Process clash detected.');process.name=fields.imageFileName;return true;},decodeDCEnd:function(header,decoder){var fields=this.decodeFields(header,decoder);var process=this.model.getOrCreateProcess(fields.processId);process.has_ended=true;return true;},decodeDefunct:function(header,decoder){var fields=this.decodeFields(header,decoder);return true;}};Parser.register(ProcessParser);return{ProcessParser:ProcessParser};});'use strict';tr.exportTo('tr.e.importer.etw',function(){var Parser=tr.e.importer.etw.Parser;var guid='3D6FA8D1-FE05-11D0-9DDA-00C04FD7BA7C';var kThreadStartOpcode=1;var kThreadEndOpcode=2;var kThreadDCStartOpcode=3;var kThreadDCEndOpcode=4;var kThreadCSwitchOpcode=36;function ThreadParser(importer){Parser.call(this,importer);importer.registerEventHandler(guid,kThreadStartOpcode,ThreadParser.prototype.decodeStart.bind(this));importer.registerEventHandler(guid,kThreadEndOpcode,ThreadParser.prototype.decodeEnd.bind(this));importer.registerEventHandler(guid,kThreadDCStartOpcode,ThreadParser.prototype.decodeDCStart.bind(this));importer.registerEventHandler(guid,kThreadDCEndOpcode,ThreadParser.prototype.decodeDCEnd.bind(this));importer.registerEventHandler(guid,kThreadCSwitchOpcode,ThreadParser.prototype.decodeCSwitch.bind(this));}
-ThreadParser.prototype={__proto__:Parser.prototype,decodeFields:function(header,decoder){if(header.version>3)
-throw new Error('Incompatible Thread event version.');var processId=decoder.decodeUInt32();var threadId=decoder.decodeUInt32();var stackBase;var stackLimit;var userStackBase;var userStackLimit;var affinity;var startAddr;var win32StartAddr;var tebBase;var subProcessTag;var basePriority;var pagePriority;var ioPriority;var threadFlags;var waitMode;if(header.version==1){if(header.opcode==kThreadStartOpcode||header.opcode==kThreadDCStartOpcode){stackBase=decoder.decodeUInteger(header.is64);stackLimit=decoder.decodeUInteger(header.is64);userStackBase=decoder.decodeUInteger(header.is64);userStackLimit=decoder.decodeUInteger(header.is64);startAddr=decoder.decodeUInteger(header.is64);win32StartAddr=decoder.decodeUInteger(header.is64);waitMode=decoder.decodeInt8();decoder.skip(3);}}else{stackBase=decoder.decodeUInteger(header.is64);stackLimit=decoder.decodeUInteger(header.is64);userStackBase=decoder.decodeUInteger(header.is64);userStackLimit=decoder.decodeUInteger(header.is64);if(header.version==2)
-startAddr=decoder.decodeUInteger(header.is64);else
-affinity=decoder.decodeUInteger(header.is64);win32StartAddr=decoder.decodeUInteger(header.is64);tebBase=decoder.decodeUInteger(header.is64);subProcessTag=decoder.decodeUInt32();if(header.version==3){basePriority=decoder.decodeUInt8();pagePriority=decoder.decodeUInt8();ioPriority=decoder.decodeUInt8();threadFlags=decoder.decodeUInt8();}}
-return{processId:processId,threadId:threadId,stackBase:stackBase,stackLimit:stackLimit,userStackBase:userStackBase,userStackLimit:userStackLimit,affinity:affinity,startAddr:startAddr,win32StartAddr:win32StartAddr,tebBase:tebBase,subProcessTag:subProcessTag,waitMode:waitMode,basePriority:basePriority,pagePriority:pagePriority,ioPriority:ioPriority,threadFlags:threadFlags};},decodeCSwitchFields:function(header,decoder){if(header.version!=2)
-throw new Error('Incompatible Thread event version.');var newThreadId=decoder.decodeUInt32();var oldThreadId=decoder.decodeUInt32();var newThreadPriority=decoder.decodeInt8();var oldThreadPriority=decoder.decodeInt8();var previousCState=decoder.decodeUInt8();var spareByte=decoder.decodeInt8();var oldThreadWaitReason=decoder.decodeInt8();var oldThreadWaitMode=decoder.decodeInt8();var oldThreadState=decoder.decodeInt8();var oldThreadWaitIdealProcessor=decoder.decodeInt8();var newThreadWaitTime=decoder.decodeUInt32();var reserved=decoder.decodeUInt32();return{newThreadId:newThreadId,oldThreadId:oldThreadId,newThreadPriority:newThreadPriority,oldThreadPriority:oldThreadPriority,previousCState:previousCState,spareByte:spareByte,oldThreadWaitReason:oldThreadWaitReason,oldThreadWaitMode:oldThreadWaitMode,oldThreadState:oldThreadState,oldThreadWaitIdealProcessor:oldThreadWaitIdealProcessor,newThreadWaitTime:newThreadWaitTime,reserved:reserved};},decodeStart:function(header,decoder){var fields=this.decodeFields(header,decoder);this.importer.createThreadIfNeeded(fields.processId,fields.threadId);return true;},decodeEnd:function(header,decoder){var fields=this.decodeFields(header,decoder);this.importer.removeThreadIfPresent(fields.threadId);return true;},decodeDCStart:function(header,decoder){var fields=this.decodeFields(header,decoder);this.importer.createThreadIfNeeded(fields.processId,fields.threadId);return true;},decodeDCEnd:function(header,decoder){var fields=this.decodeFields(header,decoder);this.importer.removeThreadIfPresent(fields.threadId);return true;},decodeCSwitch:function(header,decoder){var fields=this.decodeCSwitchFields(header,decoder);var cpu=this.importer.getOrCreateCpu(header.cpu);var new_thread=this.importer.getThreadFromWindowsTid(fields.newThreadId);var new_thread_name;if(new_thread&&new_thread.userFriendlyName){new_thread_name=new_thread.userFriendlyName;}else{var new_process_id=this.importer.getPidFromWindowsTid(fields.newThreadId);var new_process=this.model.getProcess(new_process_id);var new_process_name;if(new_process)
-new_process_name=new_process.name;else
-new_process_name='Unknown process';new_thread_name=new_process_name+' (tid '+fields.newThreadId+')';}
-cpu.switchActiveThread(header.timestamp,{},fields.newThreadId,new_thread_name,fields);return true;}};Parser.register(ThreadParser);return{ThreadParser:ThreadParser};});'use strict';tr.exportTo('tr.b',function(){function max(a,b){if(a===undefined)
-return b;if(b===undefined)
-return a;return Math.max(a,b);}
-function IntervalTree(beginPositionCb,endPositionCb){this.beginPositionCb_=beginPositionCb;this.endPositionCb_=endPositionCb;this.root_=undefined;this.size_=0;}
-IntervalTree.prototype={insert:function(datum){var startPosition=this.beginPositionCb_(datum);var endPosition=this.endPositionCb_(datum);var node=new IntervalTreeNode(datum,startPosition,endPosition);this.size_++;this.root_=this.insertNode_(this.root_,node);this.root_.colour=Colour.BLACK;return datum;},insertNode_:function(root,node){if(root===undefined)
-return node;if(root.leftNode&&root.leftNode.isRed&&root.rightNode&&root.rightNode.isRed)
-this.flipNodeColour_(root);if(node.key<root.key)
-root.leftNode=this.insertNode_(root.leftNode,node);else if(node.key===root.key)
-root.merge(node);else
-root.rightNode=this.insertNode_(root.rightNode,node);if(root.rightNode&&root.rightNode.isRed&&(root.leftNode===undefined||!root.leftNode.isRed))
-root=this.rotateLeft_(root);if(root.leftNode&&root.leftNode.isRed&&root.leftNode.leftNode&&root.leftNode.leftNode.isRed)
-root=this.rotateRight_(root);return root;},rotateRight_:function(node){var sibling=node.leftNode;node.leftNode=sibling.rightNode;sibling.rightNode=node;sibling.colour=node.colour;node.colour=Colour.RED;return sibling;},rotateLeft_:function(node){var sibling=node.rightNode;node.rightNode=sibling.leftNode;sibling.leftNode=node;sibling.colour=node.colour;node.colour=Colour.RED;return sibling;},flipNodeColour_:function(node){node.colour=this.flipColour_(node.colour);node.leftNode.colour=this.flipColour_(node.leftNode.colour);node.rightNode.colour=this.flipColour_(node.rightNode.colour);},flipColour_:function(colour){return colour===Colour.RED?Colour.BLACK:Colour.RED;},updateHighValues:function(){this.updateHighValues_(this.root_);},updateHighValues_:function(node){if(node===undefined)
-return undefined;node.maxHighLeft=this.updateHighValues_(node.leftNode);node.maxHighRight=this.updateHighValues_(node.rightNode);return max(max(node.maxHighLeft,node.highValue),node.maxHighRight);},validateFindArguments_:function(queryLow,queryHigh){if(queryLow===undefined||queryHigh===undefined)
-throw new Error('queryLow and queryHigh must be defined');if((typeof queryLow!=='number')||(typeof queryHigh!=='number'))
-throw new Error('queryLow and queryHigh must be numbers');},findIntersection:function(queryLow,queryHigh){this.validateFindArguments_(queryLow,queryHigh);if(this.root_===undefined)
-return[];var ret=[];this.root_.appendIntersectionsInto_(ret,queryLow,queryHigh);return ret;},get size(){return this.size_;},get root(){return this.root_;},dump_:function(){if(this.root_===undefined)
-return[];return this.root_.dump();}};var Colour={RED:'red',BLACK:'black'};function IntervalTreeNode(datum,lowValue,highValue){this.lowValue_=lowValue;this.data_=[{datum:datum,high:highValue,low:lowValue}];this.colour_=Colour.RED;this.parentNode_=undefined;this.leftNode_=undefined;this.rightNode_=undefined;this.maxHighLeft_=undefined;this.maxHighRight_=undefined;}
-IntervalTreeNode.prototype={appendIntersectionsInto_:function(ret,queryLow,queryHigh){if(this.lowValue_>=queryHigh){if(!this.leftNode_)
-return;return this.leftNode_.appendIntersectionsInto_(ret,queryLow,queryHigh);}
-if(this.maxHighLeft_>queryLow){this.leftNode_.appendIntersectionsInto_(ret,queryLow,queryHigh);}
-if(this.highValue>queryLow){for(var i=(this.data.length-1);i>=0;--i){if(this.data[i].high<queryLow)
-break;ret.push(this.data[i].datum);}}
-if(this.rightNode_){this.rightNode_.appendIntersectionsInto_(ret,queryLow,queryHigh);}},get colour(){return this.colour_;},set colour(colour){this.colour_=colour;},get key(){return this.lowValue_;},get lowValue(){return this.lowValue_;},get highValue(){return this.data_[this.data_.length-1].high;},set leftNode(left){this.leftNode_=left;},get leftNode(){return this.leftNode_;},get hasLeftNode(){return this.leftNode_!==undefined;},set rightNode(right){this.rightNode_=right;},get rightNode(){return this.rightNode_;},get hasRightNode(){return this.rightNode_!==undefined;},set parentNode(parent){this.parentNode_=parent;},get parentNode(){return this.parentNode_;},get isRootNode(){return this.parentNode_===undefined;},set maxHighLeft(high){this.maxHighLeft_=high;},get maxHighLeft(){return this.maxHighLeft_;},set maxHighRight(high){this.maxHighRight_=high;},get maxHighRight(){return this.maxHighRight_;},get data(){return this.data_;},get isRed(){return this.colour_===Colour.RED;},merge:function(node){for(var i=0;i<node.data.length;i++)
-this.data_.push(node.data[i]);this.data_.sort(function(a,b){return a.high-b.high;});},dump:function(){var ret={};if(this.leftNode_)
-ret['left']=this.leftNode_.dump();ret['data']=this.data_.map(function(d){return[d.low,d.high];});if(this.rightNode_)
-ret['right']=this.rightNode_.dump();return ret;}};return{IntervalTree:IntervalTree};});!function(t,n){if("object"==typeof exports&&"object"==typeof module)module.exports=n();else if("function"==typeof define&&define.amd)define(n);else{var r=n();for(var a in r)("object"==typeof exports?exports:t)[a]=r[a]}}(this,function(){return function(t){function n(a){if(r[a])return r[a].exports;var e=r[a]={exports:{},id:a,loaded:!1};return t[a].call(e.exports,e,e.exports,n),e.loaded=!0,e.exports}var r={};return n.m=t,n.c=r,n.p="",n(0)}([function(t,n,r){n.glMatrix=r(1),n.mat2=r(2),n.mat2d=r(3),n.mat3=r(4),n.mat4=r(5),n.quat=r(6),n.vec2=r(9),n.vec3=r(7),n.vec4=r(8)},function(t,n,r){var a={};a.EPSILON=1e-6,a.ARRAY_TYPE="undefined"!=typeof Float32Array?Float32Array:Array,a.RANDOM=Math.random,a.setMatrixArrayType=function(t){GLMAT_ARRAY_TYPE=t};var e=Math.PI/180;a.toRadian=function(t){return t*e},t.exports=a},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(4);return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t},e.clone=function(t){var n=new a.ARRAY_TYPE(4);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t},e.transpose=function(t,n){if(t===n){var r=n[1];t[1]=n[2],t[2]=r}else t[0]=n[0],t[1]=n[2],t[2]=n[1],t[3]=n[3];return t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*u-e*a;return o?(o=1/o,t[0]=u*o,t[1]=-a*o,t[2]=-e*o,t[3]=r*o,t):null},e.adjoint=function(t,n){var r=n[0];return t[0]=n[3],t[1]=-n[1],t[2]=-n[2],t[3]=r,t},e.determinant=function(t){return t[0]*t[3]-t[2]*t[1]},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],c=r[1],f=r[2],s=r[3];return t[0]=a*i+u*c,t[1]=e*i+o*c,t[2]=a*f+u*s,t[3]=e*f+o*s,t},e.mul=e.multiply,e.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c+u*i,t[1]=e*c+o*i,t[2]=a*-i+u*c,t[3]=e*-i+o*c,t},e.scale=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],c=r[1];return t[0]=a*i,t[1]=e*i,t[2]=u*c,t[3]=o*c,t},e.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=-r,t[3]=a,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=n[1],t},e.str=function(t){return"mat2("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2))},e.LDU=function(t,n,r,a){return t[2]=a[2]/a[0],r[0]=a[0],r[1]=a[1],r[3]=a[3]-t[2]*r[1],[t,n,r]},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(6);return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(6);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=r*u-a*e;return c?(c=1/c,t[0]=u*c,t[1]=-a*c,t[2]=-e*c,t[3]=r*c,t[4]=(e*i-u*o)*c,t[5]=(a*o-r*i)*c,t):null},e.determinant=function(t){return t[0]*t[3]-t[1]*t[2]},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=r[0],s=r[1],h=r[2],M=r[3],l=r[4],v=r[5];return t[0]=a*f+u*s,t[1]=e*f+o*s,t[2]=a*h+u*M,t[3]=e*h+o*M,t[4]=a*l+u*v+i,t[5]=e*l+o*v+c,t},e.mul=e.multiply,e.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=Math.sin(r),s=Math.cos(r);return t[0]=a*s+u*f,t[1]=e*s+o*f,t[2]=a*-f+u*s,t[3]=e*-f+o*s,t[4]=i,t[5]=c,t},e.scale=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=r[0],s=r[1];return t[0]=a*f,t[1]=e*f,t[2]=u*s,t[3]=o*s,t[4]=i,t[5]=c,t},e.translate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=r[0],s=r[1];return t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=a*f+u*s+i,t[5]=e*f+o*s+c,t},e.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=-r,t[3]=a,t[4]=0,t[5]=0,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=n[1],t[4]=0,t[5]=0,t},e.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=n[0],t[5]=n[1],t},e.str=function(t){return"mat2d("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+1)},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(9);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromMat4=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[4],t[4]=n[5],t[5]=n[6],t[6]=n[8],t[7]=n[9],t[8]=n[10],t},e.clone=function(t){var n=new a.ARRAY_TYPE(9);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.transpose=function(t,n){if(t===n){var r=n[1],a=n[2],e=n[5];t[1]=n[3],t[2]=n[6],t[3]=r,t[5]=n[7],t[6]=a,t[7]=e}else t[0]=n[0],t[1]=n[3],t[2]=n[6],t[3]=n[1],t[4]=n[4],t[5]=n[7],t[6]=n[2],t[7]=n[5],t[8]=n[8];return t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=s*o-i*f,M=-s*u+i*c,l=f*u-o*c,v=r*h+a*M+e*l;return v?(v=1/v,t[0]=h*v,t[1]=(-s*a+e*f)*v,t[2]=(i*a-e*o)*v,t[3]=M*v,t[4]=(s*r-e*c)*v,t[5]=(-i*r+e*u)*v,t[6]=l*v,t[7]=(-f*r+a*c)*v,t[8]=(o*r-a*u)*v,t):null},e.adjoint=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8];return t[0]=o*s-i*f,t[1]=e*f-a*s,t[2]=a*i-e*o,t[3]=i*c-u*s,t[4]=r*s-e*c,t[5]=e*u-r*i,t[6]=u*f-o*c,t[7]=a*c-r*f,t[8]=r*o-a*u,t},e.determinant=function(t){var n=t[0],r=t[1],a=t[2],e=t[3],u=t[4],o=t[5],i=t[6],c=t[7],f=t[8];return n*(f*u-o*c)+r*(-f*e+o*i)+a*(c*e-u*i)},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=r[0],l=r[1],v=r[2],m=r[3],p=r[4],d=r[5],A=r[6],R=r[7],w=r[8];return t[0]=M*a+l*o+v*f,t[1]=M*e+l*i+v*s,t[2]=M*u+l*c+v*h,t[3]=m*a+p*o+d*f,t[4]=m*e+p*i+d*s,t[5]=m*u+p*c+d*h,t[6]=A*a+R*o+w*f,t[7]=A*e+R*i+w*s,t[8]=A*u+R*c+w*h,t},e.mul=e.multiply,e.translate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=r[0],l=r[1];return t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=i,t[5]=c,t[6]=M*a+l*o+f,t[7]=M*e+l*i+s,t[8]=M*u+l*c+h,t},e.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=Math.sin(r),l=Math.cos(r);return t[0]=l*a+M*o,t[1]=l*e+M*i,t[2]=l*u+M*c,t[3]=l*o-M*a,t[4]=l*i-M*e,t[5]=l*c-M*u,t[6]=f,t[7]=s,t[8]=h,t},e.scale=function(t,n,r){var a=r[0],e=r[1];return t[0]=a*n[0],t[1]=a*n[1],t[2]=a*n[2],t[3]=e*n[3],t[4]=e*n[4],t[5]=e*n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t},e.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=n[0],t[7]=n[1],t[8]=1,t},e.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=0,t[3]=-r,t[4]=a,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=0,t[4]=n[1],t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromMat2d=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=0,t[3]=n[2],t[4]=n[3],t[5]=0,t[6]=n[4],t[7]=n[5],t[8]=1,t},e.fromQuat=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r+r,i=a+a,c=e+e,f=r*o,s=a*o,h=a*i,M=e*o,l=e*i,v=e*c,m=u*o,p=u*i,d=u*c;return t[0]=1-h-v,t[3]=s-d,t[6]=M+p,t[1]=s+d,t[4]=1-f-v,t[7]=l-m,t[2]=M-p,t[5]=l+m,t[8]=1-f-h,t},e.normalFromMat4=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=n[9],M=n[10],l=n[11],v=n[12],m=n[13],p=n[14],d=n[15],A=r*i-a*o,R=r*c-e*o,w=r*f-u*o,q=a*c-e*i,Y=a*f-u*i,g=e*f-u*c,y=s*m-h*v,x=s*p-M*v,P=s*d-l*v,E=h*p-M*m,T=h*d-l*m,b=M*d-l*p,D=A*b-R*T+w*E+q*P-Y*x+g*y;return D?(D=1/D,t[0]=(i*b-c*T+f*E)*D,t[1]=(c*P-o*b-f*x)*D,t[2]=(o*T-i*P+f*y)*D,t[3]=(e*T-a*b-u*E)*D,t[4]=(r*b-e*P+u*x)*D,t[5]=(a*P-r*T-u*y)*D,t[6]=(m*g-p*Y+d*q)*D,t[7]=(p*w-v*g-d*R)*D,t[8]=(v*Y-m*w+d*A)*D,t):null},e.str=function(t){return"mat3("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+Math.pow(t[6],2)+Math.pow(t[7],2)+Math.pow(t[8],2))},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(16);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.clone=function(t){var n=new a.ARRAY_TYPE(16);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t[9]=n[9],t[10]=n[10],t[11]=n[11],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.transpose=function(t,n){if(t===n){var r=n[1],a=n[2],e=n[3],u=n[6],o=n[7],i=n[11];t[1]=n[4],t[2]=n[8],t[3]=n[12],t[4]=r,t[6]=n[9],t[7]=n[13],t[8]=a,t[9]=u,t[11]=n[14],t[12]=e,t[13]=o,t[14]=i}else t[0]=n[0],t[1]=n[4],t[2]=n[8],t[3]=n[12],t[4]=n[1],t[5]=n[5],t[6]=n[9],t[7]=n[13],t[8]=n[2],t[9]=n[6],t[10]=n[10],t[11]=n[14],t[12]=n[3],t[13]=n[7],t[14]=n[11],t[15]=n[15];return t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=n[9],M=n[10],l=n[11],v=n[12],m=n[13],p=n[14],d=n[15],A=r*i-a*o,R=r*c-e*o,w=r*f-u*o,q=a*c-e*i,Y=a*f-u*i,g=e*f-u*c,y=s*m-h*v,x=s*p-M*v,P=s*d-l*v,E=h*p-M*m,T=h*d-l*m,b=M*d-l*p,D=A*b-R*T+w*E+q*P-Y*x+g*y;return D?(D=1/D,t[0]=(i*b-c*T+f*E)*D,t[1]=(e*T-a*b-u*E)*D,t[2]=(m*g-p*Y+d*q)*D,t[3]=(M*Y-h*g-l*q)*D,t[4]=(c*P-o*b-f*x)*D,t[5]=(r*b-e*P+u*x)*D,t[6]=(p*w-v*g-d*R)*D,t[7]=(s*g-M*w+l*R)*D,t[8]=(o*T-i*P+f*y)*D,t[9]=(a*P-r*T-u*y)*D,t[10]=(v*Y-m*w+d*A)*D,t[11]=(h*w-s*Y-l*A)*D,t[12]=(i*x-o*E-c*y)*D,t[13]=(r*E-a*x+e*y)*D,t[14]=(m*R-v*q-p*A)*D,t[15]=(s*q-h*R+M*A)*D,t):null},e.adjoint=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=n[9],M=n[10],l=n[11],v=n[12],m=n[13],p=n[14],d=n[15];return t[0]=i*(M*d-l*p)-h*(c*d-f*p)+m*(c*l-f*M),t[1]=-(a*(M*d-l*p)-h*(e*d-u*p)+m*(e*l-u*M)),t[2]=a*(c*d-f*p)-i*(e*d-u*p)+m*(e*f-u*c),t[3]=-(a*(c*l-f*M)-i*(e*l-u*M)+h*(e*f-u*c)),t[4]=-(o*(M*d-l*p)-s*(c*d-f*p)+v*(c*l-f*M)),t[5]=r*(M*d-l*p)-s*(e*d-u*p)+v*(e*l-u*M),t[6]=-(r*(c*d-f*p)-o*(e*d-u*p)+v*(e*f-u*c)),t[7]=r*(c*l-f*M)-o*(e*l-u*M)+s*(e*f-u*c),t[8]=o*(h*d-l*m)-s*(i*d-f*m)+v*(i*l-f*h),t[9]=-(r*(h*d-l*m)-s*(a*d-u*m)+v*(a*l-u*h)),t[10]=r*(i*d-f*m)-o*(a*d-u*m)+v*(a*f-u*i),t[11]=-(r*(i*l-f*h)-o*(a*l-u*h)+s*(a*f-u*i)),t[12]=-(o*(h*p-M*m)-s*(i*p-c*m)+v*(i*M-c*h)),t[13]=r*(h*p-M*m)-s*(a*p-e*m)+v*(a*M-e*h),t[14]=-(r*(i*p-c*m)-o*(a*p-e*m)+v*(a*c-e*i)),t[15]=r*(i*M-c*h)-o*(a*M-e*h)+s*(a*c-e*i),t},e.determinant=function(t){var n=t[0],r=t[1],a=t[2],e=t[3],u=t[4],o=t[5],i=t[6],c=t[7],f=t[8],s=t[9],h=t[10],M=t[11],l=t[12],v=t[13],m=t[14],p=t[15],d=n*o-r*u,A=n*i-a*u,R=n*c-e*u,w=r*i-a*o,q=r*c-e*o,Y=a*c-e*i,g=f*v-s*l,y=f*m-h*l,x=f*p-M*l,P=s*m-h*v,E=s*p-M*v,T=h*p-M*m;return d*T-A*E+R*P+w*x-q*y+Y*g},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=n[9],l=n[10],v=n[11],m=n[12],p=n[13],d=n[14],A=n[15],R=r[0],w=r[1],q=r[2],Y=r[3];return t[0]=R*a+w*i+q*h+Y*m,t[1]=R*e+w*c+q*M+Y*p,t[2]=R*u+w*f+q*l+Y*d,t[3]=R*o+w*s+q*v+Y*A,R=r[4],w=r[5],q=r[6],Y=r[7],t[4]=R*a+w*i+q*h+Y*m,t[5]=R*e+w*c+q*M+Y*p,t[6]=R*u+w*f+q*l+Y*d,t[7]=R*o+w*s+q*v+Y*A,R=r[8],w=r[9],q=r[10],Y=r[11],t[8]=R*a+w*i+q*h+Y*m,t[9]=R*e+w*c+q*M+Y*p,t[10]=R*u+w*f+q*l+Y*d,t[11]=R*o+w*s+q*v+Y*A,R=r[12],w=r[13],q=r[14],Y=r[15],t[12]=R*a+w*i+q*h+Y*m,t[13]=R*e+w*c+q*M+Y*p,t[14]=R*u+w*f+q*l+Y*d,t[15]=R*o+w*s+q*v+Y*A,t},e.mul=e.multiply,e.translate=function(t,n,r){var a,e,u,o,i,c,f,s,h,M,l,v,m=r[0],p=r[1],d=r[2];return n===t?(t[12]=n[0]*m+n[4]*p+n[8]*d+n[12],t[13]=n[1]*m+n[5]*p+n[9]*d+n[13],t[14]=n[2]*m+n[6]*p+n[10]*d+n[14],t[15]=n[3]*m+n[7]*p+n[11]*d+n[15]):(a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=n[9],l=n[10],v=n[11],t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=i,t[5]=c,t[6]=f,t[7]=s,t[8]=h,t[9]=M,t[10]=l,t[11]=v,t[12]=a*m+i*p+h*d+n[12],t[13]=e*m+c*p+M*d+n[13],t[14]=u*m+f*p+l*d+n[14],t[15]=o*m+s*p+v*d+n[15]),t},e.scale=function(t,n,r){var a=r[0],e=r[1],u=r[2];return t[0]=n[0]*a,t[1]=n[1]*a,t[2]=n[2]*a,t[3]=n[3]*a,t[4]=n[4]*e,t[5]=n[5]*e,t[6]=n[6]*e,t[7]=n[7]*e,t[8]=n[8]*u,t[9]=n[9]*u,t[10]=n[10]*u,t[11]=n[11]*u,t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15],t},e.rotate=function(t,n,r,e){var u,o,i,c,f,s,h,M,l,v,m,p,d,A,R,w,q,Y,g,y,x,P,E,T,b=e[0],D=e[1],L=e[2],_=Math.sqrt(b*b+D*D+L*L);return Math.abs(_)<a.EPSILON?null:(_=1/_,b*=_,D*=_,L*=_,u=Math.sin(r),o=Math.cos(r),i=1-o,c=n[0],f=n[1],s=n[2],h=n[3],M=n[4],l=n[5],v=n[6],m=n[7],p=n[8],d=n[9],A=n[10],R=n[11],w=b*b*i+o,q=D*b*i+L*u,Y=L*b*i-D*u,g=b*D*i-L*u,y=D*D*i+o,x=L*D*i+b*u,P=b*L*i+D*u,E=D*L*i-b*u,T=L*L*i+o,t[0]=c*w+M*q+p*Y,t[1]=f*w+l*q+d*Y,t[2]=s*w+v*q+A*Y,t[3]=h*w+m*q+R*Y,t[4]=c*g+M*y+p*x,t[5]=f*g+l*y+d*x,t[6]=s*g+v*y+A*x,t[7]=h*g+m*y+R*x,t[8]=c*P+M*E+p*T,t[9]=f*P+l*E+d*T,t[10]=s*P+v*E+A*T,t[11]=h*P+m*E+R*T,n!==t&&(t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t)},e.rotateX=function(t,n,r){var a=Math.sin(r),e=Math.cos(r),u=n[4],o=n[5],i=n[6],c=n[7],f=n[8],s=n[9],h=n[10],M=n[11];return n!==t&&(t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t[4]=u*e+f*a,t[5]=o*e+s*a,t[6]=i*e+h*a,t[7]=c*e+M*a,t[8]=f*e-u*a,t[9]=s*e-o*a,t[10]=h*e-i*a,t[11]=M*e-c*a,t},e.rotateY=function(t,n,r){var a=Math.sin(r),e=Math.cos(r),u=n[0],o=n[1],i=n[2],c=n[3],f=n[8],s=n[9],h=n[10],M=n[11];return n!==t&&(t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t[0]=u*e-f*a,t[1]=o*e-s*a,t[2]=i*e-h*a,t[3]=c*e-M*a,t[8]=u*a+f*e,t[9]=o*a+s*e,t[10]=i*a+h*e,t[11]=c*a+M*e,t},e.rotateZ=function(t,n,r){var a=Math.sin(r),e=Math.cos(r),u=n[0],o=n[1],i=n[2],c=n[3],f=n[4],s=n[5],h=n[6],M=n[7];return n!==t&&(t[8]=n[8],t[9]=n[9],t[10]=n[10],t[11]=n[11],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t[0]=u*e+f*a,t[1]=o*e+s*a,t[2]=i*e+h*a,t[3]=c*e+M*a,t[4]=f*e-u*a,t[5]=s*e-o*a,t[6]=h*e-i*a,t[7]=M*e-c*a,t},e.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=n[0],t[13]=n[1],t[14]=n[2],t[15]=1,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=n[1],t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=n[2],t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromRotation=function(t,n,r){var e,u,o,i=r[0],c=r[1],f=r[2],s=Math.sqrt(i*i+c*c+f*f);return Math.abs(s)<a.EPSILON?null:(s=1/s,i*=s,c*=s,f*=s,e=Math.sin(n),u=Math.cos(n),o=1-u,t[0]=i*i*o+u,t[1]=c*i*o+f*e,t[2]=f*i*o-c*e,t[3]=0,t[4]=i*c*o-f*e,t[5]=c*c*o+u,t[6]=f*c*o+i*e,t[7]=0,t[8]=i*f*o+c*e,t[9]=c*f*o-i*e,t[10]=f*f*o+u,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t)},e.fromXRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=a,t[6]=r,t[7]=0,t[8]=0,t[9]=-r,t[10]=a,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromYRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=0,t[2]=-r,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=r,t[9]=0,t[10]=a,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromZRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=0,t[3]=0,t[4]=-r,t[5]=a,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromRotationTranslation=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=a+a,c=e+e,f=u+u,s=a*i,h=a*c,M=a*f,l=e*c,v=e*f,m=u*f,p=o*i,d=o*c,A=o*f;return t[0]=1-(l+m),t[1]=h+A,t[2]=M-d,t[3]=0,t[4]=h-A,t[5]=1-(s+m),t[6]=v+p,t[7]=0,t[8]=M+d,t[9]=v-p,t[10]=1-(s+l),t[11]=0,t[12]=r[0],t[13]=r[1],t[14]=r[2],t[15]=1,t},e.fromRotationTranslationScale=function(t,n,r,a){var e=n[0],u=n[1],o=n[2],i=n[3],c=e+e,f=u+u,s=o+o,h=e*c,M=e*f,l=e*s,v=u*f,m=u*s,p=o*s,d=i*c,A=i*f,R=i*s,w=a[0],q=a[1],Y=a[2];return t[0]=(1-(v+p))*w,t[1]=(M+R)*w,t[2]=(l-A)*w,t[3]=0,t[4]=(M-R)*q,t[5]=(1-(h+p))*q,t[6]=(m+d)*q,t[7]=0,t[8]=(l+A)*Y,t[9]=(m-d)*Y,t[10]=(1-(h+v))*Y,t[11]=0,t[12]=r[0],t[13]=r[1],t[14]=r[2],t[15]=1,t},e.fromRotationTranslationScaleOrigin=function(t,n,r,a,e){var u=n[0],o=n[1],i=n[2],c=n[3],f=u+u,s=o+o,h=i+i,M=u*f,l=u*s,v=u*h,m=o*s,p=o*h,d=i*h,A=c*f,R=c*s,w=c*h,q=a[0],Y=a[1],g=a[2],y=e[0],x=e[1],P=e[2];return t[0]=(1-(m+d))*q,t[1]=(l+w)*q,t[2]=(v-R)*q,t[3]=0,t[4]=(l-w)*Y,t[5]=(1-(M+d))*Y,t[6]=(p+A)*Y,t[7]=0,t[8]=(v+R)*g,t[9]=(p-A)*g,t[10]=(1-(M+m))*g,t[11]=0,t[12]=r[0]+y-(t[0]*y+t[4]*x+t[8]*P),t[13]=r[1]+x-(t[1]*y+t[5]*x+t[9]*P),t[14]=r[2]+P-(t[2]*y+t[6]*x+t[10]*P),t[15]=1,t},e.fromQuat=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r+r,i=a+a,c=e+e,f=r*o,s=a*o,h=a*i,M=e*o,l=e*i,v=e*c,m=u*o,p=u*i,d=u*c;return t[0]=1-h-v,t[1]=s+d,t[2]=M-p,t[3]=0,t[4]=s-d,t[5]=1-f-v,t[6]=l+m,t[7]=0,t[8]=M+p,t[9]=l-m,t[10]=1-f-h,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.frustum=function(t,n,r,a,e,u,o){var i=1/(r-n),c=1/(e-a),f=1/(u-o);return t[0]=2*u*i,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=2*u*c,t[6]=0,t[7]=0,t[8]=(r+n)*i,t[9]=(e+a)*c,t[10]=(o+u)*f,t[11]=-1,t[12]=0,t[13]=0,t[14]=o*u*2*f,t[15]=0,t},e.perspective=function(t,n,r,a,e){var u=1/Math.tan(n/2),o=1/(a-e);return t[0]=u/r,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=u,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=(e+a)*o,t[11]=-1,t[12]=0,t[13]=0,t[14]=2*e*a*o,t[15]=0,t},e.perspectiveFromFieldOfView=function(t,n,r,a){var e=Math.tan(n.upDegrees*Math.PI/180),u=Math.tan(n.downDegrees*Math.PI/180),o=Math.tan(n.leftDegrees*Math.PI/180),i=Math.tan(n.rightDegrees*Math.PI/180),c=2/(o+i),f=2/(e+u);return t[0]=c,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=f,t[6]=0,t[7]=0,t[8]=-((o-i)*c*.5),t[9]=(e-u)*f*.5,t[10]=a/(r-a),t[11]=-1,t[12]=0,t[13]=0,t[14]=a*r/(r-a),t[15]=0,t},e.ortho=function(t,n,r,a,e,u,o){var i=1/(n-r),c=1/(a-e),f=1/(u-o);return t[0]=-2*i,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=-2*c,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=2*f,t[11]=0,t[12]=(n+r)*i,t[13]=(e+a)*c,t[14]=(o+u)*f,t[15]=1,t},e.lookAt=function(t,n,r,u){var o,i,c,f,s,h,M,l,v,m,p=n[0],d=n[1],A=n[2],R=u[0],w=u[1],q=u[2],Y=r[0],g=r[1],y=r[2];return Math.abs(p-Y)<a.EPSILON&&Math.abs(d-g)<a.EPSILON&&Math.abs(A-y)<a.EPSILON?e.identity(t):(M=p-Y,l=d-g,v=A-y,m=1/Math.sqrt(M*M+l*l+v*v),M*=m,l*=m,v*=m,o=w*v-q*l,i=q*M-R*v,c=R*l-w*M,m=Math.sqrt(o*o+i*i+c*c),m?(m=1/m,o*=m,i*=m,c*=m):(o=0,i=0,c=0),f=l*c-v*i,s=v*o-M*c,h=M*i-l*o,m=Math.sqrt(f*f+s*s+h*h),m?(m=1/m,f*=m,s*=m,h*=m):(f=0,s=0,h=0),t[0]=o,t[1]=f,t[2]=M,t[3]=0,t[4]=i,t[5]=s,t[6]=l,t[7]=0,t[8]=c,t[9]=h,t[10]=v,t[11]=0,t[12]=-(o*p+i*d+c*A),t[13]=-(f*p+s*d+h*A),t[14]=-(M*p+l*d+v*A),t[15]=1,t)},e.str=function(t){return"mat4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+", "+t[9]+", "+t[10]+", "+t[11]+", "+t[12]+", "+t[13]+", "+t[14]+", "+t[15]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+Math.pow(t[6],2)+Math.pow(t[7],2)+Math.pow(t[8],2)+Math.pow(t[9],2)+Math.pow(t[10],2)+Math.pow(t[11],2)+Math.pow(t[12],2)+Math.pow(t[13],2)+Math.pow(t[14],2)+Math.pow(t[15],2))},t.exports=e},function(t,n,r){var a=r(1),e=r(4),u=r(7),o=r(8),i={};i.create=function(){var t=new a.ARRAY_TYPE(4);return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},i.rotationTo=function(){var t=u.create(),n=u.fromValues(1,0,0),r=u.fromValues(0,1,0);return function(a,e,o){var c=u.dot(e,o);return-.999999>c?(u.cross(t,n,e),u.length(t)<1e-6&&u.cross(t,r,e),u.normalize(t,t),i.setAxisAngle(a,t,Math.PI),a):c>.999999?(a[0]=0,a[1]=0,a[2]=0,a[3]=1,a):(u.cross(t,e,o),a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=1+c,i.normalize(a,a))}}(),i.setAxes=function(){var t=e.create();return function(n,r,a,e){return t[0]=a[0],t[3]=a[1],t[6]=a[2],t[1]=e[0],t[4]=e[1],t[7]=e[2],t[2]=-r[0],t[5]=-r[1],t[8]=-r[2],i.normalize(n,i.fromMat3(n,t))}}(),i.clone=o.clone,i.fromValues=o.fromValues,i.copy=o.copy,i.set=o.set,i.identity=function(t){return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},i.setAxisAngle=function(t,n,r){r=.5*r;var a=Math.sin(r);return t[0]=a*n[0],t[1]=a*n[1],t[2]=a*n[2],t[3]=Math.cos(r),t},i.add=o.add,i.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],c=r[1],f=r[2],s=r[3];return t[0]=a*s+o*i+e*f-u*c,t[1]=e*s+o*c+u*i-a*f,t[2]=u*s+o*f+a*c-e*i,t[3]=o*s-a*i-e*c-u*f,t},i.mul=i.multiply,i.scale=o.scale,i.rotateX=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c+o*i,t[1]=e*c+u*i,t[2]=u*c-e*i,t[3]=o*c-a*i,t},i.rotateY=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c-u*i,t[1]=e*c+o*i,t[2]=u*c+a*i,t[3]=o*c-e*i,t},i.rotateZ=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c+e*i,t[1]=e*c-a*i,t[2]=u*c+o*i,t[3]=o*c-u*i,t},i.calculateW=function(t,n){var r=n[0],a=n[1],e=n[2];return t[0]=r,t[1]=a,t[2]=e,t[3]=Math.sqrt(Math.abs(1-r*r-a*a-e*e)),t},i.dot=o.dot,i.lerp=o.lerp,i.slerp=function(t,n,r,a){var e,u,o,i,c,f=n[0],s=n[1],h=n[2],M=n[3],l=r[0],v=r[1],m=r[2],p=r[3];return u=f*l+s*v+h*m+M*p,0>u&&(u=-u,l=-l,v=-v,m=-m,p=-p),1-u>1e-6?(e=Math.acos(u),o=Math.sin(e),i=Math.sin((1-a)*e)/o,c=Math.sin(a*e)/o):(i=1-a,c=a),t[0]=i*f+c*l,t[1]=i*s+c*v,t[2]=i*h+c*m,t[3]=i*M+c*p,t},i.sqlerp=function(){var t=i.create(),n=i.create();return function(r,a,e,u,o,c){return i.slerp(t,a,o,c),i.slerp(n,e,u,c),i.slerp(r,t,n,2*c*(1-c)),r}}(),i.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*r+a*a+e*e+u*u,i=o?1/o:0;return t[0]=-r*i,t[1]=-a*i,t[2]=-e*i,t[3]=u*i,t},i.conjugate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t[3]=n[3],t},i.length=o.length,i.len=i.length,i.squaredLength=o.squaredLength,i.sqrLen=i.squaredLength,i.normalize=o.normalize,i.fromMat3=function(t,n){var r,a=n[0]+n[4]+n[8];if(a>0)r=Math.sqrt(a+1),t[3]=.5*r,r=.5/r,t[0]=(n[5]-n[7])*r,t[1]=(n[6]-n[2])*r,t[2]=(n[1]-n[3])*r;else{var e=0;n[4]>n[0]&&(e=1),n[8]>n[3*e+e]&&(e=2);var u=(e+1)%3,o=(e+2)%3;r=Math.sqrt(n[3*e+e]-n[3*u+u]-n[3*o+o]+1),t[e]=.5*r,r=.5/r,t[3]=(n[3*u+o]-n[3*o+u])*r,t[u]=(n[3*u+e]+n[3*e+u])*r,t[o]=(n[3*o+e]+n[3*e+o])*r}return t},i.str=function(t){return"quat("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},t.exports=i},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(3);return t[0]=0,t[1]=0,t[2]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(3);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n},e.fromValues=function(t,n,r){var e=new a.ARRAY_TYPE(3);return e[0]=t,e[1]=n,e[2]=r,e},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t},e.set=function(t,n,r,a){return t[0]=n,t[1]=r,t[2]=a,t},e.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t[2]=n[2]+r[2],t},e.subtract=function(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t[2]=n[2]-r[2],t},e.sub=e.subtract,e.multiply=function(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t[2]=n[2]*r[2],t},e.mul=e.multiply,e.divide=function(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t[2]=n[2]/r[2],t},e.div=e.divide,e.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t[2]=Math.min(n[2],r[2]),t},e.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t[2]=Math.max(n[2],r[2]),t},e.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t},e.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t[2]=n[2]+r[2]*a,t},e.distance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2];return Math.sqrt(r*r+a*a+e*e)},e.dist=e.distance,e.squaredDistance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2];return r*r+a*a+e*e},e.sqrDist=e.squaredDistance,e.length=function(t){var n=t[0],r=t[1],a=t[2];return Math.sqrt(n*n+r*r+a*a)},e.len=e.length,e.squaredLength=function(t){var n=t[0],r=t[1],a=t[2];return n*n+r*r+a*a},e.sqrLen=e.squaredLength,e.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t},e.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t[2]=1/n[2],t},e.normalize=function(t,n){var r=n[0],a=n[1],e=n[2],u=r*r+a*a+e*e;return u>0&&(u=1/Math.sqrt(u),t[0]=n[0]*u,t[1]=n[1]*u,t[2]=n[2]*u),t},e.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]},e.cross=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],c=r[2];return t[0]=e*c-u*i,t[1]=u*o-a*c,t[2]=a*i-e*o,t},e.lerp=function(t,n,r,a){var e=n[0],u=n[1],o=n[2];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t[2]=o+a*(r[2]-o),t},e.hermite=function(t,n,r,a,e,u){var o=u*u,i=o*(2*u-3)+1,c=o*(u-2)+u,f=o*(u-1),s=o*(3-2*u);return t[0]=n[0]*i+r[0]*c+a[0]*f+e[0]*s,t[1]=n[1]*i+r[1]*c+a[1]*f+e[1]*s,t[2]=n[2]*i+r[2]*c+a[2]*f+e[2]*s,t},e.bezier=function(t,n,r,a,e,u){var o=1-u,i=o*o,c=u*u,f=i*o,s=3*u*i,h=3*c*o,M=c*u;return t[0]=n[0]*f+r[0]*s+a[0]*h+e[0]*M,t[1]=n[1]*f+r[1]*s+a[1]*h+e[1]*M,t[2]=n[2]*f+r[2]*s+a[2]*h+e[2]*M,t},e.random=function(t,n){n=n||1;var r=2*a.RANDOM()*Math.PI,e=2*a.RANDOM()-1,u=Math.sqrt(1-e*e)*n;return t[0]=Math.cos(r)*u,t[1]=Math.sin(r)*u,t[2]=e*n,t},e.transformMat4=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[3]*a+r[7]*e+r[11]*u+r[15];return o=o||1,t[0]=(r[0]*a+r[4]*e+r[8]*u+r[12])/o,t[1]=(r[1]*a+r[5]*e+r[9]*u+r[13])/o,t[2]=(r[2]*a+r[6]*e+r[10]*u+r[14])/o,t},e.transformMat3=function(t,n,r){var a=n[0],e=n[1],u=n[2];return t[0]=a*r[0]+e*r[3]+u*r[6],t[1]=a*r[1]+e*r[4]+u*r[7],t[2]=a*r[2]+e*r[5]+u*r[8],t},e.transformQuat=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],c=r[2],f=r[3],s=f*a+i*u-c*e,h=f*e+c*a-o*u,M=f*u+o*e-i*a,l=-o*a-i*e-c*u;return t[0]=s*f+l*-o+h*-c-M*-i,t[1]=h*f+l*-i+M*-o-s*-c,t[2]=M*f+l*-c+s*-i-h*-o,t},e.rotateX=function(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[0],u[1]=e[1]*Math.cos(a)-e[2]*Math.sin(a),u[2]=e[1]*Math.sin(a)+e[2]*Math.cos(a),t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t},e.rotateY=function(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[2]*Math.sin(a)+e[0]*Math.cos(a),u[1]=e[1],u[2]=e[2]*Math.cos(a)-e[0]*Math.sin(a),t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t},e.rotateZ=function(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[0]*Math.cos(a)-e[1]*Math.sin(a),u[1]=e[0]*Math.sin(a)+e[1]*Math.cos(a),u[2]=e[2],t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t},e.forEach=function(){var t=e.create();return function(n,r,a,e,u,o){var i,c;for(r||(r=3),a||(a=0),c=e?Math.min(e*r+a,n.length):n.length,i=a;c>i;i+=r)t[0]=n[i],t[1]=n[i+1],t[2]=n[i+2],u(t,t,o),n[i]=t[0],n[i+1]=t[1],n[i+2]=t[2];return n}}(),e.angle=function(t,n){var r=e.fromValues(t[0],t[1],t[2]),a=e.fromValues(n[0],n[1],n[2]);e.normalize(r,r),e.normalize(a,a);var u=e.dot(r,a);return u>1?0:Math.acos(u)},e.str=function(t){return"vec3("+t[0]+", "+t[1]+", "+t[2]+")"},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(4);return t[0]=0,t[1]=0,t[2]=0,t[3]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(4);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n},e.fromValues=function(t,n,r,e){var u=new a.ARRAY_TYPE(4);return u[0]=t,u[1]=n,u[2]=r,u[3]=e,u},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t},e.set=function(t,n,r,a,e){return t[0]=n,t[1]=r,t[2]=a,t[3]=e,t},e.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t[2]=n[2]+r[2],t[3]=n[3]+r[3],t},e.subtract=function(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t[2]=n[2]-r[2],t[3]=n[3]-r[3],t},e.sub=e.subtract,e.multiply=function(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t[2]=n[2]*r[2],t[3]=n[3]*r[3],t},e.mul=e.multiply,e.divide=function(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t[2]=n[2]/r[2],t[3]=n[3]/r[3],t},e.div=e.divide,e.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t[2]=Math.min(n[2],r[2]),t[3]=Math.min(n[3],r[3]),t},e.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t[2]=Math.max(n[2],r[2]),t[3]=Math.max(n[3],r[3]),t},e.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t[3]=n[3]*r,t},e.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t[2]=n[2]+r[2]*a,t[3]=n[3]+r[3]*a,t},e.distance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2],u=n[3]-t[3];return Math.sqrt(r*r+a*a+e*e+u*u)},e.dist=e.distance,e.squaredDistance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2],u=n[3]-t[3];return r*r+a*a+e*e+u*u},e.sqrDist=e.squaredDistance,e.length=function(t){var n=t[0],r=t[1],a=t[2],e=t[3];return Math.sqrt(n*n+r*r+a*a+e*e)},e.len=e.length,e.squaredLength=function(t){var n=t[0],r=t[1],a=t[2],e=t[3];return n*n+r*r+a*a+e*e},e.sqrLen=e.squaredLength,e.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t[3]=-n[3],t},e.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t[2]=1/n[2],t[3]=1/n[3],t},e.normalize=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*r+a*a+e*e+u*u;return o>0&&(o=1/Math.sqrt(o),t[0]=r*o,t[1]=a*o,t[2]=e*o,t[3]=u*o),t},e.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]+t[3]*n[3]},e.lerp=function(t,n,r,a){var e=n[0],u=n[1],o=n[2],i=n[3];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t[2]=o+a*(r[2]-o),t[3]=i+a*(r[3]-i),t},e.random=function(t,n){return n=n||1,t[0]=a.RANDOM(),t[1]=a.RANDOM(),t[2]=a.RANDOM(),t[3]=a.RANDOM(),e.normalize(t,t),e.scale(t,t,n),t},e.transformMat4=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3];return t[0]=r[0]*a+r[4]*e+r[8]*u+r[12]*o,t[1]=r[1]*a+r[5]*e+r[9]*u+r[13]*o,t[2]=r[2]*a+r[6]*e+r[10]*u+r[14]*o,t[3]=r[3]*a+r[7]*e+r[11]*u+r[15]*o,t},e.transformQuat=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],c=r[2],f=r[3],s=f*a+i*u-c*e,h=f*e+c*a-o*u,M=f*u+o*e-i*a,l=-o*a-i*e-c*u;return t[0]=s*f+l*-o+h*-c-M*-i,t[1]=h*f+l*-i+M*-o-s*-c,t[2]=M*f+l*-c+s*-i-h*-o,t[3]=n[3],t},e.forEach=function(){var t=e.create();return function(n,r,a,e,u,o){var i,c;for(r||(r=4),a||(a=0),c=e?Math.min(e*r+a,n.length):n.length,i=a;c>i;i+=r)t[0]=n[i],t[1]=n[i+1],t[2]=n[i+2],t[3]=n[i+3],u(t,t,o),n[i]=t[0],n[i+1]=t[1],n[i+2]=t[2],n[i+3]=t[3];return n}}(),e.str=function(t){return"vec4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(2);return t[0]=0,t[1]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(2);return n[0]=t[0],n[1]=t[1],n},e.fromValues=function(t,n){var r=new a.ARRAY_TYPE(2);return r[0]=t,r[1]=n,r},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t},e.set=function(t,n,r){return t[0]=n,t[1]=r,t},e.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t},e.subtract=function(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t},e.sub=e.subtract,e.multiply=function(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t},e.mul=e.multiply,e.divide=function(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t},e.div=e.divide,e.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t},e.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t},e.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t},e.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t},e.distance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1];return Math.sqrt(r*r+a*a)},e.dist=e.distance,e.squaredDistance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1];return r*r+a*a},e.sqrDist=e.squaredDistance,e.length=function(t){var n=t[0],r=t[1];return Math.sqrt(n*n+r*r)},e.len=e.length,e.squaredLength=function(t){var n=t[0],r=t[1];return n*n+r*r},e.sqrLen=e.squaredLength,e.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t},e.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t},e.normalize=function(t,n){var r=n[0],a=n[1],e=r*r+a*a;return e>0&&(e=1/Math.sqrt(e),t[0]=n[0]*e,t[1]=n[1]*e),t},e.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]},e.cross=function(t,n,r){var a=n[0]*r[1]-n[1]*r[0];return t[0]=t[1]=0,t[2]=a,t},e.lerp=function(t,n,r,a){var e=n[0],u=n[1];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t},e.random=function(t,n){n=n||1;var r=2*a.RANDOM()*Math.PI;return t[0]=Math.cos(r)*n,t[1]=Math.sin(r)*n,t},e.transformMat2=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[2]*e,t[1]=r[1]*a+r[3]*e,t},e.transformMat2d=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[2]*e+r[4],t[1]=r[1]*a+r[3]*e+r[5],t},e.transformMat3=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[3]*e+r[6],t[1]=r[1]*a+r[4]*e+r[7],t},e.transformMat4=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[4]*e+r[12],t[1]=r[1]*a+r[5]*e+r[13],t},e.forEach=function(){var t=e.create();return function(n,r,a,e,u,o){var i,c;for(r||(r=2),a||(a=0),c=e?Math.min(e*r+a,n.length):n.length,i=a;c>i;i+=r)t[0]=n[i],t[1]=n[i+1],u(t,t,o),n[i]=t[0],n[i+1]=t[1];return n}}(),e.str=function(t){return"vec2("+t[0]+", "+t[1]+")"},t.exports=e}])});'use strict';(function(global){if(tr.isNode){var glMatrixAbsPath=HTMLImportsLoader.hrefToAbsolutePath('/gl-matrix-min.js');var glMatrixModule=require(glMatrixAbsPath);for(var exportName in glMatrixModule){global[exportName]=glMatrixModule[exportName];}}})(this);'use strict';tr.exportTo('tr.b',function(){function clamp(x,lo,hi){return Math.min(Math.max(x,lo),hi);}
-function lerp(percentage,lo,hi){var range=hi-lo;return lo+percentage*range;}
+if(opt_totalRange&&(range.max<opt_totalRange.max)){emptyRanges.push(tr.b.math.Range.fromExplicitRange(range.max,opt_totalRange.max));}});return emptyRanges;}
+return{convertEventsToRanges,findEmptyRangesBetweenRanges,mergeRanges,};});!function(t,n){if("object"==typeof exports&&"object"==typeof module)module.exports=n();else if("function"==typeof define&&define.amd)define(n);else{var r=n();for(var a in r)("object"==typeof exports?exports:t)[a]=r[a]}}(this,function(){return function(t){function n(a){if(r[a])return r[a].exports;var e=r[a]={exports:{},id:a,loaded:!1};return t[a].call(e.exports,e,e.exports,n),e.loaded=!0,e.exports}var r={};return n.m=t,n.c=r,n.p="",n(0)}([function(t,n,r){n.glMatrix=r(1),n.mat2=r(2),n.mat2d=r(3),n.mat3=r(4),n.mat4=r(5),n.quat=r(6),n.vec2=r(9),n.vec3=r(7),n.vec4=r(8)},function(t,n,r){var a={};a.EPSILON=1e-6,a.ARRAY_TYPE="undefined"!=typeof Float32Array?Float32Array:Array,a.RANDOM=Math.random,a.setMatrixArrayType=function(t){GLMAT_ARRAY_TYPE=t};var e=Math.PI/180;a.toRadian=function(t){return t*e},t.exports=a},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(4);return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t},e.clone=function(t){var n=new a.ARRAY_TYPE(4);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t},e.transpose=function(t,n){if(t===n){var r=n[1];t[1]=n[2],t[2]=r}else t[0]=n[0],t[1]=n[2],t[2]=n[1],t[3]=n[3];return t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*u-e*a;return o?(o=1/o,t[0]=u*o,t[1]=-a*o,t[2]=-e*o,t[3]=r*o,t):null},e.adjoint=function(t,n){var r=n[0];return t[0]=n[3],t[1]=-n[1],t[2]=-n[2],t[3]=r,t},e.determinant=function(t){return t[0]*t[3]-t[2]*t[1]},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],c=r[1],f=r[2],s=r[3];return t[0]=a*i+u*c,t[1]=e*i+o*c,t[2]=a*f+u*s,t[3]=e*f+o*s,t},e.mul=e.multiply,e.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c+u*i,t[1]=e*c+o*i,t[2]=a*-i+u*c,t[3]=e*-i+o*c,t},e.scale=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],c=r[1];return t[0]=a*i,t[1]=e*i,t[2]=u*c,t[3]=o*c,t},e.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=-r,t[3]=a,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=n[1],t},e.str=function(t){return"mat2("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2))},e.LDU=function(t,n,r,a){return t[2]=a[2]/a[0],r[0]=a[0],r[1]=a[1],r[3]=a[3]-t[2]*r[1],[t,n,r]},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(6);return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(6);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=r*u-a*e;return c?(c=1/c,t[0]=u*c,t[1]=-a*c,t[2]=-e*c,t[3]=r*c,t[4]=(e*i-u*o)*c,t[5]=(a*o-r*i)*c,t):null},e.determinant=function(t){return t[0]*t[3]-t[1]*t[2]},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=r[0],s=r[1],h=r[2],M=r[3],l=r[4],v=r[5];return t[0]=a*f+u*s,t[1]=e*f+o*s,t[2]=a*h+u*M,t[3]=e*h+o*M,t[4]=a*l+u*v+i,t[5]=e*l+o*v+c,t},e.mul=e.multiply,e.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=Math.sin(r),s=Math.cos(r);return t[0]=a*s+u*f,t[1]=e*s+o*f,t[2]=a*-f+u*s,t[3]=e*-f+o*s,t[4]=i,t[5]=c,t},e.scale=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=r[0],s=r[1];return t[0]=a*f,t[1]=e*f,t[2]=u*s,t[3]=o*s,t[4]=i,t[5]=c,t},e.translate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=r[0],s=r[1];return t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=a*f+u*s+i,t[5]=e*f+o*s+c,t},e.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=-r,t[3]=a,t[4]=0,t[5]=0,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=n[1],t[4]=0,t[5]=0,t},e.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=n[0],t[5]=n[1],t},e.str=function(t){return"mat2d("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+1)},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(9);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromMat4=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[4],t[4]=n[5],t[5]=n[6],t[6]=n[8],t[7]=n[9],t[8]=n[10],t},e.clone=function(t){var n=new a.ARRAY_TYPE(9);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.transpose=function(t,n){if(t===n){var r=n[1],a=n[2],e=n[5];t[1]=n[3],t[2]=n[6],t[3]=r,t[5]=n[7],t[6]=a,t[7]=e}else t[0]=n[0],t[1]=n[3],t[2]=n[6],t[3]=n[1],t[4]=n[4],t[5]=n[7],t[6]=n[2],t[7]=n[5],t[8]=n[8];return t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=s*o-i*f,M=-s*u+i*c,l=f*u-o*c,v=r*h+a*M+e*l;return v?(v=1/v,t[0]=h*v,t[1]=(-s*a+e*f)*v,t[2]=(i*a-e*o)*v,t[3]=M*v,t[4]=(s*r-e*c)*v,t[5]=(-i*r+e*u)*v,t[6]=l*v,t[7]=(-f*r+a*c)*v,t[8]=(o*r-a*u)*v,t):null},e.adjoint=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8];return t[0]=o*s-i*f,t[1]=e*f-a*s,t[2]=a*i-e*o,t[3]=i*c-u*s,t[4]=r*s-e*c,t[5]=e*u-r*i,t[6]=u*f-o*c,t[7]=a*c-r*f,t[8]=r*o-a*u,t},e.determinant=function(t){var n=t[0],r=t[1],a=t[2],e=t[3],u=t[4],o=t[5],i=t[6],c=t[7],f=t[8];return n*(f*u-o*c)+r*(-f*e+o*i)+a*(c*e-u*i)},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=r[0],l=r[1],v=r[2],m=r[3],p=r[4],d=r[5],A=r[6],R=r[7],w=r[8];return t[0]=M*a+l*o+v*f,t[1]=M*e+l*i+v*s,t[2]=M*u+l*c+v*h,t[3]=m*a+p*o+d*f,t[4]=m*e+p*i+d*s,t[5]=m*u+p*c+d*h,t[6]=A*a+R*o+w*f,t[7]=A*e+R*i+w*s,t[8]=A*u+R*c+w*h,t},e.mul=e.multiply,e.translate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=r[0],l=r[1];return t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=i,t[5]=c,t[6]=M*a+l*o+f,t[7]=M*e+l*i+s,t[8]=M*u+l*c+h,t},e.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=Math.sin(r),l=Math.cos(r);return t[0]=l*a+M*o,t[1]=l*e+M*i,t[2]=l*u+M*c,t[3]=l*o-M*a,t[4]=l*i-M*e,t[5]=l*c-M*u,t[6]=f,t[7]=s,t[8]=h,t},e.scale=function(t,n,r){var a=r[0],e=r[1];return t[0]=a*n[0],t[1]=a*n[1],t[2]=a*n[2],t[3]=e*n[3],t[4]=e*n[4],t[5]=e*n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t},e.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=n[0],t[7]=n[1],t[8]=1,t},e.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=0,t[3]=-r,t[4]=a,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=0,t[4]=n[1],t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromMat2d=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=0,t[3]=n[2],t[4]=n[3],t[5]=0,t[6]=n[4],t[7]=n[5],t[8]=1,t},e.fromQuat=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r+r,i=a+a,c=e+e,f=r*o,s=a*o,h=a*i,M=e*o,l=e*i,v=e*c,m=u*o,p=u*i,d=u*c;return t[0]=1-h-v,t[3]=s-d,t[6]=M+p,t[1]=s+d,t[4]=1-f-v,t[7]=l-m,t[2]=M-p,t[5]=l+m,t[8]=1-f-h,t},e.normalFromMat4=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=n[9],M=n[10],l=n[11],v=n[12],m=n[13],p=n[14],d=n[15],A=r*i-a*o,R=r*c-e*o,w=r*f-u*o,q=a*c-e*i,Y=a*f-u*i,g=e*f-u*c,y=s*m-h*v,x=s*p-M*v,P=s*d-l*v,E=h*p-M*m,T=h*d-l*m,b=M*d-l*p,D=A*b-R*T+w*E+q*P-Y*x+g*y;return D?(D=1/D,t[0]=(i*b-c*T+f*E)*D,t[1]=(c*P-o*b-f*x)*D,t[2]=(o*T-i*P+f*y)*D,t[3]=(e*T-a*b-u*E)*D,t[4]=(r*b-e*P+u*x)*D,t[5]=(a*P-r*T-u*y)*D,t[6]=(m*g-p*Y+d*q)*D,t[7]=(p*w-v*g-d*R)*D,t[8]=(v*Y-m*w+d*A)*D,t):null},e.str=function(t){return"mat3("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+Math.pow(t[6],2)+Math.pow(t[7],2)+Math.pow(t[8],2))},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(16);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.clone=function(t){var n=new a.ARRAY_TYPE(16);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t[9]=n[9],t[10]=n[10],t[11]=n[11],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.transpose=function(t,n){if(t===n){var r=n[1],a=n[2],e=n[3],u=n[6],o=n[7],i=n[11];t[1]=n[4],t[2]=n[8],t[3]=n[12],t[4]=r,t[6]=n[9],t[7]=n[13],t[8]=a,t[9]=u,t[11]=n[14],t[12]=e,t[13]=o,t[14]=i}else t[0]=n[0],t[1]=n[4],t[2]=n[8],t[3]=n[12],t[4]=n[1],t[5]=n[5],t[6]=n[9],t[7]=n[13],t[8]=n[2],t[9]=n[6],t[10]=n[10],t[11]=n[14],t[12]=n[3],t[13]=n[7],t[14]=n[11],t[15]=n[15];return t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=n[9],M=n[10],l=n[11],v=n[12],m=n[13],p=n[14],d=n[15],A=r*i-a*o,R=r*c-e*o,w=r*f-u*o,q=a*c-e*i,Y=a*f-u*i,g=e*f-u*c,y=s*m-h*v,x=s*p-M*v,P=s*d-l*v,E=h*p-M*m,T=h*d-l*m,b=M*d-l*p,D=A*b-R*T+w*E+q*P-Y*x+g*y;return D?(D=1/D,t[0]=(i*b-c*T+f*E)*D,t[1]=(e*T-a*b-u*E)*D,t[2]=(m*g-p*Y+d*q)*D,t[3]=(M*Y-h*g-l*q)*D,t[4]=(c*P-o*b-f*x)*D,t[5]=(r*b-e*P+u*x)*D,t[6]=(p*w-v*g-d*R)*D,t[7]=(s*g-M*w+l*R)*D,t[8]=(o*T-i*P+f*y)*D,t[9]=(a*P-r*T-u*y)*D,t[10]=(v*Y-m*w+d*A)*D,t[11]=(h*w-s*Y-l*A)*D,t[12]=(i*x-o*E-c*y)*D,t[13]=(r*E-a*x+e*y)*D,t[14]=(m*R-v*q-p*A)*D,t[15]=(s*q-h*R+M*A)*D,t):null},e.adjoint=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=n[9],M=n[10],l=n[11],v=n[12],m=n[13],p=n[14],d=n[15];return t[0]=i*(M*d-l*p)-h*(c*d-f*p)+m*(c*l-f*M),t[1]=-(a*(M*d-l*p)-h*(e*d-u*p)+m*(e*l-u*M)),t[2]=a*(c*d-f*p)-i*(e*d-u*p)+m*(e*f-u*c),t[3]=-(a*(c*l-f*M)-i*(e*l-u*M)+h*(e*f-u*c)),t[4]=-(o*(M*d-l*p)-s*(c*d-f*p)+v*(c*l-f*M)),t[5]=r*(M*d-l*p)-s*(e*d-u*p)+v*(e*l-u*M),t[6]=-(r*(c*d-f*p)-o*(e*d-u*p)+v*(e*f-u*c)),t[7]=r*(c*l-f*M)-o*(e*l-u*M)+s*(e*f-u*c),t[8]=o*(h*d-l*m)-s*(i*d-f*m)+v*(i*l-f*h),t[9]=-(r*(h*d-l*m)-s*(a*d-u*m)+v*(a*l-u*h)),t[10]=r*(i*d-f*m)-o*(a*d-u*m)+v*(a*f-u*i),t[11]=-(r*(i*l-f*h)-o*(a*l-u*h)+s*(a*f-u*i)),t[12]=-(o*(h*p-M*m)-s*(i*p-c*m)+v*(i*M-c*h)),t[13]=r*(h*p-M*m)-s*(a*p-e*m)+v*(a*M-e*h),t[14]=-(r*(i*p-c*m)-o*(a*p-e*m)+v*(a*c-e*i)),t[15]=r*(i*M-c*h)-o*(a*M-e*h)+s*(a*c-e*i),t},e.determinant=function(t){var n=t[0],r=t[1],a=t[2],e=t[3],u=t[4],o=t[5],i=t[6],c=t[7],f=t[8],s=t[9],h=t[10],M=t[11],l=t[12],v=t[13],m=t[14],p=t[15],d=n*o-r*u,A=n*i-a*u,R=n*c-e*u,w=r*i-a*o,q=r*c-e*o,Y=a*c-e*i,g=f*v-s*l,y=f*m-h*l,x=f*p-M*l,P=s*m-h*v,E=s*p-M*v,T=h*p-M*m;return d*T-A*E+R*P+w*x-q*y+Y*g},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=n[9],l=n[10],v=n[11],m=n[12],p=n[13],d=n[14],A=n[15],R=r[0],w=r[1],q=r[2],Y=r[3];return t[0]=R*a+w*i+q*h+Y*m,t[1]=R*e+w*c+q*M+Y*p,t[2]=R*u+w*f+q*l+Y*d,t[3]=R*o+w*s+q*v+Y*A,R=r[4],w=r[5],q=r[6],Y=r[7],t[4]=R*a+w*i+q*h+Y*m,t[5]=R*e+w*c+q*M+Y*p,t[6]=R*u+w*f+q*l+Y*d,t[7]=R*o+w*s+q*v+Y*A,R=r[8],w=r[9],q=r[10],Y=r[11],t[8]=R*a+w*i+q*h+Y*m,t[9]=R*e+w*c+q*M+Y*p,t[10]=R*u+w*f+q*l+Y*d,t[11]=R*o+w*s+q*v+Y*A,R=r[12],w=r[13],q=r[14],Y=r[15],t[12]=R*a+w*i+q*h+Y*m,t[13]=R*e+w*c+q*M+Y*p,t[14]=R*u+w*f+q*l+Y*d,t[15]=R*o+w*s+q*v+Y*A,t},e.mul=e.multiply,e.translate=function(t,n,r){var a,e,u,o,i,c,f,s,h,M,l,v,m=r[0],p=r[1],d=r[2];return n===t?(t[12]=n[0]*m+n[4]*p+n[8]*d+n[12],t[13]=n[1]*m+n[5]*p+n[9]*d+n[13],t[14]=n[2]*m+n[6]*p+n[10]*d+n[14],t[15]=n[3]*m+n[7]*p+n[11]*d+n[15]):(a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=n[9],l=n[10],v=n[11],t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=i,t[5]=c,t[6]=f,t[7]=s,t[8]=h,t[9]=M,t[10]=l,t[11]=v,t[12]=a*m+i*p+h*d+n[12],t[13]=e*m+c*p+M*d+n[13],t[14]=u*m+f*p+l*d+n[14],t[15]=o*m+s*p+v*d+n[15]),t},e.scale=function(t,n,r){var a=r[0],e=r[1],u=r[2];return t[0]=n[0]*a,t[1]=n[1]*a,t[2]=n[2]*a,t[3]=n[3]*a,t[4]=n[4]*e,t[5]=n[5]*e,t[6]=n[6]*e,t[7]=n[7]*e,t[8]=n[8]*u,t[9]=n[9]*u,t[10]=n[10]*u,t[11]=n[11]*u,t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15],t},e.rotate=function(t,n,r,e){var u,o,i,c,f,s,h,M,l,v,m,p,d,A,R,w,q,Y,g,y,x,P,E,T,b=e[0],D=e[1],L=e[2],_=Math.sqrt(b*b+D*D+L*L);return Math.abs(_)<a.EPSILON?null:(_=1/_,b*=_,D*=_,L*=_,u=Math.sin(r),o=Math.cos(r),i=1-o,c=n[0],f=n[1],s=n[2],h=n[3],M=n[4],l=n[5],v=n[6],m=n[7],p=n[8],d=n[9],A=n[10],R=n[11],w=b*b*i+o,q=D*b*i+L*u,Y=L*b*i-D*u,g=b*D*i-L*u,y=D*D*i+o,x=L*D*i+b*u,P=b*L*i+D*u,E=D*L*i-b*u,T=L*L*i+o,t[0]=c*w+M*q+p*Y,t[1]=f*w+l*q+d*Y,t[2]=s*w+v*q+A*Y,t[3]=h*w+m*q+R*Y,t[4]=c*g+M*y+p*x,t[5]=f*g+l*y+d*x,t[6]=s*g+v*y+A*x,t[7]=h*g+m*y+R*x,t[8]=c*P+M*E+p*T,t[9]=f*P+l*E+d*T,t[10]=s*P+v*E+A*T,t[11]=h*P+m*E+R*T,n!==t&&(t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t)},e.rotateX=function(t,n,r){var a=Math.sin(r),e=Math.cos(r),u=n[4],o=n[5],i=n[6],c=n[7],f=n[8],s=n[9],h=n[10],M=n[11];return n!==t&&(t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t[4]=u*e+f*a,t[5]=o*e+s*a,t[6]=i*e+h*a,t[7]=c*e+M*a,t[8]=f*e-u*a,t[9]=s*e-o*a,t[10]=h*e-i*a,t[11]=M*e-c*a,t},e.rotateY=function(t,n,r){var a=Math.sin(r),e=Math.cos(r),u=n[0],o=n[1],i=n[2],c=n[3],f=n[8],s=n[9],h=n[10],M=n[11];return n!==t&&(t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t[0]=u*e-f*a,t[1]=o*e-s*a,t[2]=i*e-h*a,t[3]=c*e-M*a,t[8]=u*a+f*e,t[9]=o*a+s*e,t[10]=i*a+h*e,t[11]=c*a+M*e,t},e.rotateZ=function(t,n,r){var a=Math.sin(r),e=Math.cos(r),u=n[0],o=n[1],i=n[2],c=n[3],f=n[4],s=n[5],h=n[6],M=n[7];return n!==t&&(t[8]=n[8],t[9]=n[9],t[10]=n[10],t[11]=n[11],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t[0]=u*e+f*a,t[1]=o*e+s*a,t[2]=i*e+h*a,t[3]=c*e+M*a,t[4]=f*e-u*a,t[5]=s*e-o*a,t[6]=h*e-i*a,t[7]=M*e-c*a,t},e.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=n[0],t[13]=n[1],t[14]=n[2],t[15]=1,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=n[1],t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=n[2],t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromRotation=function(t,n,r){var e,u,o,i=r[0],c=r[1],f=r[2],s=Math.sqrt(i*i+c*c+f*f);return Math.abs(s)<a.EPSILON?null:(s=1/s,i*=s,c*=s,f*=s,e=Math.sin(n),u=Math.cos(n),o=1-u,t[0]=i*i*o+u,t[1]=c*i*o+f*e,t[2]=f*i*o-c*e,t[3]=0,t[4]=i*c*o-f*e,t[5]=c*c*o+u,t[6]=f*c*o+i*e,t[7]=0,t[8]=i*f*o+c*e,t[9]=c*f*o-i*e,t[10]=f*f*o+u,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t)},e.fromXRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=a,t[6]=r,t[7]=0,t[8]=0,t[9]=-r,t[10]=a,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromYRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=0,t[2]=-r,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=r,t[9]=0,t[10]=a,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromZRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=0,t[3]=0,t[4]=-r,t[5]=a,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromRotationTranslation=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=a+a,c=e+e,f=u+u,s=a*i,h=a*c,M=a*f,l=e*c,v=e*f,m=u*f,p=o*i,d=o*c,A=o*f;return t[0]=1-(l+m),t[1]=h+A,t[2]=M-d,t[3]=0,t[4]=h-A,t[5]=1-(s+m),t[6]=v+p,t[7]=0,t[8]=M+d,t[9]=v-p,t[10]=1-(s+l),t[11]=0,t[12]=r[0],t[13]=r[1],t[14]=r[2],t[15]=1,t},e.fromRotationTranslationScale=function(t,n,r,a){var e=n[0],u=n[1],o=n[2],i=n[3],c=e+e,f=u+u,s=o+o,h=e*c,M=e*f,l=e*s,v=u*f,m=u*s,p=o*s,d=i*c,A=i*f,R=i*s,w=a[0],q=a[1],Y=a[2];return t[0]=(1-(v+p))*w,t[1]=(M+R)*w,t[2]=(l-A)*w,t[3]=0,t[4]=(M-R)*q,t[5]=(1-(h+p))*q,t[6]=(m+d)*q,t[7]=0,t[8]=(l+A)*Y,t[9]=(m-d)*Y,t[10]=(1-(h+v))*Y,t[11]=0,t[12]=r[0],t[13]=r[1],t[14]=r[2],t[15]=1,t},e.fromRotationTranslationScaleOrigin=function(t,n,r,a,e){var u=n[0],o=n[1],i=n[2],c=n[3],f=u+u,s=o+o,h=i+i,M=u*f,l=u*s,v=u*h,m=o*s,p=o*h,d=i*h,A=c*f,R=c*s,w=c*h,q=a[0],Y=a[1],g=a[2],y=e[0],x=e[1],P=e[2];return t[0]=(1-(m+d))*q,t[1]=(l+w)*q,t[2]=(v-R)*q,t[3]=0,t[4]=(l-w)*Y,t[5]=(1-(M+d))*Y,t[6]=(p+A)*Y,t[7]=0,t[8]=(v+R)*g,t[9]=(p-A)*g,t[10]=(1-(M+m))*g,t[11]=0,t[12]=r[0]+y-(t[0]*y+t[4]*x+t[8]*P),t[13]=r[1]+x-(t[1]*y+t[5]*x+t[9]*P),t[14]=r[2]+P-(t[2]*y+t[6]*x+t[10]*P),t[15]=1,t},e.fromQuat=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r+r,i=a+a,c=e+e,f=r*o,s=a*o,h=a*i,M=e*o,l=e*i,v=e*c,m=u*o,p=u*i,d=u*c;return t[0]=1-h-v,t[1]=s+d,t[2]=M-p,t[3]=0,t[4]=s-d,t[5]=1-f-v,t[6]=l+m,t[7]=0,t[8]=M+p,t[9]=l-m,t[10]=1-f-h,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.frustum=function(t,n,r,a,e,u,o){var i=1/(r-n),c=1/(e-a),f=1/(u-o);return t[0]=2*u*i,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=2*u*c,t[6]=0,t[7]=0,t[8]=(r+n)*i,t[9]=(e+a)*c,t[10]=(o+u)*f,t[11]=-1,t[12]=0,t[13]=0,t[14]=o*u*2*f,t[15]=0,t},e.perspective=function(t,n,r,a,e){var u=1/Math.tan(n/2),o=1/(a-e);return t[0]=u/r,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=u,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=(e+a)*o,t[11]=-1,t[12]=0,t[13]=0,t[14]=2*e*a*o,t[15]=0,t},e.perspectiveFromFieldOfView=function(t,n,r,a){var e=Math.tan(n.upDegrees*Math.PI/180),u=Math.tan(n.downDegrees*Math.PI/180),o=Math.tan(n.leftDegrees*Math.PI/180),i=Math.tan(n.rightDegrees*Math.PI/180),c=2/(o+i),f=2/(e+u);return t[0]=c,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=f,t[6]=0,t[7]=0,t[8]=-((o-i)*c*.5),t[9]=(e-u)*f*.5,t[10]=a/(r-a),t[11]=-1,t[12]=0,t[13]=0,t[14]=a*r/(r-a),t[15]=0,t},e.ortho=function(t,n,r,a,e,u,o){var i=1/(n-r),c=1/(a-e),f=1/(u-o);return t[0]=-2*i,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=-2*c,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=2*f,t[11]=0,t[12]=(n+r)*i,t[13]=(e+a)*c,t[14]=(o+u)*f,t[15]=1,t},e.lookAt=function(t,n,r,u){var o,i,c,f,s,h,M,l,v,m,p=n[0],d=n[1],A=n[2],R=u[0],w=u[1],q=u[2],Y=r[0],g=r[1],y=r[2];return Math.abs(p-Y)<a.EPSILON&&Math.abs(d-g)<a.EPSILON&&Math.abs(A-y)<a.EPSILON?e.identity(t):(M=p-Y,l=d-g,v=A-y,m=1/Math.sqrt(M*M+l*l+v*v),M*=m,l*=m,v*=m,o=w*v-q*l,i=q*M-R*v,c=R*l-w*M,m=Math.sqrt(o*o+i*i+c*c),m?(m=1/m,o*=m,i*=m,c*=m):(o=0,i=0,c=0),f=l*c-v*i,s=v*o-M*c,h=M*i-l*o,m=Math.sqrt(f*f+s*s+h*h),m?(m=1/m,f*=m,s*=m,h*=m):(f=0,s=0,h=0),t[0]=o,t[1]=f,t[2]=M,t[3]=0,t[4]=i,t[5]=s,t[6]=l,t[7]=0,t[8]=c,t[9]=h,t[10]=v,t[11]=0,t[12]=-(o*p+i*d+c*A),t[13]=-(f*p+s*d+h*A),t[14]=-(M*p+l*d+v*A),t[15]=1,t)},e.str=function(t){return"mat4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+", "+t[9]+", "+t[10]+", "+t[11]+", "+t[12]+", "+t[13]+", "+t[14]+", "+t[15]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+Math.pow(t[6],2)+Math.pow(t[7],2)+Math.pow(t[8],2)+Math.pow(t[9],2)+Math.pow(t[10],2)+Math.pow(t[11],2)+Math.pow(t[12],2)+Math.pow(t[13],2)+Math.pow(t[14],2)+Math.pow(t[15],2))},t.exports=e},function(t,n,r){var a=r(1),e=r(4),u=r(7),o=r(8),i={};i.create=function(){var t=new a.ARRAY_TYPE(4);return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},i.rotationTo=function(){var t=u.create(),n=u.fromValues(1,0,0),r=u.fromValues(0,1,0);return function(a,e,o){var c=u.dot(e,o);return-.999999>c?(u.cross(t,n,e),u.length(t)<1e-6&&u.cross(t,r,e),u.normalize(t,t),i.setAxisAngle(a,t,Math.PI),a):c>.999999?(a[0]=0,a[1]=0,a[2]=0,a[3]=1,a):(u.cross(t,e,o),a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=1+c,i.normalize(a,a))}}(),i.setAxes=function(){var t=e.create();return function(n,r,a,e){return t[0]=a[0],t[3]=a[1],t[6]=a[2],t[1]=e[0],t[4]=e[1],t[7]=e[2],t[2]=-r[0],t[5]=-r[1],t[8]=-r[2],i.normalize(n,i.fromMat3(n,t))}}(),i.clone=o.clone,i.fromValues=o.fromValues,i.copy=o.copy,i.set=o.set,i.identity=function(t){return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},i.setAxisAngle=function(t,n,r){r=.5*r;var a=Math.sin(r);return t[0]=a*n[0],t[1]=a*n[1],t[2]=a*n[2],t[3]=Math.cos(r),t},i.add=o.add,i.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],c=r[1],f=r[2],s=r[3];return t[0]=a*s+o*i+e*f-u*c,t[1]=e*s+o*c+u*i-a*f,t[2]=u*s+o*f+a*c-e*i,t[3]=o*s-a*i-e*c-u*f,t},i.mul=i.multiply,i.scale=o.scale,i.rotateX=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c+o*i,t[1]=e*c+u*i,t[2]=u*c-e*i,t[3]=o*c-a*i,t},i.rotateY=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c-u*i,t[1]=e*c+o*i,t[2]=u*c+a*i,t[3]=o*c-e*i,t},i.rotateZ=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c+e*i,t[1]=e*c-a*i,t[2]=u*c+o*i,t[3]=o*c-u*i,t},i.calculateW=function(t,n){var r=n[0],a=n[1],e=n[2];return t[0]=r,t[1]=a,t[2]=e,t[3]=Math.sqrt(Math.abs(1-r*r-a*a-e*e)),t},i.dot=o.dot,i.lerp=o.lerp,i.slerp=function(t,n,r,a){var e,u,o,i,c,f=n[0],s=n[1],h=n[2],M=n[3],l=r[0],v=r[1],m=r[2],p=r[3];return u=f*l+s*v+h*m+M*p,0>u&&(u=-u,l=-l,v=-v,m=-m,p=-p),1-u>1e-6?(e=Math.acos(u),o=Math.sin(e),i=Math.sin((1-a)*e)/o,c=Math.sin(a*e)/o):(i=1-a,c=a),t[0]=i*f+c*l,t[1]=i*s+c*v,t[2]=i*h+c*m,t[3]=i*M+c*p,t},i.sqlerp=function(){var t=i.create(),n=i.create();return function(r,a,e,u,o,c){return i.slerp(t,a,o,c),i.slerp(n,e,u,c),i.slerp(r,t,n,2*c*(1-c)),r}}(),i.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*r+a*a+e*e+u*u,i=o?1/o:0;return t[0]=-r*i,t[1]=-a*i,t[2]=-e*i,t[3]=u*i,t},i.conjugate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t[3]=n[3],t},i.length=o.length,i.len=i.length,i.squaredLength=o.squaredLength,i.sqrLen=i.squaredLength,i.normalize=o.normalize,i.fromMat3=function(t,n){var r,a=n[0]+n[4]+n[8];if(a>0)r=Math.sqrt(a+1),t[3]=.5*r,r=.5/r,t[0]=(n[5]-n[7])*r,t[1]=(n[6]-n[2])*r,t[2]=(n[1]-n[3])*r;else{var e=0;n[4]>n[0]&&(e=1),n[8]>n[3*e+e]&&(e=2);var u=(e+1)%3,o=(e+2)%3;r=Math.sqrt(n[3*e+e]-n[3*u+u]-n[3*o+o]+1),t[e]=.5*r,r=.5/r,t[3]=(n[3*u+o]-n[3*o+u])*r,t[u]=(n[3*u+e]+n[3*e+u])*r,t[o]=(n[3*o+e]+n[3*e+o])*r}return t},i.str=function(t){return"quat("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},t.exports=i},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(3);return t[0]=0,t[1]=0,t[2]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(3);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n},e.fromValues=function(t,n,r){var e=new a.ARRAY_TYPE(3);return e[0]=t,e[1]=n,e[2]=r,e},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t},e.set=function(t,n,r,a){return t[0]=n,t[1]=r,t[2]=a,t},e.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t[2]=n[2]+r[2],t},e.subtract=function(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t[2]=n[2]-r[2],t},e.sub=e.subtract,e.multiply=function(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t[2]=n[2]*r[2],t},e.mul=e.multiply,e.divide=function(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t[2]=n[2]/r[2],t},e.div=e.divide,e.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t[2]=Math.min(n[2],r[2]),t},e.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t[2]=Math.max(n[2],r[2]),t},e.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t},e.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t[2]=n[2]+r[2]*a,t},e.distance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2];return Math.sqrt(r*r+a*a+e*e)},e.dist=e.distance,e.squaredDistance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2];return r*r+a*a+e*e},e.sqrDist=e.squaredDistance,e.length=function(t){var n=t[0],r=t[1],a=t[2];return Math.sqrt(n*n+r*r+a*a)},e.len=e.length,e.squaredLength=function(t){var n=t[0],r=t[1],a=t[2];return n*n+r*r+a*a},e.sqrLen=e.squaredLength,e.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t},e.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t[2]=1/n[2],t},e.normalize=function(t,n){var r=n[0],a=n[1],e=n[2],u=r*r+a*a+e*e;return u>0&&(u=1/Math.sqrt(u),t[0]=n[0]*u,t[1]=n[1]*u,t[2]=n[2]*u),t},e.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]},e.cross=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],c=r[2];return t[0]=e*c-u*i,t[1]=u*o-a*c,t[2]=a*i-e*o,t},e.lerp=function(t,n,r,a){var e=n[0],u=n[1],o=n[2];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t[2]=o+a*(r[2]-o),t},e.hermite=function(t,n,r,a,e,u){var o=u*u,i=o*(2*u-3)+1,c=o*(u-2)+u,f=o*(u-1),s=o*(3-2*u);return t[0]=n[0]*i+r[0]*c+a[0]*f+e[0]*s,t[1]=n[1]*i+r[1]*c+a[1]*f+e[1]*s,t[2]=n[2]*i+r[2]*c+a[2]*f+e[2]*s,t},e.bezier=function(t,n,r,a,e,u){var o=1-u,i=o*o,c=u*u,f=i*o,s=3*u*i,h=3*c*o,M=c*u;return t[0]=n[0]*f+r[0]*s+a[0]*h+e[0]*M,t[1]=n[1]*f+r[1]*s+a[1]*h+e[1]*M,t[2]=n[2]*f+r[2]*s+a[2]*h+e[2]*M,t},e.random=function(t,n){n=n||1;var r=2*a.RANDOM()*Math.PI,e=2*a.RANDOM()-1,u=Math.sqrt(1-e*e)*n;return t[0]=Math.cos(r)*u,t[1]=Math.sin(r)*u,t[2]=e*n,t},e.transformMat4=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[3]*a+r[7]*e+r[11]*u+r[15];return o=o||1,t[0]=(r[0]*a+r[4]*e+r[8]*u+r[12])/o,t[1]=(r[1]*a+r[5]*e+r[9]*u+r[13])/o,t[2]=(r[2]*a+r[6]*e+r[10]*u+r[14])/o,t},e.transformMat3=function(t,n,r){var a=n[0],e=n[1],u=n[2];return t[0]=a*r[0]+e*r[3]+u*r[6],t[1]=a*r[1]+e*r[4]+u*r[7],t[2]=a*r[2]+e*r[5]+u*r[8],t},e.transformQuat=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],c=r[2],f=r[3],s=f*a+i*u-c*e,h=f*e+c*a-o*u,M=f*u+o*e-i*a,l=-o*a-i*e-c*u;return t[0]=s*f+l*-o+h*-c-M*-i,t[1]=h*f+l*-i+M*-o-s*-c,t[2]=M*f+l*-c+s*-i-h*-o,t},e.rotateX=function(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[0],u[1]=e[1]*Math.cos(a)-e[2]*Math.sin(a),u[2]=e[1]*Math.sin(a)+e[2]*Math.cos(a),t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t},e.rotateY=function(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[2]*Math.sin(a)+e[0]*Math.cos(a),u[1]=e[1],u[2]=e[2]*Math.cos(a)-e[0]*Math.sin(a),t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t},e.rotateZ=function(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[0]*Math.cos(a)-e[1]*Math.sin(a),u[1]=e[0]*Math.sin(a)+e[1]*Math.cos(a),u[2]=e[2],t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t},e.forEach=function(){var t=e.create();return function(n,r,a,e,u,o){var i,c;for(r||(r=3),a||(a=0),c=e?Math.min(e*r+a,n.length):n.length,i=a;c>i;i+=r)t[0]=n[i],t[1]=n[i+1],t[2]=n[i+2],u(t,t,o),n[i]=t[0],n[i+1]=t[1],n[i+2]=t[2];return n}}(),e.angle=function(t,n){var r=e.fromValues(t[0],t[1],t[2]),a=e.fromValues(n[0],n[1],n[2]);e.normalize(r,r),e.normalize(a,a);var u=e.dot(r,a);return u>1?0:Math.acos(u)},e.str=function(t){return"vec3("+t[0]+", "+t[1]+", "+t[2]+")"},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(4);return t[0]=0,t[1]=0,t[2]=0,t[3]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(4);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n},e.fromValues=function(t,n,r,e){var u=new a.ARRAY_TYPE(4);return u[0]=t,u[1]=n,u[2]=r,u[3]=e,u},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t},e.set=function(t,n,r,a,e){return t[0]=n,t[1]=r,t[2]=a,t[3]=e,t},e.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t[2]=n[2]+r[2],t[3]=n[3]+r[3],t},e.subtract=function(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t[2]=n[2]-r[2],t[3]=n[3]-r[3],t},e.sub=e.subtract,e.multiply=function(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t[2]=n[2]*r[2],t[3]=n[3]*r[3],t},e.mul=e.multiply,e.divide=function(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t[2]=n[2]/r[2],t[3]=n[3]/r[3],t},e.div=e.divide,e.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t[2]=Math.min(n[2],r[2]),t[3]=Math.min(n[3],r[3]),t},e.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t[2]=Math.max(n[2],r[2]),t[3]=Math.max(n[3],r[3]),t},e.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t[3]=n[3]*r,t},e.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t[2]=n[2]+r[2]*a,t[3]=n[3]+r[3]*a,t},e.distance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2],u=n[3]-t[3];return Math.sqrt(r*r+a*a+e*e+u*u)},e.dist=e.distance,e.squaredDistance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2],u=n[3]-t[3];return r*r+a*a+e*e+u*u},e.sqrDist=e.squaredDistance,e.length=function(t){var n=t[0],r=t[1],a=t[2],e=t[3];return Math.sqrt(n*n+r*r+a*a+e*e)},e.len=e.length,e.squaredLength=function(t){var n=t[0],r=t[1],a=t[2],e=t[3];return n*n+r*r+a*a+e*e},e.sqrLen=e.squaredLength,e.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t[3]=-n[3],t},e.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t[2]=1/n[2],t[3]=1/n[3],t},e.normalize=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*r+a*a+e*e+u*u;return o>0&&(o=1/Math.sqrt(o),t[0]=r*o,t[1]=a*o,t[2]=e*o,t[3]=u*o),t},e.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]+t[3]*n[3]},e.lerp=function(t,n,r,a){var e=n[0],u=n[1],o=n[2],i=n[3];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t[2]=o+a*(r[2]-o),t[3]=i+a*(r[3]-i),t},e.random=function(t,n){return n=n||1,t[0]=a.RANDOM(),t[1]=a.RANDOM(),t[2]=a.RANDOM(),t[3]=a.RANDOM(),e.normalize(t,t),e.scale(t,t,n),t},e.transformMat4=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3];return t[0]=r[0]*a+r[4]*e+r[8]*u+r[12]*o,t[1]=r[1]*a+r[5]*e+r[9]*u+r[13]*o,t[2]=r[2]*a+r[6]*e+r[10]*u+r[14]*o,t[3]=r[3]*a+r[7]*e+r[11]*u+r[15]*o,t},e.transformQuat=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],c=r[2],f=r[3],s=f*a+i*u-c*e,h=f*e+c*a-o*u,M=f*u+o*e-i*a,l=-o*a-i*e-c*u;return t[0]=s*f+l*-o+h*-c-M*-i,t[1]=h*f+l*-i+M*-o-s*-c,t[2]=M*f+l*-c+s*-i-h*-o,t[3]=n[3],t},e.forEach=function(){var t=e.create();return function(n,r,a,e,u,o){var i,c;for(r||(r=4),a||(a=0),c=e?Math.min(e*r+a,n.length):n.length,i=a;c>i;i+=r)t[0]=n[i],t[1]=n[i+1],t[2]=n[i+2],t[3]=n[i+3],u(t,t,o),n[i]=t[0],n[i+1]=t[1],n[i+2]=t[2],n[i+3]=t[3];return n}}(),e.str=function(t){return"vec4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(2);return t[0]=0,t[1]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(2);return n[0]=t[0],n[1]=t[1],n},e.fromValues=function(t,n){var r=new a.ARRAY_TYPE(2);return r[0]=t,r[1]=n,r},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t},e.set=function(t,n,r){return t[0]=n,t[1]=r,t},e.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t},e.subtract=function(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t},e.sub=e.subtract,e.multiply=function(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t},e.mul=e.multiply,e.divide=function(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t},e.div=e.divide,e.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t},e.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t},e.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t},e.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t},e.distance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1];return Math.sqrt(r*r+a*a)},e.dist=e.distance,e.squaredDistance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1];return r*r+a*a},e.sqrDist=e.squaredDistance,e.length=function(t){var n=t[0],r=t[1];return Math.sqrt(n*n+r*r)},e.len=e.length,e.squaredLength=function(t){var n=t[0],r=t[1];return n*n+r*r},e.sqrLen=e.squaredLength,e.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t},e.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t},e.normalize=function(t,n){var r=n[0],a=n[1],e=r*r+a*a;return e>0&&(e=1/Math.sqrt(e),t[0]=n[0]*e,t[1]=n[1]*e),t},e.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]},e.cross=function(t,n,r){var a=n[0]*r[1]-n[1]*r[0];return t[0]=t[1]=0,t[2]=a,t},e.lerp=function(t,n,r,a){var e=n[0],u=n[1];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t},e.random=function(t,n){n=n||1;var r=2*a.RANDOM()*Math.PI;return t[0]=Math.cos(r)*n,t[1]=Math.sin(r)*n,t},e.transformMat2=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[2]*e,t[1]=r[1]*a+r[3]*e,t},e.transformMat2d=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[2]*e+r[4],t[1]=r[1]*a+r[3]*e+r[5],t},e.transformMat3=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[3]*e+r[6],t[1]=r[1]*a+r[4]*e+r[7],t},e.transformMat4=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[4]*e+r[12],t[1]=r[1]*a+r[5]*e+r[13],t},e.forEach=function(){var t=e.create();return function(n,r,a,e,u,o){var i,c;for(r||(r=2),a||(a=0),c=e?Math.min(e*r+a,n.length):n.length,i=a;c>i;i+=r)t[0]=n[i],t[1]=n[i+1],u(t,t,o),n[i]=t[0],n[i+1]=t[1];return n}}(),e.str=function(t){return"vec2("+t[0]+", "+t[1]+")"},t.exports=e}])});'use strict';(function(global){if(tr.isNode){const glMatrixAbsPath=HTMLImportsLoader.hrefToAbsolutePath('/gl-matrix-min.js');const glMatrixModule=require(glMatrixAbsPath);for(const exportName in glMatrixModule){global[exportName]=glMatrixModule[exportName];}}})(this);'use strict';tr.exportTo('tr.b.math',function(){const PREFERRED_NUMBER_SERIES_MULTIPLIERS=[1,2,5,10];function approximately(x,y,delta){if(delta===undefined)delta=1e-9;return Math.abs(x-y)<delta;}
+function clamp(x,lo,hi){return Math.min(Math.max(x,lo),hi);}
+function lerp(percentage,lo,hi){const range=hi-lo;return lo+percentage*range;}
 function normalize(value,lo,hi){return(value-lo)/(hi-lo);}
 function deg2rad(deg){return(Math.PI*deg)/180.0;}
-var tmp_vec2=vec2.create();var tmp_vec2b=vec2.create();var tmp_vec4=vec4.create();var tmp_mat2d=mat2d.create();vec2.createFromArray=function(arr){if(arr.length!=2)
-throw new Error('Should be length 2');var v=vec2.create();vec2.set(v,arr[0],arr[1]);return v;};vec2.createXY=function(x,y){var v=vec2.create();vec2.set(v,x,y);return v;};vec2.toString=function(a){return'['+a[0]+', '+a[1]+']';};vec2.addTwoScaledUnitVectors=function(out,u1,scale1,u2,scale2){vec2.scale(tmp_vec2,u1,scale1);vec2.scale(tmp_vec2b,u2,scale2);vec2.add(out,tmp_vec2,tmp_vec2b);};vec2.interpolatePiecewiseFunction=function(points,x){if(x<points[0][0])
-return points[0][1];for(var i=1;i<points.length;++i){if(x<points[i][0]){var percent=normalize(x,points[i-1][0],points[i][0]);return lerp(percent,points[i-1][1],points[i][1]);}}
-return points[points.length-1][1];};vec3.createXYZ=function(x,y,z){var v=vec3.create();vec3.set(v,x,y,z);return v;};vec3.toString=function(a){return'vec3('+a[0]+', '+a[1]+', '+a[2]+')';};mat2d.translateXY=function(out,x,y){vec2.set(tmp_vec2,x,y);mat2d.translate(out,out,tmp_vec2);};mat2d.scaleXY=function(out,x,y){vec2.set(tmp_vec2,x,y);mat2d.scale(out,out,tmp_vec2);};vec4.unitize=function(out,a){out[0]=a[0]/a[3];out[1]=a[1]/a[3];out[2]=a[2]/a[3];out[3]=1;return out;};vec2.copyFromVec4=function(out,a){vec4.unitize(tmp_vec4,a);vec2.copy(out,tmp_vec4);};return{clamp:clamp,lerp:lerp,normalize:normalize,deg2rad:deg2rad};});'use strict';tr.exportTo('tr.b',function(){var tmpVec2s=[];for(var i=0;i<8;i++)
-tmpVec2s[i]=vec2.create();var tmpVec2a=vec4.create();var tmpVec4a=vec4.create();var tmpVec4b=vec4.create();var tmpMat4=mat4.create();var tmpMat4b=mat4.create();var p00=vec2.createXY(0,0);var p10=vec2.createXY(1,0);var p01=vec2.createXY(0,1);var p11=vec2.createXY(1,1);var lerpingVecA=vec2.create();var lerpingVecB=vec2.create();function lerpVec2(out,a,b,amt){vec2.scale(lerpingVecA,a,amt);vec2.scale(lerpingVecB,b,1-amt);vec2.add(out,lerpingVecA,lerpingVecB);vec2.normalize(out,out);return out;}
+function erf(x){const sign=(x>=0)?1:-1;x=Math.abs(x);const a1=0.254829592;const a2=-0.284496736;const a3=1.421413741;const a4=-1.453152027;const a5=1.061405429;const p=0.3275911;const t=1.0/(1.0+p*x);const y=1.0-(((((a5*t+a4)*t)+a3)*t+a2)*t+a1)*t*Math.exp(-x*x);return sign*y;}
+const tmpVec2=vec2.create();const tmpVec2b=vec2.create();const tmpVec4=vec4.create();const tmpMat2d=mat2d.create();vec2.createFromArray=function(arr){if(arr.length!==2)throw new Error('Should be length 2');const v=vec2.create();vec2.set(v,arr[0],arr[1]);return v;};vec2.createXY=function(x,y){const v=vec2.create();vec2.set(v,x,y);return v;};vec2.toString=function(a){return'['+a[0]+', '+a[1]+']';};vec2.addTwoScaledUnitVectors=function(out,u1,scale1,u2,scale2){vec2.scale(tmpVec2,u1,scale1);vec2.scale(tmpVec2b,u2,scale2);vec2.add(out,tmpVec2,tmpVec2b);};vec2.interpolatePiecewiseFunction=function(points,x){if(x<points[0][0])return points[0][1];for(let i=1;i<points.length;++i){if(x<points[i][0]){const percent=normalize(x,points[i-1][0],points[i][0]);return lerp(percent,points[i-1][1],points[i][1]);}}
+return points[points.length-1][1];};vec3.createXYZ=function(x,y,z){const v=vec3.create();vec3.set(v,x,y,z);return v;};vec3.toString=function(a){return'vec3('+a[0]+', '+a[1]+', '+a[2]+')';};mat2d.translateXY=function(out,x,y){vec2.set(tmpVec2,x,y);mat2d.translate(out,out,tmpVec2);};mat2d.scaleXY=function(out,x,y){vec2.set(tmpVec2,x,y);mat2d.scale(out,out,tmpVec2);};vec4.unitize=function(out,a){out[0]=a[0]/a[3];out[1]=a[1]/a[3];out[2]=a[2]/a[3];out[3]=1;return out;};vec2.copyFromVec4=function(out,a){vec4.unitize(tmpVec4,a);vec2.copy(out,tmpVec4);};function logOrLog10(x,base){if(base===10)return Math.log10(x);return Math.log(x)/Math.log(base);}
+function lesserPower(x,opt_base){const base=opt_base||10;return Math.pow(base,Math.floor(logOrLog10(x,base)));}
+function greaterPower(x,opt_base){const base=opt_base||10;return Math.pow(base,Math.ceil(logOrLog10(x,base)));}
+function lesserWholeNumber(x){if(x===0)return 0;const pow10=(x<0)?-lesserPower(-x):lesserPower(x);return pow10*Math.floor(x/pow10);}
+function greaterWholeNumber(x){if(x===0)return 0;const pow10=(x<0)?-lesserPower(-x):lesserPower(x);return pow10*Math.ceil(x/pow10);}
+function truncate(value,digits){const pow10=Math.pow(10,digits);return Math.round(value*pow10)/pow10;}
+function preferredNumberLargerThanMin(min){const absMin=Math.abs(min);const conservativeGuess=tr.b.math.lesserPower(absMin);let minPreferedNumber=undefined;for(const multiplier of PREFERRED_NUMBER_SERIES_MULTIPLIERS){const tightenedGuess=conservativeGuess*multiplier;if(tightenedGuess>=absMin){minPreferedNumber=tightenedGuess;break;}}
+if(minPreferedNumber===undefined){throw new Error('Could not compute preferred number for '+min);}
+if(min<0)minPreferedNumber*=-1;return minPreferedNumber;}
+return{approximately,clamp,lerp,normalize,deg2rad,erf,lesserPower,greaterPower,lesserWholeNumber,greaterWholeNumber,preferredNumberLargerThanMin,truncate,};});'use strict';tr.exportTo('tr.b.math',function(){function Range(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;}
+Range.prototype={__proto__:Object.prototype,clone(){if(this.isEmpty)return new Range();return Range.fromExplicitRange(this.min_,this.max_);},reset(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;},get isEmpty(){return this.isEmpty_;},addRange(range){if(range.isEmpty)return;this.addValue(range.min);this.addValue(range.max);},addValue(value){if(this.isEmpty_){this.max_=value;this.min_=value;this.isEmpty_=false;return;}
+this.max_=Math.max(this.max_,value);this.min_=Math.min(this.min_,value);},set min(min){this.isEmpty_=false;this.min_=min;},get min(){if(this.isEmpty_)return undefined;return this.min_;},get max(){if(this.isEmpty_)return undefined;return this.max_;},set max(max){this.isEmpty_=false;this.max_=max;},get range(){if(this.isEmpty_)return undefined;return this.max_-this.min_;},get center(){return(this.min_+this.max_)*0.5;},get duration(){if(this.isEmpty_)return 0;return this.max_-this.min_;},enclosingPowers(opt_base){if(this.isEmpty)return new Range();return Range.fromExplicitRange(tr.b.math.lesserPower(this.min_,opt_base),tr.b.math.greaterPower(this.max_,opt_base));},normalize(x){return tr.b.math.normalize(x,this.min,this.max);},lerp(x){return tr.b.math.lerp(x,this.min,this.max);},clamp(x){return tr.b.math.clamp(x,this.min,this.max);},equals(that){if(this.isEmpty&&that.isEmpty)return true;if(this.isEmpty!==that.isEmpty)return false;return(tr.b.math.approximately(this.min,that.min)&&tr.b.math.approximately(this.max,that.max));},containsExplicitRangeInclusive(min,max){if(this.isEmpty)return false;return this.min_<=min&&max<=this.max_;},containsExplicitRangeExclusive(min,max){if(this.isEmpty)return false;return this.min_<min&&max<this.max_;},intersectsExplicitRangeInclusive(min,max){if(this.isEmpty)return false;return this.min_<=max&&min<=this.max_;},intersectsExplicitRangeExclusive(min,max){if(this.isEmpty)return false;return this.min_<max&&min<this.max_;},containsRangeInclusive(range){if(range.isEmpty)return false;return this.containsExplicitRangeInclusive(range.min_,range.max_);},containsRangeExclusive(range){if(range.isEmpty)return false;return this.containsExplicitRangeExclusive(range.min_,range.max_);},intersectsRangeInclusive(range){if(range.isEmpty)return false;return this.intersectsExplicitRangeInclusive(range.min_,range.max_);},intersectsRangeExclusive(range){if(range.isEmpty)return false;return this.intersectsExplicitRangeExclusive(range.min_,range.max_);},findExplicitIntersectionDuration(min,max){min=Math.max(this.min,min);max=Math.min(this.max,max);if(max<min)return 0;return max-min;},findIntersection(range){if(this.isEmpty||range.isEmpty)return new Range();const min=Math.max(this.min,range.min);const max=Math.min(this.max,range.max);if(max<min)return new Range();return Range.fromExplicitRange(min,max);},toJSON(){if(this.isEmpty_)return{isEmpty:true};return{isEmpty:false,max:this.max,min:this.min};},filterArray(sortedArray,opt_keyFunc,opt_this){if(this.isEmpty_)return[];const keyFunc=opt_keyFunc||(x=>x);function getValue(obj){return keyFunc.call(opt_this,obj);}
+const first=tr.b.findFirstTrueIndexInSortedArray(sortedArray,obj=>this.min_===undefined||this.min_<=getValue(obj));const last=tr.b.findFirstTrueIndexInSortedArray(sortedArray,obj=>this.max_!==undefined&&this.max_<getValue(obj));return sortedArray.slice(first,last);}};Range.fromDict=function(d){if(d.isEmpty===true)return new Range();if(d.isEmpty===false){const range=new Range();range.min=d.min;range.max=d.max;return range;}
+throw new Error('Not a range');};Range.fromExplicitRange=function(min,max){const range=new Range();range.min=min;range.max=max;return range;};Range.compareByMinTimes=function(a,b){if(!a.isEmpty&&!b.isEmpty)return a.min_-b.min_;if(a.isEmpty&&!b.isEmpty)return-1;if(!a.isEmpty&&b.isEmpty)return 1;return 0;};Range.findDifference=function(rangeA,rangeB){if(!rangeA||rangeA.duration<0||!rangeB||rangeB.duration<0){throw new Error(`Couldn't subtract ranges`);}
+const resultRanges=[];if(rangeA.isEmpty)return resultRanges;if(rangeB.isEmpty)return[rangeA.clone()];const intersection=rangeA.findIntersection(rangeB);if(intersection.isEmpty){return[rangeA.clone()];}
+if(rangeA.duration===0&&rangeB.duration===0){if(intersection.empty)return[rangeA.clone()];else if(intersection.duration===0)return resultRanges;throw new Error(`Two points' intersection can only be a point or empty`);}
+const leftRange=tr.b.math.Range.fromExplicitRange(rangeA.min,intersection.min);if(leftRange.duration>0){resultRanges.push(leftRange);}
+const rightRange=tr.b.math.Range.fromExplicitRange(intersection.max,rangeA.max);if(rightRange.duration>0){resultRanges.push(rightRange);}
+return resultRanges;};Range.PERCENT_RANGE=Range.fromExplicitRange(0,1);Object.freeze(Range.PERCENT_RANGE);return{Range,};});'use strict';(function(exports){var rank={standard:function(array,key){array=array.sort(function(a,b){var x=a[key];var y=b[key];return((x<y)?-1:((x>y)?1:0));});for(var i=1;i<array.length+1;i++){array[i-1]['rank']=i;}
+return array;},fractional:function(array,key){array=this.standard(array,key);var pos=0;while(pos<array.length){var sum=0;var i=0;for(i=0;array[pos+i+1]&&(array[pos+i][key]===array[pos+i+1][key]);i++){sum+=array[pos+i]['rank'];}
+sum+=array[pos+i]['rank'];var endPos=pos+i+1;for(pos;pos<endPos;pos++){array[pos]['rank']=sum/(i+1);}
+pos=endPos;}
+return array;},rank:function(x,y){var nx=x.length,ny=y.length,combined=[],ranked;while(nx--){combined.push({set:'x',val:x[nx]});}
+while(ny--){combined.push({set:'y',val:y[ny]});}
+ranked=this.fractional(combined,'val');return ranked}};var erf=function erf(x){var cof=[-1.3026537197817094,6.4196979235649026e-1,1.9476473204185836e-2,-9.561514786808631e-3,-9.46595344482036e-4,3.66839497852761e-4,4.2523324806907e-5,-2.0278578112534e-5,-1.624290004647e-6,1.303655835580e-6,1.5626441722e-8,-8.5238095915e-8,6.529054439e-9,5.059343495e-9,-9.91364156e-10,-2.27365122e-10,9.6467911e-11,2.394038e-12,-6.886027e-12,8.94487e-13,3.13092e-13,-1.12708e-13,3.81e-16,7.106e-15,-1.523e-15,-9.4e-17,1.21e-16,-2.8e-17];var j=cof.length-1;var isneg=false;var d=0;var dd=0;var t,ty,tmp,res;if(x<0){x=-x;isneg=true;}
+t=2/(2+x);ty=4*t-2;for(;j>0;j--){tmp=d;d=ty*d-dd+cof[j];dd=tmp;}
+res=t*Math.exp(-x*x+0.5*(cof[0]+ty*d)-dd);return isneg?res-1:1-res;};var dnorm=function(x,mean,std){return 0.5*(1+erf((x-mean)/Math.sqrt(2*std*std)));}
+var statistic=function(x,y){var ranked=rank.rank(x,y),nr=ranked.length,nx=x.length,ny=y.length,ranksums={x:0,y:0},i=0,t=0,nt=1,tcf,ux,uy;while(i<nr){if(i>0){if(ranked[i].val==ranked[i-1].val){nt++;}else{if(nt>1){t+=Math.pow(nt,3)-nt
+nt=1;}}}
+ranksums[ranked[i].set]+=ranked[i].rank
+i++;}
+tcf=1-(t/(Math.pow(nr,3)-nr))
+ux=nx*ny+(nx*(nx+1)/2)-ranksums.x;uy=nx*ny-ux;return{tcf:tcf,ux:ux,uy:uy,big:Math.max(ux,uy),small:Math.min(ux,uy)}}
+exports.test=function(x,y,alt,corr){alt=typeof alt!=='undefined'?alt:'two-sided';corr=typeof corr!=='undefined'?corr:true;var nx=x.length,ny=y.length,f=1,u,mu,std,z,p;u=statistic(x,y);if(corr){mu=(nx*ny/2)+0.5;}else{mu=nx*ny/2;}
+std=Math.sqrt(u.tcf*nx*ny*(nx+ny+1)/12);if(alt=='less'){z=(u.ux-mu)/std;}else if(alt=='greater'){z=(u.uy-mu)/std;}else if(alt=='two-sided'){z=Math.abs((u.big-mu)/std);}else{console.log('Unknown alternative argument');}
+if(alt=='two-sided'){f=2;}
+p=dnorm(-z,0,1)*f;return{U:u.small,p:p};}})(typeof exports==='undefined'?this['mannwhitneyu']={}:exports);'use strict';(function(global){if(tr.isNode){const mwuAbsPath=HTMLImportsLoader.hrefToAbsolutePath('/mannwhitneyu.js');const mwuModule=require(mwuAbsPath);for(const exportName in mwuModule){global[exportName]=mwuModule[exportName];}}})(this);'use strict';tr.exportTo('tr.b.math',function(){const Statistics={};Statistics.divideIfPossibleOrZero=function(numerator,denominator){if(denominator===0)return 0;return numerator/denominator;};Statistics.sum=function(ary,opt_func,opt_this){const func=opt_func||(x=>x);let ret=0;let i=0;for(const elt of ary){ret+=func.call(opt_this,elt,i++);}
+return ret;};Statistics.mean=function(ary,opt_func,opt_this){const func=opt_func||(x=>x);let sum=0;let i=0;for(const elt of ary){sum+=func.call(opt_this,elt,i++);}
+if(i===0)return undefined;return sum/i;};Statistics.geometricMean=function(ary,opt_func,opt_this){const func=opt_func||(x=>x);let i=0;let logsum=0;for(const elt of ary){const x=func.call(opt_this,elt,i++);if(x<=0)return 0;logsum+=Math.log(Math.abs(x));}
+if(i===0)return 1;return Math.exp(logsum/i);};Statistics.weightedMean=function(ary,weightCallback,opt_valueCallback,opt_this){const valueCallback=opt_valueCallback||(x=>x);let numerator=0;let denominator=0;let i=-1;for(const elt of ary){i++;const value=valueCallback.call(opt_this,elt,i);if(value===undefined)continue;const weight=weightCallback.call(opt_this,elt,i,value);numerator+=weight*value;denominator+=weight;}
+if(denominator===0)return undefined;return numerator/denominator;};Statistics.variance=function(ary,opt_func,opt_this){if(ary.length===0)return undefined;if(ary.length===1)return 0;const func=opt_func||(x=>x);const mean=Statistics.mean(ary,func,opt_this);const sumOfSquaredDistances=Statistics.sum(ary,function(d,i){const v=func.call(this,d,i)-mean;return v*v;},opt_this);return sumOfSquaredDistances/(ary.length-1);};Statistics.stddev=function(ary,opt_func,opt_this){if(ary.length===0)return undefined;return Math.sqrt(Statistics.variance(ary,opt_func,opt_this));};Statistics.max=function(ary,opt_func,opt_this){const func=opt_func||(x=>x);let ret=-Infinity;let i=0;for(const elt of ary){ret=Math.max(ret,func.call(opt_this,elt,i++));}
+return ret;};Statistics.min=function(ary,opt_func,opt_this){const func=opt_func||(x=>x);let ret=Infinity;let i=0;for(const elt of ary){ret=Math.min(ret,func.call(opt_this,elt,i++));}
+return ret;};Statistics.range=function(ary,opt_func,opt_this){const func=opt_func||(x=>x);const ret=new tr.b.math.Range();let i=0;for(const elt of ary){ret.addValue(func.call(opt_this,elt,i++));}
+return ret;};Statistics.percentile=function(ary,percent,opt_func,opt_this){if(!(percent>=0&&percent<=1)){throw new Error('percent must be [0,1]');}
+const func=opt_func||(x=>x);const tmp=new Array(ary.length);let i=0;for(const elt of ary){tmp[i]=func.call(opt_this,elt,i++);}
+tmp.sort((a,b)=>a-b);const idx=Math.floor((ary.length-1)*percent);return tmp[idx];};Statistics.normalizeSamples=function(samples){if(samples.length===0){return{normalized_samples:samples,scale:1.0};}
+samples=samples.slice().sort(function(a,b){return a-b;});const low=Math.min.apply(null,samples);const high=Math.max.apply(null,samples);const newLow=0.5/samples.length;const newHigh=(samples.length-0.5)/samples.length;if(high-low===0.0){samples=Array.apply(null,new Array(samples.length)).map(function(){return 0.5;});return{normalized_samples:samples,scale:1.0};}
+const scale=(newHigh-newLow)/(high-low);for(let i=0;i<samples.length;i++){samples[i]=(samples[i]-low)*scale+newLow;}
+return{normalized_samples:samples,scale};};Statistics.discrepancy=function(samples,opt_locationCount){if(samples.length===0)return 0.0;let maxLocalDiscrepancy=0;const invSampleCount=1.0/samples.length;const locations=[];const countLess=[];const countLessEqual=[];if(opt_locationCount!==undefined){let sampleIndex=0;for(let i=0;i<opt_locationCount;i++){const location=i/(opt_locationCount-1);locations.push(location);while(sampleIndex<samples.length&&samples[sampleIndex]<location){sampleIndex+=1;}
+countLess.push(sampleIndex);while(sampleIndex<samples.length&&samples[sampleIndex]<=location){sampleIndex+=1;}
+countLessEqual.push(sampleIndex);}}else{if(samples[0]>0.0){locations.push(0.0);countLess.push(0);countLessEqual.push(0);}
+for(let i=0;i<samples.length;i++){locations.push(samples[i]);countLess.push(i);countLessEqual.push(i+1);}
+if(samples[-1]<1.0){locations.push(1.0);countLess.push(samples.length);countLessEqual.push(samples.length);}}
+let maxDiff=0;let minDiff=0;for(let i=1;i<locations.length;i++){const length=locations[i]-locations[i-1];const countClosed=countLessEqual[i]-countLess[i-1];const countOpen=countLess[i]-countLessEqual[i-1];const countClosedIncrement=countLessEqual[i]-countLessEqual[i-1];const countOpenIncrement=countLess[i]-countLess[i-1];maxDiff=Math.max(countClosedIncrement*invSampleCount-length+maxDiff,countClosed*invSampleCount-length);minDiff=Math.min(countOpenIncrement*invSampleCount-length+minDiff,countOpen*invSampleCount-length);maxLocalDiscrepancy=Math.max(maxDiff,-minDiff,maxLocalDiscrepancy);}
+return maxLocalDiscrepancy;};Statistics.timestampsDiscrepancy=function(timestamps,opt_absolute,opt_locationCount){if(timestamps.length===0)return 0.0;if(opt_absolute===undefined)opt_absolute=true;if(Array.isArray(timestamps[0])){const rangeDiscrepancies=timestamps.map(function(r){return Statistics.timestampsDiscrepancy(r);});return Math.max.apply(null,rangeDiscrepancies);}
+const s=Statistics.normalizeSamples(timestamps);const samples=s.normalized_samples;const sampleScale=s.scale;let discrepancy=Statistics.discrepancy(samples,opt_locationCount);const invSampleCount=1.0/samples.length;if(opt_absolute===true){discrepancy/=sampleScale;}else{discrepancy=tr.b.math.clamp((discrepancy-invSampleCount)/(1.0-invSampleCount),0.0,1.0);}
+return discrepancy;};Statistics.uniformlySampleArray=function(samples,count){if(samples.length<=count){return samples;}
+while(samples.length>count){const i=parseInt(Math.random()*samples.length);samples.splice(i,1);}
+return samples;};Statistics.uniformlySampleStream=function(samples,streamLength,newElement,numSamples){if(streamLength<=numSamples){if(samples.length>=streamLength){samples[streamLength-1]=newElement;}else{samples.push(newElement);}
+return;}
+const probToKeep=numSamples/streamLength;if(Math.random()>probToKeep)return;const index=Math.floor(Math.random()*numSamples);samples[index]=newElement;};Statistics.mergeSampledStreams=function(samplesA,streamLengthA,samplesB,streamLengthB,numSamples){if(streamLengthB<numSamples){const nbElements=Math.min(streamLengthB,samplesB.length);for(let i=0;i<nbElements;++i){Statistics.uniformlySampleStream(samplesA,streamLengthA+i+1,samplesB[i],numSamples);}
+return;}
+if(streamLengthA<numSamples){const nbElements=Math.min(streamLengthA,samplesA.length);const tempSamples=samplesB.slice();for(let i=0;i<nbElements;++i){Statistics.uniformlySampleStream(tempSamples,streamLengthB+i+1,samplesA[i],numSamples);}
+for(let i=0;i<tempSamples.length;++i){samplesA[i]=tempSamples[i];}
+return;}
+const nbElements=Math.min(numSamples,samplesB.length);const probOfSwapping=streamLengthB/(streamLengthA+streamLengthB);for(let i=0;i<nbElements;++i){if(Math.random()<probOfSwapping){samplesA[i]=samplesB[i];}}};function Distribution(){}
+Distribution.prototype={computeDensity(x){throw Error('Not implemented');},computePercentile(x){throw Error('Not implemented');},computeComplementaryPercentile(x){return 1-this.computePercentile(x);},get mean(){throw Error('Not implemented');},get mode(){throw Error('Not implemented');},get median(){throw Error('Not implemented');},get standardDeviation(){throw Error('Not implemented');},get variance(){throw Error('Not implemented');}};Statistics.UniformDistribution=function(opt_range){if(!opt_range)opt_range=tr.b.math.Range.fromExplicitRange(0,1);this.range=opt_range;};Statistics.UniformDistribution.prototype={__proto__:Distribution.prototype,computeDensity(x){return 1/this.range.range;},computePercentile(x){return tr.b.math.normalize(x,this.range.min,this.range.max);},get mean(){return this.range.center;},get mode(){return undefined;},get median(){return this.mean;},get standardDeviation(){return Math.sqrt(this.variance);},get variance(){return Math.pow(this.range.range,2)/12;}};Statistics.NormalDistribution=function(opt_mean,opt_variance){this.mean_=opt_mean||0;this.variance_=opt_variance||1;this.standardDeviation_=Math.sqrt(this.variance_);};Statistics.NormalDistribution.prototype={__proto__:Distribution.prototype,computeDensity(x){const scale=(1.0/(this.standardDeviation*Math.sqrt(2.0*Math.PI)));const exponent=-Math.pow(x-this.mean,2)/(2.0*this.variance);return scale*Math.exp(exponent);},computePercentile(x){const standardizedX=((x-this.mean)/Math.sqrt(2.0*this.variance));return(1.0+tr.b.math.erf(standardizedX))/2.0;},get mean(){return this.mean_;},get median(){return this.mean;},get mode(){return this.mean;},get standardDeviation(){return this.standardDeviation_;},get variance(){return this.variance_;}};Statistics.LogNormalDistribution=function(opt_location,opt_shape){this.normalDistribution_=new Statistics.NormalDistribution(opt_location,Math.pow(opt_shape||1,2));};Statistics.LogNormalDistribution.prototype={__proto__:Statistics.NormalDistribution.prototype,computeDensity(x){return this.normalDistribution_.computeDensity(Math.log(x))/x;},computePercentile(x){return this.normalDistribution_.computePercentile(Math.log(x));},get mean(){return Math.exp(this.normalDistribution_.mean+
+(this.normalDistribution_.variance/2));},get variance(){const nm=this.normalDistribution_.mean;const nv=this.normalDistribution_.variance;return(Math.exp(2*(nm+nv))-
+Math.exp(2*nm+nv));},get standardDeviation(){return Math.sqrt(this.variance);},get median(){return Math.exp(this.normalDistribution_.mean);},get mode(){return Math.exp(this.normalDistribution_.mean-
+this.normalDistribution_.variance);}};Statistics.LogNormalDistribution.fromMedianAndDiminishingReturns=function(median,diminishingReturns){diminishingReturns=Math.log(diminishingReturns/median);const shape=Math.sqrt(1-3*diminishingReturns-
+Math.sqrt(Math.pow(diminishingReturns-3,2)-8))/2;const location=Math.log(median);return new Statistics.LogNormalDistribution(location,shape);};Statistics.DEFAULT_ALPHA=0.01;Statistics.MAX_SUGGESTED_SAMPLE_SIZE=20;Statistics.Significance={SIGNIFICANT:'REJECT',INSIGNIFICANT:'FAIL_TO_REJECT',NEED_MORE_DATA:'NEED_MORE_DATA',DONT_CARE:'DONT_CARE',};class HypothesisTestResult{constructor(p,u,needMoreData,opt_alpha){this.p_=p;this.u_=u;this.needMoreData_=needMoreData;this.compare(opt_alpha);}
+get p(){return this.p_;}
+get U(){return this.u_;}
+get significance(){return this.significance_;}
+compare(opt_alpha){const alpha=opt_alpha||Statistics.DEFAULT_ALPHA;if(this.p<alpha){this.significance_=Statistics.Significance.SIGNIFICANT;}else if(this.needMoreData_){this.significance_=Statistics.Significance.NEED_MORE_DATA;}else{this.significance_=Statistics.Significance.INSIGNIFICANT;}
+return this.significance_;}
+asDict(){return{p:this.p,U:this.U,significance:this.significance,};}}
+Statistics.mwu=function(a,b,opt_alpha,opt_reqSampleSize){const result=mannwhitneyu.test(a,b);const needMoreData=opt_reqSampleSize&&Math.min(a.length,b.length)<opt_reqSampleSize;return new HypothesisTestResult(result.p,result.U,needMoreData,opt_alpha);};return{Statistics,};});'use strict';tr.exportTo('tr.b',function(){const GREEK_SMALL_LETTER_MU=String.fromCharCode(956);const SECONDS_IN_A_MINUTE=60;const SECONDS_IN_AN_HOUR=SECONDS_IN_A_MINUTE*60;const SECONDS_IN_A_DAY=SECONDS_IN_AN_HOUR*24;const SECONDS_IN_A_WEEK=SECONDS_IN_A_DAY*7;const SECONDS_IN_A_YEAR=SECONDS_IN_A_DAY*365.2422;const SECONDS_IN_A_MONTH=SECONDS_IN_A_YEAR/12;const UnitPrefixScale={};const UnitScale={};function defineUnitPrefixScale(name,prefixes){if(UnitPrefixScale[name]!==undefined){throw new Error('Unit prefix scale \''+name+'\' already exists');}
+if(prefixes.AUTO!==undefined){throw new Error('The \'AUTO\' unit prefix is not supported for unit'+'prefix scales and cannot be added to scale \''+name+'\'');}
+UnitPrefixScale[name]=prefixes;}
+UnitScale.defineUnitScale=function(name,unitScale){if(UnitScale[name]!==undefined){throw new Error('Unit scale \''+name+'\' already exists');}
+if(unitScale.AUTO!==undefined){throw new Error('\'AUTO\' unit scale will be added automatically '+'for unit scale \''+name+'\'');}
+unitScale.AUTO=Object.values(unitScale);unitScale.AUTO.sort((a,b)=>a.value-b.value);if(name)UnitScale[name]=unitScale;return unitScale;};function definePrefixScaleFromUnitScale(prefixName,unitScale){if(!unitScale){throw new Error('Cannot create PrefixScale without a unit scale.');}
+const prefixScale={};for(const[curPrefix,curScale]of Object.entries(unitScale)){if(curPrefix==='AUTO'){continue;}
+if(curScale.symbol===undefined||!curScale.value){throw new Error(`Cannot create PrefixScale from malformed unit ${curScale}.`);}
+prefixScale[curPrefix]={value:curScale.value,symbol:curScale.symbol};}
+return defineUnitPrefixScale(prefixName,prefixScale);}
+UnitScale.defineUnitScaleFromPrefixScale=function(baseSymbol,baseName,prefixScale,opt_scaleName){if(baseSymbol===undefined){throw new Error('Cannot create UnitScale with undefined baseSymbol.');}
+if(!baseName){throw new Error('Cannot create UnitScale without a baseName.');}
+if(!prefixScale){throw new Error('Cannot create UnitScale without a prefix scale.');}
+const unitScale={};for(const curPrefix of Object.keys(prefixScale)){const curScale=prefixScale[curPrefix];if(curScale.symbol===undefined||!curScale.value){throw new Error(`Cannot convert PrefixScale with malformed prefix ${curScale}.`);}
+const name=curPrefix==='NONE'?baseName:`${curPrefix}_${baseName}`;unitScale[name]={value:curScale.value,symbol:curScale.symbol+baseSymbol,baseSymbol};}
+return UnitScale.defineUnitScale(opt_scaleName,unitScale);};function convertUnit(value,fromScale,toScale){if(value===undefined)return undefined;const fromScaleBase=fromScale.baseSymbol;const toScaleBase=toScale.baseSymbol;if(fromScaleBase!==undefined&&toScaleBase!==undefined&&fromScaleBase!==toScaleBase){throw new Error('Cannot convert between units with different base symbols.');}
+return value*(fromScale.value/toScale.value);}
+defineUnitPrefixScale('BINARY',{NONE:{value:Math.pow(1024,0),symbol:''},KIBI:{value:Math.pow(1024,1),symbol:'Ki'},MEBI:{value:Math.pow(1024,2),symbol:'Mi'},GIBI:{value:Math.pow(1024,3),symbol:'Gi'},TEBI:{value:Math.pow(1024,4),symbol:'Ti'}});defineUnitPrefixScale('METRIC',{NANO:{value:1e-9,symbol:'n'},MICRO:{value:1e-6,symbol:GREEK_SMALL_LETTER_MU},MILLI:{value:1e-3,symbol:'m'},NONE:{value:1,symbol:''},KILO:{value:1e3,symbol:'k'},MEGA:{value:1e6,symbol:'M'},GIGA:{value:1e9,symbol:'G'}});UnitScale.defineUnitScale('TIME',{NANO_SEC:{value:1e-9,symbol:'ns',baseSymbol:'s'},MICRO_SEC:{value:1e-6,symbol:GREEK_SMALL_LETTER_MU+'s',baseSymbol:'s'},MILLI_SEC:{value:1e-3,symbol:'ms',baseSymbol:'s'},SEC:{value:1,symbol:'s',baseSymbol:'s'},MINUTE:{value:SECONDS_IN_A_MINUTE,symbol:'min',baseSymbol:'s'},HOUR:{value:SECONDS_IN_AN_HOUR,symbol:'hr',baseSymbol:'s'},DAY:{value:SECONDS_IN_A_DAY,symbol:'days',baseSymbol:'s'},WEEK:{value:SECONDS_IN_A_WEEK,symbol:'weeks',baseSymbol:'s'},MONTH:{value:SECONDS_IN_A_MONTH,symbol:'months',baseSymbol:'s'},YEAR:{value:SECONDS_IN_A_YEAR,symbol:'years',baseSymbol:'s'}});UnitScale.defineUnitScaleFromPrefixScale('B','BYTE',UnitPrefixScale.BINARY,'MEMORY');definePrefixScaleFromUnitScale('DATA_SIZE',UnitScale.MEMORY);UnitScale.defineUnitScaleFromPrefixScale('/s','SECONDS',UnitPrefixScale.DATA_SIZE,'BANDWIDTH_BYTES');return{UnitPrefixScale,UnitScale,convertUnit,GREEK_SMALL_LETTER_MU,};});'use strict';tr.exportTo('tr.b',function(){const msDisplayMode={scale:1e-3,suffix:'ms',roundedLess(a,b){return Math.round(a*1000)<Math.round(b*1000);},formatSpec:{unitScale:[tr.b.UnitScale.TIME.MILLI_SEC],minimumFractionDigits:3,}};const nsDisplayMode={scale:1e-9,suffix:'ns',roundedLess(a,b){return Math.round(a*1000000)<Math.round(b*1000000);},formatSpec:{unitScale:[tr.b.UnitScale.TIME.NANO_SEC],maximumFractionDigits:0}};const TimeDisplayModes={ns:nsDisplayMode,ms:msDisplayMode};return{TimeDisplayModes,};});'use strict';tr.exportTo('tr.ui.b',function(){function iterateElementDeeplyImpl(element,cb,thisArg,includeElement){if(includeElement&&cb.call(thisArg,element))return true;if(element.root&&element.root!==element&&iterateElementDeeplyImpl(element.root,cb,thisArg,false)){return true;}
+const children=Polymer.dom(element).children;for(let i=0;i<children.length;i++){if(iterateElementDeeplyImpl(children[i],cb,thisArg,true)){return true;}}
+return false;}
+function iterateElementDeeply(element,cb,thisArg){iterateElementDeeplyImpl(element,cb,thisArg,false);}
+function findDeepElementMatchingPredicate(element,predicate){let foundElement=undefined;function matches(element){const match=predicate(element);if(!match){return false;}
+foundElement=element;return true;}
+iterateElementDeeply(element,matches);return foundElement;}
+function findDeepElementsMatchingPredicate(element,predicate){const foundElements=[];function matches(element){const match=predicate(element);if(match){foundElements.push(element);}
+return false;}
+iterateElementDeeply(element,matches);return foundElements;}
+function findDeepElementMatching(element,selector){return findDeepElementMatchingPredicate(element,function(element){return element.matches(selector);});}
+function findDeepElementsMatching(element,selector){return findDeepElementsMatchingPredicate(element,function(element){return element.matches(selector);});}
+function findDeepElementWithTextContent(element,re){return findDeepElementMatchingPredicate(element,function(element){if(element.children.length!==0)return false;return re.test(Polymer.dom(element).textContent);});}
+return{findDeepElementMatching,findDeepElementsMatching,findDeepElementMatchingPredicate,findDeepElementsMatchingPredicate,findDeepElementWithTextContent,};});'use strict';tr.exportTo('tr.b',function(){const TimeDisplayModes=tr.b.TimeDisplayModes;const PLUS_MINUS_SIGN=String.fromCharCode(177);const CACHED_FORMATTERS={};function getNumberFormatter(minSpec,maxSpec,minCtx,maxCtx){const key=minSpec+'-'+maxSpec+'-'+minCtx+'-'+maxCtx;let formatter=CACHED_FORMATTERS[key];if(formatter===undefined){let minimumFractionDigits=minCtx!==undefined?minCtx:minSpec;let maximumFractionDigits=maxCtx!==undefined?maxCtx:maxSpec;if(minimumFractionDigits>maximumFractionDigits){if(minCtx!==undefined&&maxCtx===undefined){maximumFractionDigits=minimumFractionDigits;}else if(minCtx===undefined&&maxCtx!==undefined){minimumFractionDigits=maximumFractionDigits;}}
+formatter=new Intl.NumberFormat(undefined,{minimumFractionDigits,maximumFractionDigits,});CACHED_FORMATTERS[key]=formatter;}
+return formatter;}
+function max(a,b){if(a===undefined)return b;if(b===undefined)return a;return a.scale>b.scale?a:b;}
+const ImprovementDirection={DONT_CARE:0,BIGGER_IS_BETTER:1,SMALLER_IS_BETTER:2};function Unit(unitName,jsonName,scaleBaseUnit,isDelta,improvementDirection,formatSpec){this.unitName=unitName;this.jsonName=jsonName;this.scaleBaseUnit=scaleBaseUnit;this.isDelta=isDelta;this.improvementDirection=improvementDirection;this.formatSpec_=formatSpec;this.baseUnit=undefined;this.correspondingDeltaUnit=undefined;}
+Unit.prototype={asJSON(){return this.jsonName;},asJSON2(){return this.asJSON().replace('_smallerIsBetter','-').replace('_biggerIsBetter','+');},truncate(value){if(typeof value!=='number')return value;if(0===(value%1))return value;if(typeof this.formatSpec_!=='function'&&(!this.formatSpec_.unitScale||((this.formatSpec_.unitScale.length===1)&&(this.formatSpec_.unitScale[0].value===1)))){const digits=this.formatSpec_.maximumFractionDigits||this.formatSpec_.minimumFractionDigits;return tr.b.math.truncate(value,digits+1);}
+const formatted=this.format(value);let test=Math.round(value);if(formatted===this.format(test))return test;let lo=1;let hi=16;while(lo<hi-1){const digits=parseInt((lo+hi)/2);test=tr.b.math.truncate(value,digits);if(formatted===this.format(test)){hi=digits;}else{lo=digits;}}
+test=tr.b.math.truncate(value,lo);if(formatted===this.format(test))return test;return tr.b.math.truncate(value,hi);},getUnitScale_(opt_context){let formatSpec=this.formatSpec_;let formatSpecWasFunction=false;if(typeof formatSpec==='function'){formatSpecWasFunction=true;formatSpec=formatSpec();}
+const context=opt_context||{};let scale=undefined;if(context.unitScale){scale=context.unitScale;}else if(context.unitPrefix){const symbol=formatSpec.baseSymbol?formatSpec.baseSymbol:this.scaleBaseUnit.baseSymbol;scale=tr.b.UnitScale.defineUnitScaleFromPrefixScale(symbol,symbol,[context.unitPrefix]).AUTO;}else{scale=formatSpec.unitScale;if(!scale){scale=[{value:1,symbol:formatSpec.baseSymbol||'',baseSymbol:formatSpec.baseSymbol||''}];if(!formatSpecWasFunction)formatSpec.unitScale=scale;}}
+if(!(scale instanceof Array)){throw new Error('Unit has a malformed unit scale.');}
+return scale;},get unitString(){const scale=this.getUnitScale_();if(!scale){throw new Error('A UnitScale could not be found for Unit '+this.unitName);}
+return scale[0].symbol;},format(value,opt_context){let signString='';if(value<0){signString='-';value=-value;}else if(this.isDelta){signString=value===0?PLUS_MINUS_SIGN:'+';}
+const context=opt_context||{};const scale=this.getUnitScale_(context);let deltaValue=context.deltaValue===undefined?value:context.deltaValue;deltaValue=Math.abs(deltaValue)*this.scaleBaseUnit.value;if(deltaValue===0){deltaValue=1;}
+let i=0;while(i<scale.length-1&&deltaValue/scale[i+1].value>=1){i++;}
+const selectedSubUnit=scale[i];let formatSpec=this.formatSpec_;if(typeof formatSpec==='function')formatSpec=formatSpec();let unitString='';if(selectedSubUnit.symbol){if(!formatSpec.avoidSpacePrecedingUnit)unitString=' ';unitString+=selectedSubUnit.symbol;}
+value=tr.b.convertUnit(value,this.scaleBaseUnit,selectedSubUnit);const numberString=getNumberFormatter(formatSpec.minimumFractionDigits,formatSpec.maximumFractionDigits,context.minimumFractionDigits,context.maximumFractionDigits).format(value);return signString+numberString+unitString;}};Unit.reset=function(){Unit.currentTimeDisplayMode=TimeDisplayModes.ms;};Unit.timestampFromUs=function(us){return tr.b.convertUnit(us,tr.b.UnitPrefixScale.METRIC.MICRO,tr.b.UnitPrefixScale.METRIC.MILLI);};Object.defineProperty(Unit,'currentTimeDisplayMode',{get(){return Unit.currentTimeDisplayMode_;},set(value){if(Unit.currentTimeDisplayMode_===value)return;Unit.currentTimeDisplayMode_=value;Unit.dispatchEvent(new tr.b.Event('display-mode-changed'));}});Unit.didPreferredTimeDisplayUnitChange=function(){let largest=undefined;const els=tr.ui.b.findDeepElementsMatching(document.body,'tr-v-ui-preferred-display-unit');els.forEach(function(el){largest=max(largest,el.preferredTimeDisplayMode);});Unit.currentTimeDisplayMode=largest===undefined?TimeDisplayModes.ms:largest;};Unit.byName={};Unit.byJSONName={};Unit.fromJSON=function(object){if(typeof(object)==='string'){if(object.endsWith('+')){object=object.slice(0,object.length-1)+'_biggerIsBetter';}else if(object.endsWith('-')){object=object.slice(0,object.length-1)+'_smallerIsBetter';}
+const u=Unit.byJSONName[object];if(u)return u;}
+throw new Error(`Unrecognized unit "${object}"`);};Unit.define=function(params){const definedUnits=[];for(const improvementDirection of Object.values(ImprovementDirection)){const regularUnit=Unit.defineUnitVariant_(params,false,improvementDirection);const deltaUnit=Unit.defineUnitVariant_(params,true,improvementDirection);regularUnit.correspondingDeltaUnit=deltaUnit;deltaUnit.correspondingDeltaUnit=deltaUnit;definedUnits.push(regularUnit,deltaUnit);}
+const baseUnit=Unit.byName[params.baseUnitName];definedUnits.forEach(u=>u.baseUnit=baseUnit);};Unit.nameSuffixForImprovementDirection=function(improvementDirection){switch(improvementDirection){case ImprovementDirection.DONT_CARE:return'';case ImprovementDirection.BIGGER_IS_BETTER:return'_biggerIsBetter';case ImprovementDirection.SMALLER_IS_BETTER:return'_smallerIsBetter';default:throw new Error('Unknown improvement direction: '+improvementDirection);}};Unit.defineUnitVariant_=function(params,isDelta,improvementDirection){let nameSuffix=isDelta?'Delta':'';nameSuffix+=Unit.nameSuffixForImprovementDirection(improvementDirection);const unitName=params.baseUnitName+nameSuffix;const jsonName=params.baseJsonName+nameSuffix;if(Unit.byName[unitName]!==undefined){throw new Error('Unit \''+unitName+'\' already exists');}
+if(Unit.byJSONName[jsonName]!==undefined){throw new Error('JSON unit \''+jsonName+'\' alread exists');}
+let scaleBaseUnit=params.scaleBaseUnit;if(!scaleBaseUnit){let formatSpec=params.formatSpec;if(typeof formatSpec==='function')formatSpec=formatSpec();const baseSymbol=formatSpec.unitScale?formatSpec.unitScale[0].baseSymbol:(formatSpec.baseSymbol||'');scaleBaseUnit={value:1,symbol:baseSymbol,baseSymbol};}
+const unit=new Unit(unitName,jsonName,scaleBaseUnit,isDelta,improvementDirection,params.formatSpec);Unit.byName[unitName]=unit;Unit.byJSONName[jsonName]=unit;return unit;};tr.b.EventTarget.decorate(Unit);Unit.reset();Unit.define({baseUnitName:'timeInMsAutoFormat',baseJsonName:'msBestFitFormat',scaleBaseUnit:tr.b.UnitScale.TIME.MILLI_SEC,formatSpec:{unitScale:tr.b.UnitScale.TIME.AUTO,minimumFractionDigits:0,maximumFractionDigits:3}});Unit.define({baseUnitName:'timeDurationInMs',baseJsonName:'ms',scaleBaseUnit:tr.b.UnitScale.TIME.MILLI_SEC,formatSpec(){return Unit.currentTimeDisplayMode_.formatSpec;}});Unit.define({baseUnitName:'timeStampInMs',baseJsonName:'tsMs',scaleBaseUnit:tr.b.UnitScale.TIME.MILLI_SEC,formatSpec(){return Unit.currentTimeDisplayMode_.formatSpec;}});Unit.define({baseUnitName:'normalizedPercentage',baseJsonName:'n%',formatSpec:{unitScale:[{value:0.01,symbol:'%'}],avoidSpacePrecedingUnit:true,minimumFractionDigits:1,maximumFractionDigits:1}});Unit.define({baseUnitName:'sizeInBytes',baseJsonName:'sizeInBytes',formatSpec:{unitScale:tr.b.UnitScale.MEMORY.AUTO,minimumFractionDigits:1,maximumFractionDigits:1}});Unit.define({baseUnitName:'bandwidthInBytesPerSecond',baseJsonName:'bytesPerSecond',formatSpec:{unitScale:tr.b.UnitScale.BANDWIDTH_BYTES.AUTO,minimumFractionDigits:1,maximumFractionDigits:1}});Unit.define({baseUnitName:'energyInJoules',baseJsonName:'J',formatSpec:{unitScale:tr.b.UnitScale.defineUnitScaleFromPrefixScale('J','JOULE',tr.b.UnitPrefixScale.METRIC,'JOULE').AUTO,minimumFractionDigits:3}});Unit.define({baseUnitName:'powerInWatts',baseJsonName:'W',formatSpec:{unitScale:tr.b.UnitScale.defineUnitScaleFromPrefixScale('W','WATT',tr.b.UnitPrefixScale.METRIC,'WATT').AUTO,minimumFractionDigits:3}});Unit.define({baseUnitName:'electricCurrentInAmperes',baseJsonName:'A',formatSpec:{baseSymbol:'A',unitScale:tr.b.UnitScale.defineUnitScaleFromPrefixScale('A','AMPERE',tr.b.UnitPrefixScale.METRIC,'AMPERE').AUTO,minimumFractionDigits:3}});Unit.define({baseUnitName:'electricPotentialInVolts',baseJsonName:'V',formatSpec:{baseSymbol:'V',unitScale:tr.b.UnitScale.defineUnitScaleFromPrefixScale('V','VOLT',tr.b.UnitPrefixScale.METRIC,'VOLT').AUTO,minimumFractionDigits:3}});Unit.define({baseUnitName:'frequencyInHertz',baseJsonName:'Hz',formatSpec:{baseSymbol:'Hz',unitScale:tr.b.UnitScale.defineUnitScaleFromPrefixScale('Hz','HERTZ',tr.b.UnitPrefixScale.METRIC,'HERTZ').AUTO,minimumFractionDigits:3}});Unit.define({baseUnitName:'unitlessNumber',baseJsonName:'unitless',formatSpec:{minimumFractionDigits:3,maximumFractionDigits:3}});Unit.define({baseUnitName:'count',baseJsonName:'count',formatSpec:{minimumFractionDigits:0,maximumFractionDigits:0}});Unit.define({baseUnitName:'sigma',baseJsonName:'sigma',formatSpec:{baseSymbol:String.fromCharCode(963),minimumFractionDigits:1,maximumFractionDigits:1}});return{ImprovementDirection,Unit,};});'use strict';tr.exportTo('tr.b',function(){class Scalar{constructor(unit,value){if(!(unit instanceof tr.b.Unit)){throw new Error('Expected Unit');}
+if(!(typeof(value)==='number')){throw new Error('Expected value to be number');}
+this.unit=unit;this.value=value;}
+asDict(){return{unit:this.unit.asJSON(),value:tr.b.numberToJson(this.value),};}
+toString(){return this.unit.format(this.value);}
+static fromDict(d){return new Scalar(tr.b.Unit.fromJSON(d.unit),tr.b.numberFromJson(d.value));}}
+return{Scalar,};});'use strict';tr.exportTo('tr.c',function(){function Auditor(model){this.model_=model;}
+Auditor.prototype={__proto__:Object.prototype,get model(){return this.model_;},runAnnotate(){},installUserFriendlyCategoryDriverIfNeeded(){},runAudit(){}};const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Auditor;tr.b.decorateExtensionRegistry(Auditor,options);return{Auditor,};});'use strict';tr.exportTo('tr.b',function(){function clamp01(value){return Math.max(0,Math.min(1,value));}
+function Color(opt_r,opt_g,opt_b,opt_a){this.r=Math.floor(opt_r)||0;this.g=Math.floor(opt_g)||0;this.b=Math.floor(opt_b)||0;this.a=opt_a;}
+Color.fromString=function(str){let tmp;let values;if(str.substr(0,4)==='rgb('){tmp=str.substr(4,str.length-5);values=tmp.split(',').map(function(v){return v.replace(/^\s+/,'','g');});if(values.length!==3){throw new Error('Malformatted rgb-expression');}
+return new Color(parseInt(values[0]),parseInt(values[1]),parseInt(values[2]));}
+if(str.substr(0,5)==='rgba('){tmp=str.substr(5,str.length-6);values=tmp.split(',').map(function(v){return v.replace(/^\s+/,'','g');});if(values.length!==4){throw new Error('Malformatted rgb-expression');}
+return new Color(parseInt(values[0]),parseInt(values[1]),parseInt(values[2]),parseFloat(values[3]));}
+if(str[0]==='#'&&str.length===7){return new Color(parseInt(str.substr(1,2),16),parseInt(str.substr(3,2),16),parseInt(str.substr(5,2),16));}
+throw new Error('Unrecognized string format.');};Color.lerp=function(a,b,percent){if(a.a!==undefined&&b.a!==undefined){return Color.lerpRGBA(a,b,percent);}
+return Color.lerpRGB(a,b,percent);};Color.lerpRGB=function(a,b,percent){return new Color(((b.r-a.r)*percent)+a.r,((b.g-a.g)*percent)+a.g,((b.b-a.b)*percent)+a.b);};Color.lerpRGBA=function(a,b,percent){return new Color(((b.r-a.r)*percent)+a.r,((b.g-a.g)*percent)+a.g,((b.b-a.b)*percent)+a.b,((b.a-a.a)*percent)+a.a);};Color.fromDict=function(dict){return new Color(dict.r,dict.g,dict.b,dict.a);};Color.fromHSLExplicit=function(h,s,l,a){let r;let g;let b;function hue2rgb(p,q,t){if(t<0)t+=1;if(t>1)t-=1;if(t<1/6)return p+(q-p)*6*t;if(t<1/2)return q;if(t<2/3)return p+(q-p)*(2/3-t)*6;return p;}
+if(s===0){r=g=b=l;}else{const q=l<0.5?l*(1+s):l+s-l*s;const p=2*l-q;r=hue2rgb(p,q,h+1/3);g=hue2rgb(p,q,h);b=hue2rgb(p,q,h-1/3);}
+return new Color(Math.floor(r*255),Math.floor(g*255),Math.floor(b*255),a);};Color.fromHSL=function(hsl){return Color.fromHSLExplicit(hsl.h,hsl.s,hsl.l,hsl.a);};Color.prototype={clone(){const c=new Color();c.r=this.r;c.g=this.g;c.b=this.b;c.a=this.a;return c;},blendOver(bgColor){const oneMinusThisAlpha=1-this.a;const outA=this.a+bgColor.a*oneMinusThisAlpha;const bgBlend=(bgColor.a*oneMinusThisAlpha)/bgColor.a;return new Color(this.r*this.a+bgColor.r*bgBlend,this.g*this.a+bgColor.g*bgBlend,this.b*this.a+bgColor.b*bgBlend,outA);},brighten(opt_k){const k=opt_k||0.45;return new Color(Math.min(255,this.r+Math.floor(this.r*k)),Math.min(255,this.g+Math.floor(this.g*k)),Math.min(255,this.b+Math.floor(this.b*k)),this.a);},lighten(k,opt_maxL){const maxL=opt_maxL!==undefined?opt_maxL:1.0;const hsl=this.toHSL();hsl.l=Math.min(hsl.l+k,maxL);return Color.fromHSL(hsl);},darken(opt_k){let k;if(opt_k!==undefined){k=opt_k;}else{k=0.45;}
+return new Color(Math.min(255,this.r-Math.floor(this.r*k)),Math.min(255,this.g-Math.floor(this.g*k)),Math.min(255,this.b-Math.floor(this.b*k)),this.a);},desaturate(opt_desaturateFactor){let desaturateFactor;if(opt_desaturateFactor!==undefined){desaturateFactor=opt_desaturateFactor;}else{desaturateFactor=1;}
+const hsl=this.toHSL();hsl.s=clamp01(hsl.s*(1-desaturateFactor));return Color.fromHSL(hsl);},withAlpha(a){return new Color(this.r,this.g,this.b,a);},toString(){if(this.a!==undefined){return'rgba('+
+this.r+','+this.g+','+
+this.b+','+this.a+')';}
+return'rgb('+this.r+','+this.g+','+this.b+')';},toHSL(){const r=this.r/255;const g=this.g/255;const b=this.b/255;const max=Math.max(r,g,b);const min=Math.min(r,g,b);let h;let s;const l=(max+min)/2;if(min===max){h=0;s=0;}else{const delta=max-min;if(l>0.5){s=delta/(2-max-min);}else{s=delta/(max+min);}
+if(r===max){h=(g-b)/delta;if(g<b)h+=6;}else if(g===max){h=2+((b-r)/delta);}else{h=4+((r-g)/delta);}
+h/=6;}
+return{h,s,l,a:this.a};},toStringWithAlphaOverride(alpha){return'rgba('+
+this.r+','+this.g+','+
+this.b+','+alpha+')';}};return{Color,};});'use strict';tr.exportTo('tr.b',function(){function SinebowColorGenerator(opt_a,opt_brightness){this.a_=(opt_a===undefined)?1:opt_a;this.brightness_=(opt_brightness===undefined)?1:opt_brightness;this.colorIndex_=0;this.keyToColor={};}
+SinebowColorGenerator.prototype={colorForKey(key){if(!this.keyToColor[key]){this.keyToColor[key]=this.nextColor();}
+return this.keyToColor[key];},nextColor(){const components=SinebowColorGenerator.nthColor(this.colorIndex_++);return tr.b.Color.fromString(SinebowColorGenerator.calculateColor(components[0],components[1],components[2],this.a_,this.brightness_));}};SinebowColorGenerator.PHI=(1+Math.sqrt(5))/2;SinebowColorGenerator.sinebow=function(h){h+=0.5;h=-h;let r=Math.sin(Math.PI*h);let g=Math.sin(Math.PI*(h+1/3));let b=Math.sin(Math.PI*(h+2/3));r*=r;g*=g;b*=b;const y=2*(0.2989*r+0.5870*g+0.1140*b);r/=y;g/=y;b/=y;return[256*r,256*g,256*b];};SinebowColorGenerator.nthColor=function(n){return SinebowColorGenerator.sinebow(n*this.PHI);};SinebowColorGenerator.calculateColor=function(r,g,b,a,brightness){if(brightness<=1){r*=brightness;g*=brightness;b*=brightness;}else{r=tr.b.math.lerp(tr.b.math.normalize(brightness,1,2),r,255);g=tr.b.math.lerp(tr.b.math.normalize(brightness,1,2),g,255);b=tr.b.math.lerp(tr.b.math.normalize(brightness,1,2),b,255);}
+r=Math.round(r);g=Math.round(g);b=Math.round(b);return'rgba('+r+','+g+','+b+', '+a+')';};return{SinebowColorGenerator,};});'use strict';tr.exportTo('tr.b',function(){const numGeneralPurposeColorIds=23;const generalPurposeColors=new Array(numGeneralPurposeColorIds);const sinebowAlpha=1.0;const sinebowBrightness=1.5;const sinebowColorGenerator=new tr.b.SinebowColorGenerator(sinebowAlpha,sinebowBrightness);for(let i=0;i<numGeneralPurposeColorIds;i++){generalPurposeColors[i]=sinebowColorGenerator.nextColor();}
+const reservedColorsByName={thread_state_uninterruptible:new tr.b.Color(182,125,143),thread_state_iowait:new tr.b.Color(255,140,0),thread_state_running:new tr.b.Color(126,200,148),thread_state_runnable:new tr.b.Color(133,160,210),thread_state_sleeping:new tr.b.Color(240,240,240),thread_state_unknown:new tr.b.Color(199,155,125),background_memory_dump:new tr.b.Color(0,180,180),light_memory_dump:new tr.b.Color(0,0,180),detailed_memory_dump:new tr.b.Color(180,0,180),vsync_highlight_color:new tr.b.Color(0,0,255),generic_work:new tr.b.Color(125,125,125),good:new tr.b.Color(0,125,0),bad:new tr.b.Color(180,125,0),terrible:new tr.b.Color(180,0,0),black:new tr.b.Color(0,0,0),grey:new tr.b.Color(221,221,221),white:new tr.b.Color(255,255,255),yellow:new tr.b.Color(255,255,0),olive:new tr.b.Color(100,100,0),rail_response:new tr.b.Color(67,135,253),rail_animation:new tr.b.Color(244,74,63),rail_idle:new tr.b.Color(238,142,0),rail_load:new tr.b.Color(13,168,97),startup:new tr.b.Color(230,230,0),heap_dump_stack_frame:new tr.b.Color(128,128,128),heap_dump_object_type:new tr.b.Color(0,0,255),heap_dump_child_node_arrow:new tr.b.Color(204,102,0),cq_build_running:new tr.b.Color(255,255,119),cq_build_passed:new tr.b.Color(153,238,102),cq_build_failed:new tr.b.Color(238,136,136),cq_build_abandoned:new tr.b.Color(187,187,187),cq_build_attempt_runnig:new tr.b.Color(222,222,75),cq_build_attempt_passed:new tr.b.Color(103,218,35),cq_build_attempt_failed:new tr.b.Color(197,81,81)};const numReservedColorIds=Object.keys(reservedColorsByName).length;const numColorsPerVariant=numGeneralPurposeColorIds+numReservedColorIds;function ColorScheme(){}
+const paletteBase=[];paletteBase.push.apply(paletteBase,generalPurposeColors);paletteBase.push.apply(paletteBase,Object.values(reservedColorsByName));ColorScheme.colors=[];ColorScheme.properties={};ColorScheme.properties={numColorsPerVariant,};function pushVariant(func){const variantColors=paletteBase.map(func);ColorScheme.colors.push.apply(ColorScheme.colors,variantColors);}
+pushVariant(function(c){return c;});ColorScheme.properties.brightenedOffsets=[];ColorScheme.properties.brightenedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.lighten(0.3,0.8);});ColorScheme.properties.brightenedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.lighten(0.48,0.85);});ColorScheme.properties.brightenedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.lighten(0.65,0.9);});ColorScheme.properties.dimmedOffsets=[];ColorScheme.properties.dimmedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.desaturate();});ColorScheme.properties.dimmedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.desaturate(0.5);});ColorScheme.properties.dimmedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.desaturate(0.3);});ColorScheme.colorsAsStrings=ColorScheme.colors.map(function(c){return c.toString();});const reservedColorNameToIdMap=(function(){const m=new Map();let i=generalPurposeColors.length;for(const key of Object.keys(reservedColorsByName)){m.set(key,i++);}
+return m;})();ColorScheme.getColorIdForReservedName=function(name){const id=reservedColorNameToIdMap.get(name);if(id===undefined){throw new Error('Unrecognized color '+name);}
+return id;};ColorScheme.getColorForReservedNameAsString=function(reservedName){const id=ColorScheme.getColorIdForReservedName(reservedName);return ColorScheme.colorsAsStrings[id];};ColorScheme.getStringHash=function(name){let hash=0;for(let i=0;i<name.length;++i){hash=(hash+37*hash+11*name.charCodeAt(i))%0xFFFFFFFF;}
+return hash;};const stringColorIdCache=new Map();ColorScheme.getColorIdForGeneralPurposeString=function(string){if(stringColorIdCache.get(string)===undefined){const hash=ColorScheme.getStringHash(string);stringColorIdCache.set(string,hash%numGeneralPurposeColorIds);}
+return stringColorIdCache.get(string);};ColorScheme.getAnotherColorId=function(colorId,n){return(colorId+n)%numColorsPerVariant;};ColorScheme.getVariantColorId=function(colorId,offset){return colorId+offset;};return{ColorScheme,};});'use strict';tr.exportTo('tr.model',function(){const ColorScheme=tr.b.ColorScheme;function EventInfo(title,description,docLinks){this.title=title;this.description=description;this.docLinks=docLinks;this.colorId=ColorScheme.getColorIdForGeneralPurposeString(title);}
+return{EventInfo,};});'use strict';tr.exportTo('tr.b',function(){let nextGUID=1;const UUID4_PATTERN='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';const GUID={allocateSimple(){return nextGUID++;},getLastSimpleGuid(){return nextGUID-1;},allocateUUID4(){return UUID4_PATTERN.replace(/[xy]/g,function(c){let r=parseInt(Math.random()*16);if(c==='y')r=(r&3)+8;return r.toString(16);});}};return{GUID,};});'use strict';tr.exportTo('tr.model',function(){function EventRegistry(){}
+const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(EventRegistry,options);EventRegistry.addEventListener('will-register',function(e){const metadata=e.typeInfo.metadata;if(metadata.name===undefined){throw new Error('Registered events must provide name metadata');}
+if(metadata.pluralName===undefined){throw new Error('Registered events must provide pluralName metadata');}
+if(metadata.subTypes===undefined){metadata.subTypes={};const options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=e.typeInfo.constructor;options.defaultConstructor=e.typeInfo.constructor;tr.b.decorateExtensionRegistry(metadata.subTypes,options);}else{if(!metadata.subTypes.register){throw new Error('metadata.subTypes must be an extension registry.');}}
+e.typeInfo.constructor.subTypes=metadata.subTypes;});let eventsByTypeName=undefined;EventRegistry.getEventTypeInfoByTypeName=function(typeName){if(eventsByTypeName===undefined){eventsByTypeName={};EventRegistry.getAllRegisteredTypeInfos().forEach(function(typeInfo){eventsByTypeName[typeInfo.metadata.name]=typeInfo;});}
+return eventsByTypeName[typeName];};EventRegistry.addEventListener('registry-changed',function(){eventsByTypeName=undefined;});function convertCamelCaseToTitleCase(name){let result=name.replace(/[A-Z]/g,' $&');result=result.charAt(0).toUpperCase()+result.slice(1);return result;}
+EventRegistry.getUserFriendlySingularName=function(typeName){const typeInfo=EventRegistry.getEventTypeInfoByTypeName(typeName);const str=typeInfo.metadata.name;return convertCamelCaseToTitleCase(str);};EventRegistry.getUserFriendlyPluralName=function(typeName){const typeInfo=EventRegistry.getEventTypeInfoByTypeName(typeName);const str=typeInfo.metadata.pluralName;return convertCamelCaseToTitleCase(str);};return{EventRegistry,};});'use strict';tr.exportTo('tr.model',function(){const EventRegistry=tr.model.EventRegistry;const RequestSelectionChangeEvent=tr.b.Event.bind(undefined,'requestSelectionChange',true,false);function EventSet(opt_events){this.bounds_=new tr.b.math.Range();this.events_=new Set();this.guid_=tr.b.GUID.allocateSimple();if(opt_events){if(opt_events instanceof Array){for(const event of opt_events){this.push(event);}}else if(opt_events instanceof EventSet){this.addEventSet(opt_events);}else{this.push(opt_events);}}}
+EventSet.prototype={__proto__:Object.prototype,get bounds(){return this.bounds_;},get duration(){if(this.bounds_.isEmpty)return 0;return this.bounds_.max-this.bounds_.min;},get length(){return this.events_.size;},get guid(){return this.guid_;},*[Symbol.iterator](){for(const event of this.events_){yield event;}},clear(){this.bounds_=new tr.b.math.Range();this.events_.clear();},push(...events){let numPushed;for(const event of events){if(event.guid===undefined){throw new Error('Event must have a GUID');}
+if(!this.events_.has(event)){this.events_.add(event);if(event.addBoundsToRange){if(this.bounds_!==undefined){event.addBoundsToRange(this.bounds_);}}}
+numPushed++;}
+return numPushed;},contains(event){if(this.events_.has(event))return event;return undefined;},addEventSet(eventSet){for(const event of eventSet){this.push(event);}},intersectionIsEmpty(otherEventSet){return!this.some(event=>otherEventSet.contains(event));},equals(that){if(this.length!==that.length)return false;return this.every(event=>that.contains(event));},sortEvents(compare){const ary=this.toArray();ary.sort(compare);this.clear();for(const event of ary){this.push(event);}},getEventsOrganizedByBaseType(opt_pruneEmpty){const allTypeInfos=EventRegistry.getAllRegisteredTypeInfos();const events=this.getEventsOrganizedByCallback(function(event){let maxEventIndex=-1;let maxEventTypeInfo=undefined;allTypeInfos.forEach(function(eventTypeInfo,eventIndex){if(!(event instanceof eventTypeInfo.constructor))return;if(eventIndex>maxEventIndex){maxEventIndex=eventIndex;maxEventTypeInfo=eventTypeInfo;}});if(maxEventIndex===-1){throw new Error(`Unrecognized event type: ${event.constructor.name}`);}
+return maxEventTypeInfo.metadata.name;});if(!opt_pruneEmpty){allTypeInfos.forEach(function(eventTypeInfo){if(events[eventTypeInfo.metadata.name]===undefined){events[eventTypeInfo.metadata.name]=new EventSet();}});}
+return events;},getEventsOrganizedByTitle(){return this.getEventsOrganizedByCallback(function(event){if(event.title===undefined){throw new Error('An event didn\'t have a title!');}
+return event.title;});},getEventsOrganizedByCallback(cb,opt_this){const groupedEvents=tr.b.groupIntoMap(this,cb,opt_this||this);const groupedEventsDict={};for(const[k,events]of groupedEvents){groupedEventsDict[k]=new EventSet(events);}
+return groupedEventsDict;},enumEventsOfType(type,func){for(const event of this){if(event instanceof type){func(event);}}},get userFriendlyName(){if(this.length===0){throw new Error('Empty event set');}
+const eventsByBaseType=this.getEventsOrganizedByBaseType(true);const eventTypeName=Object.keys(eventsByBaseType)[0];if(this.length===1){const tmp=EventRegistry.getUserFriendlySingularName(eventTypeName);return tr.b.getOnlyElement(this.events_).userFriendlyName;}
+const numEventTypes=Object.keys(eventsByBaseType).length;if(numEventTypes!==1){return this.length+' events of various types';}
+const tmp=EventRegistry.getUserFriendlyPluralName(eventTypeName);return this.length+' '+tmp;},filter(fn,opt_this){const res=new EventSet();for(const event of this){if(fn.call(opt_this,event)){res.push(event);}}
+return res;},toArray(){const ary=[];for(const event of this){ary.push(event);}
+return ary;},forEach(fn,opt_this){for(const event of this){fn.call(opt_this,event);}},map(fn,opt_this){const res=[];for(const event of this){res.push(fn.call(opt_this,event));}
+return res;},every(fn,opt_this){for(const event of this){if(!fn.call(opt_this,event)){return false;}}
+return true;},some(fn,opt_this){for(const event of this){if(fn.call(opt_this,event)){return true;}}
+return false;},asDict(){const stableIds=[];for(const event of this){stableIds.push(event.stableId);}
+return{'events':stableIds};},asSet(){return this.events_;}};EventSet.IMMUTABLE_EMPTY_SET=(function(){const s=new EventSet();s.push=function(){throw new Error('Cannot push to an immutable event set');};s.addEventSet=function(){throw new Error('Cannot add to an immutable event set');};Object.freeze(s);return s;})();return{EventSet,RequestSelectionChangeEvent,};});'use strict';tr.exportTo('tr.model',function(){const ColorScheme=tr.b.ColorScheme;const SelectionState={NONE:0,SELECTED:ColorScheme.properties.brightenedOffsets[0],HIGHLIGHTED:ColorScheme.properties.brightenedOffsets[1],DIMMED:ColorScheme.properties.dimmedOffsets[0],BRIGHTENED0:ColorScheme.properties.brightenedOffsets[0],BRIGHTENED1:ColorScheme.properties.brightenedOffsets[1],BRIGHTENED2:ColorScheme.properties.brightenedOffsets[2],DIMMED0:ColorScheme.properties.dimmedOffsets[0],DIMMED1:ColorScheme.properties.dimmedOffsets[1],DIMMED2:ColorScheme.properties.dimmedOffsets[2]};const brighteningLevels=[SelectionState.NONE,SelectionState.BRIGHTENED0,SelectionState.BRIGHTENED1,SelectionState.BRIGHTENED2];SelectionState.getFromBrighteningLevel=function(level){return brighteningLevels[level];};const dimmingLevels=[SelectionState.DIMMED0,SelectionState.DIMMED1,SelectionState.DIMMED2];SelectionState.getFromDimmingLevel=function(level){return dimmingLevels[level];};return{SelectionState,};});'use strict';tr.exportTo('tr.model',function(){const SelectionState=tr.model.SelectionState;function SelectableItem(modelItem){this.modelItem_=modelItem;}
+SelectableItem.prototype={get modelItem(){return this.modelItem_;},get selected(){return this.selectionState===SelectionState.SELECTED;},addToSelection(selection){const modelItem=this.modelItem_;if(!modelItem)return;selection.push(modelItem);},addToTrackMap(eventToTrackMap,track){const modelItem=this.modelItem_;if(!modelItem)return;eventToTrackMap.addEvent(modelItem,track);}};return{SelectableItem,};});'use strict';tr.exportTo('tr.model',function(){const SelectableItem=tr.model.SelectableItem;const SelectionState=tr.model.SelectionState;const IMMUTABLE_EMPTY_SET=tr.model.EventSet.IMMUTABLE_EMPTY_SET;function Event(){SelectableItem.call(this,this);this.guid_=tr.b.GUID.allocateSimple();this.selectionState=SelectionState.NONE;this.info=undefined;}
+Event.prototype={__proto__:SelectableItem.prototype,get guid(){return this.guid_;},get stableId(){return undefined;},get range(){const range=new tr.b.math.Range();this.addBoundsToRange(range);return range;},associatedAlerts:IMMUTABLE_EMPTY_SET,addAssociatedAlert(alert){if(this.associatedAlerts===IMMUTABLE_EMPTY_SET){this.associatedAlerts=new tr.model.EventSet();}
+this.associatedAlerts.push(alert);},addBoundsToRange(range){}};return{Event,};});'use strict';tr.exportTo('tr.model',function(){function TimedEvent(start){tr.model.Event.call(this);this.start=start;this.duration=0;this.cpuStart=undefined;this.cpuDuration=undefined;this.contexts=Object.freeze([]);}
+TimedEvent.prototype={__proto__:tr.model.Event.prototype,get end(){return this.start+this.duration;},get boundsRange(){return tr.b.math.Range.fromExplicitRange(this.start,this.end);},addBoundsToRange(range){range.addValue(this.start);range.addValue(this.end);},bounds(that,opt_precisionUnit){if(opt_precisionUnit===undefined){opt_precisionUnit=tr.b.TimeDisplayModes.ms;}
+const startsBefore=opt_precisionUnit.roundedLess(that.start,this.start);const endsAfter=opt_precisionUnit.roundedLess(this.end,that.end);return!startsBefore&&!endsAfter;}};return{TimedEvent,};});'use strict';tr.exportTo('tr.model',function(){function Alert(info,start,opt_associatedEvents,opt_args){tr.model.TimedEvent.call(this,start);this.info=info;this.args=opt_args||{};this.associatedEvents=new tr.model.EventSet(opt_associatedEvents);this.associatedEvents.forEach(function(event){event.addAssociatedAlert(this);},this);}
+Alert.prototype={__proto__:tr.model.TimedEvent.prototype,get title(){return this.info.title;},get colorId(){return this.info.colorId;},get userFriendlyName(){return'Alert '+this.title+' at '+
+tr.b.Unit.byName.timeStampInMs.format(this.start);}};tr.model.EventRegistry.register(Alert,{name:'alert',pluralName:'alerts'});return{Alert,};});'use strict';tr.exportTo('tr.model',function(){const ColorScheme=tr.b.ColorScheme;const Statistics=tr.b.math.Statistics;const FRAME_PERF_CLASS={GOOD:'good',BAD:'bad',TERRIBLE:'terrible',NEUTRAL:'generic_work'};function Frame(associatedEvents,threadTimeRanges,opt_args){tr.model.Event.call(this);this.threadTimeRanges=threadTimeRanges;this.associatedEvents=new tr.model.EventSet(associatedEvents);this.args=opt_args||{};this.title='Frame';this.start=Statistics.min(threadTimeRanges,function(x){return x.start;});this.end=Statistics.max(threadTimeRanges,function(x){return x.end;});this.totalDuration=Statistics.sum(threadTimeRanges,function(x){return x.end-x.start;});this.perfClass=FRAME_PERF_CLASS.NEUTRAL;}
+Frame.prototype={__proto__:tr.model.Event.prototype,set perfClass(perfClass){this.colorId=ColorScheme.getColorIdForReservedName(perfClass);this.perfClass_=perfClass;},get perfClass(){return this.perfClass_;},shiftTimestampsForward(amount){this.start+=amount;this.end+=amount;for(let i=0;i<this.threadTimeRanges.length;i++){this.threadTimeRanges[i].start+=amount;this.threadTimeRanges[i].end+=amount;}},addBoundsToRange(range){range.addValue(this.start);range.addValue(this.end);}};tr.model.EventRegistry.register(Frame,{name:'frame',pluralName:'frames'});return{Frame,FRAME_PERF_CLASS,};});'use strict';tr.exportTo('tr.model.helpers',function(){const Frame=tr.model.Frame;const Statistics=tr.b.math.Statistics;const UI_DRAW_TYPE={NONE:'none',LEGACY:'legacy',MARSHMALLOW:'marshmallow'};const UI_THREAD_DRAW_NAMES={'performTraversals':UI_DRAW_TYPE.LEGACY,'Choreographer#doFrame':UI_DRAW_TYPE.MARSHMALLOW};const RENDER_THREAD_DRAW_NAME='DrawFrame';const RENDER_THREAD_INDEP_DRAW_NAME='doFrame';const RENDER_THREAD_QUEUE_NAME='queueBuffer';const RENDER_THREAD_SWAP_NAME='eglSwapBuffers';const THREAD_SYNC_NAME='syncFrameState';function getSlicesForThreadTimeRanges(threadTimeRanges){const ret=[];threadTimeRanges.forEach(function(threadTimeRange){const slices=[];threadTimeRange.thread.sliceGroup.iterSlicesInTimeRange(function(slice){slices.push(slice);},threadTimeRange.start,threadTimeRange.end);ret.push.apply(ret,slices);});return ret;}
+function makeFrame(threadTimeRanges,surfaceFlinger){const args={};if(surfaceFlinger&&surfaceFlinger.hasVsyncs){const start=Statistics.min(threadTimeRanges,function(threadTimeRanges){return threadTimeRanges.start;});args.deadline=surfaceFlinger.getFrameDeadline(start);args.frameKickoff=surfaceFlinger.getFrameKickoff(start);}
+const events=getSlicesForThreadTimeRanges(threadTimeRanges);return new Frame(events,threadTimeRanges,args);}
+function findOverlappingDrawFrame(renderThread,uiDrawSlice){if(!renderThread)return undefined;let overlappingDrawFrame;const slices=tr.b.iterateOverIntersectingIntervals(renderThread.sliceGroup.slices,function(range){return range.start;},function(range){return range.end;},uiDrawSlice.start,uiDrawSlice.end,function(rtDrawSlice){if(rtDrawSlice.title===RENDER_THREAD_DRAW_NAME){const rtSyncSlice=rtDrawSlice.findDescendentSlice(THREAD_SYNC_NAME);if(rtSyncSlice&&rtSyncSlice.start>=uiDrawSlice.start&&rtSyncSlice.end<=uiDrawSlice.end){overlappingDrawFrame=rtDrawSlice;}}});return overlappingDrawFrame;}
+function getPreTraversalWorkRanges(uiThread){if(!uiThread)return[];const preFrameEvents=[];uiThread.sliceGroup.slices.forEach(function(slice){if(slice.title==='obtainView'||slice.title==='setupListItem'||slice.title==='deliverInputEvent'||slice.title==='RV Scroll'){preFrameEvents.push(slice);}});uiThread.asyncSliceGroup.slices.forEach(function(slice){if(slice.title==='deliverInputEvent'){preFrameEvents.push(slice);}});return tr.b.math.mergeRanges(tr.b.math.convertEventsToRanges(preFrameEvents),3,function(events){return{start:events[0].min,end:events[events.length-1].max};});}
+function getFrameStartTime(traversalStart,preTraversalWorkRanges){const preTraversalWorkRange=tr.b.findClosestIntervalInSortedIntervals(preTraversalWorkRanges,function(range){return range.start;},function(range){return range.end;},traversalStart,3);if(preTraversalWorkRange){return preTraversalWorkRange.start;}
+return traversalStart;}
+function getRtFrameEndTime(rtDrawSlice){const rtQueueSlice=rtDrawSlice.findDescendentSlice(RENDER_THREAD_QUEUE_NAME);if(rtQueueSlice){return rtQueueSlice.end;}
+const rtSwapSlice=rtDrawSlice.findDescendentSlice(RENDER_THREAD_SWAP_NAME);if(rtSwapSlice){return rtSwapSlice.end;}
+return rtDrawSlice.end;}
+function getUiThreadDrivenFrames(app){if(!app.uiThread)return[];let preTraversalWorkRanges=[];if(app.uiDrawType===UI_DRAW_TYPE.LEGACY){preTraversalWorkRanges=getPreTraversalWorkRanges(app.uiThread);}
+const frames=[];app.uiThread.sliceGroup.slices.forEach(function(slice){if(!(slice.title in UI_THREAD_DRAW_NAMES)){return;}
+const threadTimeRanges=[];const uiThreadTimeRange={thread:app.uiThread,start:getFrameStartTime(slice.start,preTraversalWorkRanges),end:slice.end};threadTimeRanges.push(uiThreadTimeRange);const rtDrawSlice=findOverlappingDrawFrame(app.renderThread,slice);if(rtDrawSlice){const rtSyncSlice=rtDrawSlice.findDescendentSlice(THREAD_SYNC_NAME);if(rtSyncSlice){uiThreadTimeRange.end=Math.min(uiThreadTimeRange.end,rtSyncSlice.start);}
+threadTimeRanges.push({thread:app.renderThread,start:rtDrawSlice.start,end:getRtFrameEndTime(rtDrawSlice)});}
+frames.push(makeFrame(threadTimeRanges,app.surfaceFlinger));});return frames;}
+function getRenderThreadDrivenFrames(app){if(!app.renderThread)return[];const frames=[];app.renderThread.sliceGroup.getSlicesOfName(RENDER_THREAD_INDEP_DRAW_NAME).forEach(function(slice){const threadTimeRanges=[{thread:app.renderThread,start:slice.start,end:slice.end}];frames.push(makeFrame(threadTimeRanges,app.surfaceFlinger));});return frames;}
+function getUiDrawType(uiThread){if(!uiThread){return UI_DRAW_TYPE.NONE;}
+const slices=uiThread.sliceGroup.slices;for(let i=0;i<slices.length;i++){if(slices[i].title in UI_THREAD_DRAW_NAMES){return UI_THREAD_DRAW_NAMES[slices[i].title];}}
+return UI_DRAW_TYPE.NONE;}
+function getInputSamples(process){let samples=undefined;for(const counterName in process.counters){if(/^android\.aq\:pending/.test(counterName)&&process.counters[counterName].numSeries===1){samples=process.counters[counterName].series[0].samples;break;}}
+if(!samples)return[];const inputSamples=[];let lastValue=0;samples.forEach(function(sample){if(sample.value>lastValue){inputSamples.push(sample);}
+lastValue=sample.value;});return inputSamples;}
+function getAnimationAsyncSlices(uiThread){if(!uiThread)return[];const slices=[];for(const slice of uiThread.asyncSliceGroup.getDescendantEvents()){if(/^animator\:/.test(slice.title)){slices.push(slice);}}
+return slices;}
+function AndroidApp(process,uiThread,renderThread,surfaceFlinger,uiDrawType){this.process=process;this.uiThread=uiThread;this.renderThread=renderThread;this.surfaceFlinger=surfaceFlinger;this.uiDrawType=uiDrawType;this.frames_=undefined;this.inputs_=undefined;}
+AndroidApp.createForProcessIfPossible=function(process,surfaceFlinger){let uiThread=process.getThread(process.pid);const uiDrawType=getUiDrawType(uiThread);if(uiDrawType===UI_DRAW_TYPE.NONE){uiThread=undefined;}
+const renderThreads=process.findAllThreadsNamed('RenderThread');const renderThread=(renderThreads.length===1?renderThreads[0]:undefined);if(uiThread||renderThread){return new AndroidApp(process,uiThread,renderThread,surfaceFlinger,uiDrawType);}};AndroidApp.prototype={getFrames(){if(!this.frames_){const uiFrames=getUiThreadDrivenFrames(this);const rtFrames=getRenderThreadDrivenFrames(this);this.frames_=uiFrames.concat(rtFrames);this.frames_.sort(function(a,b){a.end-b.end;});}
+return this.frames_;},getInputSamples(){if(!this.inputs_){this.inputs_=getInputSamples(this.process);}
+return this.inputs_;},getAnimationAsyncSlices(){if(!this.animations_){this.animations_=getAnimationAsyncSlices(this.uiThread);}
+return this.animations_;}};return{AndroidApp,};});'use strict';tr.exportTo('tr.model.helpers',function(){const findLowIndexInSortedArray=tr.b.findLowIndexInSortedArray;const VSYNC_SF_NAME='android.VSYNC-sf';const VSYNC_APP_NAME='android.VSYNC-app';const VSYNC_FALLBACK_NAME='android.VSYNC';const TIMESTAMP_FUDGE_MS=0.01;function getVsyncTimestamps(process,counterName){let vsync=process.counters[counterName];if(!vsync){vsync=process.counters[VSYNC_FALLBACK_NAME];}
+if(vsync&&vsync.numSeries===1&&vsync.numSamples>1){return vsync.series[0].timestamps;}
+return undefined;}
+function AndroidSurfaceFlinger(process,thread){this.process=process;this.thread=thread;this.appVsync_=undefined;this.sfVsync_=undefined;this.appVsyncTimestamps_=getVsyncTimestamps(process,VSYNC_APP_NAME);this.sfVsyncTimestamps_=getVsyncTimestamps(process,VSYNC_SF_NAME);this.deadlineDelayMs_=this.appVsyncTimestamps_!==this.sfVsyncTimestamps_?5:TIMESTAMP_FUDGE_MS;}
+AndroidSurfaceFlinger.createForProcessIfPossible=function(process){const mainThread=process.getThread(process.pid);if(mainThread&&mainThread.name&&/surfaceflinger/.test(mainThread.name)){return new AndroidSurfaceFlinger(process,mainThread);}
+const primaryThreads=process.findAllThreadsNamed('SurfaceFlinger');if(primaryThreads.length===1){return new AndroidSurfaceFlinger(process,primaryThreads[0]);}
+return undefined;};AndroidSurfaceFlinger.prototype={get hasVsyncs(){return!!this.appVsyncTimestamps_&&!!this.sfVsyncTimestamps_;},getFrameKickoff(timestamp){if(!this.hasVsyncs){throw new Error('cannot query vsync info without vsyncs');}
+const firstGreaterIndex=findLowIndexInSortedArray(this.appVsyncTimestamps_,function(x){return x;},timestamp+TIMESTAMP_FUDGE_MS);if(firstGreaterIndex<1)return undefined;return this.appVsyncTimestamps_[firstGreaterIndex-1];},getFrameDeadline(timestamp){if(!this.hasVsyncs){throw new Error('cannot query vsync info without vsyncs');}
+const firstGreaterIndex=findLowIndexInSortedArray(this.sfVsyncTimestamps_,function(x){return x;},timestamp+this.deadlineDelayMs_);if(firstGreaterIndex>=this.sfVsyncTimestamps_.length){return undefined;}
+return this.sfVsyncTimestamps_[firstGreaterIndex];}};return{AndroidSurfaceFlinger,};});'use strict';tr.exportTo('tr.model.helpers',function(){const AndroidApp=tr.model.helpers.AndroidApp;const AndroidSurfaceFlinger=tr.model.helpers.AndroidSurfaceFlinger;const IMPORTANT_SURFACE_FLINGER_SLICES={'doComposition':true,'updateTexImage':true,'postFramebuffer':true};const IMPORTANT_UI_THREAD_SLICES={'Choreographer#doFrame':true,'performTraversals':true,'deliverInputEvent':true};const IMPORTANT_RENDER_THREAD_SLICES={'doFrame':true};function iterateImportantThreadSlices(thread,important,callback){if(!thread)return;thread.sliceGroup.slices.forEach(function(slice){if(slice.title in important){callback(slice);}});}
+function AndroidModelHelper(model){this.model=model;this.apps=[];this.surfaceFlinger=undefined;const processes=model.getAllProcesses();for(let i=0;i<processes.length&&!this.surfaceFlinger;i++){this.surfaceFlinger=AndroidSurfaceFlinger.createForProcessIfPossible(processes[i]);}
+model.getAllProcesses().forEach(function(process){const app=AndroidApp.createForProcessIfPossible(process,this.surfaceFlinger);if(app){this.apps.push(app);}},this);}
+AndroidModelHelper.guid=tr.b.GUID.allocateSimple();AndroidModelHelper.supportsModel=function(model){return true;};AndroidModelHelper.prototype={iterateImportantSlices(callback){if(this.surfaceFlinger){iterateImportantThreadSlices(this.surfaceFlinger.thread,IMPORTANT_SURFACE_FLINGER_SLICES,callback);}
+this.apps.forEach(function(app){iterateImportantThreadSlices(app.uiThread,IMPORTANT_UI_THREAD_SLICES,callback);iterateImportantThreadSlices(app.renderThread,IMPORTANT_RENDER_THREAD_SLICES,callback);});}};return{AndroidModelHelper,};});'use strict';tr.exportTo('tr.model',function(){function Slice(category,title,colorId,start,args,opt_duration,opt_cpuStart,opt_cpuDuration,opt_argsStripped,opt_bindId){if(new.target){throw new Error('Can\'t instantiate pure virtual class Slice');}
+tr.model.TimedEvent.call(this,start);this.category=category||'';this.title=title;this.colorId=colorId;this.args=args;this.startStackFrame=undefined;this.endStackFrame=undefined;this.didNotFinish=false;this.inFlowEvents=[];this.outFlowEvents=[];this.subSlices=[];this.selfTime=undefined;this.cpuSelfTime=undefined;this.important=false;this.parentContainer=undefined;this.argsStripped=false;this.bind_id_=opt_bindId;this.parentSlice=undefined;this.isTopLevel=false;if(opt_duration!==undefined){this.duration=opt_duration;}
+if(opt_cpuStart!==undefined){this.cpuStart=opt_cpuStart;}
+if(opt_cpuDuration!==undefined){this.cpuDuration=opt_cpuDuration;}
+if(opt_argsStripped!==undefined){this.argsStripped=true;}}
+Slice.prototype={__proto__:tr.model.TimedEvent.prototype,get analysisTypeName(){return this.title;},get userFriendlyName(){return'Slice '+this.title+' at '+
+tr.b.Unit.byName.timeStampInMs.format(this.start);},get stableId(){const parentSliceGroup=this.parentContainer.sliceGroup;return parentSliceGroup.stableId+'.'+
+parentSliceGroup.slices.indexOf(this);},get bindId(){return this.bind_id_;},findDescendentSlice(targetTitle){if(!this.subSlices){return undefined;}
+for(let i=0;i<this.subSlices.length;i++){if(this.subSlices[i].title===targetTitle){return this.subSlices[i];}
+const slice=this.subSlices[i].findDescendentSlice(targetTitle);if(slice)return slice;}
+return undefined;},get mostTopLevelSlice(){if(!this.parentSlice)return this;return this.parentSlice.mostTopLevelSlice;},getProcess(){const thread=this.parentContainer;if(thread&&thread.getProcess){return thread.getProcess();}
+return undefined;},get model(){const process=this.getProcess();if(process!==undefined){return this.getProcess().model;}
+return undefined;},*findTopmostSlicesRelativeToThisSlice(eventPredicate){if(eventPredicate(this)){yield this;return;}
+for(const s of this.subSlices){yield*s.findTopmostSlicesRelativeToThisSlice(eventPredicate);}},iterateAllSubsequentSlices(callback,opt_this){const parentStack=[];let started=false;const topmostSlice=this.mostTopLevelSlice;parentStack.push(topmostSlice);while(parentStack.length!==0){const curSlice=parentStack.pop();if(started){callback.call(opt_this,curSlice);}else{started=(curSlice.guid===this.guid);}
+for(let i=curSlice.subSlices.length-1;i>=0;i--){parentStack.push(curSlice.subSlices[i]);}}},get subsequentSlices(){const res=[];this.iterateAllSubsequentSlices(function(subseqSlice){res.push(subseqSlice);});return res;},*enumerateAllAncestors(){let curSlice=this.parentSlice;while(curSlice){yield curSlice;curSlice=curSlice.parentSlice;}},get ancestorSlices(){return Array.from(this.enumerateAllAncestors());},iterateEntireHierarchy(callback,opt_this){const mostTopLevelSlice=this.mostTopLevelSlice;callback.call(opt_this,mostTopLevelSlice);mostTopLevelSlice.iterateAllSubsequentSlices(callback,opt_this);},get entireHierarchy(){const res=[];this.iterateEntireHierarchy(function(slice){res.push(slice);});return res;},get ancestorAndSubsequentSlices(){const res=[];res.push(this);for(const aSlice of this.enumerateAllAncestors()){res.push(aSlice);}
+this.iterateAllSubsequentSlices(function(sSlice){res.push(sSlice);});return res;},*enumerateAllDescendents(){for(const slice of this.subSlices){yield slice;}
+for(const slice of this.subSlices){yield*slice.enumerateAllDescendents();}},get descendentSlices(){const res=[];for(const slice of this.enumerateAllDescendents()){res.push(slice);}
+return res;}};return{Slice,};});'use strict';tr.exportTo('tr.model',function(){const Slice=tr.model.Slice;const SCHEDULING_STATE={DEBUG:'Debug',EXIT_DEAD:'Exit Dead',RUNNABLE:'Runnable',RUNNING:'Running',SLEEPING:'Sleeping',STOPPED:'Stopped',TASK_DEAD:'Task Dead',UNINTR_SLEEP:'Uninterruptible Sleep',UNINTR_SLEEP_WAKE_KILL:'Uninterruptible Sleep | WakeKill',UNINTR_SLEEP_WAKING:'Uninterruptible Sleep | Waking',UNINTR_SLEEP_IO:'Uninterruptible Sleep - Block I/O',UNINTR_SLEEP_WAKE_KILL_IO:'Uninterruptible Sleep | WakeKill - Block I/O',UNINTR_SLEEP_WAKING_IO:'Uninterruptible Sleep | Waking - Block I/O',UNKNOWN:'UNKNOWN',WAKE_KILL:'Wakekill',WAKING:'Waking',ZOMBIE:'Zombie'};function ThreadTimeSlice(thread,schedulingState,cat,start,args,opt_duration){Slice.call(this,cat,schedulingState,this.getColorForState_(schedulingState),start,args,opt_duration);this.thread=thread;this.schedulingState=schedulingState;this.cpuOnWhichThreadWasRunning=undefined;}
+ThreadTimeSlice.prototype={__proto__:Slice.prototype,getColorForState_(state){const getColorIdForReservedName=tr.b.ColorScheme.getColorIdForReservedName;switch(state){case SCHEDULING_STATE.RUNNABLE:return getColorIdForReservedName('thread_state_runnable');case SCHEDULING_STATE.RUNNING:return getColorIdForReservedName('thread_state_running');case SCHEDULING_STATE.SLEEPING:return getColorIdForReservedName('thread_state_sleeping');case SCHEDULING_STATE.DEBUG:case SCHEDULING_STATE.EXIT_DEAD:case SCHEDULING_STATE.STOPPED:case SCHEDULING_STATE.TASK_DEAD:case SCHEDULING_STATE.UNINTR_SLEEP:case SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL:case SCHEDULING_STATE.UNINTR_SLEEP_WAKING:case SCHEDULING_STATE.UNKNOWN:case SCHEDULING_STATE.WAKE_KILL:case SCHEDULING_STATE.WAKING:case SCHEDULING_STATE.ZOMBIE:return getColorIdForReservedName('thread_state_uninterruptible');case SCHEDULING_STATE.UNINTR_SLEEP_IO:case SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL_IO:case SCHEDULING_STATE.UNINTR_SLEEP_WAKING_IO:return getColorIdForReservedName('thread_state_iowait');default:return getColorIdForReservedName('thread_state_unknown');}},get analysisTypeName(){return'tr.ui.analysis.ThreadTimeSlice';},getAssociatedCpuSlice(){if(!this.cpuOnWhichThreadWasRunning)return undefined;const cpuSlices=this.cpuOnWhichThreadWasRunning.slices;for(let i=0;i<cpuSlices.length;i++){const cpuSlice=cpuSlices[i];if(cpuSlice.start!==this.start)continue;if(cpuSlice.duration!==this.duration)continue;return cpuSlice;}
+return undefined;},getCpuSliceThatTookCpu(){if(this.cpuOnWhichThreadWasRunning)return undefined;let curIndex=this.thread.indexOfTimeSlice(this);let cpuSliceWhenLastRunning;while(curIndex>=0){const curSlice=this.thread.timeSlices[curIndex];if(!curSlice.cpuOnWhichThreadWasRunning){curIndex--;continue;}
+cpuSliceWhenLastRunning=curSlice.getAssociatedCpuSlice();break;}
+if(!cpuSliceWhenLastRunning)return undefined;const cpu=cpuSliceWhenLastRunning.cpu;const indexOfSliceOnCpuWhenLastRunning=cpu.indexOf(cpuSliceWhenLastRunning);const nextRunningSlice=cpu.slices[indexOfSliceOnCpuWhenLastRunning+1];if(!nextRunningSlice)return undefined;if(Math.abs(nextRunningSlice.start-cpuSliceWhenLastRunning.end)<0.00001){return nextRunningSlice;}
+return undefined;}};tr.model.EventRegistry.register(ThreadTimeSlice,{name:'threadTimeSlice',pluralName:'threadTimeSlices'});return{ThreadTimeSlice,SCHEDULING_STATE,};});'use strict';tr.exportTo('tr.model',function(){const CompoundEventSelectionState={NOT_SELECTED:0,EVENT_SELECTED:0x1,SOME_ASSOCIATED_EVENTS_SELECTED:0x2,ALL_ASSOCIATED_EVENTS_SELECTED:0x4,EVENT_AND_SOME_ASSOCIATED_SELECTED:0x1|0x2,EVENT_AND_ALL_ASSOCIATED_SELECTED:0x1|0x4};return{CompoundEventSelectionState,};});'use strict';tr.exportTo('tr.model.um',function(){const CompoundEventSelectionState=tr.model.CompoundEventSelectionState;function UserExpectation(parentModel,initiatorType,start,duration){tr.model.TimedEvent.call(this,start);this.associatedEvents=new tr.model.EventSet();this.duration=duration;this.initiatorType_=initiatorType;this.parentModel=parentModel;this.typeInfo_=undefined;this.sourceEvents=new tr.model.EventSet();}
+const INITIATOR_TYPE={KEYBOARD:'Keyboard',MOUSE:'Mouse',MOUSE_WHEEL:'MouseWheel',TAP:'Tap',PINCH:'Pinch',FLING:'Fling',TOUCH:'Touch',SCROLL:'Scroll',CSS:'CSS',WEBGL:'WebGL',VIDEO:'Video',VR:'VR',};UserExpectation.prototype={__proto__:tr.model.TimedEvent.prototype,computeCompoundEvenSelectionState(selection){let cess=CompoundEventSelectionState.NOT_SELECTED;if(selection.contains(this)){cess|=CompoundEventSelectionState.EVENT_SELECTED;}
+if(this.associatedEvents.intersectionIsEmpty(selection)){return cess;}
+const allContained=this.associatedEvents.every(function(event){return selection.contains(event);});if(allContained){cess|=CompoundEventSelectionState.ALL_ASSOCIATED_EVENTS_SELECTED;}else{cess|=CompoundEventSelectionState.SOME_ASSOCIATED_EVENTS_SELECTED;}
+return cess;},get associatedSamples(){const samples=new tr.model.EventSet();this.associatedEvents.forEach(function(event){if(event instanceof tr.model.ThreadSlice){samples.addEventSet(event.overlappingSamples);}});return samples;},get userFriendlyName(){return this.title+' User Expectation at '+
+tr.b.Unit.byName.timeStampInMs.format(this.start);},get stableId(){return('UserExpectation.'+this.guid);},get typeInfo(){if(!this.typeInfo_){this.typeInfo_=UserExpectation.subTypes.findTypeInfo(this.constructor);}
+if(!this.typeInfo_){throw new Error('Unregistered UserExpectation');}
+return this.typeInfo_;},get colorId(){return this.typeInfo.metadata.colorId;},get stageTitle(){return this.typeInfo.metadata.stageTitle;},get initiatorType(){return this.initiatorType_;},get title(){if(!this.initiatorType){return this.stageTitle;}
+return this.initiatorType+' '+this.stageTitle;},get totalCpuMs(){let cpuMs=0;this.associatedEvents.forEach(function(event){if(event.cpuSelfTime){cpuMs+=event.cpuSelfTime;}});return cpuMs;}};const subTypes={};const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(subTypes,options);subTypes.addEventListener('will-register',function(e){const metadata=e.typeInfo.metadata;if(metadata.stageTitle===undefined){throw new Error('Registered UserExpectations must provide '+'stageTitle');}
+if(metadata.colorId===undefined){throw new Error('Registered UserExpectations must provide '+'colorId');}});tr.model.EventRegistry.register(UserExpectation,{name:'userExpectation',pluralName:'userExpectations',subTypes});return{UserExpectation,INITIATOR_TYPE,};});'use strict';tr.exportTo('tr.model.um',function(){function ResponseExpectation(parentModel,initiatorTitle,start,duration,opt_isAnimationBegin){tr.model.um.UserExpectation.call(this,parentModel,initiatorTitle,start,duration);this.isAnimationBegin=opt_isAnimationBegin||false;}
+ResponseExpectation.prototype={__proto__:tr.model.um.UserExpectation.prototype,constructor:ResponseExpectation};tr.model.um.UserExpectation.subTypes.register(ResponseExpectation,{stageTitle:'Response',colorId:tr.b.ColorScheme.getColorIdForReservedName('rail_response')});return{ResponseExpectation,};});'use strict';tr.exportTo('tr.e.audits',function(){const SCHEDULING_STATE=tr.model.SCHEDULING_STATE;const Auditor=tr.c.Auditor;const AndroidModelHelper=tr.model.helpers.AndroidModelHelper;const ColorScheme=tr.b.ColorScheme;const Statistics=tr.b.math.Statistics;const FRAME_PERF_CLASS=tr.model.FRAME_PERF_CLASS;const Alert=tr.model.Alert;const EventInfo=tr.model.EventInfo;const Scalar=tr.b.Scalar;const timeDurationInMs=tr.b.Unit.byName.timeDurationInMs;const EXPECTED_FRAME_TIME_MS=16.67;function getStart(e){return e.start;}
+function getDuration(e){return e.duration;}
+function getCpuDuration(e){return(e.cpuDuration!==undefined)?e.cpuDuration:e.duration;}
+function frameIsActivityStart(frame){return frame.associatedEvents.any(x=>x.title==='activityStart');}
+function frameMissedDeadline(frame){return frame.args.deadline&&frame.args.deadline<frame.end;}
+function DocLinkBuilder(){this.docLinks=[];}
+DocLinkBuilder.prototype={addAppVideo(name,videoId){this.docLinks.push({label:'Video Link',textContent:('Android Performance Patterns: '+name),href:'https://www.youtube.com/watch?list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE&v='+videoId});return this;},addDacRef(name,link){this.docLinks.push({label:'Doc Link',textContent:(name+' documentation'),href:'https://developer.android.com/reference/'+link});return this;},build(){return this.docLinks;}};function AndroidAuditor(model){Auditor.call(this,model);const helper=model.getOrCreateHelper(AndroidModelHelper);if(helper.apps.length||helper.surfaceFlinger){this.helper=helper;}}
+AndroidAuditor.viewAlphaAlertInfo_=new EventInfo('Inefficient View alpha usage','Setting an alpha between 0 and 1 has significant performance costs, if one of the fast alpha paths is not used.',new DocLinkBuilder().addAppVideo('Hidden Cost of Transparency','wIy8g8yNhNk').addDacRef('View#setAlpha()','android/view/View.html#setAlpha(float)').build());AndroidAuditor.saveLayerAlertInfo_=new EventInfo('Expensive rendering with Canvas#saveLayer()','Canvas#saveLayer() incurs extremely high rendering cost. They disrupt the rendering pipeline when drawn, forcing a flush of drawing content. Instead use View hardware layers, or static Bitmaps. This enables the offscreen buffers to be reused in between frames, and avoids the disruptive render target switch.',new DocLinkBuilder().addAppVideo('Hidden Cost of Transparency','wIy8g8yNhNk').addDacRef('Canvas#saveLayerAlpha()','android/graphics/Canvas.html#saveLayerAlpha(android.graphics.RectF, int, int)').build());AndroidAuditor.getSaveLayerAlerts_=function(frame){const badAlphaRegEx=/^(.+) alpha caused (unclipped )?saveLayer (\d+)x(\d+)$/;const saveLayerRegEx=/^(unclipped )?saveLayer (\d+)x(\d+)$/;const ret=[];const events=[];frame.associatedEvents.forEach(function(slice){const match=badAlphaRegEx.exec(slice.title);if(match){const args={'view name':match[1],'width':parseInt(match[3]),'height':parseInt(match[4])};ret.push(new Alert(AndroidAuditor.viewAlphaAlertInfo_,slice.start,[slice],args));}else if(saveLayerRegEx.test(slice.title)){events.push(slice);}},this);if(events.length>ret.length){const unclippedSeen=Statistics.sum(events,function(slice){return saveLayerRegEx.exec(slice.title)[1]?1:0;});const clippedSeen=events.length-unclippedSeen;const earliestStart=Statistics.min(events,function(slice){return slice.start;});const args={'Unclipped saveLayer count (especially bad!)':unclippedSeen,'Clipped saveLayer count':clippedSeen};events.push(frame);ret.push(new Alert(AndroidAuditor.saveLayerAlertInfo_,earliestStart,events,args));}
+return ret;};AndroidAuditor.pathAlertInfo_=new EventInfo('Path texture churn','Paths are drawn with a mask texture, so when a path is modified / newly drawn, that texture must be generated and uploaded to the GPU. Ensure that you cache paths between frames and do not unnecessarily call Path#reset(). You can cut down on this cost by sharing Path object instances between drawables/views.');AndroidAuditor.getPathAlert_=function(frame){const uploadRegEx=/^Generate Path Texture$/;const events=frame.associatedEvents.filter(function(event){return event.title==='Generate Path Texture';});const start=Statistics.min(events,getStart);const duration=Statistics.sum(events,getDuration);if(duration<3)return undefined;events.push(frame);return new Alert(AndroidAuditor.pathAlertInfo_,start,events,{'Time spent':new Scalar(timeDurationInMs,duration)});};AndroidAuditor.uploadAlertInfo_=new EventInfo('Expensive Bitmap uploads','Bitmaps that have been modified / newly drawn must be uploaded to the GPU. Since this is expensive if the total number of pixels uploaded is large, reduce the amount of Bitmap churn in this animation/context, per frame.');AndroidAuditor.getUploadAlert_=function(frame){const uploadRegEx=/^Upload (\d+)x(\d+) Texture$/;const events=[];let start=Number.POSITIVE_INFINITY;let duration=0;let pixelsUploaded=0;frame.associatedEvents.forEach(function(event){const match=uploadRegEx.exec(event.title);if(match){events.push(event);start=Math.min(start,event.start);duration+=event.duration;pixelsUploaded+=parseInt(match[1])*parseInt(match[2]);}});if(events.length===0||duration<3)return undefined;const mPixels=(pixelsUploaded/1000000).toFixed(2)+' million';const args={'Pixels uploaded':mPixels,'Time spent':new Scalar(timeDurationInMs,duration)};events.push(frame);return new Alert(AndroidAuditor.uploadAlertInfo_,start,events,args);};AndroidAuditor.ListViewInflateAlertInfo_=new EventInfo('Inflation during ListView recycling','ListView item recycling involved inflating views. Ensure your Adapter#getView() recycles the incoming View, instead of constructing a new one.');AndroidAuditor.ListViewBindAlertInfo_=new EventInfo('Inefficient ListView recycling/rebinding','ListView recycling taking too much time per frame. Ensure your Adapter#getView() binds data efficiently.');AndroidAuditor.getListViewAlert_=function(frame){const events=frame.associatedEvents.filter(function(event){return event.title==='obtainView'||event.title==='setupListItem';});const duration=Statistics.sum(events,getCpuDuration);if(events.length===0||duration<3)return undefined;let hasInflation=false;for(const event of events){if(event.findDescendentSlice('inflate')){hasInflation=true;}}
+const start=Statistics.min(events,getStart);const args={'Time spent':new Scalar(timeDurationInMs,duration)};args['ListView items '+(hasInflation?'inflated':'rebound')]=events.length/2;const eventInfo=hasInflation?AndroidAuditor.ListViewInflateAlertInfo_:AndroidAuditor.ListViewBindAlertInfo_;events.push(frame);return new Alert(eventInfo,start,events,args);};AndroidAuditor.measureLayoutAlertInfo_=new EventInfo('Expensive measure/layout pass','Measure/Layout took a significant time, contributing to jank. Avoid triggering layout during animations.',new DocLinkBuilder().addAppVideo('Invalidations, Layouts, and Performance','we6poP0kw6E').build());AndroidAuditor.getMeasureLayoutAlert_=function(frame){const events=frame.associatedEvents.filter(function(event){return event.title==='measure'||event.title==='layout';});const duration=Statistics.sum(events,getCpuDuration);if(events.length===0||duration<3)return undefined;const start=Statistics.min(events,getStart);events.push(frame);return new Alert(AndroidAuditor.measureLayoutAlertInfo_,start,events,{'Time spent':new Scalar(timeDurationInMs,duration)});};AndroidAuditor.viewDrawAlertInfo_=new EventInfo('Long View#draw()','Recording the drawing commands of invalidated Views took a long time. Avoid significant work in View or Drawable custom drawing, especially allocations or drawing to Bitmaps.',new DocLinkBuilder().addAppVideo('Invalidations, Layouts, and Performance','we6poP0kw6E').addAppVideo('Avoiding Allocations in onDraw()','HAK5acHQ53E').build());AndroidAuditor.getViewDrawAlert_=function(frame){let slice=undefined;for(const event of frame.associatedEvents){if(event.title==='getDisplayList'||event.title==='Record View#draw()'){slice=event;break;}}
+if(!slice||getCpuDuration(slice)<3)return undefined;return new Alert(AndroidAuditor.viewDrawAlertInfo_,slice.start,[slice,frame],{'Time spent':new Scalar(timeDurationInMs,getCpuDuration(slice))});};AndroidAuditor.blockingGcAlertInfo_=new EventInfo('Blocking Garbage Collection','Blocking GCs are caused by object churn, and made worse by having large numbers of objects in the heap. Avoid allocating objects during animations/scrolling, and recycle Bitmaps to avoid triggering garbage collection.',new DocLinkBuilder().addAppVideo('Garbage Collection in Android','pzfzz50W5Uo').addAppVideo('Avoiding Allocations in onDraw()','HAK5acHQ53E').build());AndroidAuditor.getBlockingGcAlert_=function(frame){const events=frame.associatedEvents.filter(function(event){return event.title==='DVM Suspend'||event.title==='GC: Wait For Concurrent';});const blockedDuration=Statistics.sum(events,getDuration);if(blockedDuration<3)return undefined;const start=Statistics.min(events,getStart);events.push(frame);return new Alert(AndroidAuditor.blockingGcAlertInfo_,start,events,{'Blocked duration':new Scalar(timeDurationInMs,blockedDuration)});};AndroidAuditor.lockContentionAlertInfo_=new EventInfo('Lock contention','UI thread lock contention is caused when another thread holds a lock that the UI thread is trying to use. UI thread progress is blocked until the lock is released. Inspect locking done within the UI thread, and ensure critical sections are short.');AndroidAuditor.getLockContentionAlert_=function(frame){const events=frame.associatedEvents.filter(function(event){return/^Lock Contention on /.test(event.title);});const blockedDuration=Statistics.sum(events,getDuration);if(blockedDuration<1)return undefined;const start=Statistics.min(events,getStart);events.push(frame);return new Alert(AndroidAuditor.lockContentionAlertInfo_,start,events,{'Blocked duration':new Scalar(timeDurationInMs,blockedDuration)});};AndroidAuditor.schedulingAlertInfo_=new EventInfo('Scheduling delay','Work to produce this frame was descheduled for several milliseconds, contributing to jank. Ensure that code on the UI thread doesn\'t block on work being done on other threads, and that background threads (doing e.g. network or bitmap loading) are running at android.os.Process#THREAD_PRIORITY_BACKGROUND or lower so they are less likely to interrupt the UI thread. These background threads should show up with a priority number of 130 or higher in the scheduling section under the Kernel process.');AndroidAuditor.getSchedulingAlert_=function(frame){let totalDuration=0;const totalStats={};for(const ttr of frame.threadTimeRanges){const stats=ttr.thread.getSchedulingStatsForRange(ttr.start,ttr.end);for(const[key,value]of Object.entries(stats)){if(!(key in totalStats)){totalStats[key]=0;}
+totalStats[key]+=value;totalDuration+=value;}}
+if(!(SCHEDULING_STATE.RUNNING in totalStats)||totalDuration===0||totalDuration-totalStats[SCHEDULING_STATE.RUNNING]<3){return;}
+const args={};for(const[key,value]of Object.entries(totalStats)){let newKey=key;if(key===SCHEDULING_STATE.RUNNABLE){newKey='Not scheduled, but runnable';}else if(key===SCHEDULING_STATE.UNINTR_SLEEP){newKey='Blocking I/O delay';}
+args[newKey]=new Scalar(timeDurationInMs,value);}
+return new Alert(AndroidAuditor.schedulingAlertInfo_,frame.start,[frame],args);};AndroidAuditor.prototype={__proto__:Auditor.prototype,renameAndSort_(){this.model.kernel.important=false;this.model.getAllProcesses().forEach(function(process){if(this.helper.surfaceFlinger&&process===this.helper.surfaceFlinger.process){if(!process.name){process.name='SurfaceFlinger';}
+process.sortIndex=Number.NEGATIVE_INFINITY;process.important=false;return;}
+const uiThread=process.getThread(process.pid);if(!process.name&&uiThread&&uiThread.name){if(/^ndroid\./.test(uiThread.name)){uiThread.name='a'+uiThread.name;}
+process.name=uiThread.name;uiThread.name='UI Thread';}
+process.sortIndex=0;for(const tid in process.threads){process.sortIndex-=process.threads[tid].sliceGroup.slices.length;}},this);this.model.getAllThreads().forEach(function(thread){if(thread.tid===thread.parent.pid){thread.sortIndex=-3;}
+if(thread.name==='RenderThread'){thread.sortIndex=-2;}
+if(/^hwuiTask/.test(thread.name)){thread.sortIndex=-1;}});},pushFramesAndJudgeJank_(){let badFramesObserved=0;let framesObserved=0;const surfaceFlinger=this.helper.surfaceFlinger;this.helper.apps.forEach(function(app){app.process.frames=app.getFrames();app.process.frames.forEach(function(frame){if(frame.totalDuration>EXPECTED_FRAME_TIME_MS*2){badFramesObserved+=2;frame.perfClass=FRAME_PERF_CLASS.TERRIBLE;}else if(frame.totalDuration>EXPECTED_FRAME_TIME_MS||frameMissedDeadline(frame)){badFramesObserved++;frame.perfClass=FRAME_PERF_CLASS.BAD;}else{frame.perfClass=FRAME_PERF_CLASS.GOOD;}});framesObserved+=app.process.frames.length;});if(framesObserved){const portionBad=badFramesObserved/framesObserved;if(portionBad>0.3){this.model.faviconHue='red';}else if(portionBad>0.05){this.model.faviconHue='yellow';}else{this.model.faviconHue='green';}}},pushEventInfo_(){const appAnnotator=new AppAnnotator();this.helper.apps.forEach(function(app){if(app.uiThread){appAnnotator.applyEventInfos(app.uiThread.sliceGroup);}
+if(app.renderThread){appAnnotator.applyEventInfos(app.renderThread.sliceGroup);}});},runAnnotate(){if(!this.helper)return;this.renameAndSort_();this.pushFramesAndJudgeJank_();this.pushEventInfo_();this.helper.iterateImportantSlices(function(slice){slice.important=true;});},runAudit(){if(!this.helper)return;const alerts=this.model.alerts;this.helper.apps.forEach(function(app){app.getFrames().forEach(function(frame){alerts.push.apply(alerts,AndroidAuditor.getSaveLayerAlerts_(frame));if(frame.perfClass===FRAME_PERF_CLASS.NEUTRAL||frame.perfClass===FRAME_PERF_CLASS.GOOD){return;}
+let alert=AndroidAuditor.getPathAlert_(frame);if(alert)alerts.push(alert);alert=AndroidAuditor.getUploadAlert_(frame);if(alert)alerts.push(alert);alert=AndroidAuditor.getListViewAlert_(frame);if(alert)alerts.push(alert);alert=AndroidAuditor.getMeasureLayoutAlert_(frame);if(alert)alerts.push(alert);alert=AndroidAuditor.getViewDrawAlert_(frame);if(alert)alerts.push(alert);alert=AndroidAuditor.getBlockingGcAlert_(frame);if(alert)alerts.push(alert);alert=AndroidAuditor.getLockContentionAlert_(frame);if(alert)alerts.push(alert);alert=AndroidAuditor.getSchedulingAlert_(frame);if(alert)alerts.push(alert);});},this);this.addRenderingInteractionRecords();this.addInputInteractionRecords();},addRenderingInteractionRecords(){const events=[];this.helper.apps.forEach(function(app){events.push.apply(events,app.getAnimationAsyncSlices());events.push.apply(events,app.getFrames());});const mergerFunction=function(events){const ir=new tr.model.um.ResponseExpectation(this.model,'Rendering',events[0].min,events[events.length-1].max-events[0].min);this.model.userModel.expectations.push(ir);}.bind(this);tr.b.math.mergeRanges(tr.b.math.convertEventsToRanges(events),30,mergerFunction);},addInputInteractionRecords(){const inputSamples=[];this.helper.apps.forEach(function(app){inputSamples.push.apply(inputSamples,app.getInputSamples());});const mergerFunction=function(events){const ir=new tr.model.um.ResponseExpectation(this.model,'Input',events[0].min,events[events.length-1].max-events[0].min);this.model.userModel.expectations.push(ir);}.bind(this);const inputRanges=inputSamples.map(function(sample){return tr.b.math.Range.fromExplicitRange(sample.timestamp,sample.timestamp);});tr.b.math.mergeRanges(inputRanges,30,mergerFunction);}};Auditor.register(AndroidAuditor);function AppAnnotator(){this.titleInfoLookup=new Map();this.titleParentLookup=new Map();this.build_();}
+AppAnnotator.prototype={build_(){const registerEventInfo=function(dict){this.titleInfoLookup.set(dict.title,new EventInfo(dict.title,dict.description,dict.docLinks));if(dict.parents){this.titleParentLookup.set(dict.title,dict.parents);}}.bind(this);registerEventInfo({title:'inflate',description:'Constructing a View hierarchy from pre-processed XML via LayoutInflater#layout. This includes constructing all of the View objects in the hierarchy, and applying styled attributes.'});registerEventInfo({title:'obtainView',description:'Adapter#getView() called to bind content to a recycled View that is being presented.'});registerEventInfo({title:'setupListItem',description:'Attached a newly-bound, recycled View to its parent ListView.'});registerEventInfo({title:'setupGridItem',description:'Attached a newly-bound, recycled View to its parent GridView.'});const choreographerLinks=new DocLinkBuilder().addDacRef('Choreographer','android/view/Choreographer.html').build();registerEventInfo({title:'Choreographer#doFrame',docLinks:choreographerLinks,description:'Choreographer executes frame callbacks for inputs, animations, and rendering traversals. When this work is done, a frame will be presented to the user.'});registerEventInfo({title:'input',parents:['Choreographer#doFrame'],docLinks:choreographerLinks,description:'Input callbacks are processed. This generally encompasses dispatching input to Views, as well as any work the Views do to process this input/gesture.'});registerEventInfo({title:'animation',parents:['Choreographer#doFrame'],docLinks:choreographerLinks,description:'Animation callbacks are processed. This is generally minimal work, as animations determine progress for the frame, and push new state to animated objects (such as setting View properties).'});registerEventInfo({title:'traversals',parents:['Choreographer#doFrame'],docLinks:choreographerLinks,description:'Primary draw traversals. This is the primary traversal of the View hierarchy, including layout and draw passes.'});const traversalParents=['Choreographer#doFrame','performTraversals'];const layoutLinks=new DocLinkBuilder().addDacRef('View#Layout','android/view/View.html#Layout').build();registerEventInfo({title:'performTraversals',description:'A drawing traversal of the View hierarchy, comprised of all layout and drawing needed to produce the frame.'});registerEventInfo({title:'measure',parents:traversalParents,docLinks:layoutLinks,description:'First of two phases in view hierarchy layout. Views are asked to size themselves according to constraints supplied by their parent. Some ViewGroups may measure a child more than once to help satisfy their own constraints. Nesting ViewGroups that measure children more than once can lead to excessive and repeated work.'});registerEventInfo({title:'layout',parents:traversalParents,docLinks:layoutLinks,description:'Second of two phases in view hierarchy layout, repositioning content and child Views into their new locations.'});const drawString='Draw pass over the View hierarchy. Every invalidated View will have its drawing commands recorded. On Android versions prior to Lollipop, this would also include the issuing of draw commands to the GPU. Starting with Lollipop, it only includes the recording of commands, and syncing that information to the RenderThread.';registerEventInfo({title:'draw',parents:traversalParents,description:drawString});const recordString='Every invalidated View\'s drawing commands are recorded. Each will have View#draw() called, and is passed a Canvas that will record and store its drawing commands until it is next invalidated/rerecorded.';registerEventInfo({title:'getDisplayList',parents:['draw'],description:recordString});registerEventInfo({title:'Record View#draw()',parents:['draw'],description:recordString});registerEventInfo({title:'drawDisplayList',parents:['draw'],description:'Execution of recorded draw commands to generate a frame. This represents the actual formation and issuing of drawing commands to the GPU. On Android L and higher devices, this work is done on a dedicated RenderThread, instead of on the UI Thread.'});registerEventInfo({title:'DrawFrame',description:'RenderThread portion of the standard UI/RenderThread split frame. This represents the actual formation and issuing of drawing commands to the GPU.'});registerEventInfo({title:'doFrame',description:'RenderThread animation frame. Represents drawing work done by the RenderThread on a frame where the UI thread did not produce new drawing content.'});registerEventInfo({title:'syncFrameState',description:'Sync stage between the UI thread and the RenderThread, where the UI thread hands off a frame (including information about modified Views). Time in this method primarily consists of uploading modified Bitmaps to the GPU. After this sync is completed, the UI thread is unblocked, and the RenderThread starts to render the frame.'});registerEventInfo({title:'flush drawing commands',description:'Issuing the now complete drawing commands to the GPU.'});registerEventInfo({title:'eglSwapBuffers',description:'Complete GPU rendering of the frame.'});registerEventInfo({title:'RV Scroll',description:'RecyclerView is calculating a scroll. If there are too many of these in Systrace, some Views inside RecyclerView might be causing it. Try to avoid using EditText, focusable views or handle them with care.'});registerEventInfo({title:'RV OnLayout',description:'OnLayout has been called by the View system. If this shows up too many times in Systrace, make sure the children of RecyclerView do not update themselves directly. This will cause a full re-layout but when it happens via the Adapter notifyItemChanged, RecyclerView can avoid full layout calculation.'});registerEventInfo({title:'RV FullInvalidate',description:'NotifyDataSetChanged or equal has been called. If this is taking a long time, try sending granular notify adapter changes instead of just calling notifyDataSetChanged or setAdapter / swapAdapter. Adding stable ids to your adapter might help.'});registerEventInfo({title:'RV PartialInvalidate',description:'RecyclerView is rebinding a View. If this is taking a lot of time, consider optimizing your layout or make sure you are not doing extra operations in onBindViewHolder call.'});registerEventInfo({title:'RV OnBindView',description:'RecyclerView is rebinding a View. If this is taking a lot of time, consider optimizing your layout or make sure you are not doing extra operations in onBindViewHolder call.'});registerEventInfo({title:'RV CreateView',description:'RecyclerView is creating a new View. If too many of these are present: 1) There might be a problem in Recycling (e.g. custom Animations that set transient state and prevent recycling or ItemAnimator not implementing the contract properly. See Adapter#onFailedToRecycleView(ViewHolder). 2) There may be too many item view types. Try merging them. 3) There might be too many itemChange animations and not enough space in RecyclerPool. Try increasing your pool size and item cache size.'});registerEventInfo({title:'eglSwapBuffers',description:'The CPU has finished producing drawing commands, and is flushing drawing work to the GPU, and posting that buffer to the consumer (which is often SurfaceFlinger window composition). Once this is completed, the GPU can produce the frame content without any involvement from the CPU.'});},applyEventInfosRecursive_(parentNames,slice){const checkExpectedParentNames=function(expectedParentNames){if(!expectedParentNames)return true;return expectedParentNames.some(function(name){return parentNames.has(name);});};if(this.titleInfoLookup.has(slice.title)){if(checkExpectedParentNames(this.titleParentLookup.get(slice.title))){slice.info=this.titleInfoLookup.get(slice.title);}}
+if(slice.subSlices.length>0){if(!parentNames.has(slice.title)){parentNames.set(slice.title,0);}
+parentNames.set(slice.title,parentNames.get(slice.title)+1);slice.subSlices.forEach(function(subSlice){this.applyEventInfosRecursive_(parentNames,subSlice);},this);parentNames.set(slice.title,parentNames.get(slice.title)-1);if(parentNames.get(slice.title)===0){delete parentNames[slice.title];}}},applyEventInfos(sliceGroup){sliceGroup.topLevelSlices.forEach(function(slice){this.applyEventInfosRecursive_(new Map(),slice);},this);}};return{AndroidAuditor,};});'use strict';tr.exportTo('tr.model',function(){function ObjectSnapshot(objectInstance,ts,args){tr.model.Event.call(this);this.objectInstance=objectInstance;this.ts=ts;this.args=args;}
+ObjectSnapshot.prototype={__proto__:tr.model.Event.prototype,preInitialize(){},initialize(){},referencedAt(item,object,field){},addBoundsToRange(range){range.addValue(this.ts);},get userFriendlyName(){return'Snapshot of '+this.objectInstance.userFriendlyName+' @ '+
+tr.b.Unit.byName.timeStampInMs.format(this.ts);}};tr.model.EventRegistry.register(ObjectSnapshot,{name:'objectSnapshot',pluralName:'objectSnapshots'});return{ObjectSnapshot,};});'use strict';tr.exportTo('tr.model',function(){const ObjectSnapshot=tr.model.ObjectSnapshot;function ObjectInstance(parent,scopedId,category,name,creationTs,opt_baseTypeName){tr.model.Event.call(this);this.parent=parent;this.scopedId=scopedId;this.category=category;this.baseTypeName=opt_baseTypeName?opt_baseTypeName:name;this.name=name;this.creationTs=creationTs;this.creationTsWasExplicit=false;this.deletionTs=Number.MAX_VALUE;this.deletionTsWasExplicit=false;this.colorId=0;this.bounds=new tr.b.math.Range();this.snapshots=[];this.hasImplicitSnapshots=false;}
+ObjectInstance.prototype={__proto__:tr.model.Event.prototype,get typeName(){return this.name;},addBoundsToRange(range){range.addRange(this.bounds);},addSnapshot(ts,args,opt_name,opt_baseTypeName){if(ts<this.creationTs){throw new Error('Snapshots must be >= instance.creationTs');}
+if(ts>=this.deletionTs){throw new Error('Snapshots cannot be added after '+'an objects deletion timestamp.');}
+let lastSnapshot;if(this.snapshots.length>0){lastSnapshot=this.snapshots[this.snapshots.length-1];if(lastSnapshot.ts===ts){throw new Error('Snapshots already exists at this time!');}
+if(ts<lastSnapshot.ts){throw new Error('Snapshots must be added in increasing timestamp order');}}
+if(opt_name&&(this.name!==opt_name)){if(!opt_baseTypeName){throw new Error('Must provide base type name for name update');}
+if(this.baseTypeName!==opt_baseTypeName){throw new Error('Cannot update type name: base types dont match');}
+this.name=opt_name;}
+const snapshotConstructor=tr.model.ObjectSnapshot.subTypes.getConstructor(this.category,this.name);const snapshot=new snapshotConstructor(this,ts,args);this.snapshots.push(snapshot);return snapshot;},wasDeleted(ts){let lastSnapshot;if(this.snapshots.length>0){lastSnapshot=this.snapshots[this.snapshots.length-1];if(lastSnapshot.ts>ts){throw new Error('Instance cannot be deleted at ts='+
+ts+'. A snapshot exists that is older.');}}
+this.deletionTs=ts;this.deletionTsWasExplicit=true;},preInitialize(){for(let i=0;i<this.snapshots.length;i++){this.snapshots[i].preInitialize();}},initialize(){for(let i=0;i<this.snapshots.length;i++){this.snapshots[i].initialize();}},isAliveAt(ts){if(ts<this.creationTs&&this.creationTsWasExplicit){return false;}
+if(ts>this.deletionTs){return false;}
+return true;},getSnapshotAt(ts){if(ts<this.creationTs){if(this.creationTsWasExplicit){throw new Error('ts must be within lifetime of this instance');}
+return this.snapshots[0];}
+if(ts>this.deletionTs){throw new Error('ts must be within lifetime of this instance');}
+const snapshots=this.snapshots;const i=tr.b.findIndexInSortedIntervals(snapshots,function(snapshot){return snapshot.ts;},function(snapshot,i){if(i===snapshots.length-1){return snapshots[i].objectInstance.deletionTs;}
+return snapshots[i+1].ts-snapshots[i].ts;},ts);if(i<0){return this.snapshots[0];}
+if(i>=this.snapshots.length){return this.snapshots[this.snapshots.length-1];}
+return this.snapshots[i];},updateBounds(){this.bounds.reset();this.bounds.addValue(this.creationTs);if(this.deletionTs!==Number.MAX_VALUE){this.bounds.addValue(this.deletionTs);}else if(this.snapshots.length>0){this.bounds.addValue(this.snapshots[this.snapshots.length-1].ts);}},shiftTimestampsForward(amount){this.creationTs+=amount;if(this.deletionTs!==Number.MAX_VALUE){this.deletionTs+=amount;}
+this.snapshots.forEach(function(snapshot){snapshot.ts+=amount;});},get userFriendlyName(){return this.typeName+' object '+this.scopedId;}};tr.model.EventRegistry.register(ObjectInstance,{name:'objectInstance',pluralName:'objectInstances'});return{ObjectInstance,};});'use strict';tr.exportTo('tr.e.chrome',function(){const ObjectSnapshot=tr.model.ObjectSnapshot;const ObjectInstance=tr.model.ObjectInstance;function BlameContextSnapshot(){ObjectSnapshot.apply(this,arguments);}
+BlameContextSnapshot.prototype={__proto__:ObjectSnapshot.prototype,get parentContext(){if(this.args.parent instanceof BlameContextSnapshot){return this.args.parent;}
+return undefined;},get userFriendlyName(){return'BlameContext';}};function BlameContextInstance(){ObjectInstance.apply(this,arguments);}
+BlameContextInstance.prototype={__proto__:ObjectInstance.prototype,get blameContextType(){throw new Error('Not implemented');}};return{BlameContextSnapshot,BlameContextInstance,};});'use strict';tr.exportTo('tr.e.chrome',function(){const BlameContextSnapshot=tr.e.chrome.BlameContextSnapshot;const BlameContextInstance=tr.e.chrome.BlameContextInstance;function FrameTreeNodeSnapshot(){BlameContextSnapshot.apply(this,arguments);}
+FrameTreeNodeSnapshot.prototype={__proto__:BlameContextSnapshot.prototype,get renderFrame(){if(this.args.renderFrame instanceof tr.e.chrome.RenderFrameSnapshot){return this.args.renderFrame;}
+return undefined;},get url(){return this.args.url;},get userFriendlyName(){return'FrameTreeNode';}};tr.model.ObjectSnapshot.subTypes.register(FrameTreeNodeSnapshot,{typeName:'FrameTreeNode'});function FrameTreeNodeInstance(){BlameContextInstance.apply(this,arguments);}
+FrameTreeNodeInstance.prototype={__proto__:BlameContextInstance.prototype,get blameContextType(){return'Frame';}};tr.model.ObjectInstance.subTypes.register(FrameTreeNodeInstance,{typeName:'FrameTreeNode'});return{FrameTreeNodeSnapshot,FrameTreeNodeInstance,};});'use strict';tr.exportTo('tr.e.chrome',function(){const BlameContextSnapshot=tr.e.chrome.BlameContextSnapshot;const BlameContextInstance=tr.e.chrome.BlameContextInstance;function RenderFrameSnapshot(){BlameContextSnapshot.apply(this,arguments);}
+RenderFrameSnapshot.prototype={__proto__:BlameContextSnapshot.prototype,referencedAt(item,object,field){if(item instanceof tr.e.chrome.FrameTreeNodeSnapshot&&object===item.args&&field==='renderFrame'){this.args.frameTreeNode=item;}},get frameTreeNode(){if(this.args.frameTreeNode instanceof
+tr.e.chrome.FrameTreeNodeSnapshot){return this.args.frameTreeNode;}
+return undefined;},get url(){if(this.frameTreeNode){return this.frameTreeNode.url;}
+return undefined;},get userFriendlyName(){return'RenderFrame';}};tr.model.ObjectSnapshot.subTypes.register(RenderFrameSnapshot,{typeName:'RenderFrame'});function RenderFrameInstance(){BlameContextInstance.apply(this,arguments);}
+RenderFrameInstance.prototype={__proto__:BlameContextInstance.prototype,get blameContextType(){return'Frame';}};tr.model.ObjectInstance.subTypes.register(RenderFrameInstance,{typeName:'RenderFrame'});return{RenderFrameSnapshot,RenderFrameInstance,};});'use strict';tr.exportTo('tr.e.chrome',function(){const BlameContextSnapshot=tr.e.chrome.BlameContextSnapshot;const BlameContextInstance=tr.e.chrome.BlameContextInstance;function TopLevelSnapshot(){BlameContextSnapshot.apply(this,arguments);}
+TopLevelSnapshot.prototype={__proto__:BlameContextSnapshot.prototype,get userFriendlyName(){return'TopLevel';}};tr.model.ObjectSnapshot.subTypes.register(TopLevelSnapshot,{typeName:'TopLevel'});function TopLevelInstance(){BlameContextInstance.apply(this,arguments);}
+TopLevelInstance.prototype={__proto__:BlameContextInstance.prototype,get blameContextType(){return'TopLevel';}};tr.model.ObjectInstance.subTypes.register(TopLevelInstance,{typeName:'TopLevel'});return{TopLevelSnapshot,TopLevelInstance,};});'use strict';tr.exportTo('tr.model',function(){function AsyncSlice(category,title,colorId,start,args,duration,opt_isTopLevel,opt_cpuStart,opt_cpuDuration,opt_argsStripped){tr.model.TimedEvent.call(this,start);this.category=category||'';this.originalTitle=title;this.title=title;this.colorId=colorId;this.args=args;this.startStackFrame=undefined;this.endStackFrame=undefined;this.didNotFinish=false;this.important=false;this.subSlices=[];this.parentContainer_=undefined;this.id=undefined;this.startThread=undefined;this.endThread=undefined;this.cpuStart=undefined;this.cpuDuration=undefined;this.argsStripped=false;this.startStackFrame=undefined;this.endStackFrame=undefined;this.duration=duration;this.isTopLevel=(opt_isTopLevel===true);if(opt_cpuStart!==undefined){this.cpuStart=opt_cpuStart;}
+if(opt_cpuDuration!==undefined){this.cpuDuration=opt_cpuDuration;}
+if(opt_argsStripped!==undefined){this.argsStripped=opt_argsStripped;}}
+AsyncSlice.prototype={__proto__:tr.model.TimedEvent.prototype,get analysisTypeName(){return this.title;},get parentContainer(){return this.parentContainer_;},set parentContainer(parentContainer){this.parentContainer_=parentContainer;for(let i=0;i<this.subSlices.length;i++){const subSlice=this.subSlices[i];if(subSlice.parentContainer===undefined){subSlice.parentContainer=parentContainer;}}},get viewSubGroupTitle(){return this.title;},get viewSubGroupGroupingKey(){return undefined;},get userFriendlyName(){return'Async slice '+this.title+' at '+
+tr.b.Unit.byName.timeStampInMs.format(this.start);},get stableId(){const parentAsyncSliceGroup=this.parentContainer.asyncSliceGroup;return parentAsyncSliceGroup.stableId+'.'+
+parentAsyncSliceGroup.slices.indexOf(this);},*findTopmostSlicesRelativeToThisSlice(eventPredicate,opt_this){if(eventPredicate(this)){yield this;return;}
+for(const s of this.subSlices){yield*s.findTopmostSlicesRelativeToThisSlice(eventPredicate);}},findDescendentSlice(targetTitle){if(!this.subSlices)return undefined;for(let i=0;i<this.subSlices.length;i++){if(this.subSlices[i].title===targetTitle){return this.subSlices[i];}
+const slice=this.subSlices[i].findDescendentSlice(targetTitle);if(slice)return slice;}
+return undefined;},*enumerateAllDescendents(){for(const slice of this.subSlices){yield slice;}
+for(const slice of this.subSlices){if(slice.enumerateAllDescendents!==undefined){yield*slice.enumerateAllDescendents();}}},compareTo(that){return this.title.localeCompare(that.title);}};tr.model.EventRegistry.register(AsyncSlice,{name:'asyncSlice',pluralName:'asyncSlices'});return{AsyncSlice,};});'use strict';tr.exportTo('tr.e.blink',function(){class BlinkSchedulerAsyncSlice extends tr.model.AsyncSlice{get viewSubGroupGroupingKey(){if(this.title.startsWith('FrameScheduler.')){return'Frame'+this.id;}
+if(this.title.startsWith('Scheduler.')){return'Renderer Scheduler';}
+return undefined;}
+get viewSubGroupTitle(){if(this.title.startsWith('FrameScheduler.')){return this.title.substring(15);}
+if(this.title.startsWith('Scheduler.')){return this.title.substring(10);}
+return this.title;}}
+tr.model.AsyncSlice.subTypes.register(BlinkSchedulerAsyncSlice,{categoryParts:['renderer.scheduler','disabled-by-default-renderer.scheduler','disabled-by-default-renderer.scheduler.debug',]});return{BlinkSchedulerAsyncSlice,};});'use strict';tr.exportTo('tr.model.helpers',function(){const MAIN_FRAMETIME_TYPE='main_frametime_type';const IMPL_FRAMETIME_TYPE='impl_frametime_type';const MAIN_RENDERING_STATS='BenchmarkInstrumentation::MainThreadRenderingStats';const IMPL_RENDERING_STATS='BenchmarkInstrumentation::ImplThreadRenderingStats';function getSlicesIntersectingRange(rangeOfInterest,slices){const slicesInFilterRange=[];for(let i=0;i<slices.length;i++){const slice=slices[i];if(rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end)){slicesInFilterRange.push(slice);}}
+return slicesInFilterRange;}
+function ChromeProcessHelper(modelHelper,process){this.modelHelper=modelHelper;this.process=process;this.telemetryInternalRanges_=undefined;}
+ChromeProcessHelper.prototype={get pid(){return this.process.pid;},isTelemetryInternalEvent(slice){if(this.telemetryInternalRanges_===undefined){this.findTelemetryInternalRanges_();}
+for(const range of this.telemetryInternalRanges_){if(range.containsExplicitRangeInclusive(slice.start,slice.end)){return true;}}
+return false;},findTelemetryInternalRanges_(){this.telemetryInternalRanges_=[];let start=0;for(const thread of Object.values(this.process.threads)){for(const slice of thread.asyncSliceGroup.getDescendantEvents()){if(/^telemetry\.internal\..*\.start$/.test(slice.title)){start=slice.start;}else if(/^telemetry\.internal\..*\.end$/.test(slice.title)&&start!==undefined){this.telemetryInternalRanges_.push(tr.b.math.Range.fromExplicitRange(start,slice.end));start=undefined;}}}},getFrameEventsInRange(frametimeType,range){const titleToGet=(frametimeType===MAIN_FRAMETIME_TYPE?MAIN_RENDERING_STATS:IMPL_RENDERING_STATS);const frameEvents=[];for(const event of this.process.getDescendantEvents()){if(event.title===titleToGet){if(range.intersectsExplicitRangeInclusive(event.start,event.end)){frameEvents.push(event);}}}
+frameEvents.sort(function(a,b){return a.start-b.start;});return frameEvents;}};function getFrametimeDataFromEvents(frameEvents){const frametimeData=[];for(let i=1;i<frameEvents.length;i++){const diff=frameEvents[i].start-frameEvents[i-1].start;frametimeData.push({'x':frameEvents[i].start,'frametime':diff});}
+return frametimeData;}
+return{ChromeProcessHelper,MAIN_FRAMETIME_TYPE,IMPL_FRAMETIME_TYPE,MAIN_RENDERING_STATS,IMPL_RENDERING_STATS,getSlicesIntersectingRange,getFrametimeDataFromEvents,};});'use strict';tr.exportTo('tr.model.helpers',function(){function ChromeBrowserHelper(modelHelper,process){tr.model.helpers.ChromeProcessHelper.call(this,modelHelper,process);this.mainThread_=process.findAtMostOneThreadNamed('CrBrowserMain');if(!process.name){process.name=ChromeBrowserHelper.PROCESS_NAME;}}
+ChromeBrowserHelper.PROCESS_NAME='Browser';ChromeBrowserHelper.isBrowserProcess=function(process){return!!process.findAtMostOneThreadNamed('CrBrowserMain');};ChromeBrowserHelper.prototype={__proto__:tr.model.helpers.ChromeProcessHelper.prototype,get browserName(){const hasInProcessRendererThread=this.process.findAllThreadsNamed('Chrome_InProcRendererThread').length>0;return hasInProcessRendererThread?'webview':'chrome';},get mainThread(){return this.mainThread_;},get rendererHelpers(){return this.modelHelper.rendererHelpers;},getLoadingEventsInRange(rangeOfInterest){return this.getAllAsyncSlicesMatching(function(slice){return slice.title.indexOf('WebContentsImpl Loading')===0&&rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end);});},getCommitProvisionalLoadEventsInRange(rangeOfInterest){return this.getAllAsyncSlicesMatching(function(slice){return slice.title==='RenderFrameImpl::didCommitProvisionalLoad'&&rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end);});},get hasLatencyEvents(){let hasLatency=false;for(const thread of this.modelHelper.model.getAllThreads()){for(const event of thread.getDescendantEvents()){if(!event.isTopLevel)continue;if(!(event instanceof tr.e.cc.InputLatencyAsyncSlice)){continue;}
+hasLatency=true;}}
+return hasLatency;},getLatencyEventsInRange(rangeOfInterest){return this.getAllAsyncSlicesMatching(function(slice){return(slice.title.indexOf('InputLatency')===0)&&rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end);});},getAllAsyncSlicesMatching(pred,opt_this){const events=[];this.iterAllThreads(function(thread){for(const slice of thread.getDescendantEvents()){if(pred.call(opt_this,slice)){events.push(slice);}}});return events;},iterAllThreads(func,opt_this){for(const thread of Object.values(this.process.threads)){func.call(opt_this,thread);}
+for(const rendererHelper of Object.values(this.rendererHelpers)){const rendererProcess=rendererHelper.process;for(const thread of Object.values(rendererProcess.threads)){func.call(opt_this,thread);}}}};return{ChromeBrowserHelper,};});'use strict';tr.exportTo('tr.model.helpers',function(){function ChromeGpuHelper(modelHelper,process){tr.model.helpers.ChromeProcessHelper.call(this,modelHelper,process);if(!process.name){process.name=ChromeGpuHelper.PROCESS_NAME;}}
+ChromeGpuHelper.PROCESS_NAME='GPU Process';ChromeGpuHelper.isGpuProcess=function(process){if(process.findAtMostOneThreadNamed('CrBrowserMain')||process.findAtMostOneThreadNamed('CrRendererMain')){return false;}
+return process.findAllThreadsNamed('CrGpuMain').length>0;};ChromeGpuHelper.prototype={__proto__:tr.model.helpers.ChromeProcessHelper.prototype};return{ChromeGpuHelper,};});'use strict';tr.exportTo('tr.model.helpers',function(){const NET_CATEGORIES=new Set(['net','netlog','disabled-by-default-netlog','disabled-by-default-network']);class ChromeThreadHelper{constructor(thread){this.thread=thread;}
+getNetworkEvents(){const networkEvents=[];for(const slice of this.thread.asyncSliceGroup.slices){const categories=tr.b.getCategoryParts(slice.category);const isNetEvent=category=>NET_CATEGORIES.has(category);if(categories.filter(isNetEvent).length===0)continue;networkEvents.push(slice);}
+return networkEvents;}}
+return{ChromeThreadHelper,};});'use strict';tr.exportTo('tr.model.helpers',function(){const ChromeThreadHelper=tr.model.helpers.ChromeThreadHelper;function ChromeRendererHelper(modelHelper,process){tr.model.helpers.ChromeProcessHelper.call(this,modelHelper,process);this.mainThread_=process.findAtMostOneThreadNamed('CrRendererMain')||process.findAtMostOneThreadNamed('Chrome_InProcRendererThread');this.compositorThread_=process.findAtMostOneThreadNamed('Compositor');this.rasterWorkerThreads_=process.findAllThreadsMatching(function(t){if(t.name===undefined)return false;if(t.name.startsWith('CompositorTileWorker'))return true;if(t.name.startsWith('CompositorRasterWorker'))return true;return false;});this.dedicatedWorkerThreads_=process.findAllThreadsMatching(function(t){return t.name&&t.name.startsWith('DedicatedWorker');});this.foregroundWorkerThreads_=process.findAllThreadsMatching(function(t){return t.name&&t.name.startsWith('ThreadPoolForegroundWorker');});if(!process.name){process.name=ChromeRendererHelper.PROCESS_NAME;}}
+ChromeRendererHelper.PROCESS_NAME='Renderer';ChromeRendererHelper.isRenderProcess=function(process){if(process.findAtMostOneThreadNamed('CrRendererMain'))return true;if(process.findAtMostOneThreadNamed('Compositor'))return true;return false;};ChromeRendererHelper.isTracingProcess=function(process){return process.labels!==undefined&&process.labels.length===1&&process.labels[0]==='chrome://tracing';};ChromeRendererHelper.prototype={__proto__:tr.model.helpers.ChromeProcessHelper.prototype,get mainThread(){return this.mainThread_;},get compositorThread(){return this.compositorThread_;},get rasterWorkerThreads(){return this.rasterWorkerThreads_;},get dedicatedWorkerThreads(){return this.dedicatedWorkerThreads_;},get foregroundWorkerThreads(){return this.foregroundWorkerThreads_;},get isChromeTracingUI(){return ChromeRendererHelper.isTracingProcess(this.process);},};return{ChromeRendererHelper,};});'use strict';tr.exportTo('tr.model.um',function(){class Segment extends tr.model.TimedEvent{constructor(start,duration){super(start);this.duration=duration;this.expectations_=[];}
+get expectations(){return this.expectations_;}
+clone(){const clone=new Segment(this.start,this.duration);clone.expectations.push(...this.expectations);return clone;}
+addSegment(other){this.duration+=other.duration;this.expectations.push(...other.expectations);}}
+return{Segment,};});'use strict';tr.exportTo('tr.model.helpers',function(){const GESTURE_EVENT='SyntheticGestureController::running';const IR_REG_EXP=/Interaction\.([^/]+)(\/[^/]*)?$/;const ChromeRendererHelper=tr.model.helpers.ChromeRendererHelper;class TelemetryHelper{constructor(modelHelper){this.modelHelper=modelHelper;this.renderersWithIR_=undefined;this.irSegments_=undefined;this.uiSegments_=undefined;this.animationSegments_=undefined;}
+get renderersWithIR(){this.findIRs_();return this.renderersWithIR_;}
+get irSegments(){this.findIRs_();return this.irSegments_;}
+get uiSegments(){this.findIRs_();return this.uiSegments_;}
+get animationSegments(){if(this.animationSegments_===undefined){const model=this.modelHelper.model;this.animationSegments_=model.userModel.segments.filter(segment=>segment.expectations.find(ue=>ue instanceof tr.model.um.AnimationExpectation));this.animationSegments_.sort((x,y)=>x.start-y.start);}
+return this.animationSegments_;}
+findIRs_(){if(this.irSegments_!==undefined)return;this.renderersWithIR_=[];const gestureEvents=[];const interactionRecords=[];const processes=Object.values(this.modelHelper.rendererHelpers).concat(this.modelHelper.browserHelpers).map(processHelper=>processHelper.process);for(const process of processes){let foundIR=false;for(const thread of Object.values(process.threads)){for(const slice of thread.asyncSliceGroup.slices){if(slice.title===GESTURE_EVENT){gestureEvents.push(slice);}else if(IR_REG_EXP.test(slice.title)){interactionRecords.push(slice);foundIR=true;}}}
+if(foundIR&&ChromeRendererHelper.isRenderProcess(process)&&!ChromeRendererHelper.isTracingProcess(process)){this.renderersWithIR_.push(new ChromeRendererHelper(this.modelHelper,process));}}
+this.irSegments_=[];this.uiSegments_=[];for(const ir of interactionRecords){const parts=IR_REG_EXP.exec(ir.title);let gestureEventFound=false;if(parts[1].startsWith('Gesture_')){for(const gestureEvent of gestureEvents){if(ir.boundsRange.intersectsRangeInclusive(gestureEvent.boundsRange)){this.irSegments_.push(new tr.model.um.Segment(gestureEvent.start,gestureEvent.duration));gestureEventFound=true;break;}}}else if(parts[1].startsWith('ui_')){this.uiSegments_.push(new tr.model.um.Segment(ir.start,ir.duration));}
+if(!gestureEventFound){this.irSegments_.push(new tr.model.um.Segment(ir.start,ir.duration));}}
+this.irSegments_.sort((x,y)=>x.start-y.start);this.uiSegments_.sort((x,y)=>x.start-y.start);}}
+return{TelemetryHelper,};});'use strict';tr.exportTo('tr.model.helpers',function(){function findChromeBrowserProcesses(model){return model.getAllProcesses(tr.model.helpers.ChromeBrowserHelper.isBrowserProcess);}
+function findChromeRenderProcesses(model){return model.getAllProcesses(tr.model.helpers.ChromeRendererHelper.isRenderProcess);}
+function findChromeGpuProcess(model){const gpuProcesses=model.getAllProcesses(tr.model.helpers.ChromeGpuHelper.isGpuProcess);if(gpuProcesses.length!==1)return undefined;return gpuProcesses[0];}
+function findTelemetrySurfaceFlingerProcess(model){const surfaceFlingerProcesses=model.getAllProcesses(process=>(process.name==='SurfaceFlinger'));if(surfaceFlingerProcesses.length!==1)return undefined;return surfaceFlingerProcesses[0];}
+function ChromeModelHelper(model){this.model_=model;const browserProcesses=findChromeBrowserProcesses(model);this.browserHelpers_=browserProcesses.map(p=>new tr.model.helpers.ChromeBrowserHelper(this,p));const gpuProcess=findChromeGpuProcess(model);if(gpuProcess){this.gpuHelper_=new tr.model.helpers.ChromeGpuHelper(this,gpuProcess);}else{this.gpuHelper_=undefined;}
+const rendererProcesses_=findChromeRenderProcesses(model);this.rendererHelpers_={};rendererProcesses_.forEach(function(renderProcess){const rendererHelper=new tr.model.helpers.ChromeRendererHelper(this,renderProcess);this.rendererHelpers_[rendererHelper.pid]=rendererHelper;},this);this.surfaceFlingerProcess_=findTelemetrySurfaceFlingerProcess(model);this.chromeBounds_=undefined;this.telemetryHelper_=new tr.model.helpers.TelemetryHelper(this);}
+ChromeModelHelper.guid=tr.b.GUID.allocateSimple();ChromeModelHelper.supportsModel=function(model){if(findChromeBrowserProcesses(model).length)return true;if(findChromeRenderProcesses(model).length)return true;return false;};ChromeModelHelper.prototype={get pid(){throw new Error('woah');},get process(){throw new Error('woah');},get model(){return this.model_;},get browserProcess(){if(this.browserHelper===undefined)return undefined;return this.browserHelper.process;},get browserHelper(){return this.browserHelpers_[0];},get browserHelpers(){return this.browserHelpers_;},get gpuHelper(){return this.gpuHelper_;},get rendererHelpers(){return this.rendererHelpers_;},get surfaceFlingerProcess(){return this.surfaceFlingerProcess_;},get chromeBounds(){if(!this.chromeBounds_){this.chromeBounds_=new tr.b.math.Range();for(const browserHelper of Object.values(this.browserHelpers)){this.chromeBounds_.addRange(browserHelper.process.bounds);}
+for(const rendererHelper of Object.values(this.rendererHelpers)){this.chromeBounds_.addRange(rendererHelper.process.bounds);}
+if(this.gpuHelper){this.chromeBounds_.addRange(this.gpuHelper.process.bounds);}}
+if(this.chromeBounds_.isEmpty){return undefined;}
+return this.chromeBounds_;},get telemetryHelper(){return this.telemetryHelper_;}};return{ChromeModelHelper,};});'use strict';tr.exportTo('tr.e.cc',function(){const AsyncSlice=tr.model.AsyncSlice;const EventSet=tr.model.EventSet;const UI_COMP_NAME='INPUT_EVENT_LATENCY_UI_COMPONENT';const ORIGINAL_COMP_NAME='INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT';const BEGIN_COMP_NAME='INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT';const END_COMP_NAME='INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT';const LEGACY_END_COMP_NAME='INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT';const MAIN_RENDERER_THREAD_NAME='CrRendererMain';const COMPOSITOR_THREAD_NAME='Compositor';const POSTTASK_FLOW_EVENT='disabled-by-default-toplevel.flow';const IPC_FLOW_EVENT='disabled-by-default-ipc.flow';const INPUT_EVENT_TYPE_NAMES={CHAR:'Char',CLICK:'GestureClick',CONTEXT_MENU:'ContextMenu',FLING_CANCEL:'GestureFlingCancel',FLING_START:'GestureFlingStart',KEY_DOWN:'KeyDown',KEY_DOWN_RAW:'RawKeyDown',KEY_UP:'KeyUp',LATENCY_SCROLL_UPDATE:'ScrollUpdate',MOUSE_DOWN:'MouseDown',MOUSE_ENTER:'MouseEnter',MOUSE_LEAVE:'MouseLeave',MOUSE_MOVE:'MouseMove',MOUSE_UP:'MouseUp',MOUSE_WHEEL:'MouseWheel',PINCH_BEGIN:'GesturePinchBegin',PINCH_END:'GesturePinchEnd',PINCH_UPDATE:'GesturePinchUpdate',SCROLL_BEGIN:'GestureScrollBegin',SCROLL_END:'GestureScrollEnd',SCROLL_UPDATE:'GestureScrollUpdate',SCROLL_UPDATE_RENDERER:'ScrollUpdate',SHOW_PRESS:'GestureShowPress',TAP:'GestureTap',TAP_CANCEL:'GestureTapCancel',TAP_DOWN:'GestureTapDown',TOUCH_CANCEL:'TouchCancel',TOUCH_END:'TouchEnd',TOUCH_MOVE:'TouchMove',TOUCH_START:'TouchStart',UNKNOWN:'UNKNOWN'};function InputLatencyAsyncSlice(){AsyncSlice.apply(this,arguments);this.associatedEvents_=new EventSet();this.typeName_=undefined;if(!this.isLegacyEvent){this.determineModernTypeName_();}}
+InputLatencyAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get isLegacyEvent(){return this.title==='InputLatency';},get typeName(){if(!this.typeName_){this.determineLegacyTypeName_();}
+return this.typeName_;},checkTypeName_(){if(!this.typeName_){throw new Error('Unable to determine typeName');}
+let found=false;for(const typeName in INPUT_EVENT_TYPE_NAMES){if(this.typeName===INPUT_EVENT_TYPE_NAMES[typeName]){found=true;break;}}
+if(!found){this.typeName_=INPUT_EVENT_TYPE_NAMES.UNKNOWN;}},determineModernTypeName_(){const lastColonIndex=this.title.lastIndexOf(':');if(lastColonIndex<0)return;const characterAfterLastColonIndex=lastColonIndex+1;this.typeName_=this.title.slice(characterAfterLastColonIndex);this.checkTypeName_();},determineLegacyTypeName_(){for(const subSlice of this.enumerateAllDescendents()){const subSliceIsAInputLatencyAsyncSlice=(subSlice instanceof InputLatencyAsyncSlice);if(!subSliceIsAInputLatencyAsyncSlice)continue;if(!subSlice.typeName)continue;if(this.typeName_&&subSlice.typeName_){const subSliceHasDifferentTypeName=(this.typeName_!==subSlice.typeName_);if(subSliceHasDifferentTypeName){throw new Error('InputLatencyAsyncSlice.determineLegacyTypeName_() '+' found multiple typeNames');}}
+this.typeName_=subSlice.typeName_;}
+if(!this.typeName_){throw new Error('InputLatencyAsyncSlice.determineLegacyTypeName_() failed');}
+this.checkTypeName_();},getRendererHelper(sourceSlices){const traceModel=this.startThread.parent.model;const modelHelper=traceModel.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(!modelHelper)return undefined;let mainThread=undefined;let compositorThread=undefined;for(const i in sourceSlices){if(sourceSlices[i].parentContainer.name===MAIN_RENDERER_THREAD_NAME){mainThread=sourceSlices[i].parentContainer;}else if(sourceSlices[i].parentContainer.name===COMPOSITOR_THREAD_NAME){compositorThread=sourceSlices[i].parentContainer;}
+if(mainThread&&compositorThread)break;}
+const rendererHelpers=modelHelper.rendererHelpers;const pids=Object.keys(rendererHelpers);for(let i=0;i<pids.length;i++){const pid=pids[i];const rendererHelper=rendererHelpers[pid];if(rendererHelper.mainThread===mainThread||rendererHelper.compositorThread===compositorThread){return rendererHelper;}}
+return undefined;},addEntireSliceHierarchy(slice){this.associatedEvents_.push(slice);slice.iterateAllSubsequentSlices(function(subsequentSlice){this.associatedEvents_.push(subsequentSlice);},this);},addDirectlyAssociatedEvents(flowEvents){const slices=[];flowEvents.forEach(function(flowEvent){this.associatedEvents_.push(flowEvent);const newSource=flowEvent.startSlice.mostTopLevelSlice;if(slices.indexOf(newSource)===-1){slices.push(newSource);}},this);const lastFlowEvent=flowEvents[flowEvents.length-1];const lastSource=lastFlowEvent.endSlice.mostTopLevelSlice;if(slices.indexOf(lastSource)===-1){slices.push(lastSource);}
+return slices;},addScrollUpdateEvents(rendererHelper){if(!rendererHelper||!rendererHelper.compositorThread){return;}
+const compositorThread=rendererHelper.compositorThread;const gestureScrollUpdateStart=this.start;const gestureScrollUpdateEnd=this.end;const allCompositorAsyncSlices=compositorThread.asyncSliceGroup.slices;for(const i in allCompositorAsyncSlices){const slice=allCompositorAsyncSlices[i];if(slice.title!=='Latency::ScrollUpdate')continue;const parentId=slice.args.data.INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT.sequence_number;if(parentId===undefined){if(slice.start<gestureScrollUpdateStart||slice.start>=gestureScrollUpdateEnd){continue;}}else{if(parseInt(parentId)!==parseInt(this.id)){continue;}}
+slice.associatedEvents.forEach(function(event){this.associatedEvents_.push(event);},this);break;}},belongToOtherInputs(slice,flowEvents){let fromOtherInputs=false;slice.iterateEntireHierarchy(function(subsequentSlice){if(fromOtherInputs)return;subsequentSlice.inFlowEvents.forEach(function(inflow){if(fromOtherInputs)return;if(inflow.category.indexOf('input')>-1){if(flowEvents.indexOf(inflow)===-1){fromOtherInputs=true;}}},this);},this);return fromOtherInputs;},triggerOtherInputs(event,flowEvents){if(event.outFlowEvents===undefined||event.outFlowEvents.length===0){return false;}
+const flow=event.outFlowEvents[0];if(flow.category!==POSTTASK_FLOW_EVENT||!flow.endSlice){return false;}
+const endSlice=flow.endSlice;if(this.belongToOtherInputs(endSlice.mostTopLevelSlice,flowEvents)){return true;}
+return false;},followSubsequentSlices(event,queue,visited,flowEvents){let stopFollowing=false;let inputAck=false;event.iterateAllSubsequentSlices(function(slice){if(stopFollowing)return;if(slice.title==='TaskQueueManager::RunTask')return;if(slice.title==='ThreadProxy::ScheduledActionSendBeginMainFrame'){return;}
+if(slice.title==='Scheduler::ScheduleBeginImplFrameDeadline'){if(this.triggerOtherInputs(slice,flowEvents))return;}
+if(slice.title==='CompositorImpl::PostComposite'){if(this.triggerOtherInputs(slice,flowEvents))return;}
+if(slice.title==='InputRouterImpl::ProcessInputEventAck'){inputAck=true;}
+if(inputAck&&slice.title==='InputRouterImpl::FilterAndSendWebInputEvent'){stopFollowing=true;}
+this.followCurrentSlice(slice,queue,visited);},this);},followCurrentSlice(event,queue,visited){event.outFlowEvents.forEach(function(outflow){if((outflow.category===POSTTASK_FLOW_EVENT||outflow.category===IPC_FLOW_EVENT)&&outflow.endSlice){this.associatedEvents_.push(outflow);const nextEvent=outflow.endSlice.mostTopLevelSlice;if(!visited.contains(nextEvent)){visited.push(nextEvent);queue.push(nextEvent);}}},this);},backtraceFromDraw(beginImplFrame,visited){const pendingEventQueue=[];pendingEventQueue.push(beginImplFrame.mostTopLevelSlice);while(pendingEventQueue.length!==0){const event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);event.inFlowEvents.forEach(function(inflow){if(inflow.category===POSTTASK_FLOW_EVENT&&inflow.startSlice){const nextEvent=inflow.startSlice.mostTopLevelSlice;if(!visited.contains(nextEvent)){visited.push(nextEvent);pendingEventQueue.push(nextEvent);}}},this);}},sortRasterizerSlices(rasterWorkerThreads,sortedRasterizerSlices){rasterWorkerThreads.forEach(function(rasterizer){Array.prototype.push.apply(sortedRasterizerSlices,rasterizer.sliceGroup.slices);},this);sortedRasterizerSlices.sort(function(a,b){if(a.start!==b.start){return a.start-b.start;}
+return a.guid-b.guid;});},addRasterizationEvents(prepareTiles,rendererHelper,visited,flowEvents,sortedRasterizerSlices){if(!prepareTiles.args.prepare_tiles_id)return;if(!rendererHelper||!rendererHelper.rasterWorkerThreads){return;}
+const rasterWorkerThreads=rendererHelper.rasterWorkerThreads;const prepareTileId=prepareTiles.args.prepare_tiles_id;const pendingEventQueue=[];if(sortedRasterizerSlices.length===0){this.sortRasterizerSlices(rasterWorkerThreads,sortedRasterizerSlices);}
+let numFinishedTasks=0;const RASTER_TASK_TITLE='RasterizerTaskImpl::RunOnWorkerThread';const IMAGEDECODE_TASK_TITLE='ImageDecodeTaskImpl::RunOnWorkerThread';const FINISHED_TASK_TITLE='TaskSetFinishedTaskImpl::RunOnWorkerThread';for(let i=0;i<sortedRasterizerSlices.length;i++){const task=sortedRasterizerSlices[i];if(task.title===RASTER_TASK_TITLE||task.title===IMAGEDECODE_TASK_TITLE){if(task.args.source_prepare_tiles_id===prepareTileId){this.addEntireSliceHierarchy(task.mostTopLevelSlice);}}else if(task.title===FINISHED_TASK_TITLE){if(task.start>prepareTiles.start){pendingEventQueue.push(task.mostTopLevelSlice);if(++numFinishedTasks===3)break;}}}
+while(pendingEventQueue.length!==0){const event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);this.followSubsequentSlices(event,pendingEventQueue,visited,flowEvents);}},addOtherCausallyRelatedEvents(rendererHelper,sourceSlices,flowEvents,sortedRasterizerSlices){const pendingEventQueue=[];const visitedEvents=new EventSet();let beginImplFrame=undefined;let prepareTiles=undefined;sortedRasterizerSlices=[];sourceSlices.forEach(function(sourceSlice){if(!visitedEvents.contains(sourceSlice)){visitedEvents.push(sourceSlice);pendingEventQueue.push(sourceSlice);}},this);while(pendingEventQueue.length!==0){const event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);this.followCurrentSlice(event,pendingEventQueue,visitedEvents);this.followSubsequentSlices(event,pendingEventQueue,visitedEvents,flowEvents);const COMPOSITOR_PREPARE_TILES='TileManager::PrepareTiles';prepareTiles=event.findDescendentSlice(COMPOSITOR_PREPARE_TILES);if(prepareTiles){this.addRasterizationEvents(prepareTiles,rendererHelper,visitedEvents,flowEvents,sortedRasterizerSlices);}
+const COMPOSITOR_ON_BIFD='Scheduler::OnBeginImplFrameDeadline';beginImplFrame=event.findDescendentSlice(COMPOSITOR_ON_BIFD);if(beginImplFrame){this.backtraceFromDraw(beginImplFrame,visitedEvents);}}
+const INPUT_GSU='InputLatency::GestureScrollUpdate';if(this.title===INPUT_GSU){this.addScrollUpdateEvents(rendererHelper);}},get associatedEvents(){if(this.associatedEvents_.length!==0){return this.associatedEvents_;}
+const modelIndices=this.startThread.parent.model.modelIndices;const flowEvents=modelIndices.getFlowEventsWithId(this.id);if(flowEvents.length===0){return this.associatedEvents_;}
+const sourceSlices=this.addDirectlyAssociatedEvents(flowEvents);const rendererHelper=this.getRendererHelper(sourceSlices);this.addOtherCausallyRelatedEvents(rendererHelper,sourceSlices,flowEvents);return this.associatedEvents_;},get inputLatency(){if(!('data'in this.args))return undefined;const data=this.args.data;const endTimeComp=data[END_COMP_NAME]||data[LEGACY_END_COMP_NAME];if(endTimeComp===undefined)return undefined;let latency=0;const endTime=endTimeComp.time;if(ORIGINAL_COMP_NAME in data){latency=endTime-data[ORIGINAL_COMP_NAME].time;}else if(UI_COMP_NAME in data){latency=endTime-data[UI_COMP_NAME].time;}else if(BEGIN_COMP_NAME in data){latency=endTime-data[BEGIN_COMP_NAME].time;}else{throw new Error('No valid begin latency component');}
+return latency;}};const eventTypeNames=['Char','ContextMenu','GestureClick','GestureFlingCancel','GestureFlingStart','GestureScrollBegin','GestureScrollEnd','GestureScrollUpdate','GestureShowPress','GestureTap','GestureTapCancel','GestureTapDown','GesturePinchBegin','GesturePinchEnd','GesturePinchUpdate','KeyDown','KeyUp','MouseDown','MouseEnter','MouseLeave','MouseMove','MouseUp','MouseWheel','RawKeyDown','ScrollUpdate','TouchCancel','TouchEnd','TouchMove','TouchStart'];const allTypeNames=['InputLatency'];eventTypeNames.forEach(function(eventTypeName){allTypeNames.push('InputLatency:'+eventTypeName);allTypeNames.push('InputLatency::'+eventTypeName);});AsyncSlice.subTypes.register(InputLatencyAsyncSlice,{typeNames:allTypeNames,categoryParts:['latencyInfo']});return{InputLatencyAsyncSlice,INPUT_EVENT_TYPE_NAMES,};});'use strict';tr.exportTo('tr.e.chrome',function(){const SAME_AS_PARENT='same-as-parent';const TITLES_FOR_USER_FRIENDLY_CATEGORY={composite:['CompositingInputsUpdater::update','ThreadProxy::SetNeedsUpdateLayers','LayerTreeHost::DoUpdateLayers','LayerTreeHost::UpdateLayers::BuildPropertyTrees','LocalFrameView::pushPaintArtifactToCompositor','LocalFrameView::updateCompositedSelectionIfNeeded','LocalFrameView::RunCompositingLifecyclePhase','UpdateLayerTree',],gc:['minorGC','majorGC','MajorGC','MinorGC','V8.GCScavenger','V8.GCIncrementalMarking','V8.GCIdleNotification','V8.GCContext','V8.GCCompactor','V8GCController::traceDOMWrappers',],iframe_creation:['WebLocalFrameImpl::createChildframe',],imageDecode:['Decode Image','ImageFrameGenerator::decode','ImageFrameGenerator::decodeAndScale','ImageFrameGenerator::decodeToYUV','ImageResourceContent::updateImage',],input:['HitTest','ScrollableArea::scrollPositionChanged','EventHandler::handleMouseMoveEvent',],layout:['IntersectionObserverController::computeTrackedIntersectionObservations','LocalFrameView::invalidateTree','LocalFrameView::layout','LocalFrameView::performLayout','LocalFrameView::performPostLayoutTasks','LocalFrameView::performPreLayoutTasks','LocalFrameView::RunStyleAndLayoutCompositingPhases','Layout','PaintLayer::updateLayerPositionsAfterLayout','ResourceLoadPriorityOptimizer::updateAllImageResourcePriorities','WebViewImpl::updateAllLifecyclePhases','WebViewImpl::beginFrame',],parseHTML:['BackgroundHTMLParser::pumpTokenizer','BackgroundHTMLParser::sendTokensToMainThread','HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser','HTMLDocumentParser::documentElementAvailable','HTMLDocumentParser::notifyPendingTokenizedChunks','HTMLDocumentParser::processParsedChunkFromBackgroundParser','HTMLDocumentParser::processTokenizedChunkFromBackgroundParser','ParseHTML',],raster:['DisplayListRasterSource::PerformSolidColorAnalysis','Picture::Raster','RasterBufferImpl::Playback','RasterTask','RasterizerTaskImpl::RunOnWorkerThread','SkCanvas::drawImageRect()','SkCanvas::drawPicture()','SkCanvas::drawTextBlob()','TileTaskWorkerPool::PlaybackToMemory',],record:['Canvas2DLayerBridge::flushRecordingOnly','CompositingInputsUpdater::update','CompositingRequirementsUpdater::updateRecursive','ContentLayerDelegate::paintContents','DisplayItemList::Finalize','LocalFrameView::RunPaintLifecyclePhase','LocalFrameView::RunPrePaintLifecyclePhase','Paint','PaintController::commitNewDisplayItems','PaintLayerCompositor::updateIfNeededRecursive','Picture::Record','PictureLayer::Update',],style:['CSSParserImpl::parseStyleSheet.parse','CSSParserImpl::parseStyleSheet.tokenize','Document::rebuildLayoutTree','Document::recalcStyle','Document::updateActiveStyle','Document::updateStyle','Document::updateStyleInvalidationIfNeeded','LocalFrameView::updateStyleAndLayoutIfNeededRecursive','ParseAuthorStyleSheet','RuleSet::addRulesFromSheet','StyleElement::processStyleSheet','StyleEngine::createResolver','StyleEngine::updateActiveStyleSheets','StyleSheetContents::parseAuthorStyleSheet','UpdateLayoutTree',],script_parse_and_compile:['V8.CompileFullCode','V8.NewContext','V8.Parse','V8.ParseLazy','V8.RecompileSynchronous','V8.ScriptCompiler','v8.compile','v8.parseOnBackground',],script_execute:['EvaluateScript','FunctionCall','HTMLParserScriptRunner ExecuteScript','V8.Execute','V8.RunMicrotasks','V8.Task','WindowProxy::initialize','v8.callFunction','v8.run',],resource_loading:['RenderFrameImpl::didFinishDocumentLoad','RenderFrameImpl::didFinishLoad','Resource::appendData','ResourceDispatcher::OnReceivedData','ResourceDispatcher::OnReceivedResponse','ResourceDispatcher::OnRequestComplete','ResourceFetcher::requestResource','WebURLLoaderImpl::Context::Cancel','WebURLLoaderImpl::Context::OnCompletedRequest','WebURLLoaderImpl::Context::OnReceivedData','WebURLLoaderImpl::Context::OnReceivedRedirect','WebURLLoaderImpl::Context::OnReceivedResponse','WebURLLoaderImpl::Context::Start','WebURLLoaderImpl::loadAsynchronously','WebURLLoaderImpl::loadSynchronously','content::mojom::URLLoaderClient',],renderer_misc:['DecodeFont','ThreadState::completeSweep',],v8_runtime:[],[SAME_AS_PARENT]:['SyncChannel::Send',]};const COLOR_FOR_USER_FRIENDLY_CATEGORY=new tr.b.SinebowColorGenerator();const USER_FRIENDLY_CATEGORY_FOR_TITLE=new Map();for(const category in TITLES_FOR_USER_FRIENDLY_CATEGORY){TITLES_FOR_USER_FRIENDLY_CATEGORY[category].forEach(function(title){USER_FRIENDLY_CATEGORY_FOR_TITLE.set(title,category);});}
+const USER_FRIENDLY_CATEGORY_FOR_EVENT_CATEGORY={netlog:'net',overhead:'overhead',startup:'startup',gpu:'gpu',};function ChromeUserFriendlyCategoryDriver(){}
+ChromeUserFriendlyCategoryDriver.fromEvent=function(event){let userFriendlyCategory=USER_FRIENDLY_CATEGORY_FOR_TITLE.get(event.title);if(userFriendlyCategory){if(userFriendlyCategory===SAME_AS_PARENT){if(event.parentSlice){return ChromeUserFriendlyCategoryDriver.fromEvent(event.parentSlice);}}else{return userFriendlyCategory;}}
+const eventCategoryParts=tr.b.getCategoryParts(event.category);for(let i=0;i<eventCategoryParts.length;++i){const eventCategory=eventCategoryParts[i];userFriendlyCategory=USER_FRIENDLY_CATEGORY_FOR_EVENT_CATEGORY[eventCategory];if(userFriendlyCategory){return userFriendlyCategory;}}
+return'other';};ChromeUserFriendlyCategoryDriver.getColor=function(ufc){return COLOR_FOR_USER_FRIENDLY_CATEGORY.colorForKey(ufc);};ChromeUserFriendlyCategoryDriver.ALL_TITLES=['other'];for(const category in TITLES_FOR_USER_FRIENDLY_CATEGORY){if(category===SAME_AS_PARENT)continue;ChromeUserFriendlyCategoryDriver.ALL_TITLES.push(category);}
+for(const category of Object.values(USER_FRIENDLY_CATEGORY_FOR_EVENT_CATEGORY)){ChromeUserFriendlyCategoryDriver.ALL_TITLES.push(category);}
+ChromeUserFriendlyCategoryDriver.ALL_TITLES.sort();for(const category of ChromeUserFriendlyCategoryDriver.ALL_TITLES){ChromeUserFriendlyCategoryDriver.getColor(category);}
+return{ChromeUserFriendlyCategoryDriver,};});'use strict';tr.exportTo('tr.model',function(){return{BROWSER_PROCESS_PID_REF:-1,OBJECT_DEFAULT_SCOPE:'ptr',LOCAL_ID_PHASES:new Set(['N','D','O','(',')'])};});'use strict';tr.exportTo('tr.e.audits',function(){const Auditor=tr.c.Auditor;const Alert=tr.model.Alert;const EventInfo=tr.model.EventInfo;function ChromeAuditor(model){Auditor.call(this,model);const modelHelper=this.model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(modelHelper&&modelHelper.browserHelper){this.modelHelper=modelHelper;}else{this.modelHelper=undefined;}}
+function getMissedFrameAlerts(rendererHelpers){const alerts=[];for(const rendererHelper of rendererHelpers){if(!rendererHelper.compositorThread)continue;const thread=rendererHelper.compositorThread;const asyncSlices=Object.values(thread.asyncSliceGroup.slices);for(const slice of asyncSlices){if(slice.title!=='PipelineReporter'||!slice.args.termination_status||slice.args.termination_status!=='missed_frame')continue;const alertSlices=[slice].concat(slice.subSlices);alerts.push(new Alert(new EventInfo('Missed Frame','Frame was not submitted before deadline.'),slice.start,alertSlices));}}
+return alerts;}
+ChromeAuditor.prototype={__proto__:Auditor.prototype,runAnnotate(){if(!this.modelHelper)return;for(const pid in this.modelHelper.rendererHelpers){const rendererHelper=this.modelHelper.rendererHelpers[pid];if(rendererHelper.isChromeTracingUI){rendererHelper.process.important=false;}}},installUserFriendlyCategoryDriverIfNeeded(){this.model.addUserFriendlyCategoryDriver(tr.e.chrome.ChromeUserFriendlyCategoryDriver);},runAudit(){if(!this.modelHelper)return;this.model.replacePIDRefsInPatchups(tr.model.BROWSER_PROCESS_PID_REF,this.modelHelper.browserProcess.pid);this.model.applyObjectRefPatchups();const alerts=getMissedFrameAlerts(Object.values(this.modelHelper.rendererHelpers));this.model.alerts=this.model.alerts.concat(alerts);}};Auditor.register(ChromeAuditor);return{ChromeAuditor,};});'use strict';tr.exportTo('tr.e.chrome',function(){const KNOWN_PROPERTIES={absX:1,absY:1,address:1,anonymous:1,childNeeds:1,children:1,classNames:1,col:1,colSpan:1,float:1,height:1,htmlId:1,name:1,posChildNeeds:1,positioned:1,positionedMovement:1,relX:1,relY:1,relativePositioned:1,row:1,rowSpan:1,selfNeeds:1,stickyPositioned:1,tag:1,width:1};function LayoutObject(snapshot,args){this.snapshot_=snapshot;this.id_=args.address;this.name_=args.name;this.childLayoutObjects_=[];this.otherProperties_={};this.tag_=args.tag;this.relativeRect_=tr.b.math.Rect.fromXYWH(args.relX,args.relY,args.width,args.height);this.absoluteRect_=tr.b.math.Rect.fromXYWH(args.absX,args.absY,args.width,args.height);this.isFloat_=args.float;this.isStickyPositioned_=args.stickyPositioned;this.isPositioned_=args.positioned;this.isRelativePositioned_=args.relativePositioned;this.isAnonymous_=args.anonymous;this.htmlId_=args.htmlId;this.classNames_=args.classNames;this.needsLayoutReasons_=[];if(args.selfNeeds){this.needsLayoutReasons_.push('self');}
+if(args.childNeeds){this.needsLayoutReasons_.push('child');}
+if(args.posChildNeeds){this.needsLayoutReasons_.push('positionedChild');}
+if(args.positionedMovement){this.needsLayoutReasons_.push('positionedMovement');}
+this.tableRow_=args.row;this.tableCol_=args.col;this.tableRowSpan_=args.rowSpan;this.tableColSpan_=args.colSpan;if(args.children){args.children.forEach(function(child){this.childLayoutObjects_.push(new LayoutObject(snapshot,child));}.bind(this));}
+for(const property in args){if(!KNOWN_PROPERTIES[property]){this.otherProperties_[property]=args[property];}}}
+LayoutObject.prototype={get snapshot(){return this.snapshot_;},get id(){return this.id_;},get name(){return this.name_;},get tag(){return this.tag_;},get relativeRect(){return this.relativeRect_;},get absoluteRect(){return this.absoluteRect_;},get isPositioned(){return this.isPositioned_;},get isFloat(){return this.isFloat_;},get isStickyPositioned(){return this.isStickyPositioned_;},get isRelativePositioned(){return this.isRelativePositioned_;},get isAnonymous(){return this.isAnonymous_;},get tableRow(){return this.tableRow_;},get tableCol(){return this.tableCol_;},get tableRowSpan(){return this.tableRowSpan_;},get tableColSpan(){return this.tableColSpan_;},get htmlId(){return this.htmlId_;},get classNames(){return this.classNames_;},get needsLayoutReasons(){return this.needsLayoutReasons_;},get hasChildLayoutObjects(){return this.childLayoutObjects_.length>0;},get childLayoutObjects(){return this.childLayoutObjects_;},traverseTree(cb,opt_this){cb.call(opt_this,this);if(!this.hasChildLayoutObjects)return;this.childLayoutObjects.forEach(function(child){child.traverseTree(cb,opt_this);});},get otherPropertyNames(){const names=[];for(const name in this.otherProperties_){names.push(name);}
+return names;},getProperty(name){return this.otherProperties_[name];},get previousSnapshotLayoutObject(){if(!this.snapshot.previousSnapshot)return undefined;return this.snapshot.previousSnapshot.getLayoutObjectById(this.id);},get nextSnapshotLayoutObject(){if(!this.snapshot.nextSnapshot)return undefined;return this.snapshot.nextSnapshot.getLayoutObjectById(this.id);}};return{LayoutObject,};});'use strict';tr.exportTo('tr.e.chrome',function(){const ObjectSnapshot=tr.model.ObjectSnapshot;const ObjectInstance=tr.model.ObjectInstance;function LayoutTreeInstance(){ObjectInstance.apply(this,arguments);}
+LayoutTreeInstance.prototype={__proto__:ObjectInstance.prototype,};ObjectInstance.subTypes.register(LayoutTreeInstance,{typeName:'LayoutTree'});function LayoutTreeSnapshot(){ObjectSnapshot.apply(this,arguments);this.rootLayoutObject=new tr.e.chrome.LayoutObject(this,this.args);}
+LayoutTreeSnapshot.prototype={__proto__:ObjectSnapshot.prototype,};ObjectSnapshot.subTypes.register(LayoutTreeSnapshot,{typeName:'LayoutTree'});return{LayoutTreeInstance,LayoutTreeSnapshot,};});'use strict';tr.exportTo('tr.model',function(){function EventContainer(){this.guid_=tr.b.GUID.allocateSimple();this.important=true;this.bounds_=new tr.b.math.Range();}
+EventContainer.prototype={get guid(){return this.guid_;},get stableId(){throw new Error('Not implemented');},get bounds(){return this.bounds_;},updateBounds(){throw new Error('Not implemented');},shiftTimestampsForward(amount){throw new Error('Not implemented');},*childEvents(){},*getDescendantEvents(){yield*this.childEvents();for(const container of this.childEventContainers()){yield*container.getDescendantEvents();}},*childEventContainers(){},*getDescendantEventContainers(){yield this;for(const container of this.childEventContainers()){yield*container.getDescendantEventContainers();}},*getDescendantEventsInSortedRanges(ranges,opt_containerPredicate){if(opt_containerPredicate===undefined||opt_containerPredicate(this)){for(const event of this.childEvents()){const i=tr.b.findFirstTrueIndexInSortedArray(ranges,range=>event.start<=range.max);if(i<ranges.length&&event.end>=ranges[i].min)yield event;}}
+for(const container of this.childEventContainers()){yield*container.getDescendantEventsInSortedRanges(ranges,opt_containerPredicate);}},*findTopmostSlicesInThisContainer(eventPredicate,opt_this){},*findTopmostSlices(eventPredicate){for(const ec of this.getDescendantEventContainers()){yield*ec.findTopmostSlicesInThisContainer(eventPredicate);}},*findTopmostSlicesNamed(name){yield*this.findTopmostSlices(e=>e.title===name);}};return{EventContainer,};});'use strict';tr.exportTo('tr.model',function(){const Event=tr.model.Event;const EventRegistry=tr.model.EventRegistry;class ResourceUsageSample extends Event{constructor(series,start,usage){super();this.series_=series;this.start_=start;this.usage_=usage;}
+get series(){return this.series_;}
+get start(){return this.start_;}
+set start(value){this.start_=value;}
+get usage(){return this.usage_;}
+set usage(value){this.usage_=value;}
+addBoundsToRange(range){range.addValue(this.start);}}
+EventRegistry.register(ResourceUsageSample,{name:'resourceUsageSample',pluralName:'resourceUsageSamples'});return{ResourceUsageSample,};});'use strict';tr.exportTo('tr.model',function(){const ResourceUsageSample=tr.model.ResourceUsageSample;class ResourceUsageSeries extends tr.model.EventContainer{constructor(device){super();this.device_=device;this.samples_=[];}
+get device(){return this.device_;}
+get samples(){return this.samples_;}
+get stableId(){return this.device_.stableId+'.ResourceUsageSeries';}
+addUsageSample(ts,val){const sample=new ResourceUsageSample(this,ts,val);this.samples_.push(sample);return sample;}
+computeResourceTimeConsumedInMs(start,end){const measurementRange=tr.b.math.Range.fromExplicitRange(start,end);let resourceTimeInMs=0;let startIndex=tr.b.findLowIndexInSortedArray(this.samples,x=>x.start,start)-1;const endIndex=tr.b.findLowIndexInSortedArray(this.samples,x=>x.start,end);if(startIndex<0)startIndex=0;for(let i=startIndex;i<endIndex;i++){const sample=this.samples[i];const nextSample=this.samples[i+1];const sampleRange=new tr.b.math.Range();sampleRange.addValue(sample.start);sampleRange.addValue(nextSample?nextSample.start:sample.start);const intersectionRangeInMs=measurementRange.findIntersection(sampleRange);resourceTimeInMs+=intersectionRangeInMs.duration*sample.usage;}
+return resourceTimeInMs;}
+getSamplesWithinRange(start,end){const startIndex=tr.b.findLowIndexInSortedArray(this.samples,x=>x.start,start);const endIndex=tr.b.findLowIndexInSortedArray(this.samples,x=>x.start,end);return this.samples.slice(startIndex,endIndex);}
+shiftTimestampsForward(amount){for(let i=0;i<this.samples_.length;++i){this.samples_[i].start+=amount;}}
+updateBounds(){this.bounds.reset();if(this.samples_.length===0)return;this.bounds.addValue(this.samples_[0].start);this.bounds.addValue(this.samples_[this.samples_.length-1].start);}*childEvents(){yield*this.samples_;}}
+return{ResourceUsageSeries,};});'use strict';tr.exportTo('tr.e.audits',function(){class CpuUsageAuditor extends tr.c.Auditor{constructor(model){super();this.model_=model;}
+runAnnotate(){this.model_.device.cpuUsageSeries=this.computeCpuUsageSeries_(this.model_.bounds.min,this.model_.bounds.max,this.computeCpuUsage_());}
+computeBinSize_(start,end){const MIN_BIN_SIZE_MS=1.0;const MAX_NUM_BINS=100000;const interval=end-start;let binSize=MIN_BIN_SIZE_MS;while(binSize*MAX_NUM_BINS<interval)binSize*=2;return binSize;}
+computeCpuUsageSeries_(start,end,usageRecords){const series=new tr.model.ResourceUsageSeries();if(start===undefined||usageRecords.length===0)return series;const binSize=this.computeBinSize_(start,end);const numBins=Math.ceil((end-start)/binSize);const arr=new Array(numBins).fill(0);for(const record of usageRecords){const firstIndex=Math.ceil((record.start-start)/binSize);const lastIndex=Math.floor((record.end-start)/binSize);for(let i=firstIndex;i<=lastIndex;i++)arr[i]+=record.usage;}
+for(let i=0;i<numBins;i++){series.addUsageSample(start+(i*binSize),arr[i]);}
+return series;}
+computeCpuUsage_(){const model=this.model_;const result=[];for(const pid in model.processes){for(const e of model.processes[pid].getDescendantEvents()){if(!(e instanceof tr.model.ThreadSlice)||e.duration===0||e.cpuDuration===undefined){continue;}
+if(e.selfTime===0||e.selfTime===undefined||e.cpuSelfTime===undefined){continue;}
+const usage=tr.b.math.clamp(e.cpuSelfTime/e.selfTime,0,1);let lastTime=e.start;for(const subslice of e.subSlices){result.push({usage,start:lastTime,end:subslice.start});lastTime=subslice.end;}
+result.push({usage,start:lastTime,end:e.end});}}
+return result;}}
+tr.c.Auditor.register(CpuUsageAuditor);return{CpuUsageAuditor};});'use strict';tr.exportTo('tr.b',function(){function Base64(){}
+function b64ToUint6(nChr){if(nChr>64&&nChr<91)return nChr-65;if(nChr>96&&nChr<123)return nChr-71;if(nChr>47&&nChr<58)return nChr+4;if(nChr===43)return 62;if(nChr===47)return 63;return 0;}
+Base64.getDecodedBufferLength=function(input){let pad=0;if(input.substr(-2)==='=='){pad=2;}else if(input.substr(-1)==='='){pad=1;}
+return((input.length*3+1)>>2)-pad;};Base64.EncodeArrayBufferToString=function(input){let binary='';const bytes=new Uint8Array(input);const len=bytes.byteLength;for(let i=0;i<len;i++){binary+=String.fromCharCode(bytes[i]);}
+return btoa(binary);};Base64.DecodeToTypedArray=function(input,output){const nInLen=input.length;const nOutLen=Base64.getDecodedBufferLength(input);let nMod3=0;let nMod4=0;let nUint24=0;let nOutIdx=0;if(nOutLen>output.byteLength){throw new Error('Output buffer too small to decode.');}
+for(let nInIdx=0;nInIdx<nInLen;nInIdx++){nMod4=nInIdx&3;nUint24|=b64ToUint6(input.charCodeAt(nInIdx))<<18-6*nMod4;if(nMod4===3||nInLen-nInIdx===1){for(nMod3=0;nMod3<3&&nOutIdx<nOutLen;nMod3++,nOutIdx++){output.setUint8(nOutIdx,nUint24>>>(16>>>nMod3&24)&255);}
+nUint24=0;}}
+return nOutLen;};Base64.btoa=function(input){return btoa(input);};Base64.atob=function(input){return atob(input);};return{Base64,};});'use strict';tr.exportTo('tr.e.importer.etw',function(){function Parser(importer){this.importer=importer;this.model=importer.model;}
+Parser.prototype={__proto__:Object.prototype};const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.mandatoryBaseClass=Parser;tr.b.decorateExtensionRegistry(Parser,options);return{Parser,};});'use strict';tr.exportTo('tr.e.importer.etw',function(){const Parser=tr.e.importer.etw.Parser;const guid='68FDD900-4A3E-11D1-84F4-0000F80464E3';const kEventTraceHeaderOpcode=0;function EventTraceParser(importer){Parser.call(this,importer);importer.registerEventHandler(guid,kEventTraceHeaderOpcode,EventTraceParser.prototype.decodeHeader.bind(this));}
+EventTraceParser.prototype={__proto__:Parser.prototype,decodeFields(header,decoder){if(header.version!==2){throw new Error('Incompatible EventTrace event version.');}
+const bufferSize=decoder.decodeUInt32();const version=decoder.decodeUInt32();const providerVersion=decoder.decodeUInt32();const numberOfProcessors=decoder.decodeUInt32();const endTime=decoder.decodeUInt64ToString();const timerResolution=decoder.decodeUInt32();const maxFileSize=decoder.decodeUInt32();const logFileMode=decoder.decodeUInt32();const buffersWritten=decoder.decodeUInt32();const startBuffers=decoder.decodeUInt32();const pointerSize=decoder.decodeUInt32();const eventsLost=decoder.decodeUInt32();const cpuSpeed=decoder.decodeUInt32();const loggerName=decoder.decodeUInteger(header.is64);const logFileName=decoder.decodeUInteger(header.is64);const timeZoneInformation=decoder.decodeTimeZoneInformation();const padding=decoder.decodeUInt32();const bootTime=decoder.decodeUInt64ToString();const perfFreq=decoder.decodeUInt64ToString();const startTime=decoder.decodeUInt64ToString();const reservedFlags=decoder.decodeUInt32();const buffersLost=decoder.decodeUInt32();const sessionNameString=decoder.decodeW16String();const logFileNameString=decoder.decodeW16String();return{bufferSize,version,providerVersion,numberOfProcessors,endTime,timerResolution,maxFileSize,logFileMode,buffersWritten,startBuffers,pointerSize,eventsLost,cpuSpeed,loggerName,logFileName,timeZoneInformation,bootTime,perfFreq,startTime,reservedFlags,buffersLost,sessionNameString,logFileNameString};},decodeHeader(header,decoder){const fields=this.decodeFields(header,decoder);return true;}};Parser.register(EventTraceParser);return{EventTraceParser,};});'use strict';tr.exportTo('tr.e.importer.etw',function(){const Parser=tr.e.importer.etw.Parser;const guid='3D6FA8D0-FE05-11D0-9DDA-00C04FD7BA7C';const kProcessStartOpcode=1;const kProcessEndOpcode=2;const kProcessDCStartOpcode=3;const kProcessDCEndOpcode=4;const kProcessDefunctOpcode=39;function ProcessParser(importer){Parser.call(this,importer);importer.registerEventHandler(guid,kProcessStartOpcode,ProcessParser.prototype.decodeStart.bind(this));importer.registerEventHandler(guid,kProcessEndOpcode,ProcessParser.prototype.decodeEnd.bind(this));importer.registerEventHandler(guid,kProcessDCStartOpcode,ProcessParser.prototype.decodeDCStart.bind(this));importer.registerEventHandler(guid,kProcessDCEndOpcode,ProcessParser.prototype.decodeDCEnd.bind(this));importer.registerEventHandler(guid,kProcessDefunctOpcode,ProcessParser.prototype.decodeDefunct.bind(this));}
+ProcessParser.prototype={__proto__:Parser.prototype,decodeFields(header,decoder){if(header.version>5){throw new Error('Incompatible Process event version.');}
+let pageDirectoryBase;if(header.version===1){pageDirectoryBase=decoder.decodeUInteger(header.is64);}
+let uniqueProcessKey;if(header.version>=2){uniqueProcessKey=decoder.decodeUInteger(header.is64);}
+const processId=decoder.decodeUInt32();const parentId=decoder.decodeUInt32();let sessionId;let exitStatus;if(header.version>=1){sessionId=decoder.decodeUInt32();exitStatus=decoder.decodeInt32();}
+let directoryTableBase;if(header.version>=3){directoryTableBase=decoder.decodeUInteger(header.is64);}
+let flags;if(header.version>=4){flags=decoder.decodeUInt32();}
+const userSID=decoder.decodeSID(header.is64);let imageFileName;if(header.version>=1){imageFileName=decoder.decodeString();}
+let commandLine;if(header.version>=2){commandLine=decoder.decodeW16String();}
+let packageFullName;let applicationId;if(header.version>=4){packageFullName=decoder.decodeW16String();applicationId=decoder.decodeW16String();}
+let exitTime;if(header.version===5&&header.opcode===kProcessDefunctOpcode){exitTime=decoder.decodeUInt64ToString();}
+return{pageDirectoryBase,uniqueProcessKey,processId,parentId,sessionId,exitStatus,directoryTableBase,flags,userSID,imageFileName,commandLine,packageFullName,applicationId,exitTime};},decodeStart(header,decoder){const fields=this.decodeFields(header,decoder);const process=this.model.getOrCreateProcess(fields.processId);if(process.hasOwnProperty('has_ended')){throw new Error('Process clash detected.');}
+process.name=fields.imageFileName;return true;},decodeEnd(header,decoder){const fields=this.decodeFields(header,decoder);const process=this.model.getOrCreateProcess(fields.processId);process.has_ended=true;return true;},decodeDCStart(header,decoder){const fields=this.decodeFields(header,decoder);const process=this.model.getOrCreateProcess(fields.processId);if(process.hasOwnProperty('has_ended')){throw new Error('Process clash detected.');}
+process.name=fields.imageFileName;return true;},decodeDCEnd(header,decoder){const fields=this.decodeFields(header,decoder);const process=this.model.getOrCreateProcess(fields.processId);process.has_ended=true;return true;},decodeDefunct(header,decoder){const fields=this.decodeFields(header,decoder);return true;}};Parser.register(ProcessParser);return{ProcessParser,};});'use strict';tr.exportTo('tr.e.importer.etw',function(){const Parser=tr.e.importer.etw.Parser;const guid='3D6FA8D1-FE05-11D0-9DDA-00C04FD7BA7C';const kThreadStartOpcode=1;const kThreadEndOpcode=2;const kThreadDCStartOpcode=3;const kThreadDCEndOpcode=4;const kThreadCSwitchOpcode=36;function ThreadParser(importer){Parser.call(this,importer);importer.registerEventHandler(guid,kThreadStartOpcode,ThreadParser.prototype.decodeStart.bind(this));importer.registerEventHandler(guid,kThreadEndOpcode,ThreadParser.prototype.decodeEnd.bind(this));importer.registerEventHandler(guid,kThreadDCStartOpcode,ThreadParser.prototype.decodeDCStart.bind(this));importer.registerEventHandler(guid,kThreadDCEndOpcode,ThreadParser.prototype.decodeDCEnd.bind(this));importer.registerEventHandler(guid,kThreadCSwitchOpcode,ThreadParser.prototype.decodeCSwitch.bind(this));}
+ThreadParser.prototype={__proto__:Parser.prototype,decodeFields(header,decoder){if(header.version>3){throw new Error('Incompatible Thread event version '+
+header.version+'.');}
+const processId=decoder.decodeUInt32();const threadId=decoder.decodeUInt32();let stackBase;let stackLimit;let userStackBase;let userStackLimit;let affinity;let startAddr;let win32StartAddr;let tebBase;let subProcessTag;let basePriority;let pagePriority;let ioPriority;let threadFlags;let waitMode;if(header.version===1){if(header.opcode===kThreadStartOpcode||header.opcode===kThreadDCStartOpcode){stackBase=decoder.decodeUInteger(header.is64);stackLimit=decoder.decodeUInteger(header.is64);userStackBase=decoder.decodeUInteger(header.is64);userStackLimit=decoder.decodeUInteger(header.is64);startAddr=decoder.decodeUInteger(header.is64);win32StartAddr=decoder.decodeUInteger(header.is64);waitMode=decoder.decodeInt8();decoder.skip(3);}}else{stackBase=decoder.decodeUInteger(header.is64);stackLimit=decoder.decodeUInteger(header.is64);userStackBase=decoder.decodeUInteger(header.is64);userStackLimit=decoder.decodeUInteger(header.is64);if(header.version===2){startAddr=decoder.decodeUInteger(header.is64);}else{affinity=decoder.decodeUInteger(header.is64);}
+win32StartAddr=decoder.decodeUInteger(header.is64);tebBase=decoder.decodeUInteger(header.is64);subProcessTag=decoder.decodeUInt32();if(header.version===3){basePriority=decoder.decodeUInt8();pagePriority=decoder.decodeUInt8();ioPriority=decoder.decodeUInt8();threadFlags=decoder.decodeUInt8();}}
+return{processId,threadId,stackBase,stackLimit,userStackBase,userStackLimit,affinity,startAddr,win32StartAddr,tebBase,subProcessTag,waitMode,basePriority,pagePriority,ioPriority,threadFlags};},decodeCSwitchFields(header,decoder){if(header.version<2||header.version>4){throw new Error('Incompatible cswitch event version '+
+header.version+'.');}
+const newThreadId=decoder.decodeUInt32();const oldThreadId=decoder.decodeUInt32();const newThreadPriority=decoder.decodeInt8();const oldThreadPriority=decoder.decodeInt8();const previousCState=decoder.decodeUInt8();const spareByte=decoder.decodeInt8();const oldThreadWaitReason=decoder.decodeInt8();const oldThreadWaitMode=decoder.decodeInt8();const oldThreadState=decoder.decodeInt8();const oldThreadWaitIdealProcessor=decoder.decodeInt8();const newThreadWaitTime=decoder.decodeUInt32();const reserved=decoder.decodeUInt32();return{newThreadId,oldThreadId,newThreadPriority,oldThreadPriority,previousCState,spareByte,oldThreadWaitReason,oldThreadWaitMode,oldThreadState,oldThreadWaitIdealProcessor,newThreadWaitTime,reserved};},decodeStart(header,decoder){const fields=this.decodeFields(header,decoder);this.importer.createThreadIfNeeded(fields.processId,fields.threadId);return true;},decodeEnd(header,decoder){const fields=this.decodeFields(header,decoder);this.importer.removeThreadIfPresent(fields.threadId);return true;},decodeDCStart(header,decoder){const fields=this.decodeFields(header,decoder);this.importer.createThreadIfNeeded(fields.processId,fields.threadId);return true;},decodeDCEnd(header,decoder){const fields=this.decodeFields(header,decoder);this.importer.removeThreadIfPresent(fields.threadId);return true;},decodeCSwitch(header,decoder){const fields=this.decodeCSwitchFields(header,decoder);const cpu=this.importer.getOrCreateCpu(header.cpu);const newThread=this.importer.getThreadFromWindowsTid(fields.newThreadId);let newThreadName;if(newThread&&newThread.userFriendlyName){newThreadName=newThread.userFriendlyName;}else{const newProcessId=this.importer.getPidFromWindowsTid(fields.newThreadId);const newProcess=this.model.getProcess(newProcessId);let newProcessName;if(newProcess){newProcessName=newProcess.name;}else{newProcessName='Unknown process';}
+newThreadName=newProcessName+' (tid '+fields.newThreadId+')';}
+cpu.switchActiveThread(header.timestamp,{},fields.newThreadId,newThreadName,fields);return true;}};Parser.register(ThreadParser);return{ThreadParser,};});'use strict';tr.exportTo('tr.b',function(){function max(a,b){if(a===undefined)return b;if(b===undefined)return a;return Math.max(a,b);}
+function IntervalTree(beginPositionCb,endPositionCb){this.beginPositionCb_=beginPositionCb;this.endPositionCb_=endPositionCb;this.root_=undefined;this.size_=0;}
+IntervalTree.prototype={insert(datum){const startPosition=this.beginPositionCb_(datum);const endPosition=this.endPositionCb_(datum);const node=new IntervalTreeNode(datum,startPosition,endPosition);this.size_++;this.root_=this.insertNode_(this.root_,node);this.root_.colour=Colour.BLACK;return datum;},insertNode_(root,node){if(root===undefined)return node;if(root.leftNode&&root.leftNode.isRed&&root.rightNode&&root.rightNode.isRed){this.flipNodeColour_(root);}
+if(node.key<root.key){root.leftNode=this.insertNode_(root.leftNode,node);}else if(node.key===root.key){root.merge(node);}else{root.rightNode=this.insertNode_(root.rightNode,node);}
+if(root.rightNode&&root.rightNode.isRed&&(root.leftNode===undefined||!root.leftNode.isRed)){root=this.rotateLeft_(root);}
+if(root.leftNode&&root.leftNode.isRed&&root.leftNode.leftNode&&root.leftNode.leftNode.isRed){root=this.rotateRight_(root);}
+return root;},rotateRight_(node){const sibling=node.leftNode;node.leftNode=sibling.rightNode;sibling.rightNode=node;sibling.colour=node.colour;node.colour=Colour.RED;return sibling;},rotateLeft_(node){const sibling=node.rightNode;node.rightNode=sibling.leftNode;sibling.leftNode=node;sibling.colour=node.colour;node.colour=Colour.RED;return sibling;},flipNodeColour_(node){node.colour=this.flipColour_(node.colour);node.leftNode.colour=this.flipColour_(node.leftNode.colour);node.rightNode.colour=this.flipColour_(node.rightNode.colour);},flipColour_(colour){return colour===Colour.RED?Colour.BLACK:Colour.RED;},updateHighValues(){this.updateHighValues_(this.root_);},updateHighValues_(node){if(node===undefined)return undefined;node.maxHighLeft=this.updateHighValues_(node.leftNode);node.maxHighRight=this.updateHighValues_(node.rightNode);return max(max(node.maxHighLeft,node.highValue),node.maxHighRight);},validateFindArguments_(queryLow,queryHigh){if(queryLow===undefined||queryHigh===undefined){throw new Error('queryLow and queryHigh must be defined');}
+if((typeof queryLow!=='number')||(typeof queryHigh!=='number')){throw new Error('queryLow and queryHigh must be numbers');}},findIntersection(queryLow,queryHigh){this.validateFindArguments_(queryLow,queryHigh);if(this.root_===undefined)return[];const ret=[];this.root_.appendIntersectionsInto_(ret,queryLow,queryHigh);return ret;},get size(){return this.size_;},get root(){return this.root_;},dump_(){if(this.root_===undefined)return[];return this.root_.dump();}};const Colour={RED:'red',BLACK:'black'};function IntervalTreeNode(datum,lowValue,highValue){this.lowValue_=lowValue;this.data_=[{datum,high:highValue,low:lowValue}];this.colour_=Colour.RED;this.parentNode_=undefined;this.leftNode_=undefined;this.rightNode_=undefined;this.maxHighLeft_=undefined;this.maxHighRight_=undefined;}
+IntervalTreeNode.prototype={appendIntersectionsInto_(ret,queryLow,queryHigh){if(this.lowValue_>=queryHigh){if(!this.leftNode_)return;return this.leftNode_.appendIntersectionsInto_(ret,queryLow,queryHigh);}
+if(this.maxHighLeft_>queryLow){this.leftNode_.appendIntersectionsInto_(ret,queryLow,queryHigh);}
+if(this.highValue>queryLow){for(let i=(this.data.length-1);i>=0;--i){if(this.data[i].high<queryLow)break;ret.push(this.data[i].datum);}}
+if(this.rightNode_){this.rightNode_.appendIntersectionsInto_(ret,queryLow,queryHigh);}},get colour(){return this.colour_;},set colour(colour){this.colour_=colour;},get key(){return this.lowValue_;},get lowValue(){return this.lowValue_;},get highValue(){return this.data_[this.data_.length-1].high;},set leftNode(left){this.leftNode_=left;},get leftNode(){return this.leftNode_;},get hasLeftNode(){return this.leftNode_!==undefined;},set rightNode(right){this.rightNode_=right;},get rightNode(){return this.rightNode_;},get hasRightNode(){return this.rightNode_!==undefined;},set parentNode(parent){this.parentNode_=parent;},get parentNode(){return this.parentNode_;},get isRootNode(){return this.parentNode_===undefined;},set maxHighLeft(high){this.maxHighLeft_=high;},get maxHighLeft(){return this.maxHighLeft_;},set maxHighRight(high){this.maxHighRight_=high;},get maxHighRight(){return this.maxHighRight_;},get data(){return this.data_;},get isRed(){return this.colour_===Colour.RED;},merge(node){for(let i=0;i<node.data.length;i++){this.data_.push(node.data[i]);}
+this.data_.sort(function(a,b){return a.high-b.high;});},dump(){const ret={};if(this.leftNode_){ret.left=this.leftNode_.dump();}
+ret.data=this.data_.map(function(d){return[d.low,d.high];});if(this.rightNode_){ret.right=this.rightNode_.dump();}
+return ret;}};return{IntervalTree,};});'use strict';tr.exportTo('tr.b.math',function(){const tmpVec2s=[];for(let i=0;i<8;i++){tmpVec2s[i]=vec2.create();}
+const tmpVec2a=vec4.create();const tmpVec4a=vec4.create();const tmpVec4b=vec4.create();const tmpMat4=mat4.create();const tmpMat4b=mat4.create();const p00=vec2.createXY(0,0);const p10=vec2.createXY(1,0);const p01=vec2.createXY(0,1);const p11=vec2.createXY(1,1);const lerpingVecA=vec2.create();const lerpingVecB=vec2.create();function lerpVec2(out,a,b,amt){vec2.scale(lerpingVecA,a,amt);vec2.scale(lerpingVecB,b,1-amt);vec2.add(out,lerpingVecA,lerpingVecB);vec2.normalize(out,out);return out;}
 function Quad(){this.p1=vec2.create();this.p2=vec2.create();this.p3=vec2.create();this.p4=vec2.create();}
-Quad.fromXYWH=function(x,y,w,h){var q=new Quad();vec2.set(q.p1,x,y);vec2.set(q.p2,x+w,y);vec2.set(q.p3,x+w,y+h);vec2.set(q.p4,x,y+h);return q;}
-Quad.fromRect=function(r){return new Quad.fromXYWH(r.x,r.y,r.width,r.height);}
-Quad.from4Vecs=function(p1,p2,p3,p4){var q=new Quad();vec2.set(q.p1,p1[0],p1[1]);vec2.set(q.p2,p2[0],p2[1]);vec2.set(q.p3,p3[0],p3[1]);vec2.set(q.p4,p4[0],p4[1]);return q;}
-Quad.from8Array=function(arr){if(arr.length!=8)
-throw new Error('Array must be 8 long');var q=new Quad();q.p1[0]=arr[0];q.p1[1]=arr[1];q.p2[0]=arr[2];q.p2[1]=arr[3];q.p3[0]=arr[4];q.p3[1]=arr[5];q.p4[0]=arr[6];q.p4[1]=arr[7];return q;};Quad.prototype={pointInside:function(point){return pointInImplicitQuad(point,this.p1,this.p2,this.p3,this.p4);},boundingRect:function(){var x0=Math.min(this.p1[0],this.p2[0],this.p3[0],this.p4[0]);var y0=Math.min(this.p1[1],this.p2[1],this.p3[1],this.p4[1]);var x1=Math.max(this.p1[0],this.p2[0],this.p3[0],this.p4[0]);var y1=Math.max(this.p1[1],this.p2[1],this.p3[1],this.p4[1]);return new tr.b.Rect.fromXYWH(x0,y0,x1-x0,y1-y0);},clone:function(){var q=new Quad();vec2.copy(q.p1,this.p1);vec2.copy(q.p2,this.p2);vec2.copy(q.p3,this.p3);vec2.copy(q.p4,this.p4);return q;},scale:function(s){var q=new Quad();this.scaleFast(q,s);return q;},scaleFast:function(dstQuad,s){vec2.copy(dstQuad.p1,this.p1,s);vec2.copy(dstQuad.p2,this.p2,s);vec2.copy(dstQuad.p3,this.p3,s);vec2.copy(dstQuad.p3,this.p3,s);},isRectangle:function(){var bounds=this.boundingRect();return(bounds.x==this.p1[0]&&bounds.y==this.p1[1]&&bounds.width==this.p2[0]-this.p1[0]&&bounds.y==this.p2[1]&&bounds.width==this.p3[0]-this.p1[0]&&bounds.height==this.p3[1]-this.p2[1]&&bounds.x==this.p4[0]&&bounds.height==this.p4[1]-this.p2[1]);},projectUnitRect:function(rect){var q=new Quad();this.projectUnitRectFast(q,rect);return q;},projectUnitRectFast:function(dstQuad,rect){var v12=tmpVec2s[0];var v14=tmpVec2s[1];var v23=tmpVec2s[2];var v43=tmpVec2s[3];var l12,l14,l23,l43;vec2.sub(v12,this.p2,this.p1);l12=vec2.length(v12);vec2.scale(v12,v12,1/l12);vec2.sub(v14,this.p4,this.p1);l14=vec2.length(v14);vec2.scale(v14,v14,1/l14);vec2.sub(v23,this.p3,this.p2);l23=vec2.length(v23);vec2.scale(v23,v23,1/l23);vec2.sub(v43,this.p3,this.p4);l43=vec2.length(v43);vec2.scale(v43,v43,1/l43);var b12=tmpVec2s[0];var b14=tmpVec2s[1];var b23=tmpVec2s[2];var b43=tmpVec2s[3];lerpVec2(b12,v12,v43,rect.y);lerpVec2(b43,v12,v43,1-rect.bottom);lerpVec2(b14,v14,v23,rect.x);lerpVec2(b23,v14,v23,1-rect.right);vec2.addTwoScaledUnitVectors(tmpVec2a,b12,l12*rect.x,b14,l14*rect.y);vec2.add(dstQuad.p1,this.p1,tmpVec2a);vec2.addTwoScaledUnitVectors(tmpVec2a,b12,l12*-(1.0-rect.right),b23,l23*rect.y);vec2.add(dstQuad.p2,this.p2,tmpVec2a);vec2.addTwoScaledUnitVectors(tmpVec2a,b43,l43*-(1.0-rect.right),b23,l23*-(1.0-rect.bottom));vec2.add(dstQuad.p3,this.p3,tmpVec2a);vec2.addTwoScaledUnitVectors(tmpVec2a,b43,l43*rect.left,b14,l14*-(1.0-rect.bottom));vec2.add(dstQuad.p4,this.p4,tmpVec2a);},toString:function(){return'Quad('+
+Quad.fromXYWH=function(x,y,w,h){const q=new Quad();vec2.set(q.p1,x,y);vec2.set(q.p2,x+w,y);vec2.set(q.p3,x+w,y+h);vec2.set(q.p4,x,y+h);return q;};Quad.fromRect=function(r){return new Quad.fromXYWH(r.x,r.y,r.width,r.height);};Quad.from4Vecs=function(p1,p2,p3,p4){const q=new Quad();vec2.set(q.p1,p1[0],p1[1]);vec2.set(q.p2,p2[0],p2[1]);vec2.set(q.p3,p3[0],p3[1]);vec2.set(q.p4,p4[0],p4[1]);return q;};Quad.from8Array=function(arr){if(arr.length!==8){throw new Error('Array must be 8 long');}
+const q=new Quad();q.p1[0]=arr[0];q.p1[1]=arr[1];q.p2[0]=arr[2];q.p2[1]=arr[3];q.p3[0]=arr[4];q.p3[1]=arr[5];q.p4[0]=arr[6];q.p4[1]=arr[7];return q;};Quad.prototype={pointInside(point){return pointInImplicitQuad(point,this.p1,this.p2,this.p3,this.p4);},boundingRect(){const x0=Math.min(this.p1[0],this.p2[0],this.p3[0],this.p4[0]);const y0=Math.min(this.p1[1],this.p2[1],this.p3[1],this.p4[1]);const x1=Math.max(this.p1[0],this.p2[0],this.p3[0],this.p4[0]);const y1=Math.max(this.p1[1],this.p2[1],this.p3[1],this.p4[1]);return new tr.b.math.Rect.fromXYWH(x0,y0,x1-x0,y1-y0);},clone(){const q=new Quad();vec2.copy(q.p1,this.p1);vec2.copy(q.p2,this.p2);vec2.copy(q.p3,this.p3);vec2.copy(q.p4,this.p4);return q;},scale(s){const q=new Quad();this.scaleFast(q,s);return q;},scaleFast(dstQuad,s){vec2.copy(dstQuad.p1,this.p1,s);vec2.copy(dstQuad.p2,this.p2,s);vec2.copy(dstQuad.p3,this.p3,s);vec2.copy(dstQuad.p3,this.p3,s);},isRectangle(){const bounds=this.boundingRect();return(bounds.x===this.p1[0]&&bounds.y===this.p1[1]&&bounds.width===this.p2[0]-this.p1[0]&&bounds.y===this.p2[1]&&bounds.width===this.p3[0]-this.p1[0]&&bounds.height===this.p3[1]-this.p2[1]&&bounds.x===this.p4[0]&&bounds.height===this.p4[1]-this.p2[1]);},projectUnitRect(rect){const q=new Quad();this.projectUnitRectFast(q,rect);return q;},projectUnitRectFast(dstQuad,rect){const v12=tmpVec2s[0];const v14=tmpVec2s[1];const v23=tmpVec2s[2];const v43=tmpVec2s[3];vec2.sub(v12,this.p2,this.p1);const l12=vec2.length(v12);vec2.scale(v12,v12,1/l12);vec2.sub(v14,this.p4,this.p1);const l14=vec2.length(v14);vec2.scale(v14,v14,1/l14);vec2.sub(v23,this.p3,this.p2);const l23=vec2.length(v23);vec2.scale(v23,v23,1/l23);vec2.sub(v43,this.p3,this.p4);const l43=vec2.length(v43);vec2.scale(v43,v43,1/l43);const b12=tmpVec2s[0];const b14=tmpVec2s[1];const b23=tmpVec2s[2];const b43=tmpVec2s[3];lerpVec2(b12,v12,v43,rect.y);lerpVec2(b43,v12,v43,1-rect.bottom);lerpVec2(b14,v14,v23,rect.x);lerpVec2(b23,v14,v23,1-rect.right);vec2.addTwoScaledUnitVectors(tmpVec2a,b12,l12*rect.x,b14,l14*rect.y);vec2.add(dstQuad.p1,this.p1,tmpVec2a);vec2.addTwoScaledUnitVectors(tmpVec2a,b12,l12*-(1.0-rect.right),b23,l23*rect.y);vec2.add(dstQuad.p2,this.p2,tmpVec2a);vec2.addTwoScaledUnitVectors(tmpVec2a,b43,l43*-(1.0-rect.right),b23,l23*-(1.0-rect.bottom));vec2.add(dstQuad.p3,this.p3,tmpVec2a);vec2.addTwoScaledUnitVectors(tmpVec2a,b43,l43*rect.left,b14,l14*-(1.0-rect.bottom));vec2.add(dstQuad.p4,this.p4,tmpVec2a);},toString(){return'Quad('+
 vec2.toString(this.p1)+', '+
 vec2.toString(this.p2)+', '+
 vec2.toString(this.p3)+', '+
 vec2.toString(this.p4)+')';}};function sign(p1,p2,p3){return(p1[0]-p3[0])*(p2[1]-p3[1])-
 (p2[0]-p3[0])*(p1[1]-p3[1]);}
-function pointInTriangle2(pt,p1,p2,p3){var b1=sign(pt,p1,p2)<0.0;var b2=sign(pt,p2,p3)<0.0;var b3=sign(pt,p3,p1)<0.0;return((b1==b2)&&(b2==b3));}
+function pointInTriangle2(pt,p1,p2,p3){const b1=sign(pt,p1,p2)<0.0;const b2=sign(pt,p2,p3)<0.0;const b3=sign(pt,p3,p1)<0.0;return((b1===b2)&&(b2===b3));}
 function pointInImplicitQuad(point,p1,p2,p3,p4){return pointInTriangle2(point,p1,p2,p3)||pointInTriangle2(point,p1,p3,p4);}
-return{pointInTriangle2:pointInTriangle2,pointInImplicitQuad:pointInImplicitQuad,Quad:Quad};});'use strict';tr.exportTo('tr.b',function(){function addSingletonGetter(ctor){ctor.getInstance=function(){return ctor.instance_||(ctor.instance_=new ctor());};}
-function deepCopy(value){if(!(value instanceof Object)){if(value===undefined||value===null)
-return value;if(typeof value=='string')
-return value.substring();if(typeof value=='boolean')
-return value;if(typeof value=='number')
-return value;throw new Error('Unrecognized: '+typeof value);}
-var object=value;if(object instanceof Array){var res=new Array(object.length);for(var i=0;i<object.length;i++)
-res[i]=deepCopy(object[i]);return res;}
-if(object.__proto__!=Object.prototype)
-throw new Error('Can only clone simple types');var res={};for(var key in object){res[key]=deepCopy(object[key]);}
-return res;}
-function normalizeException(e){if(e===undefined||e===null){return{typeName:'UndefinedError',message:'Unknown: null or undefined exception',stack:'Unknown'};}
-if(typeof(e)=='string'){return{typeName:'StringError',message:e,stack:[e]};}
-var typeName;if(e.name){typeName=e.name;}else if(e.constructor){if(e.constructor.name){typeName=e.constructor.name;}else{typeName='AnonymousError';}}else{typeName='ErrorWithNoConstructor';}
-var msg=e.message?e.message:'Unknown';return{typeName:typeName,message:msg,stack:e.stack?e.stack:[msg]};}
-function stackTraceAsString(){return new Error().stack+'';}
-function stackTrace(){var stack=stackTraceAsString();stack=stack.split('\n');return stack.slice(2);}
-function getUsingPath(path,from_dict){var parts=path.split('.');var cur=from_dict;for(var part;parts.length&&(part=parts.shift());){if(!parts.length){return cur[part];}else if(part in cur){cur=cur[part];}else{return undefined;}}
-return undefined;}
-return{addSingletonGetter:addSingletonGetter,deepCopy:deepCopy,normalizeException:normalizeException,stackTrace:stackTrace,stackTraceAsString:stackTraceAsString,getUsingPath:getUsingPath};});'use strict';tr.exportTo('tr.b',function(){var ESTIMATED_IDLE_PERIOD_LENGTH_MILLISECONDS=10;var REQUEST_IDLE_CALLBACK_TIMEOUT_MILLISECONDS=100;var recordRAFStacks=false;var pendingPreAFs=[];var pendingRAFs=[];var pendingIdleCallbacks=[];var currentRAFDispatchList=undefined;var rafScheduled=false;var idleWorkScheduled=false;function scheduleRAF(){if(rafScheduled)
-return;rafScheduled=true;if(tr.isHeadless){Promise.resolve().then(function(){processRequests(false,0);},function(e){console.log(e.stack);throw e;});}else{if(window.requestAnimationFrame){window.requestAnimationFrame(processRequests.bind(this,false));}else{var delta=Date.now()-window.performance.now();window.webkitRequestAnimationFrame(function(domTimeStamp){processRequests(false,domTimeStamp-delta);});}}}
+return{pointInTriangle2,pointInImplicitQuad,Quad,};});'use strict';tr.exportTo('tr.b',function(){const ESTIMATED_IDLE_PERIOD_LENGTH_MILLISECONDS=10;const REQUEST_IDLE_CALLBACK_TIMEOUT_MILLISECONDS=100;const recordRAFStacks=false;let pendingPreAFs=[];let pendingRAFs=[];const pendingIdleCallbacks=[];let currentRAFDispatchList=undefined;let rafScheduled=false;let idleWorkScheduled=false;function scheduleRAF(){if(rafScheduled)return;rafScheduled=true;if(tr.isHeadless){Promise.resolve().then(function(){processRequests(false,0);},function(e){throw e;});}else{if(window.requestAnimationFrame){window.requestAnimationFrame(processRequests.bind(this,false));}else{const delta=Date.now()-window.performance.now();window.webkitRequestAnimationFrame(function(domTimeStamp){processRequests(false,domTimeStamp-delta);});}}}
 function nativeRequestIdleCallbackSupported(){return!tr.isHeadless&&window.requestIdleCallback;}
-function scheduleIdleWork(){if(idleWorkScheduled)
-return;if(!nativeRequestIdleCallbackSupported()){scheduleRAF();return;}
+function scheduleIdleWork(){if(idleWorkScheduled)return;if(!nativeRequestIdleCallbackSupported()){scheduleRAF();return;}
 idleWorkScheduled=true;window.requestIdleCallback(function(deadline,didTimeout){processIdleWork(false,deadline);},{timeout:REQUEST_IDLE_CALLBACK_TIMEOUT_MILLISECONDS});}
-function onAnimationFrameError(e,opt_stack){console.log(e.stack);if(tr.isHeadless)
-throw e;if(opt_stack)
-console.log(opt_stack);if(e.message)
-console.error(e.message,e.stack);else
-console.error(e);}
+function onAnimationFrameError(e,opt_stack){console.log(e.stack);if(tr.isHeadless)throw e;if(opt_stack)console.log(opt_stack);if(e.message){console.error(e.message,e.stack);}else{console.error(e);}}
 function runTask(task,frameBeginTime){try{task.callback.call(task.context,frameBeginTime);}catch(e){tr.b.onAnimationFrameError(e,task.stack);}}
-function processRequests(forceAllTasksToRun,frameBeginTime){rafScheduled=false;var currentPreAFs=pendingPreAFs;currentRAFDispatchList=pendingRAFs;pendingPreAFs=[];pendingRAFs=[];var hasRAFTasks=currentPreAFs.length||currentRAFDispatchList.length;for(var i=0;i<currentPreAFs.length;i++)
-runTask(currentPreAFs[i],frameBeginTime);while(currentRAFDispatchList.length>0)
-runTask(currentRAFDispatchList.shift(),frameBeginTime);currentRAFDispatchList=undefined;if((!hasRAFTasks&&!nativeRequestIdleCallbackSupported())||forceAllTasksToRun){var rafCompletionDeadline=frameBeginTime+ESTIMATED_IDLE_PERIOD_LENGTH_MILLISECONDS;processIdleWork(forceAllTasksToRun,{timeRemaining:function(){return rafCompletionDeadline-window.performance.now();}});}
-if(pendingIdleCallbacks.length>0)
-scheduleIdleWork();}
+function processRequests(forceAllTasksToRun,frameBeginTime){rafScheduled=false;const currentPreAFs=pendingPreAFs;currentRAFDispatchList=pendingRAFs;pendingPreAFs=[];pendingRAFs=[];const hasRAFTasks=currentPreAFs.length||currentRAFDispatchList.length;for(let i=0;i<currentPreAFs.length;i++){runTask(currentPreAFs[i],frameBeginTime);}
+while(currentRAFDispatchList.length>0){runTask(currentRAFDispatchList.shift(),frameBeginTime);}
+currentRAFDispatchList=undefined;if((!hasRAFTasks&&!nativeRequestIdleCallbackSupported())||forceAllTasksToRun){const rafCompletionDeadline=frameBeginTime+ESTIMATED_IDLE_PERIOD_LENGTH_MILLISECONDS;processIdleWork(forceAllTasksToRun,{timeRemaining(){return rafCompletionDeadline-window.performance.now();}});}
+if(pendingIdleCallbacks.length>0)scheduleIdleWork();}
 function processIdleWork(forceAllTasksToRun,deadline){idleWorkScheduled=false;while(pendingIdleCallbacks.length>0){runTask(pendingIdleCallbacks.shift());if(!forceAllTasksToRun&&(tr.isHeadless||deadline.timeRemaining()<=0)){break;}}
-if(pendingIdleCallbacks.length>0)
-scheduleIdleWork();}
-function getStack_(){if(!recordRAFStacks)
-return'';var stackLines=tr.b.stackTrace();stackLines.shift();return stackLines.join('\n');}
-function requestPreAnimationFrame(callback,opt_this){pendingPreAFs.push({callback:callback,context:opt_this||global,stack:getStack_()});scheduleRAF();}
+if(pendingIdleCallbacks.length>0)scheduleIdleWork();}
+function getStack_(){if(!recordRAFStacks)return'';const stackLines=tr.b.stackTrace();stackLines.shift();return stackLines.join('\n');}
+function requestPreAnimationFrame(callback,opt_this){pendingPreAFs.push({callback,context:opt_this||global,stack:getStack_()});scheduleRAF();}
 function requestAnimationFrameInThisFrameIfPossible(callback,opt_this){if(!currentRAFDispatchList){requestAnimationFrame(callback,opt_this);return;}
-currentRAFDispatchList.push({callback:callback,context:opt_this||global,stack:getStack_()});return;}
-function requestAnimationFrame(callback,opt_this){pendingRAFs.push({callback:callback,context:opt_this||global,stack:getStack_()});scheduleRAF();}
-function requestIdleCallback(callback,opt_this){pendingIdleCallbacks.push({callback:callback,context:opt_this||global,stack:getStack_()});scheduleIdleWork();}
-function forcePendingRAFTasksToRun(frameBeginTime){if(!rafScheduled)
-return;processRequests(false,frameBeginTime);}
-function forceAllPendingTasksToRunForTest(){if(!rafScheduled&&!idleWorkScheduled)
-return;processRequests(true,0);}
-return{onAnimationFrameError:onAnimationFrameError,requestPreAnimationFrame:requestPreAnimationFrame,requestAnimationFrame:requestAnimationFrame,requestAnimationFrameInThisFrameIfPossible:requestAnimationFrameInThisFrameIfPossible,requestIdleCallback:requestIdleCallback,forcePendingRAFTasksToRun:forcePendingRAFTasksToRun,forceAllPendingTasksToRunForTest:forceAllPendingTasksToRunForTest};});'use strict';tr.exportTo('tr.b',function(){var Base64=tr.b.Base64;function computeUserTimingMarkName(groupName,functionName,opt_args){if(groupName===undefined)
-throw new Error('getMeasureString should have group name');if(functionName===undefined)
-throw new Error('getMeasureString should have function name');var userTimingMarkName=groupName+':'+functionName;if(opt_args!==undefined){userTimingMarkName+='/';userTimingMarkName+=Base64.btoa(JSON.stringify(opt_args));}
-return userTimingMarkName;}
-function Timing(){}
-Timing.nextMarkNumber=0;Timing.mark=function(groupName,functionName,opt_args){if(tr.isHeadless){return{end:function(){}};}
-var userTimingMarkName=computeUserTimingMarkName(groupName,functionName,opt_args);var markBeginName='tvcm.mark'+Timing.nextMarkNumber++;var markEndName='tvcm.mark'+Timing.nextMarkNumber++;window.performance.mark(markBeginName);return{end:function(){window.performance.mark(markEndName);window.performance.measure(userTimingMarkName,markBeginName,markEndName);}};};Timing.wrap=function(groupName,callback,opt_args){if(groupName===undefined)
-throw new Error('Timing.wrap should have group name');if(callback.name==='')
-throw new Error('Anonymous function is not allowed');return Timing.wrapNamedFunction(groupName,callback.name,callback,opt_args);};Timing.wrapNamedFunction=function(groupName,functionName,callback,opt_args){function timedNamedFunction(){var markedTime=Timing.mark(groupName,functionName,opt_args);try{callback.apply(this,arguments);}finally{markedTime.end();}}
-return timedNamedFunction;};function TimedNamedPromise(groupName,name,executor,opt_args){var markedTime=Timing.mark(groupName,name,opt_args);var promise=new Promise(executor);promise.then(function(result){markedTime.end();return result;},function(e){markedTime.end();throw e;});return promise;}
-return{_computeUserTimingMarkName:computeUserTimingMarkName,TimedNamedPromise:TimedNamedPromise,Timing:Timing};});'use strict';tr.exportTo('tr.b',function(){var Timing=tr.b.Timing;function Task(runCb,thisArg){if(runCb!==undefined&&thisArg===undefined)
-throw new Error('Almost certainly, you meant to pass a thisArg.');this.runCb_=runCb;this.thisArg_=thisArg;this.afterTask_=undefined;this.subTasks_=[];}
-Task.prototype={get name(){return this.runCb_.name;},subTask:function(cb,thisArg){if(cb instanceof Task)
-this.subTasks_.push(cb);else
-this.subTasks_.push(new Task(cb,thisArg));return this.subTasks_[this.subTasks_.length-1];},run:function(){if(this.runCb_!==undefined)
-this.runCb_.call(this.thisArg_,this);var subTasks=this.subTasks_;this.subTasks_=undefined;if(!subTasks.length)
-return this.afterTask_;for(var i=1;i<subTasks.length;i++)
-subTasks[i-1].afterTask_=subTasks[i];subTasks[subTasks.length-1].afterTask_=this.afterTask_;return subTasks[0];},after:function(cb,thisArg){if(this.afterTask_)
-throw new Error('Has an after task already');if(cb instanceof Task)
-this.afterTask_=cb;else
-this.afterTask_=new Task(cb,thisArg);return this.afterTask_;},timedAfter:function(groupName,cb,thisArg,opt_args){if(cb.name==='')
-throw new Error('Anonymous Task is not allowed');return this.namedTimedAfter(groupName,cb.name,cb,thisArg,opt_args);},namedTimedAfter:function(groupName,name,cb,thisArg,opt_args){if(this.afterTask_)
-throw new Error('Has an after task already');var realTask;if(cb instanceof Task)
-realTask=cb;else
-realTask=new Task(cb,thisArg);this.afterTask_=new Task(function(task){var markedTask=Timing.mark(groupName,name,opt_args);task.subTask(realTask,thisArg);task.subTask(function(){markedTask.end();},thisArg);},thisArg);return this.afterTask_;},enqueue:function(cb,thisArg){var lastTask=this;while(lastTask.afterTask_)
-lastTask=lastTask.afterTask_;return lastTask.after(cb,thisArg);}};Task.RunSynchronously=function(task){var curTask=task;while(curTask)
-curTask=curTask.run();}
-Task.RunWhenIdle=function(task){return new Promise(function(resolve,reject){var curTask=task;function runAnother(){try{curTask=curTask.run();}catch(e){reject(e);console.error(e.stack);return;}
-if(curTask){tr.b.requestIdleCallback(runAnother);return;}
+currentRAFDispatchList.push({callback,context:opt_this||global,stack:getStack_()});return;}
+function requestAnimationFrame(callback,opt_this){pendingRAFs.push({callback,context:opt_this||global,stack:getStack_()});scheduleRAF();}
+function animationFrame(){return new Promise(resolve=>requestAnimationFrame(resolve));}
+function requestIdleCallback(callback,opt_this){pendingIdleCallbacks.push({callback,context:opt_this||global,stack:getStack_()});scheduleIdleWork();}
+function forcePendingRAFTasksToRun(frameBeginTime){if(!rafScheduled)return;processRequests(false,frameBeginTime);}
+function forceAllPendingTasksToRunForTest(){if(!rafScheduled&&!idleWorkScheduled)return;processRequests(true,0);}
+function timeout(ms){return new Promise(resolve=>window.setTimeout(resolve,ms));}
+function idle(){return new Promise(resolve=>requestIdleCallback(resolve));}
+return{animationFrame,forceAllPendingTasksToRunForTest,forcePendingRAFTasksToRun,idle,onAnimationFrameError,requestAnimationFrame,requestAnimationFrameInThisFrameIfPossible,requestIdleCallback,requestPreAnimationFrame,timeout,};});'use strict';tr.exportTo('tr.b',function(){class Mark{constructor(groupName,functionName,opt_timestamp){if(tr.isHeadless)return;this.groupName_=groupName;this.functionName_=functionName;const guid=tr.b.GUID.allocateSimple();this.measureName_=`${groupName} ${functionName}`;if(opt_timestamp){this.startMark_={startTime:opt_timestamp};}else{this.startMarkName_=`${this.measureName} ${guid} start`;}
+this.endMark_=undefined;this.endMarkName_=`${this.measureName} ${guid} end`;window.performance.mark(this.startMarkName_);}
+get groupName(){return this.groupName_;}
+get functionName(){return this.functionName_;}
+get measureName(){return this.measureName_;}
+get startMark(){return this.startMark_||tr.b.getOnlyElement(window.performance.getEntriesByName(this.startMarkName_));}
+get endMark(){return this.endMark_||tr.b.getOnlyElement(window.performance.getEntriesByName(this.endMarkName_));}
+get durationMs(){return this.endMark.startTime-this.startMark.startTime;}
+end(opt_timestamp){if(tr.isHeadless)return;if(opt_timestamp){this.endMark_={startTime:opt_timestamp};}else{window.performance.mark(this.endMarkName_);}
+if(!this.startMark_&&!this.endMark_){window.performance.measure(this.measureName_,this.startMarkName_,this.endMarkName_);}else if(Timing.logVoidMarks&&!(window.ga instanceof Function)){console.log('void mark',this.groupName,this.functionName,this.durationMs);}
+if(!(window.ga instanceof Function))return;ga('send',{hitType:'event',eventCategory:this.groupName,eventAction:this.functionName,eventValue:this.durationMs,});}}
+class Timing{static mark(groupName,functionName,opt_timestamp){return new Mark(groupName,functionName,opt_timestamp);}
+static instant(groupName,functionName,opt_value){const valueString=opt_value===undefined?'':' '+opt_value;if(console&&console.timeStamp){console.timeStamp(`${groupName} ${functionName}${valueString}`);}
+if(window&&window.ga instanceof Function){ga('send',{hitType:'event',eventCategory:groupName,eventAction:functionName,eventValue:opt_value,});}}
+static getCurrentTimeMs(){try{return performance.now();}catch(error){}
+return 0;}}
+Timing.logVoidMarks=false;return{Timing,};});'use strict';tr.exportTo('tr.b',function(){const Timing=tr.b.Timing;function Task(runCb,thisArg){if(runCb!==undefined&&thisArg===undefined&&runCb.prototype!==undefined){throw new Error('Almost certainly you meant to pass a bound callback '+'or thisArg.');}
+this.runCb_=runCb;this.thisArg_=thisArg;this.afterTask_=undefined;this.subTasks_=[];this.updatesUi_=false;}
+Task.prototype={get name(){return this.runCb_.name;},set updatesUi(value){this.updatesUi_=value;},subTask(cb,thisArg){if(cb instanceof Task){this.subTasks_.push(cb);}else{this.subTasks_.push(new Task(cb,thisArg));}
+return this.subTasks_[this.subTasks_.length-1];},run(){if(this.runCb_!==undefined)this.runCb_.call(this.thisArg_,this);const subTasks=this.subTasks_;this.subTasks_=undefined;if(!subTasks.length)return this.afterTask_;for(let i=1;i<subTasks.length;i++){subTasks[i-1].afterTask_=subTasks[i];}
+subTasks[subTasks.length-1].afterTask_=this.afterTask_;return subTasks[0];},after(cb,thisArg){if(this.afterTask_){throw new Error('Has an after task already');}
+if(cb instanceof Task){this.afterTask_=cb;}else{this.afterTask_=new Task(cb,thisArg);}
+return this.afterTask_;},enqueue(cb,thisArg){if(!this.afterTask_)return this.after(cb,thisArg);return this.afterTask_.enqueue(cb,thisArg);}};Task.RunSynchronously=function(task){let curTask=task;while(curTask){curTask=curTask.run();}};Task.RunWhenIdle=function(task){return new Promise(function(resolve,reject){let curTask=task;function runAnother(){try{curTask=curTask.run();}catch(e){reject(e);return;}
+if(curTask){if(curTask.updatesUi_){tr.b.requestAnimationFrameInThisFrameIfPossible(runAnother);}else{tr.b.requestIdleCallback(runAnother);}
+return;}
 resolve();}
-tr.b.requestIdleCallback(runAnother);});}
-return{Task:Task};});'use strict';tr.exportTo('tr.c',function(){function makeCaseInsensitiveRegex(pattern){pattern=pattern.replace(/[.*+?^${}()|[\]\\]/g,'\\$&');return new RegExp(pattern,'i');}
+tr.b.requestIdleCallback(runAnother);});};return{Task,};});'use strict';tr.exportTo('tr.c',function(){function makeCaseInsensitiveRegex(pattern){pattern=pattern.replace(/[.*+?^${}()|[\]\\]/g,'\\$&');return new RegExp(pattern,'i');}
 function Filter(){}
-Filter.prototype={__proto__:Object.prototype,matchCounter:function(counter){return true;},matchCpu:function(cpu){return true;},matchProcess:function(process){return true;},matchSlice:function(slice){return true;},matchThread:function(thread){return true;}};function TitleOrCategoryFilter(text){Filter.call(this);this.regex_=makeCaseInsensitiveRegex(text);if(!text.length)
-throw new Error('Filter text is empty.');}
-TitleOrCategoryFilter.prototype={__proto__:Filter.prototype,matchSlice:function(slice){if(slice.title===undefined&&slice.category===undefined)
-return false;return this.regex_.test(slice.title)||(!!slice.category&&this.regex_.test(slice.category));}};function ExactTitleFilter(text){Filter.call(this);this.text_=text;if(!text.length)
-throw new Error('Filter text is empty.');}
-ExactTitleFilter.prototype={__proto__:Filter.prototype,matchSlice:function(slice){return slice.title===this.text_;}};function FullTextFilter(text){Filter.call(this);this.regex_=makeCaseInsensitiveRegex(text);this.titleOrCategoryFilter_=new TitleOrCategoryFilter(text);}
-FullTextFilter.prototype={__proto__:Filter.prototype,matchObject_:function(obj){for(var key in obj){if(!obj.hasOwnProperty(key))
-continue;if(this.regex_.test(key))
-return true;if(this.regex_.test(obj[key]))
-return true;}
-return false;},matchSlice:function(slice){if(this.titleOrCategoryFilter_.matchSlice(slice))
-return true;return this.matchObject_(slice.args);}};return{Filter:Filter,TitleOrCategoryFilter:TitleOrCategoryFilter,ExactTitleFilter:ExactTitleFilter,FullTextFilter:FullTextFilter};});'use strict';tr.exportTo('tr.model',function(){var ClockDomainId={BATTOR:'battor',TRACE_EVENT_IMPORTER:'trace_event_importer'};function ClockSyncManager(){this.connectorBySyncId_={};this.modelDomainId_=undefined;this.modelTimeTransformerByDomainId_=undefined;}
-ClockSyncManager.prototype={addClockSyncMarker:function(domainId,syncId,startTs,opt_endTs){if(tr.b.dictionaryValues(ClockDomainId).indexOf(domainId)<0){throw new Error('"'+domainId+'" is not in the list of known '+'clock domain IDs.');}
-if(this.modelDomainId_!==undefined){throw new Error('Cannot add new clock sync markers after getting '+'a model time transformer.');}
-var marker=new ClockSyncMarker(domainId,startTs,opt_endTs);var connector=this.connectorBySyncId_[syncId];if(connector===undefined){this.connectorBySyncId_[syncId]=new ClockSyncConnector(marker);return;}
-if(connector.marker2!==undefined){throw new Error('Clock sync with ID "'+syncId+'" is already '+'complete - cannot add a third clock sync marker to it.');}
-if(connector.marker1.domainId===domainId)
-throw new Error('A clock domain cannot sync with itself.');if(this.getConnectorBetween_(connector.marker1.domainId,domainId)!==undefined){throw new Error('Cannot add multiple connectors between the same '+'clock domains.');}
-connector.marker2=marker;},getModelTimeTransformer:function(domainId){if(this.modelTimeTransformerByDomainId_===undefined)
-this.buildModelTimeTransformerMap_();var transformer=this.modelTimeTransformerByDomainId_[domainId];if(transformer===undefined){throw new Error('No clock sync markers exist pairing clock domain "'+
-domainId+'" '+'with model clock domain "'+
-this.modelDomainId_+'".');}
-return transformer;},buildModelTimeTransformerMap_(){var completeConnectorsByDomainId=this.getCompleteConnectorsByDomainId_();var uniqueDomainIds=tr.b.dictionaryKeys(completeConnectorsByDomainId);uniqueDomainIds.sort();var isFullyConnected=function(domainId){return completeConnectorsByDomainId[domainId].length===uniqueDomainIds.length-1;};var eligibleModelDomainIds=uniqueDomainIds.filter(isFullyConnected);var traceEventImporterDomainExists=eligibleModelDomainIds.indexOf(ClockDomainId.TRACE_EVENT_IMPORTER)>=0;this.modelDomainId_=traceEventImporterDomainExists?ClockDomainId.TRACE_EVENT_IMPORTER:eligibleModelDomainIds[0];if(this.modelDomainId_===undefined){throw new Error('Unable to select a master clock domain because no '+'clock domain is directly connected to all others.');}
-this.modelTimeTransformerByDomainId_={};this.modelTimeTransformerByDomainId_[this.modelDomainId_]=tr.b.identity;var modelConnectors=completeConnectorsByDomainId[this.modelDomainId_];for(var i=0;i<modelConnectors.length;i++){var conn=modelConnectors[i];if(conn.marker1.domainId===this.modelDomainId_){this.modelTimeTransformerByDomainId_[conn.marker2.domainId]=conn.getTransformer(conn.marker2.domainId,conn.marker1.domainId);}else{this.modelTimeTransformerByDomainId_[conn.marker1.domainId]=conn.getTransformer(conn.marker1.domainId,conn.marker2.domainId);}}},getCompleteConnectorsByDomainId_:function(){var completeConnectorsByDomainId={};for(var syncId in this.connectorBySyncId_){var conn=this.connectorBySyncId_[syncId];var domain1=conn.marker1.domainId;if(completeConnectorsByDomainId[domain1]===undefined)
-completeConnectorsByDomainId[domain1]=[];if(conn.marker2===undefined)
-continue;var domain2=conn.marker2.domainId;if(completeConnectorsByDomainId[domain2]===undefined)
-completeConnectorsByDomainId[domain2]=[];completeConnectorsByDomainId[domain1].push(conn);completeConnectorsByDomainId[domain2].push(conn);}
-return completeConnectorsByDomainId;},getConnectorBetween_(domain1Id,domain2Id){for(var syncId in this.connectorBySyncId_){var connector=this.connectorBySyncId_[syncId];if(connector.isBetween(domain1Id,domain2Id))
-return connector;}
-return undefined;}};function ClockSyncMarker(domainId,startTs,opt_endTs){this.domainId=domainId;this.startTs=startTs;this.endTs=opt_endTs===undefined?startTs:opt_endTs;}
-ClockSyncMarker.prototype={get ts(){return(this.startTs+this.endTs)/2;}};function ClockSyncConnector(opt_marker1,opt_marker2){this.marker1=opt_marker1;this.marker2=opt_marker2;}
-ClockSyncConnector.prototype={getTransformer:function(fromDomainId,toDomainId){if(!this.isBetween(fromDomainId,toDomainId))
-throw new Error('This connector cannot perform this transformation.');var fromMarker,toMarker;if(this.marker1.domainId===fromDomainId){fromMarker=this.marker1;toMarker=this.marker2;}else{fromMarker=this.marker2;toMarker=this.marker1;}
-var fromTs=fromMarker.ts,toTs=toMarker.ts;if(fromDomainId==ClockDomainId.BATTOR&&toDomainId==ClockDomainId.TRACE_EVENT_IMPORTER){toTs=toMarker.startTs;}else if(fromDomainId==ClockDomainId.TRACE_EVENT_IMPORTER&&toDomainId==ClockDomainId.BATTOR){fromTs=fromMarker.startTs;}
-var tsShift=toTs-fromTs;return function(ts){return ts+tsShift;};},isBetween:function(domain1Id,domain2Id){if(this.marker1===undefined||this.marker2===undefined)
-return false;if(this.marker1.domainId===domain1Id&&this.marker2.domainId===domain2Id){return true;}
-if(this.marker1.domainId===domain2Id&&this.marker2.domainId===domain1Id){return true;}
-return false;}};return{ClockDomainId:ClockDomainId,ClockSyncManager:ClockSyncManager};});'use strict';tr.exportTo('tr.model',function(){function EventContainer(){this.guid_=tr.b.GUID.allocate();this.important=true;this.bounds_=new tr.b.Range();}
-EventContainer.prototype={get guid(){return this.guid_;},get stableId(){throw new Error('Not implemented');},get bounds(){return this.bounds_;},updateBounds:function(){throw new Error('Not implemented');},shiftTimestampsForward:function(amount){throw new Error('Not implemented');},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){throw new Error('Not implemented');},iterateAllChildEventContainers:function(callback,opt_this){throw new Error('Not implemented');},iterateAllEvents:function(callback,opt_this){this.iterateAllEventContainers(function(ec){ec.iterateAllEventsInThisContainer(function(eventType){return true;},callback,opt_this);});},iterateAllEventContainers:function(callback,opt_this){function visit(ec){callback.call(opt_this,ec);ec.iterateAllChildEventContainers(visit);}
-visit(this);}};return{EventContainer:EventContainer};});'use strict';tr.exportTo('tr.model',function(){var Event=tr.model.Event;var EventRegistry=tr.model.EventRegistry;function PowerSample(series,start,power){Event.call(this);this.series_=series;this.start_=start;this.power_=power;}
-PowerSample.prototype={__proto__:Event.prototype,get series(){return this.series_;},get start(){return this.start_;},set start(value){this.start_=value;},get power(){return this.power_;},set power(value){this.power_=value;},addBoundsToRange:function(range){range.addValue(this.start);}};EventRegistry.register(PowerSample,{name:'powerSample',pluralName:'powerSamples',singleViewElementName:'tr-ui-a-single-power-sample-sub-view',multiViewElementName:'tr-ui-a-multi-power-sample-sub-view'});return{PowerSample:PowerSample};});'use strict';tr.exportTo('tr.model',function(){var PowerSample=tr.model.PowerSample;function PowerSeries(device){tr.model.EventContainer.call(this);this.device_=device;this.samples_=[];}
-PowerSeries.prototype={__proto__:tr.model.EventContainer.prototype,get device(){return this.device_;},get samples(){return this.samples_;},get stableId(){return this.device_.stableId+'.PowerSeries';},addPowerSample:function(ts,val){var sample=new PowerSample(this,ts,val);this.samples_.push(sample);return sample;},getEnergyConsumed:function(start,end){var measurementRange=tr.b.Range.fromExplicitRange(start,end);var energyConsumed=0;for(var i=0;i<this.samples.length;i++){var sample=this.samples[i];var nextSample=this.samples[i+1];var sampleRange=new tr.b.Range();sampleRange.addValue(sample.start);sampleRange.addValue(nextSample?nextSample.start:Infinity);var timeIntersection=measurementRange.findIntersection(sampleRange);var powerInWatts=sample.power/1000.0;var durationInSeconds=timeIntersection.duration/1000;energyConsumed+=durationInSeconds*powerInWatts;}
-return energyConsumed;},shiftTimestampsForward:function(amount){for(var i=0;i<this.samples_.length;++i)
-this.samples_[i].start+=amount;},updateBounds:function(){this.bounds.reset();if(this.samples_.length===0)
-return;this.bounds.addValue(this.samples_[0].start);this.bounds.addValue(this.samples_[this.samples_.length-1].start);},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,PowerSample))
-this.samples_.forEach(callback,opt_this);},iterateAllChildEventContainers:function(callback,opt_this){}};return{PowerSeries:PowerSeries};});'use strict';tr.exportTo('tr.model',function(){function Device(model){if(!model)
-throw new Error('Must provide a model.');tr.model.EventContainer.call(this);this.powerSeries_=undefined;this.vSyncTimestamps_=[];};Device.compare=function(x,y){return x.guid-y.guid;};Device.prototype={__proto__:tr.model.EventContainer.prototype,compareTo:function(that){return Device.compare(this,that);},get userFriendlyName(){return'Device';},get userFriendlyDetails(){return'Device';},get stableId(){return'Device';},getSettingsKey:function(){return'device';},get powerSeries(){return this.powerSeries_;},set powerSeries(powerSeries){this.powerSeries_=powerSeries;},get vSyncTimestamps(){return this.vSyncTimestamps_;},set vSyncTimestamps(value){this.vSyncTimestamps_=value;},updateBounds:function(){this.bounds.reset();this.iterateAllChildEventContainers(function(child){child.updateBounds();this.bounds.addRange(child.bounds);},this);},shiftTimestampsForward:function(amount){this.iterateAllChildEventContainers(function(child){child.shiftTimestampsForward(amount);});for(var i=0;i<this.vSyncTimestamps_.length;i++)
-this.vSyncTimestamps_[i]+=amount;},addCategoriesToDict:function(categoriesDict){},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){},iterateAllChildEventContainers:function(callback,opt_this){if(this.powerSeries_)
-callback.call(opt_this,this.powerSeries_);}};return{Device:Device};});'use strict';tr.exportTo('tr.model',function(){function FlowEvent(category,id,title,colorId,start,args,opt_duration){tr.model.TimedEvent.call(this,start);this.category=category||'';this.title=title;this.colorId=colorId;this.start=start;this.args=args;this.id=id;this.startSlice=undefined;this.endSlice=undefined;this.startStackFrame=undefined;this.endStackFrame=undefined;if(opt_duration!==undefined)
-this.duration=opt_duration;}
+Filter.prototype={__proto__:Object.prototype,matchCounter(counter){return true;},matchCpu(cpu){return true;},matchProcess(process){return true;},matchSlice(slice){return true;},matchThread(thread){return true;}};function TitleOrCategoryFilter(text){Filter.call(this);this.regex_=makeCaseInsensitiveRegex(text);if(!text.length){throw new Error('Filter text is empty.');}}
+TitleOrCategoryFilter.prototype={__proto__:Filter.prototype,matchSlice(slice){if(slice.title===undefined&&slice.category===undefined){return false;}
+return this.regex_.test(slice.title)||(!!slice.category&&this.regex_.test(slice.category));}};function ExactTitleFilter(text){Filter.call(this);this.text_=text;if(!text.length){throw new Error('Filter text is empty.');}}
+ExactTitleFilter.prototype={__proto__:Filter.prototype,matchSlice(slice){return slice.title===this.text_;}};function FullTextFilter(text){Filter.call(this);this.regex_=makeCaseInsensitiveRegex(text);this.titleOrCategoryFilter_=new TitleOrCategoryFilter(text);}
+FullTextFilter.prototype={__proto__:Filter.prototype,matchObject_(obj){for(const key in obj){if(!obj.hasOwnProperty(key))continue;if(this.regex_.test(key))return true;if(this.regex_.test(obj[key]))return true;}
+return false;},matchSlice(slice){if(this.titleOrCategoryFilter_.matchSlice(slice))return true;return this.matchObject_(slice.args);}};return{Filter,TitleOrCategoryFilter,ExactTitleFilter,FullTextFilter,};});'use strict';tr.exportTo('tr.model',function(){const ClockDomainId={BATTOR:'BATTOR',UNKNOWN_CHROME_LEGACY:'UNKNOWN_CHROME_LEGACY',LINUX_CLOCK_MONOTONIC:'LINUX_CLOCK_MONOTONIC',LINUX_FTRACE_GLOBAL:'LINUX_FTRACE_GLOBAL',MAC_MACH_ABSOLUTE_TIME:'MAC_MACH_ABSOLUTE_TIME',WIN_ROLLOVER_PROTECTED_TIME_GET_TIME:'WIN_ROLLOVER_PROTECTED_TIME_GET_TIME',WIN_QPC:'WIN_QPC',SYSTRACE:'SYSTRACE',TELEMETRY:'TELEMETRY'};const POSSIBLE_CHROME_CLOCK_DOMAINS=new Set([ClockDomainId.UNKNOWN_CHROME_LEGACY,ClockDomainId.LINUX_CLOCK_MONOTONIC,ClockDomainId.MAC_MACH_ABSOLUTE_TIME,ClockDomainId.WIN_ROLLOVER_PROTECTED_TIME_GET_TIME,ClockDomainId.WIN_QPC]);const BATTOR_FAST_SYNC_THRESHOLD_MS=3;function ClockSyncManager(){this.domainsSeen_=new Set();this.markersBySyncId_=new Map();this.transformerMapByDomainId_={};}
+ClockSyncManager.prototype={addClockSyncMarker(domainId,syncId,startTs,opt_endTs){this.onDomainSeen_(domainId);if(Object.values(ClockDomainId).indexOf(domainId)<0){throw new Error('"'+domainId+'" is not in the list of known '+'clock domain IDs.');}
+if(this.modelDomainId_){throw new Error('Cannot add new clock sync markers after getting '+'a model time transformer.');}
+const marker=new ClockSyncMarker(domainId,startTs,opt_endTs);if(!this.markersBySyncId_.has(syncId)){this.markersBySyncId_.set(syncId,[marker]);return;}
+const markers=this.markersBySyncId_.get(syncId);if(markers.length===2){throw new Error('Clock sync with ID "'+syncId+'" is already '+'complete - cannot add a third clock sync marker to it.');}
+if(markers[0].domainId===domainId){throw new Error('A clock domain cannot sync with itself.');}
+markers.push(marker);this.onSyncCompleted_(markers[0],marker);},get completeSyncIds(){const completeSyncIds=[];for(const[syncId,markers]of this.markersBySyncId){if(markers.length===2)completeSyncIds.push(syncId);}
+return completeSyncIds;},get markersBySyncId(){return this.markersBySyncId_;},get domainsSeen(){return this.domainsSeen_;},getModelTimeTransformer(domainId){this.onDomainSeen_(domainId);if(!this.modelDomainId_){this.selectModelDomainId_();}
+return this.getTimeTransformerRaw_(domainId,this.modelDomainId_).fn;},getTimeTransformerError(fromDomainId,toDomainId){this.onDomainSeen_(fromDomainId);this.onDomainSeen_(toDomainId);return this.getTimeTransformerRaw_(fromDomainId,toDomainId).error;},getTimeTransformerRaw_(fromDomainId,toDomainId){const transformer=this.getTransformerBetween_(fromDomainId,toDomainId);if(!transformer){throw new Error('No clock sync markers exist pairing clock domain "'+
+fromDomainId+'" '+'with target clock domain "'+
+toDomainId+'".');}
+return transformer;},getTransformerBetween_(fromDomainId,toDomainId){const visitedDomainIds=new Set();const queue=[{domainId:fromDomainId,transformer:Transformer.IDENTITY}];while(queue.length>0){queue.sort((domain1,domain2)=>domain1.transformer.error-domain2.transformer.error);const current=queue.shift();if(current.domainId===toDomainId){return current.transformer;}
+if(visitedDomainIds.has(current.domainId)){continue;}
+visitedDomainIds.add(current.domainId);const outgoingTransformers=this.transformerMapByDomainId_[current.domainId];if(!outgoingTransformers)continue;for(const outgoingDomainId in outgoingTransformers){const toNextDomainTransformer=outgoingTransformers[outgoingDomainId];const toCurrentDomainTransformer=current.transformer;queue.push({domainId:outgoingDomainId,transformer:Transformer.compose(toNextDomainTransformer,toCurrentDomainTransformer)});}}
+return undefined;},selectModelDomainId_(){this.ensureAllDomainsAreConnected_();for(const chromeDomainId of POSSIBLE_CHROME_CLOCK_DOMAINS){if(this.domainsSeen_.has(chromeDomainId)){this.modelDomainId_=chromeDomainId;return;}}
+const domainsSeenArray=Array.from(this.domainsSeen_);domainsSeenArray.sort();this.modelDomainId_=domainsSeenArray[0];},ensureAllDomainsAreConnected_(){let firstDomainId=undefined;for(const domainId of this.domainsSeen_){if(!firstDomainId){firstDomainId=domainId;continue;}
+if(!this.getTransformerBetween_(firstDomainId,domainId)){throw new Error('Unable to select a master clock domain because no '+'path can be found from "'+firstDomainId+'" to "'+domainId+'".');}}
+return true;},onDomainSeen_(domainId){if(domainId===ClockDomainId.UNKNOWN_CHROME_LEGACY&&!this.domainsSeen_.has(ClockDomainId.UNKNOWN_CHROME_LEGACY)){for(const chromeDomainId of POSSIBLE_CHROME_CLOCK_DOMAINS){if(chromeDomainId===ClockDomainId.UNKNOWN_CHROME_LEGACY){continue;}
+this.collapseDomains_(ClockDomainId.UNKNOWN_CHROME_LEGACY,chromeDomainId);}}
+this.domainsSeen_.add(domainId);},onSyncCompleted_(marker1,marker2){const forwardTransformer=Transformer.fromMarkers(marker1,marker2);const backwardTransformer=Transformer.fromMarkers(marker2,marker1);const existingTransformer=this.getOrCreateTransformerMap_(marker1.domainId)[marker2.domainId];if(!existingTransformer||forwardTransformer.error<existingTransformer.error){this.getOrCreateTransformerMap_(marker1.domainId)[marker2.domainId]=forwardTransformer;this.getOrCreateTransformerMap_(marker2.domainId)[marker1.domainId]=backwardTransformer;}},collapseDomains_(domain1Id,domain2Id){this.getOrCreateTransformerMap_(domain1Id)[domain2Id]=this.getOrCreateTransformerMap_(domain2Id)[domain1Id]=Transformer.IDENTITY;},getOrCreateTransformerMap_(domainId){if(!this.transformerMapByDomainId_[domainId]){this.transformerMapByDomainId_[domainId]={};}
+return this.transformerMapByDomainId_[domainId];},computeDotGraph(){let dotString='graph {\n';const domainsSeen=[...this.domainsSeen_].sort();for(const domainId of domainsSeen){dotString+=`  ${domainId}[shape=box]\n`;}
+const markersBySyncIdEntries=[...this.markersBySyncId_.entries()].sort(([syncId1,markers1],[syncId2,markers2])=>syncId1.localeCompare(syncId2));for(const[syncId,markers]of markersBySyncIdEntries){const sortedMarkers=markers.sort((a,b)=>a.domainId.localeCompare(b.domainId));for(const m of markers){dotString+=`  "${syncId}" -- ${m.domainId} `;dotString+=`[label="[${m.startTs}, ${m.endTs}]"]\n`;}}
+dotString+='}';return dotString;}};function ClockSyncMarker(domainId,startTs,opt_endTs){this.domainId=domainId;this.startTs=startTs;this.endTs=opt_endTs===undefined?startTs:opt_endTs;}
+ClockSyncMarker.prototype={get duration(){return this.endTs-this.startTs;},get ts(){return this.startTs+this.duration/2;}};function Transformer(fn,error){this.fn=fn;this.error=error;}
+Transformer.IDENTITY=new Transformer((x=>x),0);Transformer.compose=function(aToB,bToC){return new Transformer((ts)=>bToC.fn(aToB.fn(ts)),aToB.error+bToC.error);};Transformer.fromMarkers=function(fromMarker,toMarker){let fromTs=fromMarker.ts;let toTs=toMarker.ts;if(fromMarker.domainId===ClockDomainId.BATTOR&&toMarker.duration>BATTOR_FAST_SYNC_THRESHOLD_MS){toTs=toMarker.startTs;}else if(toMarker.domainId===ClockDomainId.BATTOR&&fromMarker.duration>BATTOR_FAST_SYNC_THRESHOLD_MS){fromTs=fromMarker.startTs;}
+const tsShift=toTs-fromTs;return new Transformer((ts)=>ts+tsShift,fromMarker.duration+toMarker.duration);};return{ClockDomainId,ClockSyncManager,};});'use strict';tr.exportTo('tr.model',function(){function CounterSample(series,timestamp,value){tr.model.Event.call(this);this.series_=series;this.timestamp_=timestamp;this.value_=value;}
+CounterSample.groupByTimestamp=function(samples){const samplesByTimestamp=tr.b.groupIntoMap(samples,s=>s.timestamp);const timestamps=Array.from(samplesByTimestamp.keys());timestamps.sort();const groups=[];for(const ts of timestamps){const group=samplesByTimestamp.get(ts);group.sort((x,y)=>x.series.seriesIndex-y.series.seriesIndex);groups.push(group);}
+return groups;};CounterSample.prototype={__proto__:tr.model.Event.prototype,get series(){return this.series_;},get timestamp(){return this.timestamp_;},get value(){return this.value_;},set timestamp(timestamp){this.timestamp_=timestamp;},addBoundsToRange(range){range.addValue(this.timestamp);},getSampleIndex(){return tr.b.findLowIndexInSortedArray(this.series.timestamps,function(x){return x;},this.timestamp_);},get userFriendlyName(){return'Counter sample from '+this.series_.title+' at '+
+tr.b.Unit.byName.timeStampInMs.format(this.timestamp);}};tr.model.EventRegistry.register(CounterSample,{name:'counterSample',pluralName:'counterSamples'});return{CounterSample,};});'use strict';tr.exportTo('tr.model',function(){const CounterSample=tr.model.CounterSample;function CounterSeries(name,color){tr.model.EventContainer.call(this);this.name_=name;this.color_=color;this.timestamps_=[];this.samples_=[];this.counter=undefined;this.seriesIndex=undefined;}
+CounterSeries.prototype={__proto__:tr.model.EventContainer.prototype,get length(){return this.timestamps_.length;},get name(){return this.name_;},get color(){return this.color_;},get samples(){return this.samples_;},get timestamps(){return this.timestamps_;},getSample(idx){return this.samples_[idx];},getTimestamp(idx){return this.timestamps_[idx];},addCounterSample(ts,val){const sample=new CounterSample(this,ts,val);this.addSample(sample);return sample;},addSample(sample){this.timestamps_.push(sample.timestamp);this.samples_.push(sample);},getStatistics(sampleIndices){let sum=0;let min=Number.MAX_VALUE;let max=-Number.MAX_VALUE;for(let i=0;i<sampleIndices.length;++i){const sample=this.getSample(sampleIndices[i]).value;sum+=sample;min=Math.min(sample,min);max=Math.max(sample,max);}
+return{min,max,avg:(sum/sampleIndices.length),start:this.getSample(sampleIndices[0]).value,end:this.getSample(sampleIndices.length-1).value};},shiftTimestampsForward(amount){for(let i=0;i<this.timestamps_.length;++i){this.timestamps_[i]+=amount;this.samples_[i].timestamp=this.timestamps_[i];}},*childEvents(){yield*this.samples_;},*childEventContainers(){}};return{CounterSeries,};});'use strict';tr.exportTo('tr.model',function(){function Counter(parent,id,category,name){tr.model.EventContainer.call(this);this.parent_=parent;this.id_=id;this.category_=category||'';this.name_=name;this.series_=[];this.totals=[];}
+Counter.prototype={__proto__:tr.model.EventContainer.prototype,get parent(){return this.parent_;},get id(){return this.id_;},get category(){return this.category_;},get name(){return this.name_;},*childEvents(){},*childEventContainers(){yield*this.series;},set timestamps(arg){throw new Error('Bad counter API. No cookie.');},set seriesNames(arg){throw new Error('Bad counter API. No cookie.');},set seriesColors(arg){throw new Error('Bad counter API. No cookie.');},set samples(arg){throw new Error('Bad counter API. No cookie.');},addSeries(series){series.counter=this;series.seriesIndex=this.series_.length;this.series_.push(series);return series;},getSeries(idx){return this.series_[idx];},get series(){return this.series_;},get numSeries(){return this.series_.length;},get numSamples(){if(this.series_.length===0)return 0;return this.series_[0].length;},get timestamps(){if(this.series_.length===0)return[];return this.series_[0].timestamps;},getSampleStatistics(sampleIndices){sampleIndices.sort();const ret=[];this.series_.forEach(function(series){ret.push(series.getStatistics(sampleIndices));});return ret;},shiftTimestampsForward(amount){for(let i=0;i<this.series_.length;++i){this.series_[i].shiftTimestampsForward(amount);}},updateBounds(){this.totals=[];this.maxTotal=0;this.bounds.reset();if(this.series_.length===0)return;const firstSeries=this.series_[0];const lastSeries=this.series_[this.series_.length-1];this.bounds.addValue(firstSeries.getTimestamp(0));this.bounds.addValue(lastSeries.getTimestamp(lastSeries.length-1));const numSeries=this.numSeries;this.maxTotal=-Infinity;for(let i=0;i<firstSeries.length;++i){let total=0;this.series_.forEach(function(series){total+=series.getSample(i).value;this.totals.push(total);}.bind(this));this.maxTotal=Math.max(total,this.maxTotal);}}};Counter.compare=function(x,y){let tmp=x.parent.compareTo(y.parent);if(tmp!==0)return tmp;tmp=x.name.localeCompare(y.name);if(tmp===0)return x.tid-y.tid;return tmp;};return{Counter,};});'use strict';tr.exportTo('tr.model',function(){const Slice=tr.model.Slice;function CpuSlice(cat,title,colorId,start,args,opt_duration){Slice.apply(this,arguments);this.threadThatWasRunning=undefined;this.cpu=undefined;}
+CpuSlice.prototype={__proto__:Slice.prototype,get analysisTypeName(){return'tr.ui.analysis.CpuSlice';},getAssociatedTimeslice(){if(!this.threadThatWasRunning){return undefined;}
+const timeSlices=this.threadThatWasRunning.timeSlices;for(let i=0;i<timeSlices.length;i++){const timeSlice=timeSlices[i];if(timeSlice.start!==this.start){continue;}
+if(timeSlice.duration!==this.duration){continue;}
+return timeSlice;}
+return undefined;}};tr.model.EventRegistry.register(CpuSlice,{name:'cpuSlice',pluralName:'cpuSlices'});return{CpuSlice,};});'use strict';tr.exportTo('tr.model',function(){function TimeToObjectInstanceMap(createObjectInstanceFunction,parent,scopedId){this.createObjectInstanceFunction_=createObjectInstanceFunction;this.parent=parent;this.scopedId=scopedId;this.instances=[];}
+TimeToObjectInstanceMap.prototype={idWasCreated(category,name,ts){if(this.instances.length===0){this.instances.push(this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts));this.instances[0].creationTsWasExplicit=true;return this.instances[0];}
+let lastInstance=this.instances[this.instances.length-1];if(ts<lastInstance.deletionTs){throw new Error('Mutation of the TimeToObjectInstanceMap must be '+'done in ascending timestamp order.');}
+lastInstance=this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts);lastInstance.creationTsWasExplicit=true;this.instances.push(lastInstance);return lastInstance;},addSnapshot(category,name,ts,args,opt_baseTypeName){if(this.instances.length===0){this.instances.push(this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts,opt_baseTypeName));}
+const i=tr.b.findIndexInSortedIntervals(this.instances,function(inst){return inst.creationTs;},function(inst){return inst.deletionTs-inst.creationTs;},ts);let instance;if(i<0){instance=this.instances[0];if(ts>instance.deletionTs||instance.creationTsWasExplicit){throw new Error('At the provided timestamp, no instance was still alive');}
+if(instance.snapshots.length!==0){throw new Error('Cannot shift creationTs forward, '+'snapshots have been added. First snap was at ts='+
+instance.snapshots[0].ts+' and creationTs was '+
+instance.creationTs);}
+instance.creationTs=ts;}else if(i>=this.instances.length){instance=this.instances[this.instances.length-1];if(ts>=instance.deletionTs){instance=this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts,opt_baseTypeName);this.instances.push(instance);}else{let lastValidIndex;for(let i=this.instances.length-1;i>=0;i--){const tmp=this.instances[i];if(ts>=tmp.deletionTs)break;if(tmp.creationTsWasExplicit===false&&tmp.snapshots.length===0){lastValidIndex=i;}}
+if(lastValidIndex===undefined){throw new Error('Cannot add snapshot. No instance was alive that was mutable.');}
+instance=this.instances[lastValidIndex];instance.creationTs=ts;}}else{instance=this.instances[i];}
+return instance.addSnapshot(ts,args,name,opt_baseTypeName);},get lastInstance(){if(this.instances.length===0)return undefined;return this.instances[this.instances.length-1];},idWasDeleted(category,name,ts){if(this.instances.length===0){this.instances.push(this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts));}
+let lastInstance=this.instances[this.instances.length-1];if(ts<lastInstance.creationTs){throw new Error('Cannot delete an id before it was created');}
+if(lastInstance.deletionTs===Number.MAX_VALUE){lastInstance.wasDeleted(ts);return lastInstance;}
+if(ts<lastInstance.deletionTs){throw new Error('id was already deleted earlier.');}
+lastInstance=this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts);this.instances.push(lastInstance);lastInstance.wasDeleted(ts);return lastInstance;},getInstanceAt(ts){const i=tr.b.findIndexInSortedIntervals(this.instances,function(inst){return inst.creationTs;},function(inst){return inst.deletionTs-inst.creationTs;},ts);if(i<0){if(this.instances[0].creationTsWasExplicit){return undefined;}
+return this.instances[0];}else if(i>=this.instances.length){return undefined;}
+return this.instances[i];}};return{TimeToObjectInstanceMap,};});'use strict';tr.exportTo('tr.model',function(){const ObjectInstance=tr.model.ObjectInstance;const ObjectSnapshot=tr.model.ObjectSnapshot;function ObjectCollection(parent){tr.model.EventContainer.call(this);this.parent=parent;this.instanceMapsByScopedId_={};this.instancesByTypeName_={};this.createObjectInstance_=this.createObjectInstance_.bind(this);}
+ObjectCollection.prototype={__proto__:tr.model.EventContainer.prototype,*childEvents(){for(const instance of this.getAllObjectInstances()){yield instance;yield*instance.snapshots;}},createObjectInstance_(parent,scopedId,category,name,creationTs,opt_baseTypeName){const constructor=tr.model.ObjectInstance.subTypes.getConstructor(category,name);const instance=new constructor(parent,scopedId,category,name,creationTs,opt_baseTypeName);const typeName=instance.typeName;let instancesOfTypeName=this.instancesByTypeName_[typeName];if(!instancesOfTypeName){instancesOfTypeName=[];this.instancesByTypeName_[typeName]=instancesOfTypeName;}
+instancesOfTypeName.push(instance);return instance;},getOrCreateInstanceMap_(scopedId){let dict;if(scopedId.scope in this.instanceMapsByScopedId_){dict=this.instanceMapsByScopedId_[scopedId.scope];}else{dict={};this.instanceMapsByScopedId_[scopedId.scope]=dict;}
+let instanceMap=dict[scopedId.id];if(instanceMap)return instanceMap;instanceMap=new tr.model.TimeToObjectInstanceMap(this.createObjectInstance_,this.parent,scopedId);dict[scopedId.id]=instanceMap;return instanceMap;},idWasCreated(scopedId,category,name,ts){const instanceMap=this.getOrCreateInstanceMap_(scopedId);return instanceMap.idWasCreated(category,name,ts);},addSnapshot(scopedId,category,name,ts,args,opt_baseTypeName){const instanceMap=this.getOrCreateInstanceMap_(scopedId);const snapshot=instanceMap.addSnapshot(category,name,ts,args,opt_baseTypeName);if(snapshot.objectInstance.category!==category){const msg='Added snapshot name='+name+' with cat='+category+' impossible. It instance was created/snapshotted with cat='+
+snapshot.objectInstance.category+' name='+
+snapshot.objectInstance.name;throw new Error(msg);}
+if(opt_baseTypeName&&snapshot.objectInstance.baseTypeName!==opt_baseTypeName){throw new Error('Could not add snapshot with baseTypeName='+
+opt_baseTypeName+'. It '+'was previously created with name='+
+snapshot.objectInstance.baseTypeName);}
+if(snapshot.objectInstance.name!==name){throw new Error('Could not add snapshot with name='+name+'. It '+'was previously created with name='+
+snapshot.objectInstance.name);}
+return snapshot;},idWasDeleted(scopedId,category,name,ts){const instanceMap=this.getOrCreateInstanceMap_(scopedId);const deletedInstance=instanceMap.idWasDeleted(category,name,ts);if(!deletedInstance)return;if(deletedInstance.category!==category){const msg='Deleting object '+deletedInstance.name+' with a different category '+'than when it was created. It previous had cat='+
+deletedInstance.category+' but the delete command '+'had cat='+category;throw new Error(msg);}
+if(deletedInstance.baseTypeName!==name){throw new Error('Deletion requested for name='+
+name+' could not proceed: '+'An existing object with baseTypeName='+
+deletedInstance.baseTypeName+' existed.');}},autoDeleteObjects(maxTimestamp){for(const imapById of Object.values(this.instanceMapsByScopedId_)){for(const i2imap of Object.values(imapById)){const lastInstance=i2imap.lastInstance;if(lastInstance.deletionTs!==Number.MAX_VALUE)continue;i2imap.idWasDeleted(lastInstance.category,lastInstance.name,maxTimestamp);lastInstance.deletionTsWasExplicit=false;}}},getObjectInstanceAt(scopedId,ts){let instanceMap;if(scopedId.scope in this.instanceMapsByScopedId_){instanceMap=this.instanceMapsByScopedId_[scopedId.scope][scopedId.id];}
+if(!instanceMap)return undefined;return instanceMap.getInstanceAt(ts);},getSnapshotAt(scopedId,ts){const instance=this.getObjectInstanceAt(scopedId,ts);if(!instance)return undefined;return instance.getSnapshotAt(ts);},iterObjectInstances(iter,opt_this){opt_this=opt_this||this;for(const imapById of Object.values(this.instanceMapsByScopedId_)){for(const i2imap of Object.values(imapById)){i2imap.instances.forEach(iter,opt_this);}}},getAllObjectInstances(){const instances=[];this.iterObjectInstances(function(i){instances.push(i);});return instances;},getAllInstancesNamed(name){return this.instancesByTypeName_[name];},getAllInstancesByTypeName(){return this.instancesByTypeName_;},preInitializeAllObjects(){this.iterObjectInstances(function(instance){instance.preInitialize();});},initializeAllObjects(){this.iterObjectInstances(function(instance){instance.initialize();});},initializeInstances(){this.iterObjectInstances(function(instance){instance.initialize();});},updateBounds(){this.bounds.reset();this.iterObjectInstances(function(instance){instance.updateBounds();this.bounds.addRange(instance.bounds);},this);},shiftTimestampsForward(amount){this.iterObjectInstances(function(instance){instance.shiftTimestampsForward(amount);});},addCategoriesToDict(categoriesDict){this.iterObjectInstances(function(instance){categoriesDict[instance.category]=true;});}};return{ObjectCollection,};});'use strict';tr.exportTo('tr.model',function(){class AsyncSliceGroup extends tr.model.EventContainer{constructor(parentContainer,opt_name){super();this.parentContainer_=parentContainer;this.name_=opt_name;this.slices=[];this.viewSubGroups_=undefined;this.nestedLevel_=0;this.hasNestedSubGroups_=true;this.title_=undefined;}
+get parentContainer(){return this.parentContainer_;}
+get model(){return this.parentContainer_.parent.model;}
+get stableId(){return this.parentContainer_.stableId+'.AsyncSliceGroup';}
+get title(){if(this.nested_level_===0){return'<root>';}
+return this.title_;}
+getSettingsKey(){if(this.name_===undefined){return undefined;}
+const parentKey=this.parentContainer_.getSettingsKey();if(parentKey===undefined){return undefined;}
+return parentKey+'.'+this.name_;}
+push(slice){if(this.viewSubGroups_!==undefined){throw new Error('No new slices are allowed when view sub-groups already formed.');}
+slice.parentContainer=this.parentContainer;this.slices.push(slice);return slice;}
+get length(){return this.slices.length;}
+shiftTimestampsForward(amount){for(const slice of this.childEvents()){slice.start+=amount;}}
+updateBounds(){this.bounds.reset();for(let i=0;i<this.slices.length;i++){this.bounds.addValue(this.slices[i].start);this.bounds.addValue(this.slices[i].end);}}
+autoCloseOpenSlices(){const maxTimestamp=this.parentContainer_.parent.model.bounds.max;for(const slice of this.childEvents()){if(slice.didNotFinish){slice.duration=maxTimestamp-slice.start;}}}
+get viewSubGroups(){if(!this.hasNestedSubGroups_||this.nestedLevel_===2){return[];}
+if(this.viewSubGroups_!==undefined){return this.viewSubGroups_;}
+const subGroupsByTitle=new Map();for(const slice of this.slices){let subGroupTitle=slice.viewSubGroupTitle;let hasNestedSubGroups=false;if(this.nestedLevel_===0&&slice.viewSubGroupGroupingKey!==undefined){subGroupTitle=slice.viewSubGroupGroupingKey;hasNestedSubGroups=true;}
+let subGroup=subGroupsByTitle.get(subGroupTitle);if(subGroup===undefined){let name;if(this.name_!==undefined){name=this.name_+'.'+subGroupTitle;}else{name=subGroupTitle;}
+subGroup=new AsyncSliceGroup(this.parentContainer_,name);subGroup.title_=subGroupTitle;subGroup.hasNestedSubGroups_=hasNestedSubGroups;subGroup.nestedLevel_=this.nestedLevel_+1;subGroupsByTitle.set(subGroupTitle,subGroup);}
+subGroup.push(slice);}
+this.viewSubGroups_=Array.from(subGroupsByTitle.values());this.viewSubGroups_.sort((a,b)=>a.title.localeCompare(b.title));return this.viewSubGroups_;}*findTopmostSlicesInThisContainer(eventPredicate,opt_this){for(const slice of this.slices){if(slice.isTopLevel){yield*slice.findTopmostSlicesRelativeToThisSlice(eventPredicate,opt_this);}}}*childEvents(){for(const slice of this.slices){yield slice;yield*slice.enumerateAllDescendents();}}*childEventContainers(){}}
+return{AsyncSliceGroup,};});'use strict';tr.exportTo('tr.model',function(){const Slice=tr.model.Slice;function ThreadSlice(cat,title,colorId,start,args,opt_duration,opt_cpuStart,opt_cpuDuration,opt_argsStripped,opt_bindId){Slice.call(this,cat,title,colorId,start,args,opt_duration,opt_cpuStart,opt_cpuDuration,opt_argsStripped,opt_bindId);this.subSlices=[];}
+ThreadSlice.prototype={__proto__:Slice.prototype,get overlappingSamples(){const samples=new tr.model.EventSet();if(!this.parentContainer||!this.parentContainer.samples){return samples;}
+this.parentContainer.samples.forEach(function(sample){if(this.start<=sample.start&&sample.start<=this.end){samples.push(sample);}},this);return samples;}};tr.model.EventRegistry.register(ThreadSlice,{name:'slice',pluralName:'slices'});return{ThreadSlice,};});'use strict';tr.exportTo('tr.model',function(){const ColorScheme=tr.b.ColorScheme;const ThreadSlice=tr.model.ThreadSlice;function getSliceLo(s){return s.start;}
+function getSliceHi(s){return s.end;}
+function SliceGroup(parentContainer,opt_sliceConstructor,opt_name){tr.model.EventContainer.call(this);this.parentContainer_=parentContainer;const sliceConstructor=opt_sliceConstructor||ThreadSlice;this.sliceConstructor=sliceConstructor;this.sliceConstructorSubTypes=this.sliceConstructor.subTypes;if(!this.sliceConstructorSubTypes){throw new Error('opt_sliceConstructor must have a subtype registry.');}
+this.openPartialSlices_=[];this.slices=[];this.topLevelSlices=[];this.haveTopLevelSlicesBeenBuilt=false;this.name_=opt_name;if(this.model===undefined){throw new Error('SliceGroup must have model defined.');}}
+SliceGroup.prototype={__proto__:tr.model.EventContainer.prototype,get parentContainer(){return this.parentContainer_;},get model(){return this.parentContainer_.model;},get stableId(){return this.parentContainer_.stableId+'.SliceGroup';},getSettingsKey(){if(!this.name_)return undefined;const parentKey=this.parentContainer_.getSettingsKey();if(!parentKey)return undefined;return parentKey+'.'+this.name;},get length(){return this.slices.length;},pushSlice(slice){this.haveTopLevelSlicesBeenBuilt=false;slice.parentContainer=this.parentContainer_;this.slices.push(slice);return slice;},pushSlices(slices){this.haveTopLevelSlicesBeenBuilt=false;slices.forEach(function(slice){slice.parentContainer=this.parentContainer_;this.slices.push(slice);},this);},beginSlice(category,title,ts,opt_args,opt_tts,opt_argsStripped,opt_colorId,opt_bindId){const colorId=opt_colorId||ColorScheme.getColorIdForGeneralPurposeString(title);const sliceConstructorSubTypes=this.sliceConstructorSubTypes;const sliceType=sliceConstructorSubTypes.getConstructor(category,title);const slice=new sliceType(category,title,colorId,ts,opt_args?opt_args:{},null,opt_tts,undefined,opt_argsStripped,opt_bindId);this.openPartialSlices_.push(slice);slice.didNotFinish=true;this.pushSlice(slice);return slice;},isTimestampValidForBeginOrEnd(ts){if(!this.openPartialSlices_.length)return true;const top=this.openPartialSlices_[this.openPartialSlices_.length-1];return ts>=top.start;},get openSliceCount(){return this.openPartialSlices_.length;},get mostRecentlyOpenedPartialSlice(){if(!this.openPartialSlices_.length)return undefined;return this.openPartialSlices_[this.openPartialSlices_.length-1];},endSlice(ts,opt_tts,opt_colorId){if(!this.openSliceCount){throw new Error('endSlice called without an open slice');}
+const slice=this.openPartialSlices_[this.openSliceCount-1];this.openPartialSlices_.splice(this.openSliceCount-1,1);if(ts<slice.start){throw new Error('Slice '+slice.title+' end time is before its start.');}
+slice.duration=ts-slice.start;slice.didNotFinish=false;slice.colorId=opt_colorId||slice.colorId;if(opt_tts&&slice.cpuStart!==undefined){slice.cpuDuration=opt_tts-slice.cpuStart;}
+return slice;},pushCompleteSlice(category,title,ts,duration,tts,cpuDuration,opt_args,opt_argsStripped,opt_colorId,opt_bindId){const colorId=opt_colorId||ColorScheme.getColorIdForGeneralPurposeString(title);const sliceConstructorSubTypes=this.sliceConstructorSubTypes;const sliceType=sliceConstructorSubTypes.getConstructor(category,title);const slice=new sliceType(category,title,colorId,ts,opt_args?opt_args:{},duration,tts,cpuDuration,opt_argsStripped,opt_bindId);if(duration===undefined){slice.didNotFinish=true;}
+this.pushSlice(slice);return slice;},autoCloseOpenSlices(){this.updateBounds();const maxTimestamp=this.bounds.max;for(let sI=0;sI<this.slices.length;sI++){const slice=this.slices[sI];if(slice.didNotFinish){slice.duration=maxTimestamp-slice.start;}}
+this.openPartialSlices_=[];},shiftTimestampsForward(amount){for(let sI=0;sI<this.slices.length;sI++){const slice=this.slices[sI];slice.start=(slice.start+amount);}},updateBounds(){this.bounds.reset();for(let i=0;i<this.slices.length;i++){this.bounds.addValue(this.slices[i].start);this.bounds.addValue(this.slices[i].end);}},copySlice(slice){const sliceConstructorSubTypes=this.sliceConstructorSubTypes;const sliceType=sliceConstructorSubTypes.getConstructor(slice.category,slice.title);const newSlice=new sliceType(slice.category,slice.title,slice.colorId,slice.start,slice.args,slice.duration,slice.cpuStart,slice.cpuDuration);newSlice.didNotFinish=slice.didNotFinish;return newSlice;},*findTopmostSlicesInThisContainer(eventPredicate,opt_this){if(!this.haveTopLevelSlicesBeenBuilt){throw new Error('Nope');}
+for(const s of this.topLevelSlices){yield*s.findTopmostSlicesRelativeToThisSlice(eventPredicate);}},*childEvents(){yield*this.slices;},*childEventContainers(){},*getDescendantEventsInSortedRanges(ranges,opt_containerPredicate){if(ranges.length===0||(opt_containerPredicate!==undefined&&!opt_containerPredicate(this))){return;}
+let rangeIndex=0;let range=ranges[rangeIndex];for(const event of this.childEvents()){while(event.start>range.max){rangeIndex++;if(rangeIndex>=ranges.length)return;range=ranges[rangeIndex];}
+if(event.end>=range.min)yield event;}},getSlicesOfName(title){const slices=[];for(let i=0;i<this.slices.length;i++){if(this.slices[i].title===title){slices.push(this.slices[i]);}}
+return slices;},iterSlicesInTimeRange(callback,start,end){const ret=[];tr.b.iterateOverIntersectingIntervals(this.topLevelSlices,function(s){return s.start;},function(s){return s.duration;},start,end,function(topLevelSlice){callback(topLevelSlice);for(const slice of topLevelSlice.enumerateAllDescendents()){callback(slice);}});return ret;},findFirstSlice(){if(!this.haveTopLevelSlicesBeenBuilt){throw new Error('Nope');}
+if(0===this.slices.length)return undefined;return this.slices[0];},findSliceAtTs(ts){if(!this.haveTopLevelSlicesBeenBuilt)throw new Error('Nope');let i=tr.b.findIndexInSortedClosedIntervals(this.topLevelSlices,getSliceLo,getSliceHi,ts);if(i===-1||i===this.topLevelSlices.length){return undefined;}
+let curSlice=this.topLevelSlices[i];while(true){i=tr.b.findIndexInSortedClosedIntervals(curSlice.subSlices,getSliceLo,getSliceHi,ts);if(i===-1||i===curSlice.subSlices.length){return curSlice;}
+curSlice=curSlice.subSlices[i];}},findNextSliceAfter(ts,refGuid){let i=tr.b.findLowIndexInSortedArray(this.slices,getSliceLo,ts);if(i===this.slices.length){return undefined;}
+for(;i<this.slices.length;i++){const slice=this.slices[i];if(slice.start>ts)return slice;if(slice.guid<=refGuid)continue;return slice;}
+return undefined;},hasCpuDuration_(){if(this.slices.some(function(slice){return slice.cpuDuration!==undefined;}))return true;return false;},createSubSlices(){this.haveTopLevelSlicesBeenBuilt=true;this.createSubSlicesImpl_();if(!this.hasCpuDuration_()&&this.parentContainer.timeSlices){this.addCpuTimeToSubslices_(this.parentContainer.timeSlices);}
+this.slices.forEach(function(slice){let selfTime=slice.duration;for(let i=0;i<slice.subSlices.length;i++){selfTime-=slice.subSlices[i].duration;}
+slice.selfTime=selfTime;if(slice.cpuDuration===undefined)return;let cpuSelfTime=slice.cpuDuration;for(let i=0;i<slice.subSlices.length;i++){if(slice.subSlices[i].cpuDuration!==undefined){cpuSelfTime-=slice.subSlices[i].cpuDuration;}}
+slice.cpuSelfTime=cpuSelfTime;});},createSubSlicesImpl_(){const precisionUnit=this.model.intrinsicTimeUnit;function addSliceIfBounds(parent,child){if(parent.bounds(child,precisionUnit)){child.parentSlice=parent;if(parent.subSlices===undefined){parent.subSlices=[];}
+parent.subSlices.push(child);return true;}
+return false;}
+if(!this.slices.length)return;const ops=[];for(let i=0;i<this.slices.length;i++){if(this.slices[i].subSlices){this.slices[i].subSlices.splice(0,this.slices[i].subSlices.length);}
+ops.push(i);}
+const originalSlices=this.slices;ops.sort(function(ix,iy){const x=originalSlices[ix];const y=originalSlices[iy];if(x.start!==y.start){return x.start-y.start;}
+return ix-iy;});const slices=new Array(this.slices.length);for(let i=0;i<ops.length;i++){slices[i]=originalSlices[ops[i]];}
+let rootSlice=slices[0];this.topLevelSlices=[];this.topLevelSlices.push(rootSlice);rootSlice.isTopLevel=true;for(let i=1;i<slices.length;i++){const slice=slices[i];while(rootSlice!==undefined&&(!addSliceIfBounds(rootSlice,slice))){rootSlice=rootSlice.parentSlice;}
+if(rootSlice===undefined){this.topLevelSlices.push(slice);slice.isTopLevel=true;}
+rootSlice=slice;}
+this.slices=slices;},addCpuTimeToSubslices_(timeSlices){const SCHEDULING_STATE=tr.model.SCHEDULING_STATE;let sliceIdx=0;timeSlices.forEach(function(timeSlice){if(timeSlice.schedulingState===SCHEDULING_STATE.RUNNING){while(sliceIdx<this.topLevelSlices.length){if(this.addCpuTimeToSubslice_(this.topLevelSlices[sliceIdx],timeSlice)){sliceIdx++;}else{break;}}}},this);},addCpuTimeToSubslice_(slice,timeSlice){if(slice.start>timeSlice.end||slice.end<timeSlice.start){return slice.end<=timeSlice.end;}
+let duration=timeSlice.duration;if(slice.start>timeSlice.start){duration-=slice.start-timeSlice.start;}
+if(timeSlice.end>slice.end){duration-=timeSlice.end-slice.end;}
+if(slice.cpuDuration){slice.cpuDuration+=duration;}else{slice.cpuDuration=duration;}
+for(let i=0;i<slice.subSlices.length;i++){this.addCpuTimeToSubslice_(slice.subSlices[i],timeSlice);}
+return slice.end<=timeSlice.end;}};SliceGroup.merge=function(groupA,groupB){if(groupA.openPartialSlices_.length>0){throw new Error('groupA has open partial slices');}
+if(groupB.openPartialSlices_.length>0){throw new Error('groupB has open partial slices');}
+if(groupA.parentContainer!==groupB.parentContainer){throw new Error('Different parent threads. Cannot merge');}
+if(groupA.sliceConstructor!==groupB.sliceConstructor){throw new Error('Different slice constructors. Cannot merge');}
+const result=new SliceGroup(groupA.parentContainer,groupA.sliceConstructor,groupA.name_);const slicesA=groupA.slices;const slicesB=groupB.slices;let idxA=0;let idxB=0;const openA=[];const openB=[];const splitOpenSlices=function(when){for(let i=0;i<openB.length;i++){const oldSlice=openB[i];const oldEnd=oldSlice.end;if(when<oldSlice.start||oldEnd<when){throw new Error('slice should not be split');}
+const newSlice=result.copySlice(oldSlice);newSlice.start=when;newSlice.duration=oldEnd-when;if(newSlice.title.indexOf(' (cont.)')===-1){newSlice.title+=' (cont.)';}
+oldSlice.duration=when-oldSlice.start;openB[i]=newSlice;result.pushSlice(newSlice);}};const closeOpenSlices=function(upTo){while(openA.length>0||openB.length>0){const nextA=openA[openA.length-1];const nextB=openB[openB.length-1];const endA=nextA&&nextA.end;const endB=nextB&&nextB.end;if((endA===undefined||endA>upTo)&&(endB===undefined||endB>upTo)){return;}
+if(endB===undefined||endA<endB){splitOpenSlices(endA);openA.pop();}else{openB.pop();}}};while(idxA<slicesA.length||idxB<slicesB.length){const sA=slicesA[idxA];const sB=slicesB[idxB];let nextSlice;let isFromB;if(sA===undefined||(sB!==undefined&&sA.start>sB.start)){nextSlice=result.copySlice(sB);isFromB=true;idxB++;}else{nextSlice=result.copySlice(sA);isFromB=false;idxA++;}
+closeOpenSlices(nextSlice.start);result.pushSlice(nextSlice);if(isFromB){openB.push(nextSlice);}else{splitOpenSlices(nextSlice.start);openA.push(nextSlice);}}
+closeOpenSlices();return result;};return{SliceGroup,};});'use strict';tr.exportTo('tr.model',function(){const AsyncSlice=tr.model.AsyncSlice;const AsyncSliceGroup=tr.model.AsyncSliceGroup;const SliceGroup=tr.model.SliceGroup;const ThreadSlice=tr.model.ThreadSlice;const ThreadTimeSlice=tr.model.ThreadTimeSlice;function Thread(parent,tid){if(!parent){throw new Error('Parent must be provided.');}
+tr.model.EventContainer.call(this);this.parent=parent;this.sortIndex=0;this.tid=tid;this.name=undefined;this.samples_=undefined;this.sliceGroup=new SliceGroup(this,ThreadSlice,'slices');this.timeSlices=undefined;this.kernelSliceGroup=new SliceGroup(this,ThreadSlice,'kernel-slices');this.asyncSliceGroup=new AsyncSliceGroup(this,'async-slices');}
+Thread.prototype={__proto__:tr.model.EventContainer.prototype,get model(){return this.parent.model;},get stableId(){return this.parent.stableId+'.'+this.tid;},compareTo(that){return Thread.compare(this,that);},*childEventContainers(){if(this.sliceGroup.length){yield this.sliceGroup;}
+if(this.kernelSliceGroup.length){yield this.kernelSliceGroup;}
+if(this.asyncSliceGroup.length){yield this.asyncSliceGroup;}},*childEvents(){if(this.timeSlices){yield*this.timeSlices;}},iterateAllPersistableObjects(cb){cb(this);if(this.sliceGroup.length){cb(this.sliceGroup);}
+this.asyncSliceGroup.viewSubGroups.forEach(cb);},shiftTimestampsForward(amount){this.sliceGroup.shiftTimestampsForward(amount);if(this.timeSlices){for(let i=0;i<this.timeSlices.length;i++){const slice=this.timeSlices[i];slice.start+=amount;}}
+this.kernelSliceGroup.shiftTimestampsForward(amount);this.asyncSliceGroup.shiftTimestampsForward(amount);},get isEmpty(){if(this.sliceGroup.length)return false;if(this.sliceGroup.openSliceCount)return false;if(this.timeSlices&&this.timeSlices.length)return false;if(this.kernelSliceGroup.length)return false;if(this.asyncSliceGroup.length)return false;if(this.samples_.length)return false;return true;},updateBounds(){this.bounds.reset();this.sliceGroup.updateBounds();this.bounds.addRange(this.sliceGroup.bounds);this.kernelSliceGroup.updateBounds();this.bounds.addRange(this.kernelSliceGroup.bounds);this.asyncSliceGroup.updateBounds();this.bounds.addRange(this.asyncSliceGroup.bounds);if(this.timeSlices&&this.timeSlices.length){this.bounds.addValue(this.timeSlices[0].start);this.bounds.addValue(this.timeSlices[this.timeSlices.length-1].end);}
+if(this.samples_&&this.samples_.length){this.bounds.addValue(this.samples_[0].start);this.bounds.addValue(this.samples_[this.samples_.length-1].end);}},addCategoriesToDict(categoriesDict){for(let i=0;i<this.sliceGroup.length;i++){categoriesDict[this.sliceGroup.slices[i].category]=true;}
+for(let i=0;i<this.kernelSliceGroup.length;i++){categoriesDict[this.kernelSliceGroup.slices[i].category]=true;}
+for(let i=0;i<this.asyncSliceGroup.length;i++){categoriesDict[this.asyncSliceGroup.slices[i].category]=true;}
+if(this.samples_){for(let i=0;i<this.samples_.length;i++){categoriesDict[this.samples_[i].category]=true;}}},autoCloseOpenSlices(){this.sliceGroup.autoCloseOpenSlices();this.asyncSliceGroup.autoCloseOpenSlices();this.kernelSliceGroup.autoCloseOpenSlices();},mergeKernelWithUserland(){if(this.kernelSliceGroup.length>0){const newSlices=SliceGroup.merge(this.sliceGroup,this.kernelSliceGroup);this.sliceGroup.slices=newSlices.slices;this.kernelSliceGroup=new SliceGroup(this);this.updateBounds();}},createSubSlices(){this.sliceGroup.createSubSlices();this.samples_=this.parent.model.samples.filter(sample=>sample.thread===this);},get userFriendlyName(){return this.name||this.tid;},get userFriendlyDetails(){return'tid: '+this.tid+
+(this.name?', name: '+this.name:'');},getSettingsKey(){if(!this.name)return undefined;const parentKey=this.parent.getSettingsKey();if(!parentKey)return undefined;return parentKey+'.'+this.name;},getProcess(){return this.parent;},indexOfTimeSlice(timeSlice){const i=tr.b.findLowIndexInSortedArray(this.timeSlices,function(slice){return slice.start;},timeSlice.start);if(this.timeSlices[i]!==timeSlice)return undefined;return i;},sumOverToplevelSlicesInRange(range,func){let sum=0;tr.b.iterateOverIntersectingIntervals(this.sliceGroup.topLevelSlices,slice=>slice.start,slice=>slice.end,range.min,range.max,slice=>{let fractionOfSliceInsideRangeOfInterest=1;if(slice.duration>0){const intersection=range.findIntersection(slice.range);fractionOfSliceInsideRangeOfInterest=intersection.duration/slice.duration;}
+sum+=func(slice)*fractionOfSliceInsideRangeOfInterest;});return sum;},getCpuTimeForRange(range){return this.sumOverToplevelSlicesInRange(range,slice=>slice.cpuDuration||0);},getNumToplevelSlicesForRange(range){return this.sumOverToplevelSlicesInRange(range,slice=>1);},getSchedulingStatsForRange(start,end){const stats={};if(!this.timeSlices)return stats;function addStatsForSlice(threadTimeSlice){const overlapStart=Math.max(threadTimeSlice.start,start);const overlapEnd=Math.min(threadTimeSlice.end,end);const schedulingState=threadTimeSlice.schedulingState;if(!(schedulingState in stats))stats[schedulingState]=0;stats[schedulingState]+=overlapEnd-overlapStart;}
+tr.b.iterateOverIntersectingIntervals(this.timeSlices,function(x){return x.start;},function(x){return x.end;},start,end,addStatsForSlice);return stats;},get samples(){return this.samples_;},get type(){const re=/^[^0-9|\/]+/;const matches=re.exec(this.name);if(matches&&matches[0])return matches[0];throw new Error('Could not determine thread type for thread name '+
+this.name);}};Thread.compare=function(x,y){let tmp=x.parent.compareTo(y.parent);if(tmp)return tmp;tmp=x.sortIndex-y.sortIndex;if(tmp)return tmp;if(x.name!==undefined){if(y.name!==undefined){tmp=x.name.localeCompare(y.name);}else{tmp=-1;}}else if(y.name!==undefined){tmp=1;}
+if(tmp)return tmp;return x.tid-y.tid;};return{Thread,};});'use strict';tr.exportTo('tr.model',function(){const Thread=tr.model.Thread;const Counter=tr.model.Counter;function ProcessBase(model){if(!model){throw new Error('Must provide a model');}
+tr.model.EventContainer.call(this);this.model=model;this.threads={};this.counters={};this.objects=new tr.model.ObjectCollection(this);this.sortIndex=0;}
+ProcessBase.compare=function(x,y){return x.sortIndex-y.sortIndex;};ProcessBase.prototype={__proto__:tr.model.EventContainer.prototype,get stableId(){throw new Error('Not implemented');},*childEventContainers(){yield*Object.values(this.threads);yield*Object.values(this.counters);yield this.objects;},iterateAllPersistableObjects(cb){cb(this);for(const tid in this.threads){this.threads[tid].iterateAllPersistableObjects(cb);}},get numThreads(){let n=0;for(const p in this.threads){n++;}
+return n;},shiftTimestampsForward(amount){for(const child of this.childEventContainers()){child.shiftTimestampsForward(amount);}},autoCloseOpenSlices(){for(const tid in this.threads){const thread=this.threads[tid];thread.autoCloseOpenSlices();}},autoDeleteObjects(maxTimestamp){this.objects.autoDeleteObjects(maxTimestamp);},preInitializeObjects(){this.objects.preInitializeAllObjects();},initializeObjects(){this.objects.initializeAllObjects();},mergeKernelWithUserland(){for(const tid in this.threads){const thread=this.threads[tid];thread.mergeKernelWithUserland();}},updateBounds(){this.bounds.reset();for(const tid in this.threads){this.threads[tid].updateBounds();this.bounds.addRange(this.threads[tid].bounds);}
+for(const id in this.counters){this.counters[id].updateBounds();this.bounds.addRange(this.counters[id].bounds);}
+this.objects.updateBounds();this.bounds.addRange(this.objects.bounds);},addCategoriesToDict(categoriesDict){for(const tid in this.threads){this.threads[tid].addCategoriesToDict(categoriesDict);}
+for(const id in this.counters){categoriesDict[this.counters[id].category]=true;}
+this.objects.addCategoriesToDict(categoriesDict);},findAllThreadsMatching(predicate,opt_this){const threads=[];for(const tid in this.threads){const thread=this.threads[tid];if(predicate.call(opt_this,thread)){threads.push(thread);}}
+return threads;},findAllThreadsNamed(name){const threads=this.findAllThreadsMatching(function(thread){if(!thread.name)return false;return thread.name===name;});return threads;},findAtMostOneThreadNamed(name){const threads=this.findAllThreadsNamed(name);if(threads.length===0)return undefined;if(threads.length>1){throw new Error('Expected no more than one '+name);}
+return threads[0];},pruneEmptyContainers(){const threadsToKeep={};for(const tid in this.threads){const thread=this.threads[tid];if(!thread.isEmpty){threadsToKeep[tid]=thread;}}
+this.threads=threadsToKeep;},getThread(tid){return this.threads[tid];},getOrCreateThread(tid){if(!this.threads[tid]){this.threads[tid]=new Thread(this,tid);}
+return this.threads[tid];},getOrCreateCounter(cat,name){const id=cat+'.'+name;if(!this.counters[id]){this.counters[id]=new Counter(this,id,cat,name);}
+return this.counters[id];},getSettingsKey(){throw new Error('Not implemented');},createSubSlices(){for(const tid in this.threads){this.threads[tid].createSubSlices();}}};return{ProcessBase,};});'use strict';tr.exportTo('tr.model',function(){const ColorScheme=tr.b.ColorScheme;const Counter=tr.model.Counter;const CpuSlice=tr.model.CpuSlice;function Cpu(kernel,number){if(kernel===undefined||number===undefined){throw new Error('Missing arguments');}
+this.kernel=kernel;this.cpuNumber=number;this.slices=[];this.counters={};this.bounds_=new tr.b.math.Range();this.samples_=undefined;this.lastActiveTimestamp_=undefined;this.lastActiveThread_=undefined;this.lastActiveName_=undefined;this.lastActiveArgs_=undefined;}
+Cpu.prototype={__proto__:tr.model.EventContainer.prototype,get samples(){return this.samples_;},get userFriendlyName(){return'CPU '+this.cpuNumber;},*findTopmostSlicesInThisContainer(eventPredicate,opt_this){for(const s of this.slices){yield*s.findTopmostSlicesRelativeToThisSlice(eventPredicate,opt_this);}},*childEvents(){yield*this.slices;if(this.samples_){yield*this.samples_;}},*childEventContainers(){yield*Object.values(this.counters);},getOrCreateCounter(cat,name){const id=cat+'.'+name;if(!this.counters[id]){this.counters[id]=new Counter(this,id,cat,name);}
+return this.counters[id];},getCounter(cat,name){const id=cat+'.'+name;if(!this.counters[id]){return undefined;}
+return this.counters[id];},shiftTimestampsForward(amount){for(let sI=0;sI<this.slices.length;sI++){this.slices[sI].start=(this.slices[sI].start+amount);}
+for(const id in this.counters){this.counters[id].shiftTimestampsForward(amount);}},updateBounds(){this.bounds_.reset();if(this.slices.length){this.bounds_.addValue(this.slices[0].start);this.bounds_.addValue(this.slices[this.slices.length-1].end);}
+for(const id in this.counters){this.counters[id].updateBounds();this.bounds_.addRange(this.counters[id].bounds);}
+if(this.samples_&&this.samples_.length){this.bounds_.addValue(this.samples_[0].start);this.bounds_.addValue(this.samples_[this.samples_.length-1].end);}},createSubSlices(){this.samples_=this.kernel.model.samples.filter(function(sample){return sample.cpu===this;},this);},addCategoriesToDict(categoriesDict){for(let i=0;i<this.slices.length;i++){categoriesDict[this.slices[i].category]=true;}
+for(const id in this.counters){categoriesDict[this.counters[id].category]=true;}
+for(let i=0;i<this.samples_.length;i++){categoriesDict[this.samples_[i].category]=true;}},indexOf(cpuSlice){const i=tr.b.findLowIndexInSortedArray(this.slices,function(slice){return slice.start;},cpuSlice.start);if(this.slices[i]!==cpuSlice)return undefined;return i;},closeActiveThread(endTimestamp,args){if(this.lastActiveThread_===undefined||this.lastActiveThread_===0){return;}
+if(endTimestamp<this.lastActiveTimestamp_){throw new Error('The end timestamp of a thread running on CPU '+
+this.cpuNumber+' is before its start timestamp.');}
+for(const key in args){this.lastActiveArgs_[key]=args[key];}
+const duration=endTimestamp-this.lastActiveTimestamp_;const slice=new tr.model.CpuSlice('',this.lastActiveName_,ColorScheme.getColorIdForGeneralPurposeString(this.lastActiveName_),this.lastActiveTimestamp_,this.lastActiveArgs_,duration);slice.cpu=this;this.slices.push(slice);this.lastActiveTimestamp_=undefined;this.lastActiveThread_=undefined;this.lastActiveName_=undefined;this.lastActiveArgs_=undefined;},switchActiveThread(timestamp,oldThreadArgs,newThreadId,newThreadName,newThreadArgs){this.closeActiveThread(timestamp,oldThreadArgs);this.lastActiveTimestamp_=timestamp;this.lastActiveThread_=newThreadId;this.lastActiveName_=newThreadName;this.lastActiveArgs_=newThreadArgs;},getFreqStatsForRange(range){const stats={};function addStatsForFreq(freqSample,index){const freqEnd=(index<freqSample.series_.length-1)?freqSample.series_.samples_[index+1].timestamp:range.max;const freqRange=tr.b.math.Range.fromExplicitRange(freqSample.timestamp,freqEnd);const intersection=freqRange.findIntersection(range);if(!(freqSample.value in stats)){stats[freqSample.value]=0;}
+stats[freqSample.value]+=intersection.duration;}
+const freqCounter=this.getCounter('','Clock Frequency');if(freqCounter!==undefined){const freqSeries=freqCounter.getSeries(0);if(!freqSeries)return;tr.b.iterateOverIntersectingIntervals(freqSeries.samples_,function(x){return x.timestamp;},function(x,index){if(index<freqSeries.length-1){return freqSeries.samples_[index+1].timestamp;}
+return range.max;},range.min,range.max,addStatsForFreq);}
+return stats;}};Cpu.compare=function(x,y){return x.cpuNumber-y.cpuNumber;};return{Cpu,};});'use strict';tr.exportTo('tr.model',function(){const Event=tr.model.Event;const EventRegistry=tr.model.EventRegistry;function PowerSample(series,start,powerInW){Event.call(this);this.series_=series;this.start_=parseFloat(start);this.powerInW_=parseFloat(powerInW);}
+PowerSample.prototype={__proto__:Event.prototype,get series(){return this.series_;},get start(){return this.start_;},set start(value){this.start_=value;},get powerInW(){return this.powerInW_;},set powerInW(value){this.powerInW_=value;},addBoundsToRange(range){range.addValue(this.start);}};EventRegistry.register(PowerSample,{name:'powerSample',pluralName:'powerSamples'});return{PowerSample,};});'use strict';tr.exportTo('tr.model',function(){const PowerSample=tr.model.PowerSample;function PowerSeries(device){tr.model.EventContainer.call(this);this.device_=device;this.samples_=[];}
+PowerSeries.prototype={__proto__:tr.model.EventContainer.prototype,get device(){return this.device_;},get samples(){return this.samples_;},get stableId(){return this.device_.stableId+'.PowerSeries';},addPowerSample(ts,val){const sample=new PowerSample(this,ts,val);this.samples_.push(sample);return sample;},getEnergyConsumedInJ(start,end){const measurementRange=tr.b.math.Range.fromExplicitRange(start,end);let energyConsumedInJ=0;let startIndex=tr.b.findLowIndexInSortedArray(this.samples,x=>x.start,start)-1;const endIndex=tr.b.findLowIndexInSortedArray(this.samples,x=>x.start,end);if(startIndex<0){startIndex=0;}
+for(let i=startIndex;i<endIndex;i++){const sample=this.samples[i];const nextSample=this.samples[i+1];const sampleRange=new tr.b.math.Range();sampleRange.addValue(sample.start);sampleRange.addValue(nextSample?nextSample.start:sample.start);const intersectionRangeInMs=measurementRange.findIntersection(sampleRange);const durationInS=tr.b.convertUnit(intersectionRangeInMs.duration,tr.b.UnitPrefixScale.METRIC.MILLI,tr.b.UnitPrefixScale.METRIC.NONE);energyConsumedInJ+=durationInS*sample.powerInW;}
+return energyConsumedInJ;},getSamplesWithinRange(start,end){const startIndex=tr.b.findLowIndexInSortedArray(this.samples,x=>x.start,start);const endIndex=tr.b.findLowIndexInSortedArray(this.samples,x=>x.start,end);return this.samples.slice(startIndex,endIndex);},shiftTimestampsForward(amount){for(let i=0;i<this.samples_.length;++i){this.samples_[i].start+=amount;}},updateBounds(){this.bounds.reset();if(this.samples_.length===0)return;this.bounds.addValue(this.samples_[0].start);this.bounds.addValue(this.samples_[this.samples_.length-1].start);},*childEvents(){yield*this.samples_;},};return{PowerSeries,};});'use strict';tr.exportTo('tr.model',function(){function Device(model){if(!model){throw new Error('Must provide a model.');}
+tr.model.EventContainer.call(this);this.powerSeries_=undefined;this.cpuUsageSeries_=undefined;this.vSyncTimestamps_=[];}
+Device.compare=function(x,y){return x.guid-y.guid;};Device.prototype={__proto__:tr.model.EventContainer.prototype,compareTo(that){return Device.compare(this,that);},get userFriendlyName(){return'Device';},get userFriendlyDetails(){return'Device';},get stableId(){return'Device';},getSettingsKey(){return'device';},get powerSeries(){return this.powerSeries_;},set powerSeries(powerSeries){this.powerSeries_=powerSeries;},get cpuUsageSeries(){return this.cpuUsageSeries_;},set cpuUsageSeries(cpuUsageSeries){this.cpuUsageSeries_=cpuUsageSeries;},get vSyncTimestamps(){return this.vSyncTimestamps_;},set vSyncTimestamps(value){this.vSyncTimestamps_=value;},updateBounds(){this.bounds.reset();for(const child of this.childEventContainers()){child.updateBounds();this.bounds.addRange(child.bounds);}},shiftTimestampsForward(amount){for(const child of this.childEventContainers()){child.shiftTimestampsForward(amount);}
+for(let i=0;i<this.vSyncTimestamps_.length;i++){this.vSyncTimestamps_[i]+=amount;}},addCategoriesToDict(categoriesDict){},*childEventContainers(){if(this.powerSeries_){yield this.powerSeries_;}
+if(this.cpuUsageSeries_){yield this.cpuUsageSeries_;}}};return{Device,};});'use strict';tr.exportTo('tr.model',function(){function FlowEvent(category,id,title,colorId,start,args,opt_duration){tr.model.TimedEvent.call(this,start);this.category=category||'';this.title=title;this.colorId=colorId;this.start=start;this.args=args;this.id=id;this.startSlice=undefined;this.endSlice=undefined;this.startStackFrame=undefined;this.endStackFrame=undefined;if(opt_duration!==undefined){this.duration=opt_duration;}}
 FlowEvent.prototype={__proto__:tr.model.TimedEvent.prototype,get userFriendlyName(){return'Flow event named '+this.title+' at '+
-tr.v.Unit.byName.timeStampInMs.format(this.timestamp);}};tr.model.EventRegistry.register(FlowEvent,{name:'flowEvent',pluralName:'flowEvents',singleViewElementName:'tr-ui-a-single-flow-event-sub-view',multiViewElementName:'tr-ui-a-multi-flow-event-sub-view'});return{FlowEvent:FlowEvent};});'use strict';tr.exportTo('tr.model',function(){function ContainerMemoryDump(start){tr.model.TimedEvent.call(this,start);this.levelOfDetail=undefined;this.memoryAllocatorDumps_=undefined;this.memoryAllocatorDumpsByFullName_=undefined;};ContainerMemoryDump.LevelOfDetail={LIGHT:0,DETAILED:1};ContainerMemoryDump.prototype={__proto__:tr.model.TimedEvent.prototype,shiftTimestampsForward:function(amount){this.start+=amount;},get memoryAllocatorDumps(){return this.memoryAllocatorDumps_;},set memoryAllocatorDumps(memoryAllocatorDumps){this.memoryAllocatorDumps_=memoryAllocatorDumps;this.forceRebuildingMemoryAllocatorDumpByFullNameIndex();},getMemoryAllocatorDumpByFullName:function(fullName){if(this.memoryAllocatorDumps_===undefined)
-return undefined;if(this.memoryAllocatorDumpsByFullName_===undefined){var index={};function addDumpsToIndex(dumps){dumps.forEach(function(dump){index[dump.fullName]=dump;addDumpsToIndex(dump.children);});};addDumpsToIndex(this.memoryAllocatorDumps_);this.memoryAllocatorDumpsByFullName_=index;}
-return this.memoryAllocatorDumpsByFullName_[fullName];},forceRebuildingMemoryAllocatorDumpByFullNameIndex:function(){this.memoryAllocatorDumpsByFullName_=undefined;},iterateRootAllocatorDumps:function(fn,opt_this){if(this.memoryAllocatorDumps===undefined)
-return;this.memoryAllocatorDumps.forEach(fn,opt_this||this);}};return{ContainerMemoryDump:ContainerMemoryDump};});'use strict';tr.exportTo('tr.model',function(){function MemoryAllocatorDump(containerMemoryDump,fullName,opt_guid){this.fullName=fullName;this.parent=undefined;this.children=[];this.numerics={};this.diagnostics={};this.containerMemoryDump=containerMemoryDump;this.owns=undefined;this.ownedBy=[];this.ownedBySiblingSizes=new Map();this.retains=[];this.retainedBy=[];this.weak=false;this.infos=[];this.guid=opt_guid;};MemoryAllocatorDump.SIZE_NUMERIC_NAME='size';MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME='effective_size';MemoryAllocatorDump.RESIDENT_SIZE_NUMERIC_NAME='resident_size';MemoryAllocatorDump.DISPLAYED_SIZE_NUMERIC_NAME=MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME;MemoryAllocatorDump.prototype={get name(){return this.fullName.substring(this.fullName.lastIndexOf('/')+1);},get quantifiedName(){return'\''+this.fullName+'\' in '+
-this.containerMemoryDump.containerName;},isDescendantOf:function(otherDump){var dump=this;while(dump!==undefined){if(dump===otherDump)
-return true;dump=dump.parent;}
-return false;},addNumeric:function(name,numeric){if(!(numeric instanceof tr.v.ScalarNumeric))
-throw new Error('Numeric value must be an instance of ScalarNumeric.');if(name in this.numerics)
-throw new Error('Duplicate numeric name: '+name+'.');this.numerics[name]=numeric;},addDiagnostic:function(name,text){if(typeof text!=='string')
-throw new Error('Diagnostic text must be a string.');if(name in this.diagnostics)
-throw new Error('Duplicate diagnostic name: '+name+'.');this.diagnostics[name]=text;},aggregateNumericsRecursively:function(opt_model){var numericNames=new Set();this.children.forEach(function(child){child.aggregateNumericsRecursively(opt_model);tr.b.iterItems(child.numerics,numericNames.add,numericNames);},this);numericNames.forEach(function(numericName){if(numericName===MemoryAllocatorDump.SIZE_NUMERIC_NAME||numericName===MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME||this.numerics[numericName]!==undefined){return;}
-this.numerics[numericName]=MemoryAllocatorDump.aggregateNumerics(this.children.map(function(child){return child.numerics[numericName];}),opt_model);},this);}};MemoryAllocatorDump.aggregateNumerics=function(numerics,opt_model){var shouldLogWarning=!!opt_model;var aggregatedUnit=undefined;var aggregatedValue=0;numerics.forEach(function(numeric){if(numeric===undefined)
-return;var unit=numeric.unit;if(aggregatedUnit===undefined){aggregatedUnit=unit;}else if(aggregatedUnit!==unit){if(shouldLogWarning){opt_model.importWarning({type:'numeric_parse_error',message:'Multiple units provided for numeric: \''+
+tr.b.Unit.byName.timeStampInMs.format(this.timestamp);}};tr.model.EventRegistry.register(FlowEvent,{name:'flowEvent',pluralName:'flowEvents'});return{FlowEvent,};});'use strict';tr.exportTo('tr.model',function(){function ContainerMemoryDump(start){tr.model.TimedEvent.call(this,start);this.levelOfDetail=undefined;this.memoryAllocatorDumps_=undefined;this.memoryAllocatorDumpsByFullName_=undefined;}
+ContainerMemoryDump.LevelOfDetail={BACKGROUND:0,LIGHT:1,DETAILED:2};ContainerMemoryDump.prototype={__proto__:tr.model.TimedEvent.prototype,shiftTimestampsForward(amount){this.start+=amount;},get memoryAllocatorDumps(){return this.memoryAllocatorDumps_;},set memoryAllocatorDumps(memoryAllocatorDumps){this.memoryAllocatorDumps_=memoryAllocatorDumps;this.forceRebuildingMemoryAllocatorDumpByFullNameIndex();},getMemoryAllocatorDumpByFullName(fullName){if(this.memoryAllocatorDumps_===undefined)return undefined;if(this.memoryAllocatorDumpsByFullName_===undefined){const index={};function addDumpsToIndex(dumps){dumps.forEach(function(dump){index[dump.fullName]=dump;addDumpsToIndex(dump.children);});}
+addDumpsToIndex(this.memoryAllocatorDumps_);this.memoryAllocatorDumpsByFullName_=index;}
+return this.memoryAllocatorDumpsByFullName_[fullName];},forceRebuildingMemoryAllocatorDumpByFullNameIndex(){this.memoryAllocatorDumpsByFullName_=undefined;},iterateRootAllocatorDumps(fn,opt_this){if(this.memoryAllocatorDumps===undefined)return;this.memoryAllocatorDumps.forEach(fn,opt_this||this);}};return{ContainerMemoryDump,};});'use strict';tr.exportTo('tr.model',function(){function MemoryAllocatorDump(containerMemoryDump,fullName,opt_guid){this.fullName=fullName;this.parent=undefined;this.children=[];this.numerics={};this.diagnostics={};this.containerMemoryDump=containerMemoryDump;this.owns=undefined;this.ownedBy=[];this.ownedBySiblingSizes=new Map();this.retains=[];this.retainedBy=[];this.weak=false;this.infos=[];this.guid=opt_guid;}
+MemoryAllocatorDump.SIZE_NUMERIC_NAME='size';MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME='effective_size';MemoryAllocatorDump.RESIDENT_SIZE_NUMERIC_NAME='resident_size';MemoryAllocatorDump.DISPLAYED_SIZE_NUMERIC_NAME=MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME;MemoryAllocatorDump.prototype={get name(){return this.fullName.substring(this.fullName.lastIndexOf('/')+1);},get quantifiedName(){return'\''+this.fullName+'\' in '+
+this.containerMemoryDump.containerName;},getDescendantDumpByFullName(fullName){return this.containerMemoryDump.getMemoryAllocatorDumpByFullName(this.fullName+'/'+fullName);},isDescendantOf(otherDump){if(this===otherDump)return true;if(this.parent===undefined)return false;return this.parent.isDescendantOf(otherDump);},addNumeric(name,numeric){if(!(numeric instanceof tr.b.Scalar)){throw new Error('Numeric value must be an instance of Scalar.');}
+if(name in this.numerics){throw new Error('Duplicate numeric name: '+name+'.');}
+this.numerics[name]=numeric;},addDiagnostic(name,text){if(typeof text!=='string'){throw new Error('Diagnostic text must be a string.');}
+if(name in this.diagnostics){throw new Error('Duplicate diagnostic name: '+name+'.');}
+this.diagnostics[name]=text;},aggregateNumericsRecursively(opt_model){const numericNames=new Set();this.children.forEach(function(child){child.aggregateNumericsRecursively(opt_model);for(const[item,value]of Object.entries(child.numerics)){numericNames.add(item,value);}},this);numericNames.forEach(function(numericName){if(numericName===MemoryAllocatorDump.SIZE_NUMERIC_NAME||numericName===MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME||this.numerics[numericName]!==undefined){return;}
+this.numerics[numericName]=MemoryAllocatorDump.aggregateNumerics(this.children.map(function(child){return child.numerics[numericName];}),opt_model);},this);}};MemoryAllocatorDump.aggregateNumerics=function(numerics,opt_model){let shouldLogWarning=!!opt_model;let aggregatedUnit=undefined;let aggregatedValue=0;numerics.forEach(function(numeric){if(numeric===undefined)return;const unit=numeric.unit;if(aggregatedUnit===undefined){aggregatedUnit=unit;}else if(aggregatedUnit!==unit){if(shouldLogWarning){opt_model.importWarning({type:'numeric_parse_error',message:'Multiple units provided for numeric: \''+
 aggregatedUnit.unitName+'\' and \''+unit.unitName+'\'.'});shouldLogWarning=false;}
-aggregatedUnit=tr.v.Unit.byName.unitlessNumber_smallerIsBetter;}
-aggregatedValue+=numeric.value;},this);if(aggregatedUnit===undefined)
-return undefined;return new tr.v.ScalarNumeric(aggregatedUnit,aggregatedValue);};function MemoryAllocatorDumpLink(source,target,opt_importance){this.source=source;this.target=target;this.importance=opt_importance;this.size=undefined;}
-var MemoryAllocatorDumpInfoType={PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN:0,PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER:1};return{MemoryAllocatorDump:MemoryAllocatorDump,MemoryAllocatorDumpLink:MemoryAllocatorDumpLink,MemoryAllocatorDumpInfoType:MemoryAllocatorDumpInfoType};});'use strict';tr.exportTo('tr.model',function(){function GlobalMemoryDump(model,start){tr.model.ContainerMemoryDump.call(this,start);this.model=model;this.processMemoryDumps={};}
-var SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.SIZE_NUMERIC_NAME;var EFFECTIVE_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME;var MemoryAllocatorDumpInfoType=tr.model.MemoryAllocatorDumpInfoType;var PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN=MemoryAllocatorDumpInfoType.PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN;var PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER=MemoryAllocatorDumpInfoType.PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER;function inPlaceFilter(array,predicate,opt_this){opt_this=opt_this||this;var nextPosition=0;for(var i=0;i<array.length;i++){if(!predicate.call(opt_this,array[i],i))
-continue;if(nextPosition<i)
-array[nextPosition]=array[i];nextPosition++;}
-if(nextPosition<array.length)
-array.length=nextPosition;}
-function getSize(dump){var numeric=dump.numerics[SIZE_NUMERIC_NAME];if(numeric===undefined)
-return 0;return numeric.value;}
+aggregatedUnit=tr.b.Unit.byName.unitlessNumber_smallerIsBetter;}
+aggregatedValue+=numeric.value;},this);if(aggregatedUnit===undefined)return undefined;return new tr.b.Scalar(aggregatedUnit,aggregatedValue);};function MemoryAllocatorDumpLink(source,target,opt_importance){this.source=source;this.target=target;this.importance=opt_importance;this.size=undefined;}
+const MemoryAllocatorDumpInfoType={PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN:0,PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER:1};return{MemoryAllocatorDump,MemoryAllocatorDumpLink,MemoryAllocatorDumpInfoType,};});'use strict';tr.exportTo('tr.model',function(){function GlobalMemoryDump(model,start){tr.model.ContainerMemoryDump.call(this,start);this.model=model;this.processMemoryDumps={};}
+const SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.SIZE_NUMERIC_NAME;const EFFECTIVE_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME;const MemoryAllocatorDumpInfoType=tr.model.MemoryAllocatorDumpInfoType;const PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN=MemoryAllocatorDumpInfoType.PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN;const PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER=MemoryAllocatorDumpInfoType.PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER;function getSize(dump){const numeric=dump.numerics[SIZE_NUMERIC_NAME];if(numeric===undefined)return 0;return numeric.value;}
 function hasSize(dump){return dump.numerics[SIZE_NUMERIC_NAME]!==undefined;}
-function optional(value,defaultValue){if(value===undefined)
-return defaultValue;return value;}
-GlobalMemoryDump.prototype={__proto__:tr.model.ContainerMemoryDump.prototype,get userFriendlyName(){return'Global memory dump at '+
-tr.v.Unit.byName.timeStampInMs.format(this.start);},get containerName(){return'global space';},finalizeGraph:function(){this.removeWeakDumps();this.setUpTracingOverheadOwnership();this.aggregateNumerics();this.calculateSizes();this.calculateEffectiveSizes();this.discountTracingOverheadFromVmRegions();this.forceRebuildingMemoryAllocatorDumpByFullNameIndices();},removeWeakDumps:function(){this.traverseAllocatorDumpsInDepthFirstPreOrder(function(dump){if(dump.weak)
-return;if((dump.owns!==undefined&&dump.owns.target.weak)||(dump.parent!==undefined&&dump.parent.weak)){dump.weak=true;}});function removeWeakDumpsFromListRecursively(dumps){inPlaceFilter(dumps,function(dump){if(dump.weak){return false;}
-removeWeakDumpsFromListRecursively(dump.children);inPlaceFilter(dump.ownedBy,function(ownershipLink){return!ownershipLink.source.weak;});return true;});}
-this.iterateContainerDumps(function(containerDump){var memoryAllocatorDumps=containerDump.memoryAllocatorDumps;if(memoryAllocatorDumps!==undefined)
-removeWeakDumpsFromListRecursively(memoryAllocatorDumps);});},calculateSizes:function(){this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateMemoryAllocatorDumpSize_.bind(this));},calculateMemoryAllocatorDumpSize_:function(dump){var shouldDefineSize=false;function getDependencySize(dependencyDump){var numeric=dependencyDump.numerics[SIZE_NUMERIC_NAME];if(numeric===undefined)
-return 0;shouldDefineSize=true;return numeric.value;}
-var sizeNumeric=dump.numerics[SIZE_NUMERIC_NAME];var size=0;var checkDependencySizeIsConsistent=function(){};if(sizeNumeric!==undefined){size=sizeNumeric.value;shouldDefineSize=true;if(sizeNumeric.unit!==tr.v.Unit.byName.sizeInBytes_smallerIsBetter){this.model.importWarning({type:'memory_dump_parse_error',message:'Invalid unit of \'size\' numeric of memory allocator '+'dump '+dump.quantifiedName+': '+
+function optional(value,defaultValue){if(value===undefined)return defaultValue;return value;}
+GlobalMemoryDump.prototype={__proto__:tr.model.ContainerMemoryDump.prototype,get stableId(){return'memory.'+this.model.globalMemoryDumps.indexOf(this);},get userFriendlyName(){return'Global memory dump at '+
+tr.b.Unit.byName.timeStampInMs.format(this.start);},get containerName(){return'global space';},finalizeGraph(){this.removeWeakDumps();this.setUpTracingOverheadOwnership();this.aggregateNumerics();this.calculateSizes();this.calculateEffectiveSizes();this.discountTracingOverheadFromVmRegions();this.forceRebuildingMemoryAllocatorDumpByFullNameIndices();},removeWeakDumps(){this.traverseAllocatorDumpsInDepthFirstPreOrder(function(dump){if(dump.weak)return;if((dump.owns!==undefined&&dump.owns.target.weak)||(dump.parent!==undefined&&dump.parent.weak)){dump.weak=true;}});function removeWeakDumpsFromListRecursively(dumps){tr.b.inPlaceFilter(dumps,function(dump){if(dump.weak){return false;}
+removeWeakDumpsFromListRecursively(dump.children);tr.b.inPlaceFilter(dump.ownedBy,function(ownershipLink){return!ownershipLink.source.weak;});return true;});}
+this.iterateContainerDumps(function(containerDump){const memoryAllocatorDumps=containerDump.memoryAllocatorDumps;if(memoryAllocatorDumps!==undefined){removeWeakDumpsFromListRecursively(memoryAllocatorDumps);}});},calculateSizes(){this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateMemoryAllocatorDumpSize_.bind(this));},calculateMemoryAllocatorDumpSize_(dump){let shouldDefineSize=false;function getDependencySize(dependencyDump){const numeric=dependencyDump.numerics[SIZE_NUMERIC_NAME];if(numeric===undefined)return 0;shouldDefineSize=true;return numeric.value;}
+const sizeNumeric=dump.numerics[SIZE_NUMERIC_NAME];let size=0;let checkDependencySizeIsConsistent=function(){};if(sizeNumeric!==undefined){size=sizeNumeric.value;shouldDefineSize=true;if(sizeNumeric.unit!==tr.b.Unit.byName.sizeInBytes_smallerIsBetter){this.model.importWarning({type:'memory_dump_parse_error',message:'Invalid unit of \'size\' numeric of memory allocator '+'dump '+dump.quantifiedName+': '+
 sizeNumeric.unit.unitName+'.'});}
-checkDependencySizeIsConsistent=function(dependencySize,dependencyInfoType,dependencyName){if(size>=dependencySize)
-return;this.model.importWarning({type:'memory_dump_parse_error',message:'Size provided by memory allocator dump \''+
+checkDependencySizeIsConsistent=function(dependencySize,dependencyInfoType,dependencyName){if(size>=dependencySize)return;this.model.importWarning({type:'memory_dump_parse_error',message:'Size provided by memory allocator dump \''+
 dump.fullName+'\''+
-tr.v.Unit.byName.sizeInBytes.format(size)+') is less than '+dependencyName+' ('+
-tr.v.Unit.byName.sizeInBytes.format(dependencySize)+').'});dump.infos.push({type:dependencyInfoType,providedSize:size,dependencySize:dependencySize});}.bind(this);}
-var aggregatedChildrenSize=0;var allOverlaps={};dump.children.forEach(function(childDump){function aggregateDescendantDump(descendantDump){var ownedDumpLink=descendantDump.owns;if(ownedDumpLink!==undefined&&ownedDumpLink.target.isDescendantOf(dump)){var ownedChildDump=ownedDumpLink.target;while(ownedChildDump.parent!==dump)
-ownedChildDump=ownedChildDump.parent;if(childDump!==ownedChildDump){var ownedBySiblingSize=getDependencySize(descendantDump);if(ownedBySiblingSize>0){var previousTotalOwnedBySiblingSize=ownedChildDump.ownedBySiblingSizes.get(childDump)||0;var updatedTotalOwnedBySiblingSize=previousTotalOwnedBySiblingSize+ownedBySiblingSize;ownedChildDump.ownedBySiblingSizes.set(childDump,updatedTotalOwnedBySiblingSize);}}
+tr.b.Unit.byName.sizeInBytes.format(size)+') is less than '+dependencyName+' ('+
+tr.b.Unit.byName.sizeInBytes.format(dependencySize)+').'});dump.infos.push({type:dependencyInfoType,providedSize:size,dependencySize});}.bind(this);}
+let aggregatedChildrenSize=0;const allOverlaps={};dump.children.forEach(function(childDump){function aggregateDescendantDump(descendantDump){const ownedDumpLink=descendantDump.owns;if(ownedDumpLink!==undefined&&ownedDumpLink.target.isDescendantOf(dump)){let ownedChildDump=ownedDumpLink.target;while(ownedChildDump.parent!==dump){ownedChildDump=ownedChildDump.parent;}
+if(childDump!==ownedChildDump){const ownedBySiblingSize=getDependencySize(descendantDump);if(ownedBySiblingSize>0){const previousTotalOwnedBySiblingSize=ownedChildDump.ownedBySiblingSizes.get(childDump)||0;const updatedTotalOwnedBySiblingSize=previousTotalOwnedBySiblingSize+ownedBySiblingSize;ownedChildDump.ownedBySiblingSizes.set(childDump,updatedTotalOwnedBySiblingSize);}}
 return;}
 if(descendantDump.children.length===0){aggregatedChildrenSize+=getDependencySize(descendantDump);return;}
 descendantDump.children.forEach(aggregateDescendantDump);}
-aggregateDescendantDump(childDump);});checkDependencySizeIsConsistent(aggregatedChildrenSize,PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN,'the aggregated size of its children');var largestOwnerSize=0;dump.ownedBy.forEach(function(ownershipLink){var owner=ownershipLink.source;var ownerSize=getDependencySize(owner);largestOwnerSize=Math.max(largestOwnerSize,ownerSize);});checkDependencySizeIsConsistent(largestOwnerSize,PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER,'the size of its largest owner');if(!shouldDefineSize){delete dump.numerics[SIZE_NUMERIC_NAME];return;}
-size=Math.max(size,aggregatedChildrenSize,largestOwnerSize);dump.numerics[SIZE_NUMERIC_NAME]=new tr.v.ScalarNumeric(tr.v.Unit.byName.sizeInBytes_smallerIsBetter,size);if(aggregatedChildrenSize<size&&dump.children!==undefined&&dump.children.length>0){var virtualChild=new tr.model.MemoryAllocatorDump(dump.containerMemoryDump,dump.fullName+'/<unspecified>');virtualChild.parent=dump;dump.children.unshift(virtualChild);virtualChild.numerics[SIZE_NUMERIC_NAME]=new tr.v.ScalarNumeric(tr.v.Unit.byName.sizeInBytes_smallerIsBetter,size-aggregatedChildrenSize);}},calculateEffectiveSizes:function(){this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateDumpSubSizes_.bind(this));this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateDumpOwnershipCoefficient_.bind(this));this.traverseAllocatorDumpsInDepthFirstPreOrder(this.calculateDumpCumulativeOwnershipCoefficient_.bind(this));this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateDumpEffectiveSize_.bind(this));},calculateDumpSubSizes_:function(dump){if(!hasSize(dump))
-return;if(dump.children===undefined||dump.children.length===0){var size=getSize(dump);dump.notOwningSubSize_=size;dump.notOwnedSubSize_=size;return;}
-var notOwningSubSize=0;dump.children.forEach(function(childDump){if(childDump.owns!==undefined)
-return;notOwningSubSize+=optional(childDump.notOwningSubSize_,0);});dump.notOwningSubSize_=notOwningSubSize;var notOwnedSubSize=0;dump.children.forEach(function(childDump){if(childDump.ownedBy.length===0){notOwnedSubSize+=optional(childDump.notOwnedSubSize_,0);return;}
-var largestChildOwnerSize=0;childDump.ownedBy.forEach(function(ownershipLink){largestChildOwnerSize=Math.max(largestChildOwnerSize,getSize(ownershipLink.source));});notOwnedSubSize+=getSize(childDump)-largestChildOwnerSize;});dump.notOwnedSubSize_=notOwnedSubSize;},calculateDumpOwnershipCoefficient_:function(dump){if(!hasSize(dump))
-return;if(dump.ownedBy.length===0)
-return;var owners=dump.ownedBy.map(function(ownershipLink){return{dump:ownershipLink.source,importance:optional(ownershipLink.importance,0),notOwningSubSize:optional(ownershipLink.source.notOwningSubSize_,0)};});owners.sort(function(a,b){if(a.importance===b.importance)
-return a.notOwningSubSize-b.notOwningSubSize;return b.importance-a.importance;});var currentImportanceStartPos=0;var alreadyAttributedSubSize=0;while(currentImportanceStartPos<owners.length){var currentImportance=owners[currentImportanceStartPos].importance;var nextImportanceStartPos=currentImportanceStartPos+1;while(nextImportanceStartPos<owners.length&&owners[nextImportanceStartPos].importance===currentImportance){nextImportanceStartPos++;}
-var attributedNotOwningSubSize=0;for(var pos=currentImportanceStartPos;pos<nextImportanceStartPos;pos++){var owner=owners[pos];var notOwningSubSize=owner.notOwningSubSize;if(notOwningSubSize>alreadyAttributedSubSize){attributedNotOwningSubSize+=(notOwningSubSize-alreadyAttributedSubSize)/(nextImportanceStartPos-pos);alreadyAttributedSubSize=notOwningSubSize;}
-var owningCoefficient=0;if(notOwningSubSize!==0)
-owningCoefficient=attributedNotOwningSubSize/notOwningSubSize;owner.dump.owningCoefficient_=owningCoefficient;}
+aggregateDescendantDump(childDump);});checkDependencySizeIsConsistent(aggregatedChildrenSize,PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN,'the aggregated size of its children');let largestOwnerSize=0;dump.ownedBy.forEach(function(ownershipLink){const owner=ownershipLink.source;const ownerSize=getDependencySize(owner);largestOwnerSize=Math.max(largestOwnerSize,ownerSize);});checkDependencySizeIsConsistent(largestOwnerSize,PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER,'the size of its largest owner');if(!shouldDefineSize){delete dump.numerics[SIZE_NUMERIC_NAME];return;}
+size=Math.max(size,aggregatedChildrenSize,largestOwnerSize);dump.numerics[SIZE_NUMERIC_NAME]=new tr.b.Scalar(tr.b.Unit.byName.sizeInBytes_smallerIsBetter,size);if(aggregatedChildrenSize<size&&dump.children!==undefined&&dump.children.length>0){const virtualChild=new tr.model.MemoryAllocatorDump(dump.containerMemoryDump,dump.fullName+'/<unspecified>');virtualChild.parent=dump;dump.children.unshift(virtualChild);virtualChild.numerics[SIZE_NUMERIC_NAME]=new tr.b.Scalar(tr.b.Unit.byName.sizeInBytes_smallerIsBetter,size-aggregatedChildrenSize);}},calculateEffectiveSizes(){this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateDumpSubSizes_.bind(this));this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateDumpOwnershipCoefficient_.bind(this));this.traverseAllocatorDumpsInDepthFirstPreOrder(this.calculateDumpCumulativeOwnershipCoefficient_.bind(this));this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateDumpEffectiveSize_.bind(this));},calculateDumpSubSizes_(dump){if(!hasSize(dump))return;if(dump.children===undefined||dump.children.length===0){const size=getSize(dump);dump.notOwningSubSize_=size;dump.notOwnedSubSize_=size;return;}
+let notOwningSubSize=0;dump.children.forEach(function(childDump){if(childDump.owns!==undefined)return;notOwningSubSize+=optional(childDump.notOwningSubSize_,0);});dump.notOwningSubSize_=notOwningSubSize;let notOwnedSubSize=0;dump.children.forEach(function(childDump){if(childDump.ownedBy.length===0){notOwnedSubSize+=optional(childDump.notOwnedSubSize_,0);return;}
+let largestChildOwnerSize=0;childDump.ownedBy.forEach(function(ownershipLink){largestChildOwnerSize=Math.max(largestChildOwnerSize,getSize(ownershipLink.source));});notOwnedSubSize+=getSize(childDump)-largestChildOwnerSize;});dump.notOwnedSubSize_=notOwnedSubSize;},calculateDumpOwnershipCoefficient_(dump){if(!hasSize(dump))return;if(dump.ownedBy.length===0)return;const owners=dump.ownedBy.map(function(ownershipLink){return{dump:ownershipLink.source,importance:optional(ownershipLink.importance,0),notOwningSubSize:optional(ownershipLink.source.notOwningSubSize_,0)};});owners.sort(function(a,b){if(a.importance===b.importance){return a.notOwningSubSize-b.notOwningSubSize;}
+return b.importance-a.importance;});let currentImportanceStartPos=0;let alreadyAttributedSubSize=0;while(currentImportanceStartPos<owners.length){const currentImportance=owners[currentImportanceStartPos].importance;let nextImportanceStartPos=currentImportanceStartPos+1;while(nextImportanceStartPos<owners.length&&owners[nextImportanceStartPos].importance===currentImportance){nextImportanceStartPos++;}
+let attributedNotOwningSubSize=0;for(let pos=currentImportanceStartPos;pos<nextImportanceStartPos;pos++){const owner=owners[pos];const notOwningSubSize=owner.notOwningSubSize;if(notOwningSubSize>alreadyAttributedSubSize){attributedNotOwningSubSize+=(notOwningSubSize-alreadyAttributedSubSize)/(nextImportanceStartPos-pos);alreadyAttributedSubSize=notOwningSubSize;}
+let owningCoefficient=0;if(notOwningSubSize!==0){owningCoefficient=attributedNotOwningSubSize/notOwningSubSize;}
+owner.dump.owningCoefficient_=owningCoefficient;}
 currentImportanceStartPos=nextImportanceStartPos;}
-var notOwnedSubSize=optional(dump.notOwnedSubSize_,0);var remainderSubSize=notOwnedSubSize-alreadyAttributedSubSize;var ownedCoefficient=0;if(notOwnedSubSize!==0)
-ownedCoefficient=remainderSubSize/notOwnedSubSize;dump.ownedCoefficient_=ownedCoefficient;},calculateDumpCumulativeOwnershipCoefficient_:function(dump){if(!hasSize(dump))
-return;var cumulativeOwnedCoefficient=optional(dump.ownedCoefficient_,1);var parent=dump.parent;if(dump.parent!==undefined)
-cumulativeOwnedCoefficient*=dump.parent.cumulativeOwnedCoefficient_;dump.cumulativeOwnedCoefficient_=cumulativeOwnedCoefficient;var cumulativeOwningCoefficient;if(dump.owns!==undefined){cumulativeOwningCoefficient=dump.owningCoefficient_*dump.owns.target.cumulativeOwningCoefficient_;}else if(dump.parent!==undefined){cumulativeOwningCoefficient=dump.parent.cumulativeOwningCoefficient_;}else{cumulativeOwningCoefficient=1;}
-dump.cumulativeOwningCoefficient_=cumulativeOwningCoefficient;},calculateDumpEffectiveSize_:function(dump){if(!hasSize(dump)){delete dump.numerics[EFFECTIVE_SIZE_NUMERIC_NAME];return;}
-var effectiveSize;if(dump.children===undefined||dump.children.length===0){effectiveSize=getSize(dump)*dump.cumulativeOwningCoefficient_*dump.cumulativeOwnedCoefficient_;}else{effectiveSize=0;dump.children.forEach(function(childDump){if(!hasSize(childDump))
-return;effectiveSize+=childDump.numerics[EFFECTIVE_SIZE_NUMERIC_NAME].value;});}
-dump.numerics[EFFECTIVE_SIZE_NUMERIC_NAME]=new tr.v.ScalarNumeric(tr.v.Unit.byName.sizeInBytes_smallerIsBetter,effectiveSize);},aggregateNumerics:function(){this.iterateRootAllocatorDumps(function(dump){dump.aggregateNumericsRecursively(this.model);});this.iterateRootAllocatorDumps(this.propagateNumericsAndDiagnosticsRecursively);tr.b.iterItems(this.processMemoryDumps,function(pid,processMemoryDump){processMemoryDump.iterateRootAllocatorDumps(function(dump){dump.aggregateNumericsRecursively(this.model);},this);},this);},propagateNumericsAndDiagnosticsRecursively:function(globalAllocatorDump){['numerics','diagnostics'].forEach(function(field){tr.b.iterItems(globalAllocatorDump[field],function(name,value){globalAllocatorDump.ownedBy.forEach(function(ownershipLink){var processAllocatorDump=ownershipLink.source;if(processAllocatorDump[field][name]!==undefined){return;}
-processAllocatorDump[field][name]=value;});});});globalAllocatorDump.children.forEach(this.propagateNumericsAndDiagnosticsRecursively,this);},setUpTracingOverheadOwnership:function(){tr.b.iterItems(this.processMemoryDumps,function(pid,dump){dump.setUpTracingOverheadOwnership(this.model);},this);},discountTracingOverheadFromVmRegions:function(){tr.b.iterItems(this.processMemoryDumps,function(pid,dump){dump.discountTracingOverheadFromVmRegions(this.model);},this);},forceRebuildingMemoryAllocatorDumpByFullNameIndices:function(){this.iterateContainerDumps(function(containerDump){containerDump.forceRebuildingMemoryAllocatorDumpByFullNameIndex();});},iterateContainerDumps:function(fn){fn.call(this,this);tr.b.iterItems(this.processMemoryDumps,function(pid,processDump){fn.call(this,processDump);},this);},iterateAllRootAllocatorDumps:function(fn){this.iterateContainerDumps(function(containerDump){containerDump.iterateRootAllocatorDumps(fn,this);});},traverseAllocatorDumpsInDepthFirstPostOrder:function(fn){var visitedDumps=new WeakSet();var openDumps=new WeakSet();function visit(dump){if(visitedDumps.has(dump))
-return;if(openDumps.has(dump))
-throw new Error(dump.userFriendlyName+' contains a cycle');openDumps.add(dump);dump.ownedBy.forEach(function(ownershipLink){visit.call(this,ownershipLink.source);},this);dump.children.forEach(visit,this);fn.call(this,dump);visitedDumps.add(dump);openDumps.delete(dump);}
-this.iterateAllRootAllocatorDumps(visit);},traverseAllocatorDumpsInDepthFirstPreOrder:function(fn){var visitedDumps=new WeakSet();function visit(dump){if(visitedDumps.has(dump))
-return;if(dump.owns!==undefined&&!visitedDumps.has(dump.owns.target))
-return;if(dump.parent!==undefined&&!visitedDumps.has(dump.parent))
-return;fn.call(this,dump);visitedDumps.add(dump);dump.ownedBy.forEach(function(ownershipLink){visit.call(this,ownershipLink.source);},this);dump.children.forEach(visit,this);}
-this.iterateAllRootAllocatorDumps(visit);}};tr.model.EventRegistry.register(GlobalMemoryDump,{name:'globalMemoryDump',pluralName:'globalMemoryDumps',singleViewElementName:'tr-ui-a-container-memory-dump-sub-view',multiViewElementName:'tr-ui-a-container-memory-dump-sub-view'});return{GlobalMemoryDump:GlobalMemoryDump};});'use strict';tr.exportTo('tr.model',function(){var InstantEventType={GLOBAL:1,PROCESS:2};function InstantEvent(category,title,colorId,start,args){tr.model.TimedEvent.call(this,start);this.category=category||'';this.title=title;this.colorId=colorId;this.args=args;this.type=undefined;};InstantEvent.prototype={__proto__:tr.model.TimedEvent.prototype};function GlobalInstantEvent(category,title,colorId,start,args){InstantEvent.apply(this,arguments);this.type=InstantEventType.GLOBAL;};GlobalInstantEvent.prototype={__proto__:InstantEvent.prototype,get userFriendlyName(){return'Global instant event '+this.title+' @ '+
-tr.v.Unit.byName.timeStampInMs.format(start);}};function ProcessInstantEvent(category,title,colorId,start,args){InstantEvent.apply(this,arguments);this.type=InstantEventType.PROCESS;};ProcessInstantEvent.prototype={__proto__:InstantEvent.prototype,get userFriendlyName(){return'Process-level instant event '+this.title+' @ '+
-tr.v.Unit.byName.timeStampInMs.format(start);}};tr.model.EventRegistry.register(InstantEvent,{name:'instantEvent',pluralName:'instantEvents',singleViewElementName:'tr-ui-a-single-instant-event-sub-view',multiViewElementName:'tr-ui-a-multi-instant-event-sub-view'});return{GlobalInstantEvent:GlobalInstantEvent,ProcessInstantEvent:ProcessInstantEvent,InstantEventType:InstantEventType,InstantEvent:InstantEvent};});'use strict';tr.exportTo('tr.model',function(){function CounterSample(series,timestamp,value){tr.model.Event.call(this);this.series_=series;this.timestamp_=timestamp;this.value_=value;}
-CounterSample.groupByTimestamp=function(samples){var samplesByTimestamp=tr.b.group(samples,function(sample){return sample.timestamp;});var timestamps=tr.b.dictionaryKeys(samplesByTimestamp);timestamps.sort();var groups=[];for(var i=0;i<timestamps.length;i++){var ts=timestamps[i];var group=samplesByTimestamp[ts];group.sort(function(x,y){return x.series.seriesIndex-y.series.seriesIndex;});groups.push(group);}
-return groups;};CounterSample.prototype={__proto__:tr.model.Event.prototype,get series(){return this.series_;},get timestamp(){return this.timestamp_;},get value(){return this.value_;},set timestamp(timestamp){this.timestamp_=timestamp;},addBoundsToRange:function(range){range.addValue(this.timestamp);},getSampleIndex:function(){return tr.b.findLowIndexInSortedArray(this.series.timestamps,function(x){return x;},this.timestamp_);},get userFriendlyName(){return'Counter sample from '+this.series_.title+' at '+
-tr.v.Unit.byName.timeStampInMs.format(this.timestamp);}};tr.model.EventRegistry.register(CounterSample,{name:'counterSample',pluralName:'counterSamples',singleViewElementName:'tr-ui-a-counter-sample-sub-view',multiViewElementName:'tr-ui-a-counter-sample-sub-view'});return{CounterSample:CounterSample};});'use strict';tr.exportTo('tr.model',function(){var CounterSample=tr.model.CounterSample;function CounterSeries(name,color){tr.model.EventContainer.call(this);this.name_=name;this.color_=color;this.timestamps_=[];this.samples_=[];this.counter=undefined;this.seriesIndex=undefined;}
-CounterSeries.prototype={__proto__:tr.model.EventContainer.prototype,get length(){return this.timestamps_.length;},get name(){return this.name_;},get color(){return this.color_;},get samples(){return this.samples_;},get timestamps(){return this.timestamps_;},getSample:function(idx){return this.samples_[idx];},getTimestamp:function(idx){return this.timestamps_[idx];},addCounterSample:function(ts,val){var sample=new CounterSample(this,ts,val);this.addSample(sample);return sample;},addSample:function(sample){this.timestamps_.push(sample.timestamp);this.samples_.push(sample);},getStatistics:function(sampleIndices){var sum=0;var min=Number.MAX_VALUE;var max=-Number.MAX_VALUE;for(var i=0;i<sampleIndices.length;++i){var sample=this.getSample(sampleIndices[i]).value;sum+=sample;min=Math.min(sample,min);max=Math.max(sample,max);}
-return{min:min,max:max,avg:(sum/sampleIndices.length),start:this.getSample(sampleIndices[0]).value,end:this.getSample(sampleIndices.length-1).value};},shiftTimestampsForward:function(amount){for(var i=0;i<this.timestamps_.length;++i){this.timestamps_[i]+=amount;this.samples_[i].timestamp=this.timestamps_[i];}},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,tr.model.CounterSample)){this.samples_.forEach(callback,opt_this);}},iterateAllChildEventContainers:function(callback,opt_this){}};return{CounterSeries:CounterSeries};});'use strict';tr.exportTo('tr.model',function(){function Counter(parent,id,category,name){tr.model.EventContainer.call(this);this.parent_=parent;this.id_=id;this.category_=category||'';this.name_=name;this.series_=[];this.totals=[];}
-Counter.prototype={__proto__:tr.model.EventContainer.prototype,get parent(){return this.parent_;},get id(){return this.id_;},get category(){return this.category_;},get name(){return this.name_;},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){},iterateAllChildEventContainers:function(callback,opt_this){for(var i=0;i<this.series_.length;i++)
-callback.call(opt_this,this.series_[i]);},set timestamps(arg){throw new Error('Bad counter API. No cookie.');},set seriesNames(arg){throw new Error('Bad counter API. No cookie.');},set seriesColors(arg){throw new Error('Bad counter API. No cookie.');},set samples(arg){throw new Error('Bad counter API. No cookie.');},addSeries:function(series){series.counter=this;series.seriesIndex=this.series_.length;this.series_.push(series);return series;},getSeries:function(idx){return this.series_[idx];},get series(){return this.series_;},get numSeries(){return this.series_.length;},get numSamples(){if(this.series_.length===0)
-return 0;return this.series_[0].length;},get timestamps(){if(this.series_.length===0)
-return[];return this.series_[0].timestamps;},getSampleStatistics:function(sampleIndices){sampleIndices.sort();var ret=[];this.series_.forEach(function(series){ret.push(series.getStatistics(sampleIndices));});return ret;},shiftTimestampsForward:function(amount){for(var i=0;i<this.series_.length;++i)
-this.series_[i].shiftTimestampsForward(amount);},updateBounds:function(){this.totals=[];this.maxTotal=0;this.bounds.reset();if(this.series_.length===0)
-return;var firstSeries=this.series_[0];var lastSeries=this.series_[this.series_.length-1];this.bounds.addValue(firstSeries.getTimestamp(0));this.bounds.addValue(lastSeries.getTimestamp(lastSeries.length-1));var numSeries=this.numSeries;this.maxTotal=-Infinity;for(var i=0;i<firstSeries.length;++i){var total=0;this.series_.forEach(function(series){total+=series.getSample(i).value;this.totals.push(total);}.bind(this));this.maxTotal=Math.max(total,this.maxTotal);}}};Counter.compare=function(x,y){var tmp=x.parent.compareTo(y);if(tmp!=0)
-return tmp;var tmp=x.name.localeCompare(y.name);if(tmp==0)
-return x.tid-y.tid;return tmp;};return{Counter:Counter};});'use strict';tr.exportTo('tr.model',function(){var Slice=tr.model.Slice;function CpuSlice(cat,title,colorId,start,args,opt_duration){Slice.apply(this,arguments);this.threadThatWasRunning=undefined;this.cpu=undefined;}
-CpuSlice.prototype={__proto__:Slice.prototype,get analysisTypeName(){return'tr.ui.analysis.CpuSlice';},getAssociatedTimeslice:function(){if(!this.threadThatWasRunning)
-return undefined;var timeSlices=this.threadThatWasRunning.timeSlices;for(var i=0;i<timeSlices.length;i++){var timeSlice=timeSlices[i];if(timeSlice.start!==this.start)
-continue;if(timeSlice.duration!==this.duration)
-continue;return timeSlice;}
-return undefined;}};tr.model.EventRegistry.register(CpuSlice,{name:'cpuSlice',pluralName:'cpuSlices',singleViewElementName:'tr-ui-a-single-cpu-slice-sub-view',multiViewElementName:'tr-ui-a-multi-cpu-slice-sub-view'});return{CpuSlice:CpuSlice};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;var Counter=tr.model.Counter;var CpuSlice=tr.model.CpuSlice;var Slice=tr.model.Slice;function Cpu(kernel,number){if(kernel===undefined||number===undefined)
-throw new Error('Missing arguments');this.kernel=kernel;this.cpuNumber=number;this.slices=[];this.counters={};this.bounds=new tr.b.Range();this.samples_=undefined;this.lastActiveTimestamp_=undefined;this.lastActiveThread_=undefined;this.lastActiveName_=undefined;this.lastActiveArgs_=undefined;};Cpu.prototype={get samples(){return this.samples_;},get userFriendlyName(){return'CPU '+this.cpuNumber;},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,tr.model.CpuSlice))
-this.slices.forEach(callback,opt_this);if(this.samples_){if(eventTypePredicate.call(opt_this,tr.model.Sample))
-this.samples_.forEach(callback,opt_this);}},iterateAllChildEventContainers:function(callback,opt_this){for(var id in this.counters)
-callback.call(opt_this,this.counters[id]);},getOrCreateCounter:function(cat,name){var id=cat+'.'+name;if(!this.counters[id])
-this.counters[id]=new Counter(this,id,cat,name);return this.counters[id];},getCounter:function(cat,name){var id=cat+'.'+name;if(!this.counters[id])
-return undefined;return this.counters[id];},shiftTimestampsForward:function(amount){for(var sI=0;sI<this.slices.length;sI++)
-this.slices[sI].start=(this.slices[sI].start+amount);for(var id in this.counters)
-this.counters[id].shiftTimestampsForward(amount);},updateBounds:function(){this.bounds.reset();if(this.slices.length){this.bounds.addValue(this.slices[0].start);this.bounds.addValue(this.slices[this.slices.length-1].end);}
-for(var id in this.counters){this.counters[id].updateBounds();this.bounds.addRange(this.counters[id].bounds);}
-if(this.samples_&&this.samples_.length){this.bounds.addValue(this.samples_[0].start);this.bounds.addValue(this.samples_[this.samples_.length-1].end);}},createSubSlices:function(){this.samples_=this.kernel.model.samples.filter(function(sample){return sample.cpu==this;},this);},addCategoriesToDict:function(categoriesDict){for(var i=0;i<this.slices.length;i++)
-categoriesDict[this.slices[i].category]=true;for(var id in this.counters)
-categoriesDict[this.counters[id].category]=true;for(var i=0;i<this.samples_.length;i++)
-categoriesDict[this.samples_[i].category]=true;},indexOf:function(cpuSlice){var i=tr.b.findLowIndexInSortedArray(this.slices,function(slice){return slice.start;},cpuSlice.start);if(this.slices[i]!==cpuSlice)
-return undefined;return i;},closeActiveThread:function(end_timestamp,args){if(this.lastActiveThread_==undefined||this.lastActiveThread_==0)
-return;if(end_timestamp<this.lastActiveTimestamp_){throw new Error('The end timestamp of a thread running on CPU '+
-this.cpuNumber+' is before its start timestamp.');}
-for(var key in args){this.lastActiveArgs_[key]=args[key];}
-var duration=end_timestamp-this.lastActiveTimestamp_;var slice=new tr.model.CpuSlice('',this.lastActiveName_,ColorScheme.getColorIdForGeneralPurposeString(this.lastActiveName_),this.lastActiveTimestamp_,this.lastActiveArgs_,duration);slice.cpu=this;this.slices.push(slice);this.lastActiveTimestamp_=undefined;this.lastActiveThread_=undefined;this.lastActiveName_=undefined;this.lastActiveArgs_=undefined;},switchActiveThread:function(timestamp,old_thread_args,new_thread_id,new_thread_name,new_thread_args){this.closeActiveThread(timestamp,old_thread_args);this.lastActiveTimestamp_=timestamp;this.lastActiveThread_=new_thread_id;this.lastActiveName_=new_thread_name;this.lastActiveArgs_=new_thread_args;},getFreqStatsForRange:function(range){var stats={};function addStatsForFreq(freqSample,index){var freqEnd=(index<freqSample.series_.length-1)?freqSample.series_.samples_[index+1].timestamp:range.max;var freqRange=tr.b.Range.fromExplicitRange(freqSample.timestamp,freqEnd);var intersection=freqRange.findIntersection(range);if(!(freqSample.value in stats))
-stats[freqSample.value]=0;stats[freqSample.value]+=intersection.duration;}
-var freqCounter=this.getCounter('','Clock Frequency');if(freqCounter!==undefined){var freqSeries=freqCounter.getSeries(0);if(!freqSeries)
-return;tr.b.iterateOverIntersectingIntervals(freqSeries.samples_,function(x){return x.timestamp;},function(x,index){return index<freqSeries.length-1?freqSeries.samples_[index+1].timestamp:range.max;},range.min,range.max,addStatsForFreq);}
-return stats;}};Cpu.compare=function(x,y){return x.cpuNumber-y.cpuNumber;};return{Cpu:Cpu};});'use strict';tr.exportTo('tr.model',function(){function TimeToObjectInstanceMap(createObjectInstanceFunction,parent,scopedId){this.createObjectInstanceFunction_=createObjectInstanceFunction;this.parent=parent;this.scopedId=scopedId;this.instances=[];}
-TimeToObjectInstanceMap.prototype={idWasCreated:function(category,name,ts){if(this.instances.length==0){this.instances.push(this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts));this.instances[0].creationTsWasExplicit=true;return this.instances[0];}
-var lastInstance=this.instances[this.instances.length-1];if(ts<lastInstance.deletionTs){throw new Error('Mutation of the TimeToObjectInstanceMap must be '+'done in ascending timestamp order.');}
-lastInstance=this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts);lastInstance.creationTsWasExplicit=true;this.instances.push(lastInstance);return lastInstance;},addSnapshot:function(category,name,ts,args,opt_baseTypeName){if(this.instances.length==0){this.instances.push(this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts,opt_baseTypeName));}
-var i=tr.b.findIndexInSortedIntervals(this.instances,function(inst){return inst.creationTs;},function(inst){return inst.deletionTs-inst.creationTs;},ts);var instance;if(i<0){instance=this.instances[0];if(ts>instance.deletionTs||instance.creationTsWasExplicit){throw new Error('At the provided timestamp, no instance was still alive');}
-if(instance.snapshots.length!=0){throw new Error('Cannot shift creationTs forward, '+'snapshots have been added. First snap was at ts='+
-instance.snapshots[0].ts+' and creationTs was '+
-instance.creationTs);}
-instance.creationTs=ts;}else if(i>=this.instances.length){instance=this.instances[this.instances.length-1];if(ts>=instance.deletionTs){instance=this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts,opt_baseTypeName);this.instances.push(instance);}else{var lastValidIndex;for(var i=this.instances.length-1;i>=0;i--){var tmp=this.instances[i];if(ts>=tmp.deletionTs)
-break;if(tmp.creationTsWasExplicit==false&&tmp.snapshots.length==0)
-lastValidIndex=i;}
-if(lastValidIndex===undefined){throw new Error('Cannot add snapshot. No instance was alive that was mutable.');}
-instance=this.instances[lastValidIndex];instance.creationTs=ts;}}else{instance=this.instances[i];}
-return instance.addSnapshot(ts,args,name,opt_baseTypeName);},get lastInstance(){if(this.instances.length==0)
-return undefined;return this.instances[this.instances.length-1];},idWasDeleted:function(category,name,ts){if(this.instances.length==0){this.instances.push(this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts));}
-var lastInstance=this.instances[this.instances.length-1];if(ts<lastInstance.creationTs)
-throw new Error('Cannot delete an id before it was created');if(lastInstance.deletionTs==Number.MAX_VALUE){lastInstance.wasDeleted(ts);return lastInstance;}
-if(ts<lastInstance.deletionTs)
-throw new Error('id was already deleted earlier.');lastInstance=this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts);this.instances.push(lastInstance);lastInstance.wasDeleted(ts);return lastInstance;},getInstanceAt:function(ts){var i=tr.b.findIndexInSortedIntervals(this.instances,function(inst){return inst.creationTs;},function(inst){return inst.deletionTs-inst.creationTs;},ts);if(i<0){if(this.instances[0].creationTsWasExplicit)
-return undefined;return this.instances[0];}else if(i>=this.instances.length){return undefined;}
-return this.instances[i];},logToConsole:function(){for(var i=0;i<this.instances.length;i++){var instance=this.instances[i];var cEF='';var dEF='';if(instance.creationTsWasExplicit)
-cEF='(explicitC)';if(instance.deletionTsWasExplicit)
-dEF='(explicit)';console.log(instance.creationTs,cEF,instance.deletionTs,dEF,instance.category,instance.name,instance.snapshots.length+' snapshots');}}};return{TimeToObjectInstanceMap:TimeToObjectInstanceMap};});'use strict';tr.exportTo('tr.model',function(){var ObjectInstance=tr.model.ObjectInstance;var ObjectSnapshot=tr.model.ObjectSnapshot;function ObjectCollection(parent){tr.model.EventContainer.call(this);this.parent=parent;this.instanceMapsByScopedId_={};this.instancesByTypeName_={};this.createObjectInstance_=this.createObjectInstance_.bind(this);}
-ObjectCollection.prototype={__proto__:tr.model.EventContainer.prototype,iterateAllChildEventContainers:function(callback,opt_this){},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){var bI=!!eventTypePredicate.call(opt_this,ObjectInstance);var bS=!!eventTypePredicate.call(opt_this,ObjectSnapshot);if(bI===false&&bS===false)
-return;this.iterObjectInstances(function(instance){if(bI)
-callback.call(opt_this,instance);if(bS)
-instance.snapshots.forEach(callback,opt_this);},opt_this);},createObjectInstance_:function(parent,scopedId,category,name,creationTs,opt_baseTypeName){var constructor=tr.model.ObjectInstance.getConstructor(category,name);var instance=new constructor(parent,scopedId,category,name,creationTs,opt_baseTypeName);var typeName=instance.typeName;var instancesOfTypeName=this.instancesByTypeName_[typeName];if(!instancesOfTypeName){instancesOfTypeName=[];this.instancesByTypeName_[typeName]=instancesOfTypeName;}
-instancesOfTypeName.push(instance);return instance;},getOrCreateInstanceMap_:function(scopedId){var dict;if(scopedId.scope in this.instanceMapsByScopedId_){dict=this.instanceMapsByScopedId_[scopedId.scope];}else{dict={};this.instanceMapsByScopedId_[scopedId.scope]=dict;}
-var instanceMap=dict[scopedId.id];if(instanceMap)
-return instanceMap;instanceMap=new tr.model.TimeToObjectInstanceMap(this.createObjectInstance_,this.parent,scopedId);dict[scopedId.id]=instanceMap;return instanceMap;},idWasCreated:function(scopedId,category,name,ts){var instanceMap=this.getOrCreateInstanceMap_(scopedId);return instanceMap.idWasCreated(category,name,ts);},addSnapshot:function(scopedId,category,name,ts,args,opt_baseTypeName){var instanceMap=this.getOrCreateInstanceMap_(scopedId);var snapshot=instanceMap.addSnapshot(category,name,ts,args,opt_baseTypeName);if(snapshot.objectInstance.category!=category){var msg='Added snapshot name='+name+' with cat='+category+' impossible. It instance was created/snapshotted with cat='+
-snapshot.objectInstance.category+' name='+
-snapshot.objectInstance.name;throw new Error(msg);}
-if(opt_baseTypeName&&snapshot.objectInstance.baseTypeName!=opt_baseTypeName){throw new Error('Could not add snapshot with baseTypeName='+
-opt_baseTypeName+'. It '+'was previously created with name='+
-snapshot.objectInstance.baseTypeName);}
-if(snapshot.objectInstance.name!=name){throw new Error('Could not add snapshot with name='+name+'. It '+'was previously created with name='+
-snapshot.objectInstance.name);}
-return snapshot;},idWasDeleted:function(scopedId,category,name,ts){var instanceMap=this.getOrCreateInstanceMap_(scopedId);var deletedInstance=instanceMap.idWasDeleted(category,name,ts);if(!deletedInstance)
-return;if(deletedInstance.category!=category){var msg='Deleting object '+deletedInstance.name+' with a different category '+'than when it was created. It previous had cat='+
-deletedInstance.category+' but the delete command '+'had cat='+category;throw new Error(msg);}
-if(deletedInstance.baseTypeName!=name){throw new Error('Deletion requested for name='+
-name+' could not proceed: '+'An existing object with baseTypeName='+
-deletedInstance.baseTypeName+' existed.');}},autoDeleteObjects:function(maxTimestamp){tr.b.iterItems(this.instanceMapsByScopedId_,function(scope,imapById){tr.b.iterItems(imapById,function(id,i2imap){var lastInstance=i2imap.lastInstance;if(lastInstance.deletionTs!=Number.MAX_VALUE)
-return;i2imap.idWasDeleted(lastInstance.category,lastInstance.name,maxTimestamp);lastInstance.deletionTsWasExplicit=false;});});},getObjectInstanceAt:function(scopedId,ts){var instanceMap;if(scopedId.scope in this.instanceMapsByScopedId_)
-instanceMap=this.instanceMapsByScopedId_[scopedId.scope][scopedId.id];if(!instanceMap)
-return undefined;return instanceMap.getInstanceAt(ts);},getSnapshotAt:function(scopedId,ts){var instance=this.getObjectInstanceAt(scopedId,ts);if(!instance)
-return undefined;return instance.getSnapshotAt(ts);},iterObjectInstances:function(iter,opt_this){opt_this=opt_this||this;tr.b.iterItems(this.instanceMapsByScopedId_,function(scope,imapById){tr.b.iterItems(imapById,function(id,i2imap){i2imap.instances.forEach(iter,opt_this);});});},getAllObjectInstances:function(){var instances=[];this.iterObjectInstances(function(i){instances.push(i);});return instances;},getAllInstancesNamed:function(name){return this.instancesByTypeName_[name];},getAllInstancesByTypeName:function(){return this.instancesByTypeName_;},preInitializeAllObjects:function(){this.iterObjectInstances(function(instance){instance.preInitialize();});},initializeAllObjects:function(){this.iterObjectInstances(function(instance){instance.initialize();});},initializeInstances:function(){this.iterObjectInstances(function(instance){instance.initialize();});},updateBounds:function(){this.bounds.reset();this.iterObjectInstances(function(instance){instance.updateBounds();this.bounds.addRange(instance.bounds);},this);},shiftTimestampsForward:function(amount){this.iterObjectInstances(function(instance){instance.shiftTimestampsForward(amount);});},addCategoriesToDict:function(categoriesDict){this.iterObjectInstances(function(instance){categoriesDict[instance.category]=true;});}};return{ObjectCollection:ObjectCollection};});'use strict';tr.exportTo('tr.model',function(){function AsyncSliceGroup(parentContainer,opt_name){tr.model.EventContainer.call(this);this.parentContainer_=parentContainer;this.slices=[];this.name_=opt_name;this.viewSubGroups_=undefined;}
-AsyncSliceGroup.prototype={__proto__:tr.model.EventContainer.prototype,get parentContainer(){return this.parentContainer_;},get model(){return this.parentContainer_.parent.model;},get stableId(){return this.parentContainer_.stableId+'.AsyncSliceGroup';},getSettingsKey:function(){if(!this.name_)
-return undefined;var parentKey=this.parentContainer_.getSettingsKey();if(!parentKey)
-return undefined;return parentKey+'.'+this.name_;},push:function(slice){slice.parentContainer=this.parentContainer;this.slices.push(slice);return slice;},get length(){return this.slices.length;},shiftTimestampsForward:function(amount){for(var sI=0;sI<this.slices.length;sI++){var slice=this.slices[sI];slice.start=(slice.start+amount);var shiftSubSlices=function(subSlices){if(subSlices===undefined||subSlices.length===0)
-return;for(var sJ=0;sJ<subSlices.length;sJ++){subSlices[sJ].start+=amount;shiftSubSlices(subSlices[sJ].subSlices);}};shiftSubSlices(slice.subSlices);}},updateBounds:function(){this.bounds.reset();for(var i=0;i<this.slices.length;i++){this.bounds.addValue(this.slices[i].start);this.bounds.addValue(this.slices[i].end);}},get viewSubGroups(){if(this.viewSubGroups_===undefined){var prefix='';if(this.name!==undefined)
-prefix=this.name+'.';else
-prefix='';var subGroupsByTitle={};for(var i=0;i<this.slices.length;++i){var slice=this.slices[i];var subGroupTitle=slice.viewSubGroupTitle;if(!subGroupsByTitle[subGroupTitle]){subGroupsByTitle[subGroupTitle]=new AsyncSliceGroup(this.parentContainer_,prefix+subGroupTitle);}
-subGroupsByTitle[subGroupTitle].push(slice);}
-this.viewSubGroups_=tr.b.dictionaryValues(subGroupsByTitle);this.viewSubGroups_.sort(function(a,b){return a.slices[0].compareTo(b.slices[0]);});}
-return this.viewSubGroups_;},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,tr.model.AsyncSlice)){for(var i=0;i<this.slices.length;i++){var slice=this.slices[i];callback.call(opt_this,slice);if(slice.subSlices)
-slice.subSlices.forEach(callback,opt_this);}}},iterateAllChildEventContainers:function(callback,opt_this){}};return{AsyncSliceGroup:AsyncSliceGroup};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;var Slice=tr.model.Slice;function getSliceLo(s){return s.start;}
-function getSliceHi(s){return s.end;}
-function SliceGroup(parentContainer,opt_sliceConstructor,opt_name){tr.model.EventContainer.call(this);this.parentContainer_=parentContainer;var sliceConstructor=opt_sliceConstructor||Slice;this.sliceConstructor=sliceConstructor;this.openPartialSlices_=[];this.slices=[];this.topLevelSlices=[];this.haveTopLevelSlicesBeenBuilt=false;this.name_=opt_name;if(this.model===undefined)
-throw new Error('SliceGroup must have model defined.');}
-SliceGroup.prototype={__proto__:tr.model.EventContainer.prototype,get parentContainer(){return this.parentContainer_;},get model(){return this.parentContainer_.model;},get stableId(){return this.parentContainer_.stableId+'.SliceGroup';},getSettingsKey:function(){if(!this.name_)
-return undefined;var parentKey=this.parentContainer_.getSettingsKey();if(!parentKey)
-return undefined;return parentKey+'.'+this.name;},get length(){return this.slices.length;},pushSlice:function(slice){this.haveTopLevelSlicesBeenBuilt=false;slice.parentContainer=this.parentContainer_;this.slices.push(slice);return slice;},pushSlices:function(slices){this.haveTopLevelSlicesBeenBuilt=false;slices.forEach(function(slice){slice.parentContainer=this.parentContainer_;this.slices.push(slice);},this);},beginSlice:function(category,title,ts,opt_args,opt_tts,opt_argsStripped,opt_colorId){if(this.openPartialSlices_.length){var prevSlice=this.openPartialSlices_[this.openPartialSlices_.length-1];if(ts<prevSlice.start)
-throw new Error('Slices must be added in increasing timestamp order');}
-var colorId=opt_colorId||ColorScheme.getColorIdForGeneralPurposeString(title);var slice=new this.sliceConstructor(category,title,colorId,ts,opt_args?opt_args:{},null,opt_tts,undefined,opt_argsStripped);this.openPartialSlices_.push(slice);slice.didNotFinish=true;this.pushSlice(slice);return slice;},isTimestampValidForBeginOrEnd:function(ts){if(!this.openPartialSlices_.length)
-return true;var top=this.openPartialSlices_[this.openPartialSlices_.length-1];return ts>=top.start;},get openSliceCount(){return this.openPartialSlices_.length;},get mostRecentlyOpenedPartialSlice(){if(!this.openPartialSlices_.length)
-return undefined;return this.openPartialSlices_[this.openPartialSlices_.length-1];},endSlice:function(ts,opt_tts,opt_colorId){if(!this.openSliceCount)
-throw new Error('endSlice called without an open slice');var slice=this.openPartialSlices_[this.openSliceCount-1];this.openPartialSlices_.splice(this.openSliceCount-1,1);if(ts<slice.start)
-throw new Error('Slice '+slice.title+' end time is before its start.');slice.duration=ts-slice.start;slice.didNotFinish=false;slice.colorId=opt_colorId||slice.colorId;if(opt_tts&&slice.cpuStart!==undefined)
-slice.cpuDuration=opt_tts-slice.cpuStart;return slice;},pushCompleteSlice:function(category,title,ts,duration,tts,cpuDuration,opt_args,opt_argsStripped,opt_colorId,opt_bind_id){var colorId=opt_colorId||ColorScheme.getColorIdForGeneralPurposeString(title);var slice=new this.sliceConstructor(category,title,colorId,ts,opt_args?opt_args:{},duration,tts,cpuDuration,opt_argsStripped,opt_bind_id);if(duration===undefined)
-slice.didNotFinish=true;this.pushSlice(slice);return slice;},autoCloseOpenSlices:function(){this.updateBounds();var maxTimestamp=this.bounds.max;for(var sI=0;sI<this.slices.length;sI++){var slice=this.slices[sI];if(slice.didNotFinish)
-slice.duration=maxTimestamp-slice.start;}
-this.openPartialSlices_=[];},shiftTimestampsForward:function(amount){for(var sI=0;sI<this.slices.length;sI++){var slice=this.slices[sI];slice.start=(slice.start+amount);}},updateBounds:function(){this.bounds.reset();for(var i=0;i<this.slices.length;i++){this.bounds.addValue(this.slices[i].start);this.bounds.addValue(this.slices[i].end);}},copySlice:function(slice){var newSlice=new this.sliceConstructor(slice.category,slice.title,slice.colorId,slice.start,slice.args,slice.duration,slice.cpuStart,slice.cpuDuration);newSlice.didNotFinish=slice.didNotFinish;return newSlice;},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,this.sliceConstructor))
-this.slices.forEach(callback,opt_this);},iterateAllChildEventContainers:function(callback,opt_this){},getSlicesOfName:function(title){var slices=[];for(var i=0;i<this.slices.length;i++){if(this.slices[i].title==title){slices.push(this.slices[i]);}}
-return slices;},iterSlicesInTimeRange:function(callback,start,end){var ret=[];tr.b.iterateOverIntersectingIntervals(this.topLevelSlices,function(s){return s.start;},function(s){return s.duration;},start,end,function(topLevelSlice){callback(topLevelSlice);topLevelSlice.iterateAllDescendents(callback);});return ret;},findFirstSlice:function(){if(!this.haveTopLevelSlicesBeenBuilt)
-throw new Error('Nope');if(0===this.slices.length)
-return undefined;return this.slices[0];},findSliceAtTs:function(ts){if(!this.haveTopLevelSlicesBeenBuilt)
-throw new Error('Nope');var i=tr.b.findIndexInSortedClosedIntervals(this.topLevelSlices,getSliceLo,getSliceHi,ts);if(i==-1||i==this.topLevelSlices.length)
-return undefined;var curSlice=this.topLevelSlices[i];while(true){var i=tr.b.findIndexInSortedClosedIntervals(curSlice.subSlices,getSliceLo,getSliceHi,ts);if(i==-1||i==curSlice.subSlices.length)
-return curSlice;curSlice=curSlice.subSlices[i];}},findNextSliceAfter:function(ts,refGuid){var i=tr.b.findLowIndexInSortedArray(this.slices,getSliceLo,ts);if(i===this.slices.length)
-return undefined;for(;i<this.slices.length;i++){var slice=this.slices[i];if(slice.start>ts)
-return slice;if(slice.guid<=refGuid)
-continue;return slice;}
-return undefined;},createSubSlices:function(){this.haveTopLevelSlicesBeenBuilt=true;this.createSubSlicesImpl_();if(this.parentContainer.timeSlices)
-this.addCpuTimeToSubslices_(this.parentContainer.timeSlices);this.slices.forEach(function(slice){var selfTime=slice.duration;for(var i=0;i<slice.subSlices.length;i++)
-selfTime-=slice.subSlices[i].duration;slice.selfTime=selfTime;if(slice.cpuDuration===undefined)
-return;var cpuSelfTime=slice.cpuDuration;for(var i=0;i<slice.subSlices.length;i++){if(slice.subSlices[i].cpuDuration!==undefined)
-cpuSelfTime-=slice.subSlices[i].cpuDuration;}
-slice.cpuSelfTime=cpuSelfTime;});},createSubSlicesImpl_:function(){var precisionUnit=this.model.intrinsicTimeUnit;function addSliceIfBounds(root,child){if(root.bounds(child,precisionUnit)){if(root.subSlices&&root.subSlices.length>0){if(addSliceIfBounds(root.subSlices[root.subSlices.length-1],child))
-return true;}
-child.parentSlice=root;if(root.subSlices===undefined)
-root.subSlices=[];root.subSlices.push(child);return true;}
-return false;}
-if(!this.slices.length)
-return;var ops=[];for(var i=0;i<this.slices.length;i++){if(this.slices[i].subSlices)
-this.slices[i].subSlices.splice(0,this.slices[i].subSlices.length);ops.push(i);}
-var originalSlices=this.slices;ops.sort(function(ix,iy){var x=originalSlices[ix];var y=originalSlices[iy];if(x.start!=y.start)
-return x.start-y.start;return ix-iy;});var slices=new Array(this.slices.length);for(var i=0;i<ops.length;i++){slices[i]=originalSlices[ops[i]];}
-var rootSlice=slices[0];this.topLevelSlices=[];this.topLevelSlices.push(rootSlice);rootSlice.isTopLevel=true;for(var i=1;i<slices.length;i++){var slice=slices[i];if(!addSliceIfBounds(rootSlice,slice)){rootSlice=slice;rootSlice.isTopLevel=true;this.topLevelSlices.push(rootSlice);}}
-this.slices=slices;},addCpuTimeToSubslices_:function(timeSlices){var SCHEDULING_STATE=tr.model.SCHEDULING_STATE;var sliceIdx=0;timeSlices.forEach(function(timeSlice){if(timeSlice.schedulingState==SCHEDULING_STATE.RUNNING){while(sliceIdx<this.topLevelSlices.length){if(this.addCpuTimeToSubslice_(this.topLevelSlices[sliceIdx],timeSlice)){sliceIdx++;}else{break;}}}},this);},addCpuTimeToSubslice_:function(slice,timeSlice){if(slice.start>timeSlice.end||slice.end<timeSlice.start)
-return slice.end<=timeSlice.end;var duration=timeSlice.duration;if(slice.start>timeSlice.start)
-duration-=slice.start-timeSlice.start;if(timeSlice.end>slice.end)
-duration-=timeSlice.end-slice.end;if(slice.cpuDuration){slice.cpuDuration+=duration;}else{slice.cpuDuration=duration;}
-for(var i=0;i<slice.subSlices.length;i++){this.addCpuTimeToSubslice_(slice.subSlices[i],timeSlice);}
-return slice.end<=timeSlice.end;}};SliceGroup.merge=function(groupA,groupB){if(groupA.openPartialSlices_.length>0)
-throw new Error('groupA has open partial slices');if(groupB.openPartialSlices_.length>0)
-throw new Error('groupB has open partial slices');if(groupA.parentContainer!=groupB.parentContainer)
-throw new Error('Different parent threads. Cannot merge');if(groupA.sliceConstructor!=groupB.sliceConstructor)
-throw new Error('Different slice constructors. Cannot merge');var result=new SliceGroup(groupA.parentContainer,groupA.sliceConstructor,groupA.name_);var slicesA=groupA.slices;var slicesB=groupB.slices;var idxA=0;var idxB=0;var openA=[];var openB=[];var splitOpenSlices=function(when){for(var i=0;i<openB.length;i++){var oldSlice=openB[i];var oldEnd=oldSlice.end;if(when<oldSlice.start||oldEnd<when){throw new Error('slice should not be split');}
-var newSlice=result.copySlice(oldSlice);newSlice.start=when;newSlice.duration=oldEnd-when;if(newSlice.title.indexOf(' (cont.)')==-1)
-newSlice.title+=' (cont.)';oldSlice.duration=when-oldSlice.start;openB[i]=newSlice;result.pushSlice(newSlice);}};var closeOpenSlices=function(upTo){while(openA.length>0||openB.length>0){var nextA=openA[openA.length-1];var nextB=openB[openB.length-1];var endA=nextA&&nextA.end;var endB=nextB&&nextB.end;if((endA===undefined||endA>upTo)&&(endB===undefined||endB>upTo)){return;}
-if(endB===undefined||endA<endB){splitOpenSlices(endA);openA.pop();}else{openB.pop();}}};while(idxA<slicesA.length||idxB<slicesB.length){var sA=slicesA[idxA];var sB=slicesB[idxB];var nextSlice,isFromB;if(sA===undefined||(sB!==undefined&&sA.start>sB.start)){nextSlice=result.copySlice(sB);isFromB=true;idxB++;}else{nextSlice=result.copySlice(sA);isFromB=false;idxA++;}
-closeOpenSlices(nextSlice.start);result.pushSlice(nextSlice);if(isFromB){openB.push(nextSlice);}else{splitOpenSlices(nextSlice.start);openA.push(nextSlice);}}
-closeOpenSlices();return result;};return{SliceGroup:SliceGroup};});'use strict';tr.exportTo('tr.model',function(){var Slice=tr.model.Slice;function ThreadSlice(cat,title,colorId,start,args,opt_duration,opt_cpuStart,opt_cpuDuration,opt_argsStripped,opt_bind_id){Slice.call(this,cat,title,colorId,start,args,opt_duration,opt_cpuStart,opt_cpuDuration,opt_argsStripped,opt_bind_id);this.subSlices=[];}
-ThreadSlice.prototype={__proto__:Slice.prototype};tr.model.EventRegistry.register(ThreadSlice,{name:'slice',pluralName:'slices',singleViewElementName:'tr-ui-a-single-thread-slice-sub-view',multiViewElementName:'tr-ui-a-multi-thread-slice-sub-view'});return{ThreadSlice:ThreadSlice};});'use strict';tr.exportTo('tr.model',function(){var AsyncSlice=tr.model.AsyncSlice;var AsyncSliceGroup=tr.model.AsyncSliceGroup;var Slice=tr.model.Slice;var SliceGroup=tr.model.SliceGroup;var ThreadSlice=tr.model.ThreadSlice;var ThreadTimeSlice=tr.model.ThreadTimeSlice;function Thread(parent,tid){if(!parent)
-throw new Error('Parent must be provided.');tr.model.EventContainer.call(this);this.parent=parent;this.sortIndex=0;this.tid=tid;this.name=undefined;this.samples_=undefined;var that=this;this.sliceGroup=new SliceGroup(this,ThreadSlice,'slices');this.timeSlices=undefined;this.kernelSliceGroup=new SliceGroup(this,ThreadSlice,'kernel-slices');this.asyncSliceGroup=new AsyncSliceGroup(this,'async-slices');}
-Thread.prototype={__proto__:tr.model.EventContainer.prototype,get model(){return this.parent.model;},get stableId(){return this.parent.stableId+'.'+this.tid;},compareTo:function(that){return Thread.compare(this,that);},iterateAllChildEventContainers:function(callback,opt_this){if(this.sliceGroup.length)
-callback.call(opt_this,this.sliceGroup);if(this.kernelSliceGroup.length)
-callback.call(opt_this,this.kernelSliceGroup);if(this.asyncSliceGroup.length)
-callback.call(opt_this,this.asyncSliceGroup);},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(this.timeSlices&&this.timeSlices.length){if(eventTypePredicate.call(opt_this,ThreadTimeSlice))
-this.timeSlices.forEach(callback,opt_this);}},iterateAllPersistableObjects:function(cb){cb(this);if(this.sliceGroup.length)
-cb(this.sliceGroup);this.asyncSliceGroup.viewSubGroups.forEach(cb);},shiftTimestampsForward:function(amount){this.sliceGroup.shiftTimestampsForward(amount);if(this.timeSlices){for(var i=0;i<this.timeSlices.length;i++){var slice=this.timeSlices[i];slice.start+=amount;}}
-this.kernelSliceGroup.shiftTimestampsForward(amount);this.asyncSliceGroup.shiftTimestampsForward(amount);},get isEmpty(){if(this.sliceGroup.length)
-return false;if(this.sliceGroup.openSliceCount)
-return false;if(this.timeSlices&&this.timeSlices.length)
-return false;if(this.kernelSliceGroup.length)
-return false;if(this.asyncSliceGroup.length)
-return false;if(this.samples_.length)
-return false;return true;},updateBounds:function(){this.bounds.reset();this.sliceGroup.updateBounds();this.bounds.addRange(this.sliceGroup.bounds);this.kernelSliceGroup.updateBounds();this.bounds.addRange(this.kernelSliceGroup.bounds);this.asyncSliceGroup.updateBounds();this.bounds.addRange(this.asyncSliceGroup.bounds);if(this.timeSlices&&this.timeSlices.length){this.bounds.addValue(this.timeSlices[0].start);this.bounds.addValue(this.timeSlices[this.timeSlices.length-1].end);}
-if(this.samples_&&this.samples_.length){this.bounds.addValue(this.samples_[0].start);this.bounds.addValue(this.samples_[this.samples_.length-1].end);}},addCategoriesToDict:function(categoriesDict){for(var i=0;i<this.sliceGroup.length;i++)
-categoriesDict[this.sliceGroup.slices[i].category]=true;for(var i=0;i<this.kernelSliceGroup.length;i++)
-categoriesDict[this.kernelSliceGroup.slices[i].category]=true;for(var i=0;i<this.asyncSliceGroup.length;i++)
-categoriesDict[this.asyncSliceGroup.slices[i].category]=true;if(this.samples_){for(var i=0;i<this.samples_.length;i++)
-categoriesDict[this.samples_[i].category]=true;}},autoCloseOpenSlices:function(){this.sliceGroup.autoCloseOpenSlices();this.kernelSliceGroup.autoCloseOpenSlices();},mergeKernelWithUserland:function(){if(this.kernelSliceGroup.length>0){var newSlices=SliceGroup.merge(this.sliceGroup,this.kernelSliceGroup);this.sliceGroup.slices=newSlices.slices;this.kernelSliceGroup=new SliceGroup(this);this.updateBounds();}},createSubSlices:function(){this.sliceGroup.createSubSlices();this.samples_=this.parent.model.samples.filter(function(sample){return sample.thread==this;},this);},get userFriendlyName(){return this.name||this.tid;},get userFriendlyDetails(){return'tid: '+this.tid+
-(this.name?', name: '+this.name:'');},getSettingsKey:function(){if(!this.name)
-return undefined;var parentKey=this.parent.getSettingsKey();if(!parentKey)
-return undefined;return parentKey+'.'+this.name;},getProcess:function(){return this.parent;},indexOfTimeSlice:function(timeSlice){var i=tr.b.findLowIndexInSortedArray(this.timeSlices,function(slice){return slice.start;},timeSlice.start);if(this.timeSlices[i]!==timeSlice)
-return undefined;return i;},getCpuStatsForRange:function(range){var stats={};stats.total=0;if(!this.timeSlices)
-return stats;function addStatsForSlice(threadTimeSlice){var freqRange=tr.b.Range.fromExplicitRange(threadTimeSlice.start,threadTimeSlice.end);var intersection=freqRange.findIntersection(range);if(threadTimeSlice.schedulingState==tr.model.SCHEDULING_STATE.RUNNING){var cpu=threadTimeSlice.cpuOnWhichThreadWasRunning;if(!(cpu.cpuNumber in stats))
-stats[cpu.cpuNumber]=0;stats[cpu.cpuNumber]+=intersection.duration;stats.total+=intersection.duration;}}
-tr.b.iterateOverIntersectingIntervals(this.timeSlices,function(x){return x.start;},function(x){return x.end;},range.min,range.max,addStatsForSlice);return stats;},getSchedulingStatsForRange:function(start,end){var stats={};if(!this.timeSlices)return stats;function addStatsForSlice(threadTimeSlice){var overlapStart=Math.max(threadTimeSlice.start,start);var overlapEnd=Math.min(threadTimeSlice.end,end);var schedulingState=threadTimeSlice.schedulingState;if(!(schedulingState in stats))
-stats[schedulingState]=0;stats[schedulingState]+=overlapEnd-overlapStart;}
-tr.b.iterateOverIntersectingIntervals(this.timeSlices,function(x){return x.start;},function(x){return x.end;},start,end,addStatsForSlice);return stats;},get samples(){return this.samples_;}};Thread.compare=function(x,y){var tmp=x.parent.compareTo(y.parent);if(tmp)
-return tmp;tmp=x.sortIndex-y.sortIndex;if(tmp)
-return tmp;tmp=tr.b.comparePossiblyUndefinedValues(x.name,y.name,function(x,y){return x.localeCompare(y);});if(tmp)
-return tmp;return x.tid-y.tid;};return{Thread:Thread};});'use strict';tr.exportTo('tr.model',function(){var Thread=tr.model.Thread;var Counter=tr.model.Counter;function ProcessBase(model){if(!model)
-throw new Error('Must provide a model');tr.model.EventContainer.call(this);this.model=model;this.threads={};this.counters={};this.objects=new tr.model.ObjectCollection(this);this.sortIndex=0;};ProcessBase.compare=function(x,y){return x.sortIndex-y.sortIndex;};ProcessBase.prototype={__proto__:tr.model.EventContainer.prototype,get stableId(){throw new Error('Not implemented');},iterateAllChildEventContainers:function(callback,opt_this){for(var tid in this.threads)
-callback.call(opt_this,this.threads[tid]);for(var id in this.counters)
-callback.call(opt_this,this.counters[id]);callback.call(opt_this,this.objects);},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){},iterateAllPersistableObjects:function(cb){cb(this);for(var tid in this.threads)
-this.threads[tid].iterateAllPersistableObjects(cb);},get numThreads(){var n=0;for(var p in this.threads){n++;}
-return n;},shiftTimestampsForward:function(amount){this.iterateAllChildEventContainers(function(child){child.shiftTimestampsForward(amount);});},autoCloseOpenSlices:function(){for(var tid in this.threads){var thread=this.threads[tid];thread.autoCloseOpenSlices();}},autoDeleteObjects:function(maxTimestamp){this.objects.autoDeleteObjects(maxTimestamp);},preInitializeObjects:function(){this.objects.preInitializeAllObjects();},initializeObjects:function(){this.objects.initializeAllObjects();},mergeKernelWithUserland:function(){for(var tid in this.threads){var thread=this.threads[tid];thread.mergeKernelWithUserland();}},updateBounds:function(){this.bounds.reset();for(var tid in this.threads){this.threads[tid].updateBounds();this.bounds.addRange(this.threads[tid].bounds);}
-for(var id in this.counters){this.counters[id].updateBounds();this.bounds.addRange(this.counters[id].bounds);}
-this.objects.updateBounds();this.bounds.addRange(this.objects.bounds);},addCategoriesToDict:function(categoriesDict){for(var tid in this.threads)
-this.threads[tid].addCategoriesToDict(categoriesDict);for(var id in this.counters)
-categoriesDict[this.counters[id].category]=true;this.objects.addCategoriesToDict(categoriesDict);},findAllThreadsMatching:function(predicate,opt_this){var threads=[];for(var tid in this.threads){var thread=this.threads[tid];if(predicate.call(opt_this,thread))
-threads.push(thread);}
-return threads;},findAllThreadsNamed:function(name){var threads=this.findAllThreadsMatching(function(thread){if(!thread.name)
-return false;return thread.name===name;});return threads;},findAtMostOneThreadNamed:function(name){var threads=this.findAllThreadsNamed(name);if(threads.length===0)
-return undefined;if(threads.length>1)
-throw new Error('Expected no more than one '+name);return threads[0];},pruneEmptyContainers:function(){var threadsToKeep={};for(var tid in this.threads){var thread=this.threads[tid];if(!thread.isEmpty)
-threadsToKeep[tid]=thread;}
-this.threads=threadsToKeep;},getThread:function(tid){return this.threads[tid];},getOrCreateThread:function(tid){if(!this.threads[tid])
-this.threads[tid]=new Thread(this,tid);return this.threads[tid];},getOrCreateCounter:function(cat,name){var id=cat+'.'+name;if(!this.counters[id])
-this.counters[id]=new Counter(this,id,cat,name);return this.counters[id];},getSettingsKey:function(){throw new Error('Not implemented');},createSubSlices:function(){for(var tid in this.threads)
-this.threads[tid].createSubSlices();}};return{ProcessBase:ProcessBase};});'use strict';tr.exportTo('tr.model',function(){var Cpu=tr.model.Cpu;var ProcessBase=tr.model.ProcessBase;function Kernel(model){ProcessBase.call(this,model);this.cpus={};this.softwareMeasuredCpuCount_=undefined;};Kernel.compare=function(x,y){return 0;};Kernel.prototype={__proto__:ProcessBase.prototype,compareTo:function(that){return Kernel.compare(this,that);},get userFriendlyName(){return'Kernel';},get userFriendlyDetails(){return'Kernel';},get stableId(){return'Kernel';},getOrCreateCpu:function(cpuNumber){if(!this.cpus[cpuNumber])
-this.cpus[cpuNumber]=new Cpu(this,cpuNumber);return this.cpus[cpuNumber];},get softwareMeasuredCpuCount(){return this.softwareMeasuredCpuCount_;},set softwareMeasuredCpuCount(softwareMeasuredCpuCount){if(this.softwareMeasuredCpuCount_!==undefined&&this.softwareMeasuredCpuCount_!==softwareMeasuredCpuCount){throw new Error('Cannot change the softwareMeasuredCpuCount once it is set');}
-this.softwareMeasuredCpuCount_=softwareMeasuredCpuCount;},get bestGuessAtCpuCount(){var realCpuCount=tr.b.dictionaryLength(this.cpus);if(realCpuCount!==0)
-return realCpuCount;return this.softwareMeasuredCpuCount;},updateBounds:function(){ProcessBase.prototype.updateBounds.call(this);for(var cpuNumber in this.cpus){var cpu=this.cpus[cpuNumber];cpu.updateBounds();this.bounds.addRange(cpu.bounds);}},createSubSlices:function(){ProcessBase.prototype.createSubSlices.call(this);for(var cpuNumber in this.cpus){var cpu=this.cpus[cpuNumber];cpu.createSubSlices();}},addCategoriesToDict:function(categoriesDict){ProcessBase.prototype.addCategoriesToDict.call(this,categoriesDict);for(var cpuNumber in this.cpus)
-this.cpus[cpuNumber].addCategoriesToDict(categoriesDict);},getSettingsKey:function(){return'kernel';},iterateAllChildEventContainers:function(callback,opt_this){ProcessBase.prototype.iterateAllChildEventContainers.call(this,callback,opt_this);for(var cpuId in this.cpus)
-callback.call(opt_this,this.cpus[cpuId]);},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){ProcessBase.prototype.iterateAllEventsInThisContainer.call(this,eventTypePredicate,callback,opt_this);}};return{Kernel:Kernel};});'use strict';tr.exportTo('tr.model',function(){function ModelIndices(model){this.flowEventsById_={};model.flowEvents.forEach(function(fe){if(fe.id!==undefined){if(!this.flowEventsById_.hasOwnProperty(fe.id)){this.flowEventsById_[fe.id]=new Array();}
+const notOwnedSubSize=optional(dump.notOwnedSubSize_,0);const remainderSubSize=notOwnedSubSize-alreadyAttributedSubSize;let ownedCoefficient=0;if(notOwnedSubSize!==0){ownedCoefficient=remainderSubSize/notOwnedSubSize;}
+dump.ownedCoefficient_=ownedCoefficient;},calculateDumpCumulativeOwnershipCoefficient_(dump){if(!hasSize(dump))return;let cumulativeOwnedCoefficient=optional(dump.ownedCoefficient_,1);const parent=dump.parent;if(dump.parent!==undefined){cumulativeOwnedCoefficient*=dump.parent.cumulativeOwnedCoefficient_;}
+dump.cumulativeOwnedCoefficient_=cumulativeOwnedCoefficient;let cumulativeOwningCoefficient;if(dump.owns!==undefined){cumulativeOwningCoefficient=dump.owningCoefficient_*dump.owns.target.cumulativeOwningCoefficient_;}else if(dump.parent!==undefined){cumulativeOwningCoefficient=dump.parent.cumulativeOwningCoefficient_;}else{cumulativeOwningCoefficient=1;}
+dump.cumulativeOwningCoefficient_=cumulativeOwningCoefficient;},calculateDumpEffectiveSize_(dump){if(!hasSize(dump)){delete dump.numerics[EFFECTIVE_SIZE_NUMERIC_NAME];return;}
+let effectiveSize;if(dump.children===undefined||dump.children.length===0){effectiveSize=getSize(dump)*dump.cumulativeOwningCoefficient_*dump.cumulativeOwnedCoefficient_;}else{effectiveSize=0;dump.children.forEach(function(childDump){if(!hasSize(childDump))return;effectiveSize+=childDump.numerics[EFFECTIVE_SIZE_NUMERIC_NAME].value;});}
+dump.numerics[EFFECTIVE_SIZE_NUMERIC_NAME]=new tr.b.Scalar(tr.b.Unit.byName.sizeInBytes_smallerIsBetter,effectiveSize);},aggregateNumerics(){this.iterateRootAllocatorDumps(function(dump){dump.aggregateNumericsRecursively(this.model);});this.iterateRootAllocatorDumps(this.propagateNumericsAndDiagnosticsRecursively);for(const processMemoryDump of Object.values(this.processMemoryDumps)){processMemoryDump.iterateRootAllocatorDumps(function(dump){dump.aggregateNumericsRecursively(this.model);},this);}},propagateNumericsAndDiagnosticsRecursively(globalAllocatorDump){['numerics','diagnostics'].forEach(function(field){for(const[name,value]of
+Object.entries(globalAllocatorDump[field])){globalAllocatorDump.ownedBy.forEach(function(ownershipLink){const processAllocatorDump=ownershipLink.source;if(processAllocatorDump[field][name]!==undefined){return;}
+processAllocatorDump[field][name]=value;});}});globalAllocatorDump.children.forEach(this.propagateNumericsAndDiagnosticsRecursively,this);},setUpTracingOverheadOwnership(){for(const dump of Object.values(this.processMemoryDumps)){dump.setUpTracingOverheadOwnership(this.model);}},discountTracingOverheadFromVmRegions(){for(const dump of Object.values(this.processMemoryDumps)){dump.discountTracingOverheadFromVmRegions(this.model);}},forceRebuildingMemoryAllocatorDumpByFullNameIndices(){this.iterateContainerDumps(function(containerDump){containerDump.forceRebuildingMemoryAllocatorDumpByFullNameIndex();});},iterateContainerDumps(fn){fn.call(this,this);for(const processDump of Object.values(this.processMemoryDumps)){fn.call(this,processDump);}},iterateAllRootAllocatorDumps(fn){this.iterateContainerDumps(function(containerDump){containerDump.iterateRootAllocatorDumps(fn,this);});},traverseAllocatorDumpsInDepthFirstPostOrder(fn){const visitedDumps=new WeakSet();const openDumps=new WeakSet();function visit(dump){if(visitedDumps.has(dump))return;if(openDumps.has(dump)){throw new Error(dump.userFriendlyName+' contains a cycle');}
+openDumps.add(dump);dump.ownedBy.forEach(function(ownershipLink){visit.call(this,ownershipLink.source);},this);dump.children.forEach(visit,this);fn.call(this,dump);visitedDumps.add(dump);openDumps.delete(dump);}
+this.iterateAllRootAllocatorDumps(visit);},traverseAllocatorDumpsInDepthFirstPreOrder(fn){const visitedDumps=new WeakSet();function visit(dump){if(visitedDumps.has(dump))return;if(dump.owns!==undefined&&!visitedDumps.has(dump.owns.target)){return;}
+if(dump.parent!==undefined&&!visitedDumps.has(dump.parent)){return;}
+fn.call(this,dump);visitedDumps.add(dump);dump.ownedBy.forEach(function(ownershipLink){visit.call(this,ownershipLink.source);},this);dump.children.forEach(visit,this);}
+this.iterateAllRootAllocatorDumps(visit);}};tr.model.EventRegistry.register(GlobalMemoryDump,{name:'globalMemoryDump',pluralName:'globalMemoryDumps'});return{GlobalMemoryDump,};});'use strict';tr.exportTo('tr.model',function(){const InstantEventType={GLOBAL:1,PROCESS:2};function InstantEvent(category,title,colorId,start,args,parent){tr.model.TimedEvent.call(this,start);this.category=category||'';this.title=title;this.colorId=colorId;this.args=args;this.parent_=parent;this.type=undefined;}
+InstantEvent.prototype={__proto__:tr.model.TimedEvent.prototype,};function GlobalInstantEvent(category,title,colorId,start,args,parent){InstantEvent.apply(this,arguments);this.type=InstantEventType.GLOBAL;}
+GlobalInstantEvent.prototype={__proto__:InstantEvent.prototype,get userFriendlyName(){return'Global instant event '+this.title+' @ '+
+tr.b.Unit.byName.timeStampInMs.format(start);},get stableId(){return'instant.'+this.parent_.instantEvents.indexOf(this);},};function ProcessInstantEvent(category,title,colorId,start,args,parent){InstantEvent.apply(this,arguments);this.type=InstantEventType.PROCESS;}
+ProcessInstantEvent.prototype={__proto__:InstantEvent.prototype,get userFriendlyName(){return'Process-level instant event '+this.title+' @ '+
+tr.b.Unit.byName.timeStampInMs.format(start);},get stableId(){return this.parent_.stableId+'.instant.'+
+this.parent_.instantEvents.indexOf(this);},};tr.model.EventRegistry.register(InstantEvent,{name:'instantEvent',pluralName:'instantEvents'});return{GlobalInstantEvent,ProcessInstantEvent,InstantEventType,InstantEvent,};});'use strict';tr.exportTo('tr.model',function(){const Cpu=tr.model.Cpu;const ProcessBase=tr.model.ProcessBase;function Kernel(model){ProcessBase.call(this,model);this.cpus={};this.softwareMeasuredCpuCount_=undefined;}
+Kernel.compare=function(x,y){return 0;};Kernel.prototype={__proto__:ProcessBase.prototype,compareTo(that){return Kernel.compare(this,that);},get userFriendlyName(){return'Kernel';},get userFriendlyDetails(){return'Kernel';},get stableId(){return'Kernel';},getOrCreateCpu(cpuNumber){if(!this.cpus[cpuNumber]){this.cpus[cpuNumber]=new Cpu(this,cpuNumber);}
+return this.cpus[cpuNumber];},get softwareMeasuredCpuCount(){return this.softwareMeasuredCpuCount_;},set softwareMeasuredCpuCount(softwareMeasuredCpuCount){if(this.softwareMeasuredCpuCount_!==undefined&&this.softwareMeasuredCpuCount_!==softwareMeasuredCpuCount){throw new Error('Cannot change the softwareMeasuredCpuCount once it is set');}
+this.softwareMeasuredCpuCount_=softwareMeasuredCpuCount;},get bestGuessAtCpuCount(){const realCpuCount=Object.keys(this.cpus).length;if(realCpuCount!==0){return realCpuCount;}
+return this.softwareMeasuredCpuCount;},updateBounds(){ProcessBase.prototype.updateBounds.call(this);for(const cpuNumber in this.cpus){const cpu=this.cpus[cpuNumber];cpu.updateBounds();this.bounds.addRange(cpu.bounds);}},createSubSlices(){ProcessBase.prototype.createSubSlices.call(this);for(const cpuNumber in this.cpus){const cpu=this.cpus[cpuNumber];cpu.createSubSlices();}},addCategoriesToDict(categoriesDict){ProcessBase.prototype.addCategoriesToDict.call(this,categoriesDict);for(const cpuNumber in this.cpus){this.cpus[cpuNumber].addCategoriesToDict(categoriesDict);}},getSettingsKey(){return'kernel';},*childEventContainers(){yield*ProcessBase.prototype.childEventContainers.call(this);yield*Object.values(this.cpus);},};return{Kernel,};});'use strict';tr.exportTo('tr.model',function(){function ModelIndices(model){this.flowEventsById_={};model.flowEvents.forEach(function(fe){if(fe.id!==undefined){if(!this.flowEventsById_.hasOwnProperty(fe.id)){this.flowEventsById_[fe.id]=[];}
 this.flowEventsById_[fe.id].push(fe);}},this);}
-ModelIndices.prototype={addEventWithId:function(id,event){if(!this.flowEventsById_.hasOwnProperty(id)){this.flowEventsById_[id]=new Array();}
-this.flowEventsById_[id].push(event);},getFlowEventsWithId:function(id){if(!this.flowEventsById_.hasOwnProperty(id))
-return[];return this.flowEventsById_[id];}};return{ModelIndices:ModelIndices};});'use strict';tr.exportTo('tr.model',function(){function ModelStats(){this.traceEventCountsByKey_=new Map();this.allTraceEventStats_=[];this.traceEventStatsInTimeIntervals_=new Map();this.allTraceEventStatsInTimeIntervals_=[];this.hasEventSizesinBytes_=false;}
-ModelStats.prototype={TIME_INTERVAL_SIZE_IN_MS:100,willProcessBasicTraceEvent:function(phase,category,title,ts,opt_eventSizeinBytes){var key=phase+'/'+category+'/'+title;var eventStats=this.traceEventCountsByKey_.get(key);if(eventStats===undefined){eventStats={phase:phase,category:category,title:title,numEvents:0,totalEventSizeinBytes:0};this.traceEventCountsByKey_.set(key,eventStats);this.allTraceEventStats_.push(eventStats);}
-eventStats.numEvents++;var timeIntervalKey=Math.floor(tr.v.Unit.timestampFromUs(ts)/this.TIME_INTERVAL_SIZE_IN_MS);var eventStatsByTimeInverval=this.traceEventStatsInTimeIntervals_.get(timeIntervalKey);if(eventStatsByTimeInverval===undefined){eventStatsByTimeInverval={timeInterval:timeIntervalKey,numEvents:0,totalEventSizeinBytes:0};this.traceEventStatsInTimeIntervals_.set(timeIntervalKey,eventStatsByTimeInverval);this.allTraceEventStatsInTimeIntervals_.push(eventStatsByTimeInverval);}
-eventStatsByTimeInverval.numEvents++;if(opt_eventSizeinBytes!==undefined){this.hasEventSizesinBytes_=true;eventStats.totalEventSizeinBytes+=opt_eventSizeinBytes;eventStatsByTimeInverval.totalEventSizeinBytes+=opt_eventSizeinBytes;}},get allTraceEventStats(){return this.allTraceEventStats_;},get allTraceEventStatsInTimeIntervals(){return this.allTraceEventStatsInTimeIntervals_;},get hasEventSizesinBytes(){return this.hasEventSizesinBytes_;}};return{ModelStats:ModelStats};});'use strict';tr.exportTo('tr.model',function(){function VMRegion(startAddress,sizeInBytes,protectionFlags,mappedFile,byteStats){this.startAddress=startAddress;this.sizeInBytes=sizeInBytes;this.protectionFlags=protectionFlags;this.mappedFile=mappedFile||'';this.byteStats=byteStats||{};};VMRegion.PROTECTION_FLAG_READ=4;VMRegion.PROTECTION_FLAG_WRITE=2;VMRegion.PROTECTION_FLAG_EXECUTE=1;VMRegion.PROTECTION_FLAG_MAYSHARE=128;VMRegion.prototype={get uniqueIdWithinProcess(){return this.mappedFile+'#'+this.startAddress;},get protectionFlagsToString(){if(this.protectionFlags===undefined)
-return undefined;return((this.protectionFlags&VMRegion.PROTECTION_FLAG_READ?'r':'-')+
+ModelIndices.prototype={addEventWithId(id,event){if(!this.flowEventsById_.hasOwnProperty(id)){this.flowEventsById_[id]=[];}
+this.flowEventsById_[id].push(event);},getFlowEventsWithId(id){if(!this.flowEventsById_.hasOwnProperty(id)){return[];}
+return this.flowEventsById_[id];}};return{ModelIndices,};});'use strict';tr.exportTo('tr.model',function(){function ModelStats(){this.traceEventCountsByKey_=new Map();this.allTraceEventStats_=[];this.traceEventStatsInTimeIntervals_=new Map();this.allTraceEventStatsInTimeIntervals_=[];this.hasEventSizesinBytes_=false;this.traceImportDurationMs_=undefined;}
+ModelStats.prototype={TIME_INTERVAL_SIZE_IN_MS:100,willProcessBasicTraceEvent(phase,category,title,ts,opt_eventSizeinBytes){const key=phase+'/'+category+'/'+title;let eventStats=this.traceEventCountsByKey_.get(key);if(eventStats===undefined){eventStats={phase,category,title,numEvents:0,totalEventSizeinBytes:0};this.traceEventCountsByKey_.set(key,eventStats);this.allTraceEventStats_.push(eventStats);}
+eventStats.numEvents++;const timeIntervalKey=Math.floor(tr.b.Unit.timestampFromUs(ts)/this.TIME_INTERVAL_SIZE_IN_MS);let eventStatsByTimeInverval=this.traceEventStatsInTimeIntervals_.get(timeIntervalKey);if(eventStatsByTimeInverval===undefined){eventStatsByTimeInverval={timeInterval:timeIntervalKey,numEvents:0,totalEventSizeinBytes:0};this.traceEventStatsInTimeIntervals_.set(timeIntervalKey,eventStatsByTimeInverval);this.allTraceEventStatsInTimeIntervals_.push(eventStatsByTimeInverval);}
+eventStatsByTimeInverval.numEvents++;if(opt_eventSizeinBytes!==undefined){this.hasEventSizesinBytes_=true;eventStats.totalEventSizeinBytes+=opt_eventSizeinBytes;eventStatsByTimeInverval.totalEventSizeinBytes+=opt_eventSizeinBytes;}},get allTraceEventStats(){return this.allTraceEventStats_;},get allTraceEventStatsInTimeIntervals(){return this.allTraceEventStatsInTimeIntervals_;},get hasEventSizesinBytes(){return this.hasEventSizesinBytes_;},get traceImportDurationMs(){return this.traceImportDurationMs_;},set traceImportDurationMs(traceImportDurationMs){this.traceImportDurationMs_=traceImportDurationMs;}};return{ModelStats,};});'use strict';tr.exportTo('tr.model',function(){function VMRegion(startAddress,sizeInBytes,protectionFlags,mappedFile,byteStats){this.startAddress=startAddress;this.sizeInBytes=sizeInBytes;this.protectionFlags=protectionFlags;this.mappedFile=mappedFile||'';this.byteStats=byteStats||{};}
+VMRegion.PROTECTION_FLAG_READ=4;VMRegion.PROTECTION_FLAG_WRITE=2;VMRegion.PROTECTION_FLAG_EXECUTE=1;VMRegion.PROTECTION_FLAG_MAYSHARE=128;VMRegion.prototype={get uniqueIdWithinProcess(){return this.mappedFile+'#'+this.startAddress;},get protectionFlagsToString(){if(this.protectionFlags===undefined)return undefined;return((this.protectionFlags&VMRegion.PROTECTION_FLAG_READ?'r':'-')+
 (this.protectionFlags&VMRegion.PROTECTION_FLAG_WRITE?'w':'-')+
 (this.protectionFlags&VMRegion.PROTECTION_FLAG_EXECUTE?'x':'-')+
 (this.protectionFlags&VMRegion.PROTECTION_FLAG_MAYSHARE?'s':'p'));}};VMRegion.fromDict=function(dict){return new VMRegion(dict.startAddress,dict.sizeInBytes,dict.protectionFlags,dict.mappedFile,dict.byteStats);};function VMRegionClassificationNode(opt_rule){this.rule_=opt_rule||VMRegionClassificationNode.CLASSIFICATION_RULES;this.hasRegions=false;this.sizeInBytes=undefined;this.byteStats={};this.children_=undefined;this.regions_=[];}
-VMRegionClassificationNode.CLASSIFICATION_RULES={name:'Total',children:[{name:'Android',file:/^\/dev\/ashmem(?!\/libc malloc)/,children:[{name:'Java runtime',file:/^\/dev\/ashmem\/dalvik-/,children:[{name:'Spaces',file:/\/dalvik-(alloc|main|large object|non moving|zygote) space/,children:[{name:'Normal',file:/\/dalvik-(alloc|main)/},{name:'Large',file:/\/dalvik-large object/},{name:'Zygote',file:/\/dalvik-zygote/},{name:'Non-moving',file:/\/dalvik-non moving/}]},{name:'Linear Alloc',file:/\/dalvik-LinearAlloc/},{name:'Indirect Reference Table',file:/\/dalvik-indirect.ref/},{name:'Cache',file:/\/dalvik-jit-code-cache/},{name:'Accounting'}]},{name:'Cursor',file:/\/CursorWindow/},{name:'Ashmem'}]},{name:'Native heap',file:/^((\[heap\])|(\[anon:)|(\/dev\/ashmem\/libc malloc)|(\[discounted tracing overhead\])|$)/},{name:'Stack',file:/^\[stack/},{name:'Files',file:/\.((((jar)|(apk)|(ttf)|(odex)|(oat)|(art))$)|(dex)|(so))/,children:[{name:'so',file:/\.so/},{name:'jar',file:/\.jar$/},{name:'apk',file:/\.apk$/},{name:'ttf',file:/\.ttf$/},{name:'dex',file:/\.((dex)|(odex$))/},{name:'oat',file:/\.oat$/},{name:'art',file:/\.art$/}]},{name:'Devices',file:/(^\/dev\/)|(anon_inode:dmabuf)/,children:[{name:'GPU',file:/\/((nv)|(mali)|(kgsl))/},{name:'DMA',file:/anon_inode:dmabuf/}]}]};VMRegionClassificationNode.OTHER_RULE={name:'Other'};VMRegionClassificationNode.fromRegions=function(regions,opt_rules){var tree=new VMRegionClassificationNode(opt_rules);tree.regions_=regions;for(var i=0;i<regions.length;i++)
-tree.addStatsFromRegion_(regions[i]);return tree;};VMRegionClassificationNode.prototype={get title(){return this.rule_.name;},get children(){if(this.isLeafNode)
-return undefined;if(this.children_===undefined)
-this.buildTree_();return this.children_;},get regions(){if(!this.isLeafNode){return undefined;}
+VMRegionClassificationNode.CLASSIFICATION_RULES={name:'Total',children:[{name:'Android',file:/^\/dev\/ashmem(?!\/libc malloc)/,children:[{name:'Java runtime',file:/^\/dev\/ashmem\/dalvik-/,children:[{name:'Spaces',file:/\/dalvik-(alloc|main|large object|non moving|zygote) space/,children:[{name:'Normal',file:/\/dalvik-(alloc|main)/},{name:'Large',file:/\/dalvik-large object/},{name:'Zygote',file:/\/dalvik-zygote/},{name:'Non-moving',file:/\/dalvik-non moving/}]},{name:'Linear Alloc',file:/\/dalvik-LinearAlloc/},{name:'Indirect Reference Table',file:/\/dalvik-indirect.ref/},{name:'Cache',file:/\/dalvik-jit-code-cache/},{name:'Accounting'}]},{name:'Cursor',file:/\/CursorWindow/},{name:'Ashmem'}]},{name:'Native heap',file:/^((\[heap\])|(\[anon:)|(\/dev\/ashmem\/libc malloc)|(\[discounted tracing overhead\])|$)/},{name:'Stack',file:/^\[stack/},{name:'Files',file:/\.((((jar)|(apk)|(ttf)|(odex)|(oat)|(art))$)|(dex)|(so))/,children:[{name:'so',file:/\.so/},{name:'jar',file:/\.jar$/},{name:'apk',file:/\.apk$/},{name:'ttf',file:/\.ttf$/},{name:'dex',file:/\.((dex)|(odex$))/},{name:'oat',file:/\.oat$/},{name:'art',file:/\.art$/}]},{name:'Devices',file:/(^\/dev\/)|(anon_inode:dmabuf)/,children:[{name:'GPU',file:/\/((nv)|(mali)|(kgsl))/},{name:'DMA',file:/anon_inode:dmabuf/}]}]};VMRegionClassificationNode.OTHER_RULE={name:'Other'};VMRegionClassificationNode.fromRegions=function(regions,opt_rules){const tree=new VMRegionClassificationNode(opt_rules);tree.regions_=regions;for(let i=0;i<regions.length;i++){tree.addStatsFromRegion_(regions[i]);}
+return tree;};VMRegionClassificationNode.prototype={get title(){return this.rule_.name;},get children(){if(this.isLeafNode){return undefined;}
+if(this.children_===undefined){this.buildTree_();}
+return this.children_;},get regions(){if(!this.isLeafNode){return undefined;}
 return this.regions_;},get allRegionsForTesting(){if(this.regions_!==undefined){if(this.children_!==undefined){throw new Error('Internal error: a VM region classification node '+'cannot have both regions and children');}
 return this.regions_;}
-var regions=[];this.children_.forEach(function(childNode){regions=regions.concat(childNode.allRegionsForTesting);});return regions;},get isLeafNode(){var children=this.rule_.children;return children===undefined||children.length===0;},addRegion:function(region){this.addRegionRecursively_(region,true);},someRegion:function(fn,opt_this){if(this.regions_!==undefined){return this.regions_.some(fn,opt_this);}
-return this.children_.some(function(childNode){return childNode.someRegion(fn,opt_this);});},addRegionRecursively_:function(region,addStatsToThisNode){if(addStatsToThisNode)
-this.addStatsFromRegion_(region);if(this.regions_!==undefined){if(this.children_!==undefined){throw new Error('Internal error: a VM region classification node '+'cannot have both regions and children');}
+let regions=[];this.children_.forEach(function(childNode){regions=regions.concat(childNode.allRegionsForTesting);});return regions;},get isLeafNode(){const children=this.rule_.children;return children===undefined||children.length===0;},addRegion(region){this.addRegionRecursively_(region,true);},someRegion(fn,opt_this){if(this.regions_!==undefined){return this.regions_.some(fn,opt_this);}
+return this.children_.some(function(childNode){return childNode.someRegion(fn,opt_this);});},addRegionRecursively_(region,addStatsToThisNode){if(addStatsToThisNode){this.addStatsFromRegion_(region);}
+if(this.regions_!==undefined){if(this.children_!==undefined){throw new Error('Internal error: a VM region classification node '+'cannot have both regions and children');}
 this.regions_.push(region);return;}
-function regionRowMatchesChildNide(child){var fileRegExp=child.rule_.file;if(fileRegExp===undefined)
-return true;return fileRegExp.test(region.mappedFile);}
-var matchedChild=tr.b.findFirstInArray(this.children_,regionRowMatchesChildNide);if(matchedChild===undefined){if(this.children_.length!==this.rule_.children.length)
-throw new Error('Internal error');matchedChild=new VMRegionClassificationNode(VMRegionClassificationNode.OTHER_RULE);this.children_.push(matchedChild);}
-matchedChild.addRegionRecursively_(region,true);},buildTree_:function(){var cachedRegions=this.regions_;this.regions_=undefined;this.buildChildNodesRecursively_();for(var i=0;i<cachedRegions.length;i++){this.addRegionRecursively_(cachedRegions[i],false);}},buildChildNodesRecursively_:function(){if(this.children_!==undefined){throw new Error('Internal error: Classification node already has children');}
+function regionRowMatchesChildNide(child){const fileRegExp=child.rule_.file;if(fileRegExp===undefined)return true;return fileRegExp.test(region.mappedFile);}
+let matchedChild=this.children_.find(regionRowMatchesChildNide);if(matchedChild===undefined){if(this.children_.length!==this.rule_.children.length){throw new Error('Internal error');}
+matchedChild=new VMRegionClassificationNode(VMRegionClassificationNode.OTHER_RULE);this.children_.push(matchedChild);}
+matchedChild.addRegionRecursively_(region,true);},buildTree_(){const cachedRegions=this.regions_;this.regions_=undefined;this.buildChildNodesRecursively_();for(let i=0;i<cachedRegions.length;i++){this.addRegionRecursively_(cachedRegions[i],false);}},buildChildNodesRecursively_(){if(this.children_!==undefined){throw new Error('Internal error: Classification node already has children');}
 if(this.regions_!==undefined&&this.regions_.length!==0){throw new Error('Internal error: Classification node should have no regions');}
-if(this.isLeafNode)
-return;this.regions_=undefined;this.children_=this.rule_.children.map(function(childRule){var child=new VMRegionClassificationNode(childRule);child.buildChildNodesRecursively_();return child;});},addStatsFromRegion_:function(region){this.hasRegions=true;var regionSizeInBytes=region.sizeInBytes;if(regionSizeInBytes!==undefined)
-this.sizeInBytes=(this.sizeInBytes||0)+regionSizeInBytes;var thisByteStats=this.byteStats;var regionByteStats=region.byteStats;for(var byteStatName in regionByteStats){var regionByteStatValue=regionByteStats[byteStatName];if(regionByteStatValue===undefined)
-continue;thisByteStats[byteStatName]=(thisByteStats[byteStatName]||0)+regionByteStatValue;}}};return{VMRegion:VMRegion,VMRegionClassificationNode:VMRegionClassificationNode};});'use strict';tr.exportTo('tr.model',function(){var DISCOUNTED_ALLOCATOR_NAMES=['winheap','malloc'];var TRACING_OVERHEAD_PATH=['allocated_objects','tracing_overhead'];var SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.SIZE_NUMERIC_NAME;var RESIDENT_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.RESIDENT_SIZE_NUMERIC_NAME;function getSizeNumericValue(dump,sizeNumericName){var sizeNumeric=dump.numerics[sizeNumericName];if(sizeNumeric===undefined)
-return 0;return sizeNumeric.value;}
-function ProcessMemoryDump(globalMemoryDump,process,start){tr.model.ContainerMemoryDump.call(this,start);this.process=process;this.globalMemoryDump=globalMemoryDump;this.totals=undefined;this.vmRegions=undefined;this.heapDumps=undefined;this.tracingOverheadOwnershipSetUp_=false;this.tracingOverheadDiscountedFromVmRegions_=false;};ProcessMemoryDump.prototype={__proto__:tr.model.ContainerMemoryDump.prototype,get userFriendlyName(){return'Process memory dump at '+
-tr.v.Unit.byName.timeStampInMs.format(this.start);},get containerName(){return this.process.userFriendlyName;},get processMemoryDumps(){var dumps={};dumps[this.process.pid]=this;return dumps;},get hasOwnVmRegions(){return this.vmRegions!==undefined;},setUpTracingOverheadOwnership:function(opt_model){if(this.tracingOverheadOwnershipSetUp_)
-return;this.tracingOverheadOwnershipSetUp_=true;var tracingDump=this.getMemoryAllocatorDumpByFullName('tracing');if(tracingDump===undefined||tracingDump.owns!==undefined){return;}
-if(tracingDump.owns!==undefined)
-return;var hasDiscountedFromAllocatorDumps=DISCOUNTED_ALLOCATOR_NAMES.some(function(allocatorName){var allocatorDump=this.getMemoryAllocatorDumpByFullName(allocatorName);if(allocatorDump===undefined)
-return false;var nextPathIndex=0;var currentDump=allocatorDump;var currentFullName=allocatorName;for(;nextPathIndex<TRACING_OVERHEAD_PATH.length;nextPathIndex++){var childFullName=currentFullName+'/'+
-TRACING_OVERHEAD_PATH[nextPathIndex];var childDump=this.getMemoryAllocatorDumpByFullName(childFullName);if(childDump===undefined)
-break;currentDump=childDump;currentFullName=childFullName;}
-for(;nextPathIndex<TRACING_OVERHEAD_PATH.length;nextPathIndex++){var childFullName=currentFullName+'/'+
-TRACING_OVERHEAD_PATH[nextPathIndex];var childDump=new tr.model.MemoryAllocatorDump(currentDump.containerMemoryDump,childFullName);childDump.parent=currentDump;currentDump.children.push(childDump);currentFullName=childFullName;currentDump=childDump;}
-var ownershipLink=new tr.model.MemoryAllocatorDumpLink(tracingDump,currentDump);tracingDump.owns=ownershipLink;currentDump.ownedBy.push(ownershipLink);return true;},this);if(hasDiscountedFromAllocatorDumps)
-this.forceRebuildingMemoryAllocatorDumpByFullNameIndex();},discountTracingOverheadFromVmRegions:function(opt_model){if(this.tracingOverheadDiscountedFromVmRegions_)
-return;this.tracingOverheadDiscountedFromVmRegions_=true;var tracingDump=this.getMemoryAllocatorDumpByFullName('tracing');if(tracingDump===undefined)
-return;var discountedSize=getSizeNumericValue(tracingDump,SIZE_NUMERIC_NAME);var discountedResidentSize=getSizeNumericValue(tracingDump,RESIDENT_SIZE_NUMERIC_NAME);if(discountedSize<=0&&discountedResidentSize<=0)
-return;if(this.totals!==undefined){if(this.totals.residentBytes!==undefined)
-this.totals.residentBytes-=discountedResidentSize;if(this.totals.peakResidentBytes!==undefined)
-this.totals.peakResidentBytes-=discountedResidentSize;}
-if(this.vmRegions!==undefined){var hasSizeInBytes=this.vmRegions.sizeInBytes!==undefined;var hasPrivateDirtyResident=this.vmRegions.byteStats.privateDirtyResident!==undefined;var hasProportionalResident=this.vmRegions.byteStats.proportionalResident!==undefined;if((hasSizeInBytes&&discountedSize>0)||((hasPrivateDirtyResident||hasProportionalResident)&&discountedResidentSize>0)){var byteStats={};if(hasPrivateDirtyResident)
-byteStats.privateDirtyResident=-discountedResidentSize;if(hasProportionalResident)
-byteStats.proportionalResident=-discountedResidentSize;this.vmRegions.addRegion(tr.model.VMRegion.fromDict({mappedFile:'[discounted tracing overhead]',sizeInBytes:hasSizeInBytes?-discountedSize:undefined,byteStats:byteStats}));}}}};ProcessMemoryDump.hookUpMostRecentVmRegionsLinks=function(processDumps){var mostRecentVmRegions=undefined;processDumps.forEach(function(processDump){if(processDump.vmRegions!==undefined)
-mostRecentVmRegions=processDump.vmRegions;processDump.mostRecentVmRegions=mostRecentVmRegions;});};tr.model.EventRegistry.register(ProcessMemoryDump,{name:'processMemoryDump',pluralName:'processMemoryDumps',singleViewElementName:'tr-ui-a-container-memory-dump-sub-view',multiViewElementName:'tr-ui-a-container-memory-dump-sub-view'});return{ProcessMemoryDump:ProcessMemoryDump};});'use strict';tr.exportTo('tr.model',function(){var ProcessBase=tr.model.ProcessBase;var ProcessInstantEvent=tr.model.ProcessInstantEvent;var Frame=tr.model.Frame;var ProcessMemoryDump=tr.model.ProcessMemoryDump;function Process(model,pid){if(model===undefined)
-throw new Error('model must be provided');if(pid===undefined)
-throw new Error('pid must be provided');tr.model.ProcessBase.call(this,model);this.pid=pid;this.name=undefined;this.labels=[];this.instantEvents=[];this.memoryDumps=[];this.frames=[];this.activities=[];};Process.compare=function(x,y){var tmp=tr.model.ProcessBase.compare(x,y);if(tmp)
-return tmp;tmp=tr.b.comparePossiblyUndefinedValues(x.name,y.name,function(x,y){return x.localeCompare(y);});if(tmp)
-return tmp;tmp=tr.b.compareArrays(x.labels,y.labels,function(x,y){return x.localeCompare(y);});if(tmp)
-return tmp;return x.pid-y.pid;};Process.prototype={__proto__:tr.model.ProcessBase.prototype,get stableId(){return this.pid;},compareTo:function(that){return Process.compare(this,that);},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){ProcessBase.prototype.iterateAllEventsInThisContainer.call(this,eventTypePredicate,callback,opt_this);if(eventTypePredicate.call(opt_this,ProcessInstantEvent))
-this.instantEvents.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,Frame))
-this.frames.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,ProcessMemoryDump))
-this.memoryDumps.forEach(callback,opt_this);},addLabelIfNeeded:function(labelName){for(var i=0;i<this.labels.length;i++){if(this.labels[i]===labelName)
+if(this.isLeafNode){return;}
+this.regions_=undefined;this.children_=this.rule_.children.map(function(childRule){const child=new VMRegionClassificationNode(childRule);child.buildChildNodesRecursively_();return child;});},addStatsFromRegion_(region){this.hasRegions=true;const regionSizeInBytes=region.sizeInBytes;if(regionSizeInBytes!==undefined){this.sizeInBytes=(this.sizeInBytes||0)+regionSizeInBytes;}
+const thisByteStats=this.byteStats;const regionByteStats=region.byteStats;for(const byteStatName in regionByteStats){const regionByteStatValue=regionByteStats[byteStatName];if(regionByteStatValue===undefined)continue;thisByteStats[byteStatName]=(thisByteStats[byteStatName]||0)+regionByteStatValue;}
+if(region.mappedFile.includes('/base.odex')||region.mappedFile.includes('/base.vdex')){if(region.byteStats.proportionalResident!==undefined){thisByteStats.javaBasePss=(thisByteStats.javaBasePss||0)+
+region.byteStats.proportionalResident;}
+if(region.byteStats.privateCleanResident!==undefined){thisByteStats.javaBaseCleanResident=(thisByteStats.javaBaseCleanResident||0)+
+region.byteStats.privateCleanResident;}
+if(region.byteStats.sharedCleanResident!==undefined){thisByteStats.javaBaseCleanResident=(thisByteStats.javaBaseCleanResident||0)+
+region.byteStats.sharedCleanResident;}}
+const textProtectionFlags=(VMRegion.PROTECTION_FLAG_READ|VMRegion.PROTECTION_FLAG_EXECUTE);if((region.protectionFlags===textProtectionFlags)&&(region.mappedFile.includes('/base.apk')||region.mappedFile.includes('/libchrome.so'))){if(regionSizeInBytes!==undefined){this.nativeLibrarySizeInBytes=(this.nativeLibrarySizeInBytes||0)+regionSizeInBytes;}
+if(region.byteStats.privateCleanResident!==undefined){thisByteStats.nativeLibraryPrivateCleanResident=(thisByteStats.nativeLibraryPrivateCleanResident||0)+
+region.byteStats.privateCleanResident;}
+if(region.byteStats.sharedCleanResident!==undefined){thisByteStats.nativeLibrarySharedCleanResident=(thisByteStats.nativeLibrarySharedCleanResident||0)+
+region.byteStats.sharedCleanResident;}
+if(region.byteStats.proportionalResident!==undefined){thisByteStats.nativeLibraryProportionalResident=(thisByteStats.nativeLibraryProportionalResident||0)+
+region.byteStats.proportionalResident;}}}};return{VMRegion,VMRegionClassificationNode,};});'use strict';tr.exportTo('tr.model',function(){const DISCOUNTED_ALLOCATOR_NAMES=['winheap','malloc'];const TRACING_OVERHEAD_PATH=['allocated_objects','tracing_overhead'];const SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.SIZE_NUMERIC_NAME;const RESIDENT_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.RESIDENT_SIZE_NUMERIC_NAME;function getSizeNumericValue(dump,sizeNumericName){const sizeNumeric=dump.numerics[sizeNumericName];if(sizeNumeric===undefined)return 0;return sizeNumeric.value;}
+function ProcessMemoryDump(globalMemoryDump,process,start){tr.model.ContainerMemoryDump.call(this,start);this.process=process;this.globalMemoryDump=globalMemoryDump;this.totals=undefined;this.vmRegions=undefined;this.heapDumps=undefined;this.tracingOverheadOwnershipSetUp_=false;this.tracingOverheadDiscountedFromVmRegions_=false;}
+ProcessMemoryDump.prototype={__proto__:tr.model.ContainerMemoryDump.prototype,get stableId(){return this.process.stableId+'.memory.'+
+this.process.memoryDumps.indexOf(this);},get userFriendlyName(){return'Process memory dump at '+
+tr.b.Unit.byName.timeStampInMs.format(this.start);},get containerName(){return this.process.userFriendlyName;},get processMemoryDumps(){const dumps={};dumps[this.process.pid]=this;return dumps;},get hasOwnVmRegions(){return this.vmRegions!==undefined;},setUpTracingOverheadOwnership(opt_model){if(this.tracingOverheadOwnershipSetUp_)return;this.tracingOverheadOwnershipSetUp_=true;const tracingDump=this.getMemoryAllocatorDumpByFullName('tracing');if(tracingDump===undefined||tracingDump.owns!==undefined){return;}
+if(tracingDump.owns!==undefined)return;const hasDiscountedFromAllocatorDumps=DISCOUNTED_ALLOCATOR_NAMES.some(function(allocatorName){const allocatorDump=this.getMemoryAllocatorDumpByFullName(allocatorName);if(allocatorDump===undefined){return false;}
+let nextPathIndex=0;let currentDump=allocatorDump;let currentFullName=allocatorName;for(;nextPathIndex<TRACING_OVERHEAD_PATH.length;nextPathIndex++){const childFullName=currentFullName+'/'+
+TRACING_OVERHEAD_PATH[nextPathIndex];const childDump=this.getMemoryAllocatorDumpByFullName(childFullName);if(childDump===undefined)break;currentDump=childDump;currentFullName=childFullName;}
+for(;nextPathIndex<TRACING_OVERHEAD_PATH.length;nextPathIndex++){const childFullName=currentFullName+'/'+
+TRACING_OVERHEAD_PATH[nextPathIndex];const childDump=new tr.model.MemoryAllocatorDump(currentDump.containerMemoryDump,childFullName);childDump.parent=currentDump;currentDump.children.push(childDump);currentFullName=childFullName;currentDump=childDump;}
+const ownershipLink=new tr.model.MemoryAllocatorDumpLink(tracingDump,currentDump);tracingDump.owns=ownershipLink;currentDump.ownedBy.push(ownershipLink);return true;},this);if(hasDiscountedFromAllocatorDumps){this.forceRebuildingMemoryAllocatorDumpByFullNameIndex();}},discountTracingOverheadFromVmRegions(opt_model){if(this.tracingOverheadDiscountedFromVmRegions_)return;this.tracingOverheadDiscountedFromVmRegions_=true;const tracingDump=this.getMemoryAllocatorDumpByFullName('tracing');if(tracingDump===undefined)return;const discountedSize=getSizeNumericValue(tracingDump,SIZE_NUMERIC_NAME);const discountedResidentSize=getSizeNumericValue(tracingDump,RESIDENT_SIZE_NUMERIC_NAME);if(discountedSize<=0&&discountedResidentSize<=0)return;if(this.totals!==undefined){if(this.totals.residentBytes!==undefined){this.totals.residentBytes-=discountedResidentSize;}
+if(this.totals.peakResidentBytes!==undefined){this.totals.peakResidentBytes-=discountedResidentSize;}}
+if(this.vmRegions!==undefined){const hasSizeInBytes=this.vmRegions.sizeInBytes!==undefined;const hasPrivateDirtyResident=this.vmRegions.byteStats.privateDirtyResident!==undefined;const hasProportionalResident=this.vmRegions.byteStats.proportionalResident!==undefined;if((hasSizeInBytes&&discountedSize>0)||((hasPrivateDirtyResident||hasProportionalResident)&&discountedResidentSize>0)){const byteStats={};if(hasPrivateDirtyResident){byteStats.privateDirtyResident=-discountedResidentSize;}
+if(hasProportionalResident){byteStats.proportionalResident=-discountedResidentSize;}
+this.vmRegions.addRegion(tr.model.VMRegion.fromDict({mappedFile:'[discounted tracing overhead]',sizeInBytes:hasSizeInBytes?-discountedSize:undefined,byteStats}));}}}};ProcessMemoryDump.hookUpMostRecentVmRegionsLinks=function(processDumps){let mostRecentVmRegions=undefined;processDumps.forEach(function(processDump){if(processDump.vmRegions!==undefined){mostRecentVmRegions=processDump.vmRegions;}
+processDump.mostRecentVmRegions=mostRecentVmRegions;});};tr.model.EventRegistry.register(ProcessMemoryDump,{name:'processMemoryDump',pluralName:'processMemoryDumps'});return{ProcessMemoryDump,};});'use strict';tr.exportTo('tr.model',function(){const ProcessBase=tr.model.ProcessBase;const ProcessInstantEvent=tr.model.ProcessInstantEvent;const Frame=tr.model.Frame;const ProcessMemoryDump=tr.model.ProcessMemoryDump;function Process(model,pid){if(model===undefined){throw new Error('model must be provided');}
+if(pid===undefined){throw new Error('pid must be provided');}
+tr.model.ProcessBase.call(this,model);this.pid=pid;this.name=undefined;this.labels=[];this.uptime_seconds=0;this.instantEvents=[];this.memoryDumps=[];this.frames=[];this.activities=[];}
+Process.compare=function(x,y){let tmp=tr.model.ProcessBase.compare(x,y);if(tmp)return tmp;if(x.name!==undefined){if(y.name!==undefined){tmp=x.name.localeCompare(y.name);}else{tmp=-1;}}else if(y.name!==undefined){tmp=1;}
+if(tmp)return tmp;tmp=tr.b.compareArrays(x.labels,y.labels,function(x,y){return x.localeCompare(y);});if(tmp)return tmp;return x.pid-y.pid;};Process.prototype={__proto__:tr.model.ProcessBase.prototype,get stableId(){return this.pid;},compareTo(that){return Process.compare(this,that);},*childEvents(){yield*ProcessBase.prototype.childEvents.call(this);yield*this.instantEvents;yield*this.frames;yield*this.memoryDumps;},addLabelIfNeeded(labelName){for(let i=0;i<this.labels.length;i++){if(this.labels[i]===labelName)return;}
+this.labels.push(labelName);},get userFriendlyName(){let res;if(this.name){res=this.name+' (pid '+this.pid+')';}else{res='Process '+this.pid;}
+if(this.labels.length){res+=': '+this.labels.join(', ');}
+if(this.uptime_seconds){res+=', uptime:'+this.uptime_seconds+'s';}
+return res;},get userFriendlyDetails(){if(this.name){return this.name+' (pid '+this.pid+')';}
+return'pid: '+this.pid;},getSettingsKey(){if(!this.name)return undefined;if(!this.labels.length)return'processes.'+this.name;return'processes.'+this.name+'.'+this.labels.join('.');},shiftTimestampsForward(amount){for(let i=0;i<this.instantEvents.length;i++){this.instantEvents[i].start+=amount;}
+for(let i=0;i<this.frames.length;i++){this.frames[i].shiftTimestampsForward(amount);}
+for(let i=0;i<this.memoryDumps.length;i++){this.memoryDumps[i].shiftTimestampsForward(amount);}
+for(let i=0;i<this.activities.length;i++){this.activities[i].shiftTimestampsForward(amount);}
+tr.model.ProcessBase.prototype.shiftTimestampsForward.apply(this,arguments);},updateBounds(){tr.model.ProcessBase.prototype.updateBounds.apply(this);for(let i=0;i<this.frames.length;i++){this.frames[i].addBoundsToRange(this.bounds);}
+for(let i=0;i<this.memoryDumps.length;i++){this.memoryDumps[i].addBoundsToRange(this.bounds);}
+for(let i=0;i<this.activities.length;i++){this.activities[i].addBoundsToRange(this.bounds);}},sortMemoryDumps(){this.memoryDumps.sort(function(x,y){return x.start-y.start;});tr.model.ProcessMemoryDump.hookUpMostRecentVmRegionsLinks(this.memoryDumps);}};return{Process,};});'use strict';tr.exportTo('tr.model',function(){function Sample(start,title,leafNode,thread,opt_cpu,opt_weight,opt_args){tr.model.TimedEvent.call(this,start);this.start_=start;this.title_=title;this.leafNode_=leafNode;this.thread_=thread;this.colorId_=leafNode.colorId;this.cpu_=opt_cpu;this.weight_=opt_weight;this.args=opt_args||{};}
+Sample.prototype={__proto__:tr.model.TimedEvent.prototype,get title(){return this.title_;},get colorId(){return this.colorId_;},get thread(){return this.thread_;},get leafNode(){return this.leafNode_;},get userFriendlyName(){return'Sample at '+
+tr.b.Unit.byName.timeStampInMs.format(this.start);},get userFriendlyStack(){return this.leafNode_.userFriendlyStack;},getNodesAsArray(){const nodes=[];let node=this.leafNode_;while(node!==undefined){nodes.push(node);node=node.parentNode;}
+return nodes;},get cpu(){return this.cpu_;},get weight(){return this.weight_;},};tr.model.EventRegistry.register(Sample,{name:'Sample',pluralName:'Samples'});return{Sample,};});'use strict';tr.exportTo('tr.model',function(){function StackFrame(parentFrame,id,title,colorId,opt_sourceInfo){if(id===undefined){throw new Error('id must be given');}
+this.parentFrame_=parentFrame;this.id=id;this.title_=title;this.colorId=colorId;this.children=[];this.sourceInfo_=opt_sourceInfo;if(this.parentFrame_){this.parentFrame_.addChild(this);}}
+StackFrame.prototype={get parentFrame(){return this.parentFrame_;},get title(){if(this.sourceInfo_){const src=this.sourceInfo_.toString();return this.title_+(src===''?'':' '+src);}
+return this.title_;},get domain(){let result='unknown';if(this.sourceInfo_&&this.sourceInfo_.domain){result=this.sourceInfo_.domain;}
+if(result==='unknown'&&this.parentFrame){result=this.parentFrame.domain;}
+return result;},get sourceInfo(){return this.sourceInfo_;},set parentFrame(parentFrame){if(this.parentFrame_){Polymer.dom(this.parentFrame_).removeChild(this);}
+this.parentFrame_=parentFrame;if(this.parentFrame_){this.parentFrame_.addChild(this);}},addChild(child){this.children.push(child);},removeChild(child){const i=this.children.indexOf(child.id);if(i===-1){throw new Error('omg');}
+this.children.splice(i,1);},removeAllChildren(){for(let i=0;i<this.children.length;i++){this.children[i].parentFrame_=undefined;}
+this.children.splice(0,this.children.length);},get stackTrace(){const stack=[this];let cur=this.parentFrame;while(cur){stack.push(cur);cur=cur.parentFrame;}
+return stack;},getUserFriendlyStackTrace(){return this.stackTrace.map(function(x){return x.title;});}};return{StackFrame,};});'use strict';tr.exportTo('tr.model.um',function(){class UserModel extends tr.model.EventContainer{constructor(parentModel){super();this.parentModel_=parentModel;this.expectations_=new tr.model.EventSet();this.segments_=[];}
+get stableId(){return'UserModel';}
+get parentModel(){return this.parentModel_;}
+sortExpectations(){this.expectations_.sortEvents((x,y)=>(x.start-y.start));}
+get expectations(){return this.expectations_;}
+shiftTimestampsForward(amount){}
+addCategoriesToDict(categoriesDict){}
+get segments(){return this.segments_;}*childEvents(){yield*this.expectations;}*childEventContainers(){}
+updateBounds(){this.bounds.reset();for(const expectation of this.expectations){expectation.addBoundsToRange(this.bounds);}}
+resegment(getKeyForSegment){const newSegments=[];let prevKey=undefined;let prevSegment=undefined;for(let i=0;i<this.segments.length;++i){const segment=this.segments[i];const key=getKeyForSegment(segment,i);if(prevSegment!==undefined&&key===prevKey){prevSegment.addSegment(segment);}else{prevSegment=segment.clone();newSegments.push(prevSegment);}
+prevKey=key;}
+return newSegments;}}
+return{UserModel,};});'use strict';tr.exportTo('tr',function(){const Process=tr.model.Process;const Device=tr.model.Device;const Kernel=tr.model.Kernel;const GlobalMemoryDump=tr.model.GlobalMemoryDump;const GlobalInstantEvent=tr.model.GlobalInstantEvent;const FlowEvent=tr.model.FlowEvent;const Alert=tr.model.Alert;const Sample=tr.model.Sample;function Model(){tr.model.EventContainer.call(this);tr.b.EventTarget.decorate(this);this.timestampShiftToZeroAmount_=0;this.faviconHue='blue';this.device=new Device(this);this.kernel=new Kernel(this);this.processes={};this.metadata=[];this.categories=[];this.instantEvents=[];this.flowEvents=[];this.clockSyncManager=new tr.model.ClockSyncManager();this.intrinsicTimeUnit_=undefined;this.stackFrames={};this.samples=[];this.alerts=[];this.userModel=new tr.model.um.UserModel(this);this.flowIntervalTree=new tr.b.IntervalTree((f)=>f.start,(f)=>f.end);this.globalMemoryDumps=[];this.userFriendlyCategoryDrivers_=[];this.annotationsByGuid_={};this.modelIndices=undefined;this.stats=new tr.model.ModelStats();this.importWarnings_=[];this.reportedImportWarnings_={};this.isTimeHighResolution_=true;this.patchupsToApply_=[];this.doesHelperGUIDSupportThisModel_={};this.helpersByConstructorGUID_={};this.eventsByStableId_=undefined;}
+Model.prototype={__proto__:tr.model.EventContainer.prototype,getEventByStableId(stableId){if(this.eventsByStableId_===undefined){this.eventsByStableId_={};for(const event of this.getDescendantEvents()){this.eventsByStableId_[event.stableId]=event;}}
+return this.eventsByStableId_[stableId];},getOrCreateHelper(constructor){if(!constructor.guid){throw new Error('Helper constructors must have GUIDs');}
+if(this.helpersByConstructorGUID_[constructor.guid]===undefined){if(this.doesHelperGUIDSupportThisModel_[constructor.guid]===undefined){this.doesHelperGUIDSupportThisModel_[constructor.guid]=constructor.supportsModel(this);}
+if(!this.doesHelperGUIDSupportThisModel_[constructor.guid]){return undefined;}
+this.helpersByConstructorGUID_[constructor.guid]=new constructor(this);}
+return this.helpersByConstructorGUID_[constructor.guid];},*childEvents(){yield*this.globalMemoryDumps;yield*this.instantEvents;yield*this.flowEvents;yield*this.alerts;yield*this.samples;},*childEventContainers(){yield this.userModel;yield this.device;yield this.kernel;yield*Object.values(this.processes);},iterateAllPersistableObjects(callback){this.kernel.iterateAllPersistableObjects(callback);for(const pid in this.processes){this.processes[pid].iterateAllPersistableObjects(callback);}},updateBounds(){this.bounds.reset();const bounds=this.bounds;for(const ec of this.childEventContainers()){ec.updateBounds();bounds.addRange(ec.bounds);}
+for(const event of this.childEvents()){event.addBoundsToRange(bounds);}},shiftWorldToZero(){const shiftAmount=-this.bounds.min;this.timestampShiftToZeroAmount_=shiftAmount;for(const ec of this.childEventContainers()){ec.shiftTimestampsForward(shiftAmount);}
+for(const event of this.childEvents()){event.start+=shiftAmount;}
+this.updateBounds();},convertTimestampToModelTime(sourceClockDomainName,ts){if(sourceClockDomainName!=='traceEventClock'){throw new Error('Only traceEventClock is supported.');}
+return tr.b.Unit.timestampFromUs(ts)+
+this.timestampShiftToZeroAmount_;},get numProcesses(){let n=0;for(const p in this.processes){n++;}
+return n;},getProcess(pid){return this.processes[pid];},getOrCreateProcess(pid){if(!this.processes[pid]){this.processes[pid]=new Process(this,pid);}
+return this.processes[pid];},addStackFrame(stackFrame){if(this.stackFrames[stackFrame.id]){throw new Error('Stack frame already exists');}
+this.stackFrames[stackFrame.id]=stackFrame;return stackFrame;},updateCategories_(){const categoriesDict={};this.userModel.addCategoriesToDict(categoriesDict);this.device.addCategoriesToDict(categoriesDict);this.kernel.addCategoriesToDict(categoriesDict);for(const pid in this.processes){this.processes[pid].addCategoriesToDict(categoriesDict);}
+this.categories=[];for(const category in categoriesDict){if(category!==''){this.categories.push(category);}}},getAllThreads(){const threads=[];for(const tid in this.kernel.threads){threads.push(process.threads[tid]);}
+for(const pid in this.processes){const process=this.processes[pid];for(const tid in process.threads){threads.push(process.threads[tid]);}}
+return threads;},getAllProcesses(opt_predicate){const processes=[];for(const pid in this.processes){const process=this.processes[pid];if(opt_predicate===undefined||opt_predicate(process)){processes.push(process);}}
+return processes;},getAllCounters(){const counters=[];counters.push.apply(counters,Object.values(this.device.counters||{}));counters.push.apply(counters,Object.values(this.kernel.counters||{}));for(const pid in this.processes){const process=this.processes[pid];for(const tid in process.counters){counters.push(process.counters[tid]);}}
+return counters;},getAnnotationByGUID(guid){return this.annotationsByGuid_[guid];},addAnnotation(annotation){if(!annotation.guid){throw new Error('Annotation with undefined guid given');}
+this.annotationsByGuid_[annotation.guid]=annotation;tr.b.dispatchSimpleEvent(this,'annotationChange');},removeAnnotation(annotation){this.annotationsByGuid_[annotation.guid].onRemove();delete this.annotationsByGuid_[annotation.guid];tr.b.dispatchSimpleEvent(this,'annotationChange');},getAllAnnotations(){return Object.values(this.annotationsByGuid_);},addUserFriendlyCategoryDriver(ufcd){this.userFriendlyCategoryDrivers_.push(ufcd);},getUserFriendlyCategoryFromEvent(event){for(let i=0;i<this.userFriendlyCategoryDrivers_.length;i++){const ufc=this.userFriendlyCategoryDrivers_[i].fromEvent(event);if(ufc!==undefined)return ufc;}
+return undefined;},findAllThreadsNamed(name){const namedThreads=[];namedThreads.push.apply(namedThreads,this.kernel.findAllThreadsNamed(name));for(const pid in this.processes){namedThreads.push.apply(namedThreads,this.processes[pid].findAllThreadsNamed(name));}
+return namedThreads;},get importOptions(){return this.importOptions_;},set importOptions(options){this.importOptions_=options;},get intrinsicTimeUnit(){if(this.intrinsicTimeUnit_===undefined){return tr.b.TimeDisplayModes.ms;}
+return this.intrinsicTimeUnit_;},set intrinsicTimeUnit(value){if(this.intrinsicTimeUnit_===value)return;if(this.intrinsicTimeUnit_!==undefined){throw new Error('Intrinsic time unit already set');}
+this.intrinsicTimeUnit_=value;},get isTimeHighResolution(){return this.isTimeHighResolution_;},set isTimeHighResolution(value){this.isTimeHighResolution_=value;},get canonicalUrl(){return this.canonicalUrl_;},set canonicalUrl(value){if(this.canonicalUrl_===value)return;if(this.canonicalUrl_!==undefined){throw new Error('canonicalUrl already set');}
+this.canonicalUrl_=value;},importWarning(data){data.showToUser=!!data.showToUser;this.importWarnings_.push(data);if(this.reportedImportWarnings_[data.type]===true)return;this.reportedImportWarnings_[data.type]=true;},get hasImportWarnings(){return(this.importWarnings_.length>0);},get importWarnings(){return this.importWarnings_;},get importWarningsThatShouldBeShownToUser(){return this.importWarnings_.filter(function(warning){return warning.showToUser;});},autoCloseOpenSlices(){this.samples.sort(function(x,y){return x.start-y.start;});this.updateBounds();this.kernel.autoCloseOpenSlices();for(const pid in this.processes){this.processes[pid].autoCloseOpenSlices();}},createSubSlices(){this.kernel.createSubSlices();for(const pid in this.processes){this.processes[pid].createSubSlices();}},preInitializeObjects(){for(const pid in this.processes){this.processes[pid].preInitializeObjects();}},initializeObjects(){for(const pid in this.processes){this.processes[pid].initializeObjects();}},pruneEmptyContainers(){this.kernel.pruneEmptyContainers();for(const pid in this.processes){this.processes[pid].pruneEmptyContainers();}},mergeKernelWithUserland(){for(const pid in this.processes){this.processes[pid].mergeKernelWithUserland();}},computeWorldBounds(shiftWorldToZero){this.updateBounds();this.updateCategories_();if(shiftWorldToZero){this.shiftWorldToZero();}},buildFlowEventIntervalTree(){for(let i=0;i<this.flowEvents.length;++i){const flowEvent=this.flowEvents[i];this.flowIntervalTree.insert(flowEvent);}
+this.flowIntervalTree.updateHighValues();},cleanupUndeletedObjects(){for(const pid in this.processes){this.processes[pid].autoDeleteObjects(this.bounds.max);}},sortMemoryDumps(){this.globalMemoryDumps.sort(function(x,y){return x.start-y.start;});for(const pid in this.processes){this.processes[pid].sortMemoryDumps();}},finalizeMemoryGraphs(){this.globalMemoryDumps.forEach(function(dump){dump.finalizeGraph();});},buildEventIndices(){this.modelIndices=new tr.model.ModelIndices(this);},sortAlerts(){this.alerts.sort(function(x,y){return x.start-y.start;});},applyObjectRefPatchups(){const unresolved=[];this.patchupsToApply_.forEach(function(patchup){if(patchup.pidRef in this.processes){const snapshot=this.processes[patchup.pidRef].objects.getSnapshotAt(patchup.scopedId,patchup.ts);if(snapshot){patchup.object[patchup.field]=snapshot;snapshot.referencedAt(patchup.item,patchup.object,patchup.field);return;}}
+unresolved.push(patchup);},this);this.patchupsToApply_=unresolved;},replacePIDRefsInPatchups(oldPidRef,newPidRef){this.patchupsToApply_.forEach(function(patchup){if(patchup.pidRef===oldPidRef){patchup.pidRef=newPidRef;}});},joinRefs(){this.joinObjectRefs_();this.applyObjectRefPatchups();},joinObjectRefs_(){for(const[pid,process]of Object.entries(this.processes)){this.joinObjectRefsForProcess_(pid,process);}},joinObjectRefsForProcess_(pid,process){for(const thread of Object.values(process.threads)){thread.asyncSliceGroup.slices.forEach(function(item){this.searchItemForIDRefs_(pid,'start',item);},this);thread.sliceGroup.slices.forEach(function(item){this.searchItemForIDRefs_(pid,'start',item);},this);}
+process.objects.iterObjectInstances(function(instance){instance.snapshots.forEach(function(item){this.searchItemForIDRefs_(pid,'ts',item);},this);},this);},searchItemForIDRefs_(pid,itemTimestampField,item){if(!item.args&&!item.contexts)return;const patchupsToApply=this.patchupsToApply_;function handleField(object,fieldName,fieldValue){if(!fieldValue||(!fieldValue.id_ref&&!fieldValue.idRef)){return;}
+const scope=fieldValue.scope||tr.model.OBJECT_DEFAULT_SCOPE;const idRef=fieldValue.id_ref||fieldValue.idRef;const scopedId=new tr.model.ScopedId(scope,idRef);const pidRef=fieldValue.pid_ref||fieldValue.pidRef||pid;const ts=item[itemTimestampField];patchupsToApply.push({item,object,field:fieldName,pidRef,scopedId,ts});}
+function iterObjectFieldsRecursively(object){if(!(object instanceof Object))return;if((object instanceof tr.model.ObjectSnapshot)||(object instanceof Float32Array)||(object instanceof tr.b.math.Quad)){return;}
+if(object instanceof Array){for(let i=0;i<object.length;i++){handleField(object,i,object[i]);iterObjectFieldsRecursively(object[i]);}
 return;}
-this.labels.push(labelName);},get userFriendlyName(){var res;if(this.name)
-res=this.name+' (pid '+this.pid+')';else
-res='Process '+this.pid;if(this.labels.length)
-res+=': '+this.labels.join(', ');return res;},get userFriendlyDetails(){if(this.name)
-return this.name+' (pid '+this.pid+')';return'pid: '+this.pid;},getSettingsKey:function(){if(!this.name)
-return undefined;if(!this.labels.length)
-return'processes.'+this.name;return'processes.'+this.name+'.'+this.labels.join('.');},shiftTimestampsForward:function(amount){for(var i=0;i<this.instantEvents.length;i++)
-this.instantEvents[i].start+=amount;for(var i=0;i<this.frames.length;i++)
-this.frames[i].shiftTimestampsForward(amount);for(var i=0;i<this.memoryDumps.length;i++)
-this.memoryDumps[i].shiftTimestampsForward(amount);for(var i=0;i<this.activities.length;i++)
-this.activities[i].shiftTimestampsForward(amount);tr.model.ProcessBase.prototype.shiftTimestampsForward.apply(this,arguments);},updateBounds:function(){tr.model.ProcessBase.prototype.updateBounds.apply(this);for(var i=0;i<this.frames.length;i++)
-this.frames[i].addBoundsToRange(this.bounds);for(var i=0;i<this.memoryDumps.length;i++)
-this.memoryDumps[i].addBoundsToRange(this.bounds);for(var i=0;i<this.activities.length;i++)
-this.activities[i].addBoundsToRange(this.bounds);},sortMemoryDumps:function(){this.memoryDumps.sort(function(x,y){return x.start-y.start;});tr.model.ProcessMemoryDump.hookUpMostRecentVmRegionsLinks(this.memoryDumps);}};return{Process:Process};});'use strict';tr.exportTo('tr.model',function(){function Sample(cpu,thread,title,start,leafStackFrame,opt_weight,opt_args){tr.model.TimedEvent.call(this,start);this.title=title;this.cpu=cpu;this.thread=thread;this.leafStackFrame=leafStackFrame;this.weight=opt_weight;this.args=opt_args||{};}
-Sample.prototype={__proto__:tr.model.TimedEvent.prototype,get colorId(){return this.leafStackFrame.colorId;},get stackTrace(){return this.leafStackFrame.stackTrace;},getUserFriendlyStackTrace:function(){return this.leafStackFrame.getUserFriendlyStackTrace();},get userFriendlyName(){return'Sample at '+tr.v.Unit.byName.timeStampInMs.format(this.start);}};tr.model.EventRegistry.register(Sample,{name:'sample',pluralName:'samples',singleViewElementName:'tr-ui-a-single-sample-sub-view',multiViewElementName:'tr-ui-a-multi-sample-sub-view'});return{Sample:Sample};});'use strict';tr.exportTo('tr.model',function(){function StackFrame(parentFrame,id,title,colorId,opt_sourceInfo){if(id===undefined)
-throw new Error('id must be given');this.parentFrame_=parentFrame;this.id=id;this.title_=title;this.colorId=colorId;this.children=[];this.sourceInfo_=opt_sourceInfo;if(this.parentFrame_)
-this.parentFrame_.addChild(this);}
-StackFrame.prototype={get parentFrame(){return this.parentFrame_;},get title(){if(this.sourceInfo_){var src=this.sourceInfo_.toString();return this.title_+(src===''?'':' '+src);}
-return this.title_;},get domain(){var result='unknown';if(this.sourceInfo_&&this.sourceInfo_.domain)
-result=this.sourceInfo_.domain;if(result==='unknown'&&this.parentFrame)
-result=this.parentFrame.domain;return result;},get sourceInfo(){return this.sourceInfo_;},set parentFrame(parentFrame){if(this.parentFrame_)
-this.parentFrame_.removeChild(this);this.parentFrame_=parentFrame;if(this.parentFrame_)
-this.parentFrame_.addChild(this);},addChild:function(child){this.children.push(child);},removeChild:function(child){var i=this.children.indexOf(child.id);if(i==-1)
-throw new Error('omg');this.children.splice(i,1);},removeAllChildren:function(){for(var i=0;i<this.children.length;i++)
-this.children[i].parentFrame_=undefined;this.children.splice(0,this.children.length);},get stackTrace(){var stack=[];var cur=this;while(cur){stack.push(cur);cur=cur.parentFrame;}
-return stack;},getUserFriendlyStackTrace:function(){return this.stackTrace.map(function(x){return x.title;});}};return{StackFrame:StackFrame};});'use strict';tr.exportTo('tr.model.um',function(){function UserModel(parentModel){tr.model.EventContainer.call(this);this.parentModel_=parentModel;this.expectations_=new tr.model.EventSet();}
-UserModel.prototype={__proto__:tr.model.EventContainer.prototype,get stableId(){return'UserModel';},get parentModel(){return this.parentModel_;},sortExpectations:function(){Array.prototype.sort.call(this.expectations_,function(x,y){return x.start-y.start;});},get expectations(){return this.expectations_;},shiftTimestampsForward:function(amount){},addCategoriesToDict:function(categoriesDict){},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,tr.model.um.UserExpectation))
-this.expectations.forEach(callback,opt_this);},iterateAllChildEventContainers:function(callback,opt_this){},updateBounds:function(){this.bounds.reset();this.expectations.forEach(function(expectation){expectation.addBoundsToRange(this.bounds);},this);}};return{UserModel:UserModel};});'use strict';tr.exportTo('tr.ui.b',function(){function decorate(source,constr){var elements;if(typeof source=='string')
-elements=tr.doc.querySelectorAll(source);else
-elements=[source];for(var i=0,el;el=elements[i];i++){if(!(el instanceof constr))
-constr.decorate(el);}}
-function define(className,opt_parentConstructor,opt_tagNS){if(typeof className=='function'){throw new Error('Passing functions as className is deprecated. Please '+'use (className, opt_parentConstructor) to subclass');}
-var className=className.toLowerCase();if(opt_parentConstructor&&!opt_parentConstructor.tagName)
-throw new Error('opt_parentConstructor was not '+'created by tr.ui.b.define');var tagName=className;var tagNS=undefined;if(opt_parentConstructor){if(opt_tagNS)
-throw new Error('Must not specify tagNS if parentConstructor is given');var parent=opt_parentConstructor;while(parent&&parent.tagName){tagName=parent.tagName;tagNS=parent.tagNS;parent=parent.parentConstructor;}}else{tagNS=opt_tagNS;}
-function f(){if(opt_parentConstructor&&f.prototype.__proto__!=opt_parentConstructor.prototype){throw new Error(className+' prototye\'s __proto__ field is messed up. '+'It MUST be the prototype of '+opt_parentConstructor.tagName);}
-var el;if(tagNS===undefined)
-el=tr.doc.createElement(tagName);else
-el=tr.doc.createElementNS(tagNS,tagName);f.decorate.call(this,el,arguments);return el;}
-f.decorate=function(el){el.__proto__=f.prototype;el.decorate.apply(el,arguments[1]);el.constructor=f;};f.className=className;f.tagName=tagName;f.tagNS=tagNS;f.parentConstructor=(opt_parentConstructor?opt_parentConstructor:undefined);f.toString=function(){if(!f.parentConstructor)
-return f.tagName;return f.parentConstructor.toString()+'::'+f.className;};return f;}
-function elementIsChildOf(el,potentialParent){if(el==potentialParent)
-return false;var cur=el;while(cur.parentNode){if(cur==potentialParent)
-return true;cur=cur.parentNode;}
-return false;};return{decorate:decorate,define:define,elementIsChildOf:elementIsChildOf};});'use strict';tr.exportTo('tr.b',function(){function Rect(){this.x=0;this.y=0;this.width=0;this.height=0;};Rect.fromXYWH=function(x,y,w,h){var rect=new Rect();rect.x=x;rect.y=y;rect.width=w;rect.height=h;return rect;}
-Rect.fromArray=function(ary){if(ary.length!=4)
-throw new Error('ary.length must be 4');var rect=new Rect();rect.x=ary[0];rect.y=ary[1];rect.width=ary[2];rect.height=ary[3];return rect;}
-Rect.prototype={__proto__:Object.prototype,get left(){return this.x;},get top(){return this.y;},get right(){return this.x+this.width;},get bottom(){return this.y+this.height;},toString:function(){return'Rect('+this.x+', '+this.y+', '+
-this.width+', '+this.height+')';},toArray:function(){return[this.x,this.y,this.width,this.height];},clone:function(){var rect=new Rect();rect.x=this.x;rect.y=this.y;rect.width=this.width;rect.height=this.height;return rect;},enlarge:function(pad){var rect=new Rect();this.enlargeFast(rect,pad);return rect;},enlargeFast:function(out,pad){out.x=this.x-pad;out.y=this.y-pad;out.width=this.width+2*pad;out.height=this.height+2*pad;return out;},size:function(){return{width:this.width,height:this.height};},scale:function(s){var rect=new Rect();this.scaleFast(rect,s);return rect;},scaleSize:function(s){return Rect.fromXYWH(this.x,this.y,this.width*s,this.height*s);},scaleFast:function(out,s){out.x=this.x*s;out.y=this.y*s;out.width=this.width*s;out.height=this.height*s;return out;},translate:function(v){var rect=new Rect();this.translateFast(rect,v);return rect;},translateFast:function(out,v){out.x=this.x+v[0];out.y=this.x+v[1];out.width=this.width;out.height=this.height;return out;},asUVRectInside:function(containingRect){var rect=new Rect();rect.x=(this.x-containingRect.x)/containingRect.width;rect.y=(this.y-containingRect.y)/containingRect.height;rect.width=this.width/containingRect.width;rect.height=this.height/containingRect.height;return rect;},intersects:function(that){var ok=true;ok&=this.x<that.right;ok&=this.right>that.x;ok&=this.y<that.bottom;ok&=this.bottom>that.y;return ok;},equalTo:function(rect){return rect&&(this.x===rect.x)&&(this.y===rect.y)&&(this.width===rect.width)&&(this.height===rect.height);}};return{Rect:Rect};});'use strict';tr.exportTo('tr.ui.b',function(){function instantiateTemplate(selector,doc){doc=doc||document;var el=doc.querySelector(selector);if(!el)
-throw new Error('Element not found');return el.createInstance();}
-function windowRectForElement(element){var position=[element.offsetLeft,element.offsetTop];var size=[element.offsetWidth,element.offsetHeight];var node=element.offsetParent;while(node){position[0]+=node.offsetLeft;position[1]+=node.offsetTop;node=node.offsetParent;}
-return tr.b.Rect.fromXYWH(position[0],position[1],size[0],size[1]);}
-function scrollIntoViewIfNeeded(el){var pr=el.parentElement.getBoundingClientRect();var cr=el.getBoundingClientRect();if(cr.top<pr.top){el.scrollIntoView(true);}else if(cr.bottom>pr.bottom){el.scrollIntoView(false);}}
-function extractUrlString(url){var extracted=url.replace(/url\((.*)\)/,'$1');extracted=extracted.replace(/\"(.*)\"/,'$1');return extracted;}
-function toThreeDigitLocaleString(value){return value.toLocaleString(undefined,{minimumFractionDigits:3,maximumFractionDigits:3});}
-return{toThreeDigitLocaleString:toThreeDigitLocaleString,instantiateTemplate:instantiateTemplate,windowRectForElement:windowRectForElement,scrollIntoViewIfNeeded:scrollIntoViewIfNeeded,extractUrlString:extractUrlString};});'use strict';tr.exportTo('tr.ui.b',function(){if(tr.isHeadless)
-return{};var THIS_DOC=document.currentScript.ownerDocument;var Overlay=tr.ui.b.define('overlay');Overlay.prototype={__proto__:HTMLDivElement.prototype,decorate:function(){this.classList.add('overlay');this.parentEl_=this.ownerDocument.body;this.visible_=false;this.userCanClose_=true;this.onKeyDown_=this.onKeyDown_.bind(this);this.onClick_=this.onClick_.bind(this);this.onFocusIn_=this.onFocusIn_.bind(this);this.onDocumentClick_=this.onDocumentClick_.bind(this);this.onClose_=this.onClose_.bind(this);this.addEventListener('visible-change',tr.ui.b.Overlay.prototype.onVisibleChange_.bind(this),true);var createShadowRoot=this.createShadowRoot||this.webkitCreateShadowRoot;this.shadow_=createShadowRoot.call(this);this.shadow_.appendChild(tr.ui.b.instantiateTemplate('#overlay-template',THIS_DOC));this.closeBtn_=this.shadow_.querySelector('close-button');this.closeBtn_.addEventListener('click',this.onClose_);this.shadow_.querySelector('overlay-frame').addEventListener('click',this.onClick_);this.observer_=new WebKitMutationObserver(this.didButtonBarMutate_.bind(this));this.observer_.observe(this.shadow_.querySelector('button-bar'),{childList:true});Object.defineProperty(this,'title',{get:function(){return this.shadow_.querySelector('title').textContent;},set:function(title){this.shadow_.querySelector('title').textContent=title;}});},set userCanClose(userCanClose){this.userCanClose_=userCanClose;this.closeBtn_.style.display=userCanClose?'block':'none';},get buttons(){return this.shadow_.querySelector('button-bar');},get visible(){return this.visible_;},set visible(newValue){if(this.visible_===newValue)
-return;this.visible_=newValue;var e=new tr.b.Event('visible-change');this.dispatchEvent(e);},onVisibleChange_:function(){this.visible_?this.show_():this.hide_();},show_:function(){this.parentEl_.appendChild(this);if(this.userCanClose_){this.addEventListener('keydown',this.onKeyDown_.bind(this));this.addEventListener('click',this.onDocumentClick_.bind(this));}
-this.parentEl_.addEventListener('focusin',this.onFocusIn_);this.tabIndex=0;var focusEl=undefined;var elList=this.querySelectorAll('button, input, list, select, a');if(elList.length>0){if(elList[0]===this.closeBtn_){if(elList.length>1)
-focusEl=elList[1];}else{focusEl=elList[0];}}
-if(focusEl===undefined)
-focusEl=this;focusEl.focus();},hide_:function(){this.parentEl_.removeChild(this);this.parentEl_.removeEventListener('focusin',this.onFocusIn_);if(this.closeBtn_)
-this.closeBtn_.removeEventListener('click',this.onClose_);document.removeEventListener('keydown',this.onKeyDown_);document.removeEventListener('click',this.onDocumentClick_);},onClose_:function(e){this.visible=false;if((e.type!='keydown')||(e.type==='keydown'&&e.keyCode===27))
-e.stopPropagation();e.preventDefault();tr.b.dispatchSimpleEvent(this,'closeclick');},onFocusIn_:function(e){if(e.target===this)
-return;window.setTimeout(function(){this.focus();},0);e.preventDefault();e.stopPropagation();},didButtonBarMutate_:function(e){var hasButtons=this.buttons.children.length>0;if(hasButtons)
-this.shadow_.querySelector('button-bar').style.display=undefined;else
-this.shadow_.querySelector('button-bar').style.display='none';},onKeyDown_:function(e){if(e.keyCode===9&&e.shiftKey&&e.target===this){e.preventDefault();return;}
-if(e.keyCode!==27)
-return;this.onClose_(e);},onClick_:function(e){e.stopPropagation();},onDocumentClick_:function(e){if(!this.userCanClose_)
-return;this.onClose_(e);}};Overlay.showError=function(msg,opt_err){var o=new Overlay();o.title='Error';o.textContent=msg;if(opt_err){var e=tr.b.normalizeException(opt_err);var stackDiv=document.createElement('pre');stackDiv.textContent=e.stack;stackDiv.style.paddingLeft='8px';stackDiv.style.margin=0;o.appendChild(stackDiv);}
-var b=document.createElement('button');b.textContent='OK';b.addEventListener('click',function(){o.visible=false;});o.buttons.appendChild(b);o.visible=true;return o;}
-return{Overlay:Overlay};});'use strict';tr.exportTo('tr',function(){var Process=tr.model.Process;var Device=tr.model.Device;var Kernel=tr.model.Kernel;var GlobalMemoryDump=tr.model.GlobalMemoryDump;var GlobalInstantEvent=tr.model.GlobalInstantEvent;var FlowEvent=tr.model.FlowEvent;var Alert=tr.model.Alert;var Sample=tr.model.Sample;function Model(){tr.model.EventContainer.call(this);tr.b.EventTarget.decorate(this);this.timestampShiftToZeroAmount_=0;this.faviconHue='blue';this.device=new Device(this);this.kernel=new Kernel(this);this.processes={};this.metadata=[];this.categories=[];this.instantEvents=[];this.flowEvents=[];this.clockSyncManager=new tr.model.ClockSyncManager();this.clockSyncRecords=[];this.intrinsicTimeUnit_=undefined;this.stackFrames={};this.samples=[];this.alerts=[];this.userModel=new tr.model.um.UserModel(this);this.flowIntervalTree=new tr.b.IntervalTree((f)=>f.start,(f)=>f.end);this.globalMemoryDumps=[];this.userFriendlyCategoryDrivers_=[];this.annotationsByGuid_={};this.modelIndices=undefined;this.stats=new tr.model.ModelStats();this.importWarnings_=[];this.reportedImportWarnings_={};this.isTimeHighResolution_=undefined;this.patchupsToApply_=[];this.doesHelperGUIDSupportThisModel_={};this.helpersByConstructorGUID_={};}
-Model.prototype={__proto__:tr.model.EventContainer.prototype,getOrCreateHelper:function(constructor){if(!constructor.guid)
-throw new Error('Helper constructors must have GUIDs');if(this.helpersByConstructorGUID_[constructor.guid]===undefined){if(this.doesHelperGUIDSupportThisModel_[constructor.guid]===undefined){this.doesHelperGUIDSupportThisModel_[constructor.guid]=constructor.supportsModel(this);}
-if(!this.doesHelperGUIDSupportThisModel_[constructor.guid])
-return undefined;this.helpersByConstructorGUID_[constructor.guid]=new constructor(this);}
-return this.helpersByConstructorGUID_[constructor.guid];},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,GlobalMemoryDump))
-this.globalMemoryDumps.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,GlobalInstantEvent))
-this.instantEvents.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,FlowEvent))
-this.flowEvents.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,Alert))
-this.alerts.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,Sample))
-this.samples.forEach(callback,opt_this);},iterateAllChildEventContainers:function(callback,opt_this){callback.call(opt_this,this.userModel);callback.call(opt_this,this.device);callback.call(opt_this,this.kernel);for(var pid in this.processes)
-callback.call(opt_this,this.processes[pid]);},iterateAllPersistableObjects:function(callback){this.kernel.iterateAllPersistableObjects(callback);for(var pid in this.processes)
-this.processes[pid].iterateAllPersistableObjects(callback);},updateBounds:function(){this.bounds.reset();var bounds=this.bounds;this.iterateAllChildEventContainers(function(ec){ec.updateBounds();bounds.addRange(ec.bounds);});this.iterateAllEventsInThisContainer(function(eventConstructor){return true;},function(event){event.addBoundsToRange(bounds);});},shiftWorldToZero:function(){var shiftAmount=-this.bounds.min;this.timestampShiftToZeroAmount_=shiftAmount;this.iterateAllChildEventContainers(function(ec){ec.shiftTimestampsForward(shiftAmount);});this.iterateAllEventsInThisContainer(function(eventConstructor){return true;},function(event){event.start+=shiftAmount;});this.updateBounds();},convertTimestampToModelTime:function(sourceClockDomainName,ts){if(sourceClockDomainName!=='traceEventClock')
-throw new Error('Only traceEventClock is supported.');return tr.v.Unit.timestampFromUs(ts)+
-this.timestampShiftToZeroAmount_;},get numProcesses(){var n=0;for(var p in this.processes)
-n++;return n;},getProcess:function(pid){return this.processes[pid];},getOrCreateProcess:function(pid){if(!this.processes[pid])
-this.processes[pid]=new Process(this,pid);return this.processes[pid];},addStackFrame:function(stackFrame){if(this.stackFrames[stackFrame.id])
-throw new Error('Stack frame already exists');this.stackFrames[stackFrame.id]=stackFrame;return stackFrame;},getClockSyncRecordsWithSyncId:function(syncId){return this.clockSyncRecords.filter(function(x){return x.syncId===syncId;});},updateCategories_:function(){var categoriesDict={};this.userModel.addCategoriesToDict(categoriesDict);this.device.addCategoriesToDict(categoriesDict);this.kernel.addCategoriesToDict(categoriesDict);for(var pid in this.processes)
-this.processes[pid].addCategoriesToDict(categoriesDict);this.categories=[];for(var category in categoriesDict)
-if(category!='')
-this.categories.push(category);},getAllThreads:function(){var threads=[];for(var tid in this.kernel.threads){threads.push(process.threads[tid]);}
-for(var pid in this.processes){var process=this.processes[pid];for(var tid in process.threads){threads.push(process.threads[tid]);}}
-return threads;},getAllProcesses:function(){var processes=[];for(var pid in this.processes)
-processes.push(this.processes[pid]);return processes;},getAllCounters:function(){var counters=[];counters.push.apply(counters,tr.b.dictionaryValues(this.device.counters));counters.push.apply(counters,tr.b.dictionaryValues(this.kernel.counters));for(var pid in this.processes){var process=this.processes[pid];for(var tid in process.counters){counters.push(process.counters[tid]);}}
-return counters;},getAnnotationByGUID:function(guid){return this.annotationsByGuid_[guid];},addAnnotation:function(annotation){if(!annotation.guid)
-throw new Error('Annotation with undefined guid given');this.annotationsByGuid_[annotation.guid]=annotation;tr.b.dispatchSimpleEvent(this,'annotationChange');},removeAnnotation:function(annotation){this.annotationsByGuid_[annotation.guid].onRemove();delete this.annotationsByGuid_[annotation.guid];tr.b.dispatchSimpleEvent(this,'annotationChange');},getAllAnnotations:function(){return tr.b.dictionaryValues(this.annotationsByGuid_);},addUserFriendlyCategoryDriver:function(ufcd){this.userFriendlyCategoryDrivers_.push(ufcd);},getUserFriendlyCategoryFromEvent:function(event){for(var i=0;i<this.userFriendlyCategoryDrivers_.length;i++){var ufc=this.userFriendlyCategoryDrivers_[i].fromEvent(event);if(ufc!==undefined)
-return ufc;}
-return undefined;},findAllThreadsNamed:function(name){var namedThreads=[];namedThreads.push.apply(namedThreads,this.kernel.findAllThreadsNamed(name));for(var pid in this.processes){namedThreads.push.apply(namedThreads,this.processes[pid].findAllThreadsNamed(name));}
-return namedThreads;},get importOptions(){return this.importOptions_;},set importOptions(options){this.importOptions_=options;},get intrinsicTimeUnit(){if(this.intrinsicTimeUnit_===undefined)
-return tr.v.TimeDisplayModes.ms;return this.intrinsicTimeUnit_;},set intrinsicTimeUnit(value){if(this.intrinsicTimeUnit_===value)
-return;if(this.intrinsicTimeUnit_!==undefined)
-throw new Error('Intrinsic time unit already set');this.intrinsicTimeUnit_=value;},get isTimeHighResolution(){if(this.isTimeHighResolution_===undefined)
-this.isTimeHighResolution_=this.isTimeHighResolutionHeuristic_();return this.isTimeHighResolution_;},set isTimeHighResolution(value){if(this.isTimeHighResolution_===value)
-return;if(this.isTimeHighResolution_!==undefined)
-throw new Error('isTimeHighResolution already set');this.isTimeHighResolution_=value;},get canonicalUrl(){return this.canonicalUrl_;},set canonicalUrl(value){if(this.canonicalUrl_===value)
-return;if(this.canonicalUrl_!==undefined)
-throw new Error('canonicalUrl already set');this.canonicalUrl_=value;},importWarning:function(data){data.showToUser=!!data.showToUser;this.importWarnings_.push(data);if(this.reportedImportWarnings_[data.type]===true)
-return;if(this.importOptions_.showImportWarnings)
-console.warn(data.message);this.reportedImportWarnings_[data.type]=true;},get hasImportWarnings(){return(this.importWarnings_.length>0);},get importWarnings(){return this.importWarnings_;},get importWarningsThatShouldBeShownToUser(){return this.importWarnings_.filter(function(warning){return warning.showToUser;});},autoCloseOpenSlices:function(){this.samples.sort(function(x,y){return x.start-y.start;});this.updateBounds();this.kernel.autoCloseOpenSlices();for(var pid in this.processes)
-this.processes[pid].autoCloseOpenSlices();},createSubSlices:function(){this.kernel.createSubSlices();for(var pid in this.processes)
-this.processes[pid].createSubSlices();},preInitializeObjects:function(){for(var pid in this.processes)
-this.processes[pid].preInitializeObjects();},initializeObjects:function(){for(var pid in this.processes)
-this.processes[pid].initializeObjects();},pruneEmptyContainers:function(){this.kernel.pruneEmptyContainers();for(var pid in this.processes)
-this.processes[pid].pruneEmptyContainers();},mergeKernelWithUserland:function(){for(var pid in this.processes)
-this.processes[pid].mergeKernelWithUserland();},computeWorldBounds:function(shiftWorldToZero){this.updateBounds();this.updateCategories_();if(shiftWorldToZero)
-this.shiftWorldToZero();},buildFlowEventIntervalTree:function(){for(var i=0;i<this.flowEvents.length;++i){var flowEvent=this.flowEvents[i];this.flowIntervalTree.insert(flowEvent);}
-this.flowIntervalTree.updateHighValues();},cleanupUndeletedObjects:function(){for(var pid in this.processes)
-this.processes[pid].autoDeleteObjects(this.bounds.max);},sortMemoryDumps:function(){this.globalMemoryDumps.sort(function(x,y){return x.start-y.start;});for(var pid in this.processes)
-this.processes[pid].sortMemoryDumps();},finalizeMemoryGraphs:function(){this.globalMemoryDumps.forEach(function(dump){dump.finalizeGraph();});},buildEventIndices:function(){this.modelIndices=new tr.model.ModelIndices(this);},sortAlerts:function(){this.alerts.sort(function(x,y){return x.start-y.start;});},applyObjectRefPatchups:function(){var unresolved=[];this.patchupsToApply_.forEach(function(patchup){if(patchup.pidRef in this.processes){var snapshot=this.processes[patchup.pidRef].objects.getSnapshotAt(patchup.scopedId,patchup.ts);if(snapshot){patchup.object[patchup.field]=snapshot;return;}}
-unresolved.push(patchup);},this);this.patchupsToApply_=unresolved;},replacePIDRefsInPatchups:function(old_pid_ref,new_pid_ref){this.patchupsToApply_.forEach(function(patchup){if(patchup.pidRef===old_pid_ref)
-patchup.pidRef=new_pid_ref;});},isTimeHighResolutionHeuristic_:function(){if(this.intrinsicTimeUnit!==tr.v.TimeDisplayModes.ms)
-return false;var nbEvents=0;var nbPerBin=[];var maxEvents=0;for(var i=0;i<100;++i)
-nbPerBin.push(0);this.iterateAllEvents(function(event){nbEvents++;if(event.start!==undefined){var remainder=Math.floor((event.start-Math.floor(event.start))*100);nbPerBin[remainder]++;maxEvents=Math.max(maxEvents,nbPerBin[remainder]);}});if(nbEvents<100)
-return true;return(maxEvents/nbEvents)<0.9;},joinRefs:function(){this.joinObjectRefs_();this.applyObjectRefPatchups();},joinObjectRefs_:function(){tr.b.iterItems(this.processes,function(pid,process){this.joinObjectRefsForProcess_(pid,process);},this);},joinObjectRefsForProcess_:function(pid,process){tr.b.iterItems(process.threads,function(tid,thread){thread.asyncSliceGroup.slices.forEach(function(item){this.searchItemForIDRefs_(pid,'start',item);},this);thread.sliceGroup.slices.forEach(function(item){this.searchItemForIDRefs_(pid,'start',item);},this);},this);process.objects.iterObjectInstances(function(instance){instance.snapshots.forEach(function(item){this.searchItemForIDRefs_(pid,'ts',item);},this);},this);},searchItemForIDRefs_:function(pid,itemTimestampField,item){if(!item.args)
-return;var patchupsToApply=this.patchupsToApply_;function handleField(object,fieldName,fieldValue){if(!fieldValue||(!fieldValue.id_ref&&!fieldValue.idRef))
-return;var scope=fieldValue.scope||tr.model.OBJECT_DEFAULT_SCOPE;var idRef=fieldValue.id_ref||fieldValue.idRef;var scopedId=new tr.model.ScopedId(scope,idRef);var pidRef=fieldValue.pid_ref||fieldValue.pidRef||pid;var ts=item[itemTimestampField];patchupsToApply.push({object:object,field:fieldName,pidRef:pidRef,scopedId:scopedId,ts:ts});}
-function iterObjectFieldsRecursively(object){if(!(object instanceof Object))
-return;if((object instanceof tr.model.ObjectSnapshot)||(object instanceof Float32Array)||(object instanceof tr.b.Quad))
-return;if(object instanceof Array){for(var i=0;i<object.length;i++){handleField(object,i,object[i]);iterObjectFieldsRecursively(object[i]);}
-return;}
-for(var key in object){var value=object[key];handleField(object,key,value);iterObjectFieldsRecursively(value);}}
-iterObjectFieldsRecursively(item.args);}};return{Model:Model};});'use strict';tr.exportTo('tr.e.importer.etw',function(){var kThreadGuid='3D6FA8D1-FE05-11D0-9DDA-00C04FD7BA7C';var kThreadDCStartOpcode=3;function Decoder(){this.payload_=new DataView(new ArrayBuffer(256));};Decoder.prototype={__proto__:Object.prototype,reset:function(base64_payload){var decoded_size=tr.b.Base64.getDecodedBufferLength(base64_payload);if(decoded_size>this.payload_.byteLength)
-this.payload_=new DataView(new ArrayBuffer(decoded_size));tr.b.Base64.DecodeToTypedArray(base64_payload,this.payload_);this.position_=0;},skip:function(length){this.position_+=length;},decodeUInt8:function(){var result=this.payload_.getUint8(this.position_,true);this.position_+=1;return result;},decodeUInt16:function(){var result=this.payload_.getUint16(this.position_,true);this.position_+=2;return result;},decodeUInt32:function(){var result=this.payload_.getUint32(this.position_,true);this.position_+=4;return result;},decodeUInt64ToString:function(){var low=this.decodeUInt32();var high=this.decodeUInt32();var low_str=('0000000'+low.toString(16)).substr(-8);var high_str=('0000000'+high.toString(16)).substr(-8);var result=high_str+low_str;return result;},decodeInt8:function(){var result=this.payload_.getInt8(this.position_,true);this.position_+=1;return result;},decodeInt16:function(){var result=this.payload_.getInt16(this.position_,true);this.position_+=2;return result;},decodeInt32:function(){var result=this.payload_.getInt32(this.position_,true);this.position_+=4;return result;},decodeInt64ToString:function(){return this.decodeUInt64ToString();},decodeUInteger:function(is64){if(is64)
-return this.decodeUInt64ToString();return this.decodeUInt32();},decodeString:function(){var str='';while(true){var c=this.decodeUInt8();if(!c)
-return str;str=str+String.fromCharCode(c);}},decodeW16String:function(){var str='';while(true){var c=this.decodeUInt16();if(!c)
-return str;str=str+String.fromCharCode(c);}},decodeFixedW16String:function(length){var old_position=this.position_;var str='';for(var i=0;i<length;i++){var c=this.decodeUInt16();if(!c)
-break;str=str+String.fromCharCode(c);}
-this.position_=old_position+2*length;return str;},decodeBytes:function(length){var bytes=[];for(var i=0;i<length;++i){var c=this.decodeUInt8();bytes.push(c);}
-return bytes;},decodeSID:function(is64){var pSid=this.decodeUInteger(is64);var attributes=this.decodeUInt32();if(is64)
-this.decodeUInt32();var revision=this.decodeUInt8();var subAuthorityCount=this.decodeUInt8();this.decodeUInt16();this.decodeUInt32();if(revision!=1)
-throw'Invalid SID revision: could not decode the SID structure.';var sid=this.decodeBytes(4*subAuthorityCount);return{pSid:pSid,attributes:attributes,sid:sid};},decodeSystemTime:function(){var wYear=this.decodeInt16();var wMonth=this.decodeInt16();var wDayOfWeek=this.decodeInt16();var wDay=this.decodeInt16();var wHour=this.decodeInt16();var wMinute=this.decodeInt16();var wSecond=this.decodeInt16();var wMilliseconds=this.decodeInt16();return{wYear:wYear,wMonth:wMonth,wDayOfWeek:wDayOfWeek,wDay:wDay,wHour:wHour,wMinute:wMinute,wSecond:wSecond,wMilliseconds:wMilliseconds};},decodeTimeZoneInformation:function(){var bias=this.decodeUInt32();var standardName=this.decodeFixedW16String(32);var standardDate=this.decodeSystemTime();var standardBias=this.decodeUInt32();var daylightName=this.decodeFixedW16String(32);var daylightDate=this.decodeSystemTime();var daylightBias=this.decodeUInt32();return{bias:bias,standardName:standardName,standardDate:standardDate,standardBias:standardBias,daylightName:daylightName,daylightDate:daylightDate,daylightBias:daylightBias};}};function EtwImporter(model,events){this.importPriority=3;this.model_=model;this.events_=events;this.handlers_={};this.decoder_=new Decoder();this.walltime_=undefined;this.ticks_=undefined;this.is64bit_=undefined;this.tidsToPid_={};var allTypeInfos=tr.e.importer.etw.Parser.getAllRegisteredTypeInfos();this.parsers_=allTypeInfos.map(function(typeInfo){return new typeInfo.constructor(this);},this);}
+for(const key in object){const value=object[key];handleField(object,key,value);iterObjectFieldsRecursively(value);}}
+iterObjectFieldsRecursively(item.args);iterObjectFieldsRecursively(item.contexts);}};return{Model,};});'use strict';tr.exportTo('tr.e.importer.etw',function(){const kThreadGuid='3D6FA8D1-FE05-11D0-9DDA-00C04FD7BA7C';const kThreadDCStartOpcode=3;function Decoder(){this.payload_=new DataView(new ArrayBuffer(256));}
+Decoder.prototype={__proto__:Object.prototype,reset(base64Payload){const decodedSize=tr.b.Base64.getDecodedBufferLength(base64Payload);if(decodedSize>this.payload_.byteLength){this.payload_=new DataView(new ArrayBuffer(decodedSize));}
+tr.b.Base64.DecodeToTypedArray(base64Payload,this.payload_);this.position_=0;},skip(length){this.position_+=length;},decodeUInt8(){const result=this.payload_.getUint8(this.position_,true);this.position_+=1;return result;},decodeUInt16(){const result=this.payload_.getUint16(this.position_,true);this.position_+=2;return result;},decodeUInt32(){const result=this.payload_.getUint32(this.position_,true);this.position_+=4;return result;},decodeUInt64ToString(){const low=this.decodeUInt32();const high=this.decodeUInt32();const lowStr=('0000000'+low.toString(16)).substr(-8);const highStr=('0000000'+high.toString(16)).substr(-8);const result=highStr+lowStr;return result;},decodeInt8(){const result=this.payload_.getInt8(this.position_,true);this.position_+=1;return result;},decodeInt16(){const result=this.payload_.getInt16(this.position_,true);this.position_+=2;return result;},decodeInt32(){const result=this.payload_.getInt32(this.position_,true);this.position_+=4;return result;},decodeInt64ToString(){return this.decodeUInt64ToString();},decodeUInteger(is64){if(is64){return this.decodeUInt64ToString();}
+return this.decodeUInt32();},decodeString(){let str='';while(true){const c=this.decodeUInt8();if(!c)return str;str=str+String.fromCharCode(c);}},decodeW16String(){let str='';while(true){const c=this.decodeUInt16();if(!c)return str;str=str+String.fromCharCode(c);}},decodeFixedW16String(length){const oldPosition=this.position_;let str='';for(let i=0;i<length;i++){const c=this.decodeUInt16();if(!c)break;str=str+String.fromCharCode(c);}
+this.position_=oldPosition+2*length;return str;},decodeBytes(length){const bytes=[];for(let i=0;i<length;++i){const c=this.decodeUInt8();bytes.push(c);}
+return bytes;},decodeSID(is64){const pSid=this.decodeUInteger(is64);const attributes=this.decodeUInt32();if(is64){this.decodeUInt32();}
+const revision=this.decodeUInt8();const subAuthorityCount=this.decodeUInt8();this.decodeUInt16();this.decodeUInt32();if(revision!==1){throw new Error('Invalid SID revision: could not decode the SID structure.');}
+const sid=this.decodeBytes(4*subAuthorityCount);return{pSid,attributes,sid};},decodeSystemTime(){const wYear=this.decodeInt16();const wMonth=this.decodeInt16();const wDayOfWeek=this.decodeInt16();const wDay=this.decodeInt16();const wHour=this.decodeInt16();const wMinute=this.decodeInt16();const wSecond=this.decodeInt16();const wMilliseconds=this.decodeInt16();return{wYear,wMonth,wDayOfWeek,wDay,wHour,wMinute,wSecond,wMilliseconds};},decodeTimeZoneInformation(){const bias=this.decodeUInt32();const standardName=this.decodeFixedW16String(32);const standardDate=this.decodeSystemTime();const standardBias=this.decodeUInt32();const daylightName=this.decodeFixedW16String(32);const daylightDate=this.decodeSystemTime();const daylightBias=this.decodeUInt32();return{bias,standardName,standardDate,standardBias,daylightName,daylightDate,daylightBias};}};function EtwImporter(model,events){this.importPriority=3;this.model_=model;this.events_=events;this.handlers_={};this.decoder_=new Decoder();this.walltime_=undefined;this.ticks_=undefined;this.is64bit_=undefined;this.tidsToPid_={};const allTypeInfos=tr.e.importer.etw.Parser.getAllRegisteredTypeInfos();this.parsers_=allTypeInfos.map(function(typeInfo){return new typeInfo.constructor(this);},this);}
 EtwImporter.canImport=function(events){if(!events.hasOwnProperty('name')||!events.hasOwnProperty('content')||events.name!=='ETW'){return false;}
-return true;};EtwImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'EtwImporter';},get model(){return this.model_;},createThreadIfNeeded:function(pid,tid){this.tidsToPid_[tid]=pid;},removeThreadIfPresent:function(tid){this.tidsToPid_[tid]=undefined;},getPidFromWindowsTid:function(tid){if(tid==0)
-return 0;var pid=this.tidsToPid_[tid];if(pid==undefined){return 0;}
-return pid;},getThreadFromWindowsTid:function(tid){var pid=this.getPidFromWindowsTid(tid);var process=this.model_.getProcess(pid);if(!process)
-return undefined;return process.getThread(tid);},getOrCreateCpu:function(cpuNumber){var cpu=this.model_.kernel.getOrCreateCpu(cpuNumber);return cpu;},importEvents:function(){this.events_.content.forEach(this.parseInfo.bind(this));if(this.walltime_==undefined||this.ticks_==undefined)
-throw Error('Cannot find clock sync information in the system trace.');if(this.is64bit_==undefined)
-throw Error('Cannot determine pointer size of the system trace.');this.events_.content.forEach(this.parseEvent.bind(this));},importTimestamp:function(timestamp){var ts=parseInt(timestamp,16);return(ts-this.walltime_+this.ticks_)/1000.;},parseInfo:function(event){if(event.hasOwnProperty('guid')&&event.hasOwnProperty('walltime')&&event.hasOwnProperty('tick')&&event.guid==='ClockSync'){this.walltime_=parseInt(event.walltime,16);this.ticks_=parseInt(event.tick,16);}
-if(this.is64bit_==undefined&&event.hasOwnProperty('guid')&&event.hasOwnProperty('op')&&event.hasOwnProperty('ver')&&event.hasOwnProperty('payload')&&event.guid===kThreadGuid&&event.op==kThreadDCStartOpcode){var decoded_size=tr.b.Base64.getDecodedBufferLength(event.payload);if(event.ver==1){if(decoded_size>=52)
-this.is64bit_=true;else
-this.is64bit_=false;}else if(event.ver==2){if(decoded_size>=64)
-this.is64bit_=true;else
-this.is64bit_=false;}else if(event.ver==3){if(decoded_size>=60)
-this.is64bit_=true;else
-this.is64bit_=false;}}
-return true;},parseEvent:function(event){if(!event.hasOwnProperty('guid')||!event.hasOwnProperty('op')||!event.hasOwnProperty('ver')||!event.hasOwnProperty('cpu')||!event.hasOwnProperty('ts')||!event.hasOwnProperty('payload')){return false;}
-var timestamp=this.importTimestamp(event.ts);var header={guid:event.guid,opcode:event.op,version:event.ver,cpu:event.cpu,timestamp:timestamp,is64:this.is64bit_};var decoder=this.decoder_;decoder.reset(event.payload);var handler=this.getEventHandler(header.guid,header.opcode);if(!handler)
-return false;if(!handler(header,decoder)){this.model_.importWarning({type:'parse_error',message:'Malformed '+header.guid+' event ('+text+')'});return false;}
-return true;},registerEventHandler:function(guid,opcode,handler){if(this.handlers_[guid]==undefined)
-this.handlers_[guid]=[];this.handlers_[guid][opcode]=handler;},getEventHandler:function(guid,opcode){if(this.handlers_[guid]==undefined)
-return undefined;return this.handlers_[guid][opcode];}};tr.importer.Importer.register(EtwImporter);return{EtwImporter:EtwImporter};});!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;"undefined"!=typeof window?b=window:"undefined"!=typeof global?b=global:"undefined"!=typeof self&&(b=self),b.JSZip=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}({1:[function(a,b,c){"use strict";var d="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";c.encode=function(a){for(var b,c,e,f,g,h,i,j="",k=0;k<a.length;)b=a.charCodeAt(k++),c=a.charCodeAt(k++),e=a.charCodeAt(k++),f=b>>2,g=(3&b)<<4|c>>4,h=(15&c)<<2|e>>6,i=63&e,isNaN(c)?h=i=64:isNaN(e)&&(i=64),j=j+d.charAt(f)+d.charAt(g)+d.charAt(h)+d.charAt(i);return j},c.decode=function(a){var b,c,e,f,g,h,i,j="",k=0;for(a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");k<a.length;)f=d.indexOf(a.charAt(k++)),g=d.indexOf(a.charAt(k++)),h=d.indexOf(a.charAt(k++)),i=d.indexOf(a.charAt(k++)),b=f<<2|g>>4,c=(15&g)<<4|h>>2,e=(3&h)<<6|i,j+=String.fromCharCode(b),64!=h&&(j+=String.fromCharCode(c)),64!=i&&(j+=String.fromCharCode(e));return j}},{}],2:[function(a,b){"use strict";function c(){this.compressedSize=0,this.uncompressedSize=0,this.crc32=0,this.compressionMethod=null,this.compressedContent=null}c.prototype={getContent:function(){return null},getCompressedContent:function(){return null}},b.exports=c},{}],3:[function(a,b,c){"use strict";c.STORE={magic:"\x00\x00",compress:function(a){return a},uncompress:function(a){return a},compressInputType:null,uncompressInputType:null},c.DEFLATE=a("./flate")},{"./flate":8}],4:[function(a,b){"use strict";var c=a("./utils"),d=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117];b.exports=function(a,b){if("undefined"==typeof a||!a.length)return 0;var e="string"!==c.getTypeOf(a);"undefined"==typeof b&&(b=0);var f=0,g=0,h=0;b=-1^b;for(var i=0,j=a.length;j>i;i++)h=e?a[i]:a.charCodeAt(i),g=255&(b^h),f=d[g],b=b>>>8^f;return-1^b}},{"./utils":21}],5:[function(a,b){"use strict";function c(){this.data=null,this.length=0,this.index=0}var d=a("./utils");c.prototype={checkOffset:function(a){this.checkIndex(this.index+a)},checkIndex:function(a){if(this.length<a||0>a)throw new Error("End of data reached (data length = "+this.length+", asked index = "+a+"). Corrupted zip ?")},setIndex:function(a){this.checkIndex(a),this.index=a},skip:function(a){this.setIndex(this.index+a)},byteAt:function(){},readInt:function(a){var b,c=0;for(this.checkOffset(a),b=this.index+a-1;b>=this.index;b--)c=(c<<8)+this.byteAt(b);return this.index+=a,c},readString:function(a){return d.transformTo("string",this.readData(a))},readData:function(){},lastIndexOfSignature:function(){},readDate:function(){var a=this.readInt(4);return new Date((a>>25&127)+1980,(a>>21&15)-1,a>>16&31,a>>11&31,a>>5&63,(31&a)<<1)}},b.exports=c},{"./utils":21}],6:[function(a,b,c){"use strict";c.base64=!1,c.binary=!1,c.dir=!1,c.createFolders=!1,c.date=null,c.compression=null,c.comment=null},{}],7:[function(a,b,c){"use strict";var d=a("./utils");c.string2binary=function(a){return d.string2binary(a)},c.string2Uint8Array=function(a){return d.transformTo("uint8array",a)},c.uint8Array2String=function(a){return d.transformTo("string",a)},c.string2Blob=function(a){var b=d.transformTo("arraybuffer",a);return d.arrayBuffer2Blob(b)},c.arrayBuffer2Blob=function(a){return d.arrayBuffer2Blob(a)},c.transformTo=function(a,b){return d.transformTo(a,b)},c.getTypeOf=function(a){return d.getTypeOf(a)},c.checkSupport=function(a){return d.checkSupport(a)},c.MAX_VALUE_16BITS=d.MAX_VALUE_16BITS,c.MAX_VALUE_32BITS=d.MAX_VALUE_32BITS,c.pretty=function(a){return d.pretty(a)},c.findCompression=function(a){return d.findCompression(a)},c.isRegExp=function(a){return d.isRegExp(a)}},{"./utils":21}],8:[function(a,b,c){"use strict";var d="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Uint32Array,e=a("pako");c.uncompressInputType=d?"uint8array":"array",c.compressInputType=d?"uint8array":"array",c.magic="\b\x00",c.compress=function(a){return e.deflateRaw(a)},c.uncompress=function(a){return e.inflateRaw(a)}},{pako:24}],9:[function(a,b){"use strict";function c(a,b){return this instanceof c?(this.files={},this.comment=null,this.root="",a&&this.load(a,b),void(this.clone=function(){var a=new c;for(var b in this)"function"!=typeof this[b]&&(a[b]=this[b]);return a})):new c(a,b)}var d=a("./base64");c.prototype=a("./object"),c.prototype.load=a("./load"),c.support=a("./support"),c.defaults=a("./defaults"),c.utils=a("./deprecatedPublicUtils"),c.base64={encode:function(a){return d.encode(a)},decode:function(a){return d.decode(a)}},c.compressions=a("./compressions"),b.exports=c},{"./base64":1,"./compressions":3,"./defaults":6,"./deprecatedPublicUtils":7,"./load":10,"./object":13,"./support":17}],10:[function(a,b){"use strict";var c=a("./base64"),d=a("./zipEntries");b.exports=function(a,b){var e,f,g,h;for(b=b||{},b.base64&&(a=c.decode(a)),f=new d(a,b),e=f.files,g=0;g<e.length;g++)h=e[g],this.file(h.fileName,h.decompressed,{binary:!0,optimizedBinaryString:!0,date:h.date,dir:h.dir,comment:h.fileComment.length?h.fileComment:null,createFolders:b.createFolders});return f.zipComment.length&&(this.comment=f.zipComment),this}},{"./base64":1,"./zipEntries":22}],11:[function(a,b){(function(a){"use strict";b.exports=function(b,c){return new a(b,c)},b.exports.test=function(b){return a.isBuffer(b)}}).call(this,"undefined"!=typeof Buffer?Buffer:void 0)},{}],12:[function(a,b){"use strict";function c(a){this.data=a,this.length=this.data.length,this.index=0}var d=a("./uint8ArrayReader");c.prototype=new d,c.prototype.readData=function(a){this.checkOffset(a);var b=this.data.slice(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./uint8ArrayReader":18}],13:[function(a,b){"use strict";var c=a("./support"),d=a("./utils"),e=a("./crc32"),f=a("./signature"),g=a("./defaults"),h=a("./base64"),i=a("./compressions"),j=a("./compressedObject"),k=a("./nodeBuffer"),l=a("./utf8"),m=a("./stringWriter"),n=a("./uint8ArrayWriter"),o=function(a){if(a._data instanceof j&&(a._data=a._data.getContent(),a.options.binary=!0,a.options.base64=!1,"uint8array"===d.getTypeOf(a._data))){var b=a._data;a._data=new Uint8Array(b.length),0!==b.length&&a._data.set(b,0)}return a._data},p=function(a){var b=o(a),e=d.getTypeOf(b);return"string"===e?!a.options.binary&&c.nodebuffer?k(b,"utf-8"):a.asBinary():b},q=function(a){var b=o(this);return null===b||"undefined"==typeof b?"":(this.options.base64&&(b=h.decode(b)),b=a&&this.options.binary?A.utf8decode(b):d.transformTo("string",b),a||this.options.binary||(b=d.transformTo("string",A.utf8encode(b))),b)},r=function(a,b,c){this.name=a,this.dir=c.dir,this.date=c.date,this.comment=c.comment,this._data=b,this.options=c,this._initialMetadata={dir:c.dir,date:c.date}};r.prototype={asText:function(){return q.call(this,!0)},asBinary:function(){return q.call(this,!1)},asNodeBuffer:function(){var a=p(this);return d.transformTo("nodebuffer",a)},asUint8Array:function(){var a=p(this);return d.transformTo("uint8array",a)},asArrayBuffer:function(){return this.asUint8Array().buffer}};var s=function(a,b){var c,d="";for(c=0;b>c;c++)d+=String.fromCharCode(255&a),a>>>=8;return d},t=function(){var a,b,c={};for(a=0;a<arguments.length;a++)for(b in arguments[a])arguments[a].hasOwnProperty(b)&&"undefined"==typeof c[b]&&(c[b]=arguments[a][b]);return c},u=function(a){return a=a||{},a.base64!==!0||null!==a.binary&&void 0!==a.binary||(a.binary=!0),a=t(a,g),a.date=a.date||new Date,null!==a.compression&&(a.compression=a.compression.toUpperCase()),a},v=function(a,b,c){var e,f=d.getTypeOf(b);if(c=u(c),c.createFolders&&(e=w(a))&&x.call(this,e,!0),c.dir||null===b||"undefined"==typeof b)c.base64=!1,c.binary=!1,b=null;else if("string"===f)c.binary&&!c.base64&&c.optimizedBinaryString!==!0&&(b=d.string2binary(b));else{if(c.base64=!1,c.binary=!0,!(f||b instanceof j))throw new Error("The data of '"+a+"' is in an unsupported format !");"arraybuffer"===f&&(b=d.transformTo("uint8array",b))}var g=new r(a,b,c);return this.files[a]=g,g},w=function(a){"/"==a.slice(-1)&&(a=a.substring(0,a.length-1));var b=a.lastIndexOf("/");return b>0?a.substring(0,b):""},x=function(a,b){return"/"!=a.slice(-1)&&(a+="/"),b="undefined"!=typeof b?b:!1,this.files[a]||v.call(this,a,null,{dir:!0,createFolders:b}),this.files[a]},y=function(a,b){var c,f=new j;return a._data instanceof j?(f.uncompressedSize=a._data.uncompressedSize,f.crc32=a._data.crc32,0===f.uncompressedSize||a.dir?(b=i.STORE,f.compressedContent="",f.crc32=0):a._data.compressionMethod===b.magic?f.compressedContent=a._data.getCompressedContent():(c=a._data.getContent(),f.compressedContent=b.compress(d.transformTo(b.compressInputType,c)))):(c=p(a),(!c||0===c.length||a.dir)&&(b=i.STORE,c=""),f.uncompressedSize=c.length,f.crc32=e(c),f.compressedContent=b.compress(d.transformTo(b.compressInputType,c))),f.compressedSize=f.compressedContent.length,f.compressionMethod=b.magic,f},z=function(a,b,c,g){var h,i,j,k,m=(c.compressedContent,d.transformTo("string",l.utf8encode(b.name))),n=b.comment||"",o=d.transformTo("string",l.utf8encode(n)),p=m.length!==b.name.length,q=o.length!==n.length,r=b.options,t="",u="",v="";j=b._initialMetadata.dir!==b.dir?b.dir:r.dir,k=b._initialMetadata.date!==b.date?b.date:r.date,h=k.getHours(),h<<=6,h|=k.getMinutes(),h<<=5,h|=k.getSeconds()/2,i=k.getFullYear()-1980,i<<=4,i|=k.getMonth()+1,i<<=5,i|=k.getDate(),p&&(u=s(1,1)+s(e(m),4)+m,t+="up"+s(u.length,2)+u),q&&(v=s(1,1)+s(this.crc32(o),4)+o,t+="uc"+s(v.length,2)+v);var w="";w+="\n\x00",w+=p||q?"\x00\b":"\x00\x00",w+=c.compressionMethod,w+=s(h,2),w+=s(i,2),w+=s(c.crc32,4),w+=s(c.compressedSize,4),w+=s(c.uncompressedSize,4),w+=s(m.length,2),w+=s(t.length,2);var x=f.LOCAL_FILE_HEADER+w+m+t,y=f.CENTRAL_FILE_HEADER+"\x00"+w+s(o.length,2)+"\x00\x00\x00\x00"+(j===!0?"\x00\x00\x00":"\x00\x00\x00\x00")+s(g,4)+m+t+o;return{fileRecord:x,dirRecord:y,compressedObject:c}},A={load:function(){throw new Error("Load method is not defined. Is the file jszip-load.js included ?")},filter:function(a){var b,c,d,e,f=[];for(b in this.files)this.files.hasOwnProperty(b)&&(d=this.files[b],e=new r(d.name,d._data,t(d.options)),c=b.slice(this.root.length,b.length),b.slice(0,this.root.length)===this.root&&a(c,e)&&f.push(e));return f},file:function(a,b,c){if(1===arguments.length){if(d.isRegExp(a)){var e=a;return this.filter(function(a,b){return!b.dir&&e.test(a)})}return this.filter(function(b,c){return!c.dir&&b===a})[0]||null}return a=this.root+a,v.call(this,a,b,c),this},folder:function(a){if(!a)return this;if(d.isRegExp(a))return this.filter(function(b,c){return c.dir&&a.test(b)});var b=this.root+a,c=x.call(this,b),e=this.clone();return e.root=c.name,e},remove:function(a){a=this.root+a;var b=this.files[a];if(b||("/"!=a.slice(-1)&&(a+="/"),b=this.files[a]),b&&!b.dir)delete this.files[a];else for(var c=this.filter(function(b,c){return c.name.slice(0,a.length)===a}),d=0;d<c.length;d++)delete this.files[c[d].name];return this},generate:function(a){a=t(a||{},{base64:!0,compression:"STORE",type:"base64",comment:null}),d.checkSupport(a.type);var b,c,e=[],g=0,j=0,k=d.transformTo("string",this.utf8encode(a.comment||this.comment||""));for(var l in this.files)if(this.files.hasOwnProperty(l)){var o=this.files[l],p=o.options.compression||a.compression.toUpperCase(),q=i[p];if(!q)throw new Error(p+" is not a valid compression method !");var r=y.call(this,o,q),u=z.call(this,l,o,r,g);g+=u.fileRecord.length+r.compressedSize,j+=u.dirRecord.length,e.push(u)}var v="";v=f.CENTRAL_DIRECTORY_END+"\x00\x00\x00\x00"+s(e.length,2)+s(e.length,2)+s(j,4)+s(g,4)+s(k.length,2)+k;var w=a.type.toLowerCase();for(b="uint8array"===w||"arraybuffer"===w||"blob"===w||"nodebuffer"===w?new n(g+j+v.length):new m(g+j+v.length),c=0;c<e.length;c++)b.append(e[c].fileRecord),b.append(e[c].compressedObject.compressedContent);for(c=0;c<e.length;c++)b.append(e[c].dirRecord);b.append(v);var x=b.finalize();switch(a.type.toLowerCase()){case"uint8array":case"arraybuffer":case"nodebuffer":return d.transformTo(a.type.toLowerCase(),x);case"blob":return d.arrayBuffer2Blob(d.transformTo("arraybuffer",x));case"base64":return a.base64?h.encode(x):x;default:return x}},crc32:function(a,b){return e(a,b)},utf8encode:function(a){return d.transformTo("string",l.utf8encode(a))},utf8decode:function(a){return l.utf8decode(a)}};b.exports=A},{"./base64":1,"./compressedObject":2,"./compressions":3,"./crc32":4,"./defaults":6,"./nodeBuffer":11,"./signature":14,"./stringWriter":16,"./support":17,"./uint8ArrayWriter":19,"./utf8":20,"./utils":21}],14:[function(a,b,c){"use strict";c.LOCAL_FILE_HEADER="PK",c.CENTRAL_FILE_HEADER="PK",c.CENTRAL_DIRECTORY_END="PK",c.ZIP64_CENTRAL_DIRECTORY_LOCATOR="PK",c.ZIP64_CENTRAL_DIRECTORY_END="PK",c.DATA_DESCRIPTOR="PK\b"},{}],15:[function(a,b){"use strict";function c(a,b){this.data=a,b||(this.data=e.string2binary(this.data)),this.length=this.data.length,this.index=0}var d=a("./dataReader"),e=a("./utils");c.prototype=new d,c.prototype.byteAt=function(a){return this.data.charCodeAt(a)},c.prototype.lastIndexOfSignature=function(a){return this.data.lastIndexOf(a)},c.prototype.readData=function(a){this.checkOffset(a);var b=this.data.slice(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./dataReader":5,"./utils":21}],16:[function(a,b){"use strict";var c=a("./utils"),d=function(){this.data=[]};d.prototype={append:function(a){a=c.transformTo("string",a),this.data.push(a)},finalize:function(){return this.data.join("")}},b.exports=d},{"./utils":21}],17:[function(a,b,c){(function(a){"use strict";if(c.base64=!0,c.array=!0,c.string=!0,c.arraybuffer="undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array,c.nodebuffer="undefined"!=typeof a,c.uint8array="undefined"!=typeof Uint8Array,"undefined"==typeof ArrayBuffer)c.blob=!1;else{var b=new ArrayBuffer(0);try{c.blob=0===new Blob([b],{type:"application/zip"}).size}catch(d){try{var e=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,f=new e;f.append(b),c.blob=0===f.getBlob("application/zip").size}catch(d){c.blob=!1}}}}).call(this,"undefined"!=typeof Buffer?Buffer:void 0)},{}],18:[function(a,b){"use strict";function c(a){a&&(this.data=a,this.length=this.data.length,this.index=0)}var d=a("./dataReader");c.prototype=new d,c.prototype.byteAt=function(a){return this.data[a]},c.prototype.lastIndexOfSignature=function(a){for(var b=a.charCodeAt(0),c=a.charCodeAt(1),d=a.charCodeAt(2),e=a.charCodeAt(3),f=this.length-4;f>=0;--f)if(this.data[f]===b&&this.data[f+1]===c&&this.data[f+2]===d&&this.data[f+3]===e)return f;return-1},c.prototype.readData=function(a){if(this.checkOffset(a),0===a)return new Uint8Array(0);var b=this.data.subarray(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./dataReader":5}],19:[function(a,b){"use strict";var c=a("./utils"),d=function(a){this.data=new Uint8Array(a),this.index=0};d.prototype={append:function(a){0!==a.length&&(a=c.transformTo("uint8array",a),this.data.set(a,this.index),this.index+=a.length)},finalize:function(){return this.data}},b.exports=d},{"./utils":21}],20:[function(a,b,c){"use strict";for(var d=a("./utils"),e=a("./support"),f=a("./nodeBuffer"),g=new Array(256),h=0;256>h;h++)g[h]=h>=252?6:h>=248?5:h>=240?4:h>=224?3:h>=192?2:1;g[254]=g[254]=1;var i=function(a){var b,c,d,f,g,h=a.length,i=0;for(f=0;h>f;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),i+=128>c?1:2048>c?2:65536>c?3:4;for(b=e.uint8array?new Uint8Array(i):new Array(i),g=0,f=0;i>g;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),128>c?b[g++]=c:2048>c?(b[g++]=192|c>>>6,b[g++]=128|63&c):65536>c?(b[g++]=224|c>>>12,b[g++]=128|c>>>6&63,b[g++]=128|63&c):(b[g++]=240|c>>>18,b[g++]=128|c>>>12&63,b[g++]=128|c>>>6&63,b[g++]=128|63&c);return b},j=function(a,b){var c;for(b=b||a.length,b>a.length&&(b=a.length),c=b-1;c>=0&&128===(192&a[c]);)c--;return 0>c?b:0===c?b:c+g[a[c]]>b?c:b},k=function(a){var b,c,e,f,h=a.length,i=new Array(2*h);for(c=0,b=0;h>b;)if(e=a[b++],128>e)i[c++]=e;else if(f=g[e],f>4)i[c++]=65533,b+=f-1;else{for(e&=2===f?31:3===f?15:7;f>1&&h>b;)e=e<<6|63&a[b++],f--;f>1?i[c++]=65533:65536>e?i[c++]=e:(e-=65536,i[c++]=55296|e>>10&1023,i[c++]=56320|1023&e)}return i.length!==c&&(i.subarray?i=i.subarray(0,c):i.length=c),d.applyFromCharCode(i)};c.utf8encode=function(a){return e.nodebuffer?f(a,"utf-8"):i(a)},c.utf8decode=function(a){if(e.nodebuffer)return d.transformTo("nodebuffer",a).toString("utf-8");a=d.transformTo(e.uint8array?"uint8array":"array",a);for(var b=[],c=0,f=a.length,g=65536;f>c;){var h=j(a,Math.min(c+g,f));b.push(e.uint8array?k(a.subarray(c,h)):k(a.slice(c,h))),c=h}return b.join("")}},{"./nodeBuffer":11,"./support":17,"./utils":21}],21:[function(a,b,c){"use strict";function d(a){return a}function e(a,b){for(var c=0;c<a.length;++c)b[c]=255&a.charCodeAt(c);return b}function f(a){var b=65536,d=[],e=a.length,f=c.getTypeOf(a),g=0,h=!0;try{switch(f){case"uint8array":String.fromCharCode.apply(null,new Uint8Array(0));break;case"nodebuffer":String.fromCharCode.apply(null,j(0))}}catch(i){h=!1}if(!h){for(var k="",l=0;l<a.length;l++)k+=String.fromCharCode(a[l]);return k}for(;e>g&&b>1;)try{d.push("array"===f||"nodebuffer"===f?String.fromCharCode.apply(null,a.slice(g,Math.min(g+b,e))):String.fromCharCode.apply(null,a.subarray(g,Math.min(g+b,e)))),g+=b}catch(i){b=Math.floor(b/2)}return d.join("")}function g(a,b){for(var c=0;c<a.length;c++)b[c]=a[c];return b}var h=a("./support"),i=a("./compressions"),j=a("./nodeBuffer");c.string2binary=function(a){for(var b="",c=0;c<a.length;c++)b+=String.fromCharCode(255&a.charCodeAt(c));return b},c.arrayBuffer2Blob=function(a){c.checkSupport("blob");try{return new Blob([a],{type:"application/zip"})}catch(b){try{var d=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,e=new d;return e.append(a),e.getBlob("application/zip")}catch(b){throw new Error("Bug : can't construct the Blob.")}}},c.applyFromCharCode=f;var k={};k.string={string:d,array:function(a){return e(a,new Array(a.length))},arraybuffer:function(a){return k.string.uint8array(a).buffer},uint8array:function(a){return e(a,new Uint8Array(a.length))},nodebuffer:function(a){return e(a,j(a.length))}},k.array={string:f,array:d,arraybuffer:function(a){return new Uint8Array(a).buffer},uint8array:function(a){return new Uint8Array(a)},nodebuffer:function(a){return j(a)}},k.arraybuffer={string:function(a){return f(new Uint8Array(a))},array:function(a){return g(new Uint8Array(a),new Array(a.byteLength))},arraybuffer:d,uint8array:function(a){return new Uint8Array(a)},nodebuffer:function(a){return j(new Uint8Array(a))}},k.uint8array={string:f,array:function(a){return g(a,new Array(a.length))},arraybuffer:function(a){return a.buffer},uint8array:d,nodebuffer:function(a){return j(a)}},k.nodebuffer={string:f,array:function(a){return g(a,new Array(a.length))},arraybuffer:function(a){return k.nodebuffer.uint8array(a).buffer},uint8array:function(a){return g(a,new Uint8Array(a.length))},nodebuffer:d},c.transformTo=function(a,b){if(b||(b=""),!a)return b;c.checkSupport(a);var d=c.getTypeOf(b),e=k[d][a](b);return e},c.getTypeOf=function(a){return"string"==typeof a?"string":"[object Array]"===Object.prototype.toString.call(a)?"array":h.nodebuffer&&j.test(a)?"nodebuffer":h.uint8array&&a instanceof Uint8Array?"uint8array":h.arraybuffer&&a instanceof ArrayBuffer?"arraybuffer":void 0},c.checkSupport=function(a){var b=h[a.toLowerCase()];if(!b)throw new Error(a+" is not supported by this browser")},c.MAX_VALUE_16BITS=65535,c.MAX_VALUE_32BITS=-1,c.pretty=function(a){var b,c,d="";for(c=0;c<(a||"").length;c++)b=a.charCodeAt(c),d+="\\x"+(16>b?"0":"")+b.toString(16).toUpperCase();return d},c.findCompression=function(a){for(var b in i)if(i.hasOwnProperty(b)&&i[b].magic===a)return i[b];return null},c.isRegExp=function(a){return"[object RegExp]"===Object.prototype.toString.call(a)}},{"./compressions":3,"./nodeBuffer":11,"./support":17}],22:[function(a,b){"use strict";function c(a,b){this.files=[],this.loadOptions=b,a&&this.load(a)}var d=a("./stringReader"),e=a("./nodeBufferReader"),f=a("./uint8ArrayReader"),g=a("./utils"),h=a("./signature"),i=a("./zipEntry"),j=a("./support"),k=a("./object");c.prototype={checkSignature:function(a){var b=this.reader.readString(4);if(b!==a)throw new Error("Corrupted zip or bug : unexpected signature ("+g.pretty(b)+", expected "+g.pretty(a)+")")},readBlockEndOfCentral:function(){this.diskNumber=this.reader.readInt(2),this.diskWithCentralDirStart=this.reader.readInt(2),this.centralDirRecordsOnThisDisk=this.reader.readInt(2),this.centralDirRecords=this.reader.readInt(2),this.centralDirSize=this.reader.readInt(4),this.centralDirOffset=this.reader.readInt(4),this.zipCommentLength=this.reader.readInt(2),this.zipComment=this.reader.readString(this.zipCommentLength),this.zipComment=k.utf8decode(this.zipComment)},readBlockZip64EndOfCentral:function(){this.zip64EndOfCentralSize=this.reader.readInt(8),this.versionMadeBy=this.reader.readString(2),this.versionNeeded=this.reader.readInt(2),this.diskNumber=this.reader.readInt(4),this.diskWithCentralDirStart=this.reader.readInt(4),this.centralDirRecordsOnThisDisk=this.reader.readInt(8),this.centralDirRecords=this.reader.readInt(8),this.centralDirSize=this.reader.readInt(8),this.centralDirOffset=this.reader.readInt(8),this.zip64ExtensibleData={};for(var a,b,c,d=this.zip64EndOfCentralSize-44,e=0;d>e;)a=this.reader.readInt(2),b=this.reader.readInt(4),c=this.reader.readString(b),this.zip64ExtensibleData[a]={id:a,length:b,value:c}},readBlockZip64EndOfCentralLocator:function(){if(this.diskWithZip64CentralDirStart=this.reader.readInt(4),this.relativeOffsetEndOfZip64CentralDir=this.reader.readInt(8),this.disksCount=this.reader.readInt(4),this.disksCount>1)throw new Error("Multi-volumes zip are not supported")},readLocalFiles:function(){var a,b;for(a=0;a<this.files.length;a++)b=this.files[a],this.reader.setIndex(b.localHeaderOffset),this.checkSignature(h.LOCAL_FILE_HEADER),b.readLocalPart(this.reader),b.handleUTF8()},readCentralDir:function(){var a;for(this.reader.setIndex(this.centralDirOffset);this.reader.readString(4)===h.CENTRAL_FILE_HEADER;)a=new i({zip64:this.zip64},this.loadOptions),a.readCentralPart(this.reader),this.files.push(a)},readEndOfCentral:function(){var a=this.reader.lastIndexOfSignature(h.CENTRAL_DIRECTORY_END);if(-1===a)throw new Error("Corrupted zip : can't find end of central directory");if(this.reader.setIndex(a),this.checkSignature(h.CENTRAL_DIRECTORY_END),this.readBlockEndOfCentral(),this.diskNumber===g.MAX_VALUE_16BITS||this.diskWithCentralDirStart===g.MAX_VALUE_16BITS||this.centralDirRecordsOnThisDisk===g.MAX_VALUE_16BITS||this.centralDirRecords===g.MAX_VALUE_16BITS||this.centralDirSize===g.MAX_VALUE_32BITS||this.centralDirOffset===g.MAX_VALUE_32BITS){if(this.zip64=!0,a=this.reader.lastIndexOfSignature(h.ZIP64_CENTRAL_DIRECTORY_LOCATOR),-1===a)throw new Error("Corrupted zip : can't find the ZIP64 end of central directory locator");this.reader.setIndex(a),this.checkSignature(h.ZIP64_CENTRAL_DIRECTORY_LOCATOR),this.readBlockZip64EndOfCentralLocator(),this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir),this.checkSignature(h.ZIP64_CENTRAL_DIRECTORY_END),this.readBlockZip64EndOfCentral()}},prepareReader:function(a){var b=g.getTypeOf(a);this.reader="string"!==b||j.uint8array?"nodebuffer"===b?new e(a):new f(g.transformTo("uint8array",a)):new d(a,this.loadOptions.optimizedBinaryString)},load:function(a){this.prepareReader(a),this.readEndOfCentral(),this.readCentralDir(),this.readLocalFiles()}},b.exports=c},{"./nodeBufferReader":12,"./object":13,"./signature":14,"./stringReader":15,"./support":17,"./uint8ArrayReader":18,"./utils":21,"./zipEntry":23}],23:[function(a,b){"use strict";function c(a,b){this.options=a,this.loadOptions=b}var d=a("./stringReader"),e=a("./utils"),f=a("./compressedObject"),g=a("./object");c.prototype={isEncrypted:function(){return 1===(1&this.bitFlag)},useUTF8:function(){return 2048===(2048&this.bitFlag)},prepareCompressedContent:function(a,b,c){return function(){var d=a.index;a.setIndex(b);var e=a.readData(c);return a.setIndex(d),e}},prepareContent:function(a,b,c,d,f){return function(){var a=e.transformTo(d.uncompressInputType,this.getCompressedContent()),b=d.uncompress(a);if(b.length!==f)throw new Error("Bug : uncompressed data size mismatch");return b}},readLocalPart:function(a){var b,c;if(a.skip(22),this.fileNameLength=a.readInt(2),c=a.readInt(2),this.fileName=a.readString(this.fileNameLength),a.skip(c),-1==this.compressedSize||-1==this.uncompressedSize)throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory (compressedSize == -1 || uncompressedSize == -1)");if(b=e.findCompression(this.compressionMethod),null===b)throw new Error("Corrupted zip : compression "+e.pretty(this.compressionMethod)+" unknown (inner file : "+this.fileName+")");if(this.decompressed=new f,this.decompressed.compressedSize=this.compressedSize,this.decompressed.uncompressedSize=this.uncompressedSize,this.decompressed.crc32=this.crc32,this.decompressed.compressionMethod=this.compressionMethod,this.decompressed.getCompressedContent=this.prepareCompressedContent(a,a.index,this.compressedSize,b),this.decompressed.getContent=this.prepareContent(a,a.index,this.compressedSize,b,this.uncompressedSize),this.loadOptions.checkCRC32&&(this.decompressed=e.transformTo("string",this.decompressed.getContent()),g.crc32(this.decompressed)!==this.crc32))throw new Error("Corrupted zip : CRC32 mismatch")},readCentralPart:function(a){if(this.versionMadeBy=a.readString(2),this.versionNeeded=a.readInt(2),this.bitFlag=a.readInt(2),this.compressionMethod=a.readString(2),this.date=a.readDate(),this.crc32=a.readInt(4),this.compressedSize=a.readInt(4),this.uncompressedSize=a.readInt(4),this.fileNameLength=a.readInt(2),this.extraFieldsLength=a.readInt(2),this.fileCommentLength=a.readInt(2),this.diskNumberStart=a.readInt(2),this.internalFileAttributes=a.readInt(2),this.externalFileAttributes=a.readInt(4),this.localHeaderOffset=a.readInt(4),this.isEncrypted())throw new Error("Encrypted zip are not supported");this.fileName=a.readString(this.fileNameLength),this.readExtraFields(a),this.parseZIP64ExtraField(a),this.fileComment=a.readString(this.fileCommentLength),this.dir=16&this.externalFileAttributes?!0:!1},parseZIP64ExtraField:function(){if(this.extraFields[1]){var a=new d(this.extraFields[1].value);this.uncompressedSize===e.MAX_VALUE_32BITS&&(this.uncompressedSize=a.readInt(8)),this.compressedSize===e.MAX_VALUE_32BITS&&(this.compressedSize=a.readInt(8)),this.localHeaderOffset===e.MAX_VALUE_32BITS&&(this.localHeaderOffset=a.readInt(8)),this.diskNumberStart===e.MAX_VALUE_32BITS&&(this.diskNumberStart=a.readInt(4))}},readExtraFields:function(a){var b,c,d,e=a.index;for(this.extraFields=this.extraFields||{};a.index<e+this.extraFieldsLength;)b=a.readInt(2),c=a.readInt(2),d=a.readString(c),this.extraFields[b]={id:b,length:c,value:d}},handleUTF8:function(){if(this.useUTF8())this.fileName=g.utf8decode(this.fileName),this.fileComment=g.utf8decode(this.fileComment);else{var a=this.findExtraFieldUnicodePath();null!==a&&(this.fileName=a);var b=this.findExtraFieldUnicodeComment();null!==b&&(this.fileComment=b)}},findExtraFieldUnicodePath:function(){var a=this.extraFields[28789];if(a){var b=new d(a.value);return 1!==b.readInt(1)?null:g.crc32(this.fileName)!==b.readInt(4)?null:g.utf8decode(b.readString(a.length-5))}return null},findExtraFieldUnicodeComment:function(){var a=this.extraFields[25461];if(a){var b=new d(a.value);return 1!==b.readInt(1)?null:g.crc32(this.fileComment)!==b.readInt(4)?null:g.utf8decode(b.readString(a.length-5))}return null}},b.exports=c},{"./compressedObject":2,"./object":13,"./stringReader":15,"./utils":21}],24:[function(a,b){"use strict";var c=a("./lib/utils/common").assign,d=a("./lib/deflate"),e=a("./lib/inflate"),f=a("./lib/zlib/constants"),g={};c(g,d,e,f),b.exports=g},{"./lib/deflate":25,"./lib/inflate":26,"./lib/utils/common":27,"./lib/zlib/constants":30}],25:[function(a,b,c){"use strict";function d(a,b){var c=new s(b);if(c.push(a,!0),c.err)throw c.msg;return c.result}function e(a,b){return b=b||{},b.raw=!0,d(a,b)}function f(a,b){return b=b||{},b.gzip=!0,d(a,b)}var g=a("./zlib/deflate.js"),h=a("./utils/common"),i=a("./utils/strings"),j=a("./zlib/messages"),k=a("./zlib/zstream"),l=0,m=4,n=0,o=1,p=-1,q=0,r=8,s=function(a){this.options=h.assign({level:p,method:r,chunkSize:16384,windowBits:15,memLevel:8,strategy:q,to:""},a||{});var b=this.options;b.raw&&b.windowBits>0?b.windowBits=-b.windowBits:b.gzip&&b.windowBits>0&&b.windowBits<16&&(b.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new k,this.strm.avail_out=0;var c=g.deflateInit2(this.strm,b.level,b.method,b.windowBits,b.memLevel,b.strategy);if(c!==n)throw new Error(j[c]);b.header&&g.deflateSetHeader(this.strm,b.header)};s.prototype.push=function(a,b){var c,d,e=this.strm,f=this.options.chunkSize;if(this.ended)return!1;d=b===~~b?b:b===!0?m:l,e.input="string"==typeof a?i.string2buf(a):a,e.next_in=0,e.avail_in=e.input.length;do{if(0===e.avail_out&&(e.output=new h.Buf8(f),e.next_out=0,e.avail_out=f),c=g.deflate(e,d),c!==o&&c!==n)return this.onEnd(c),this.ended=!0,!1;(0===e.avail_out||0===e.avail_in&&d===m)&&this.onData("string"===this.options.to?i.buf2binstring(h.shrinkBuf(e.output,e.next_out)):h.shrinkBuf(e.output,e.next_out))}while((e.avail_in>0||0===e.avail_out)&&c!==o);return d===m?(c=g.deflateEnd(this.strm),this.onEnd(c),this.ended=!0,c===n):!0},s.prototype.onData=function(a){this.chunks.push(a)},s.prototype.onEnd=function(a){a===n&&(this.result="string"===this.options.to?this.chunks.join(""):h.flattenChunks(this.chunks)),this.chunks=[],this.err=a,this.msg=this.strm.msg},c.Deflate=s,c.deflate=d,c.deflateRaw=e,c.gzip=f},{"./utils/common":27,"./utils/strings":28,"./zlib/deflate.js":32,"./zlib/messages":37,"./zlib/zstream":39}],26:[function(a,b,c){"use strict";function d(a,b){var c=new m(b);if(c.push(a,!0),c.err)throw c.msg;return c.result}function e(a,b){return b=b||{},b.raw=!0,d(a,b)}var f=a("./zlib/inflate.js"),g=a("./utils/common"),h=a("./utils/strings"),i=a("./zlib/constants"),j=a("./zlib/messages"),k=a("./zlib/zstream"),l=a("./zlib/gzheader"),m=function(a){this.options=g.assign({chunkSize:16384,windowBits:0,to:""},a||{});var b=this.options;b.raw&&b.windowBits>=0&&b.windowBits<16&&(b.windowBits=-b.windowBits,0===b.windowBits&&(b.windowBits=-15)),!(b.windowBits>=0&&b.windowBits<16)||a&&a.windowBits||(b.windowBits+=32),b.windowBits>15&&b.windowBits<48&&0===(15&b.windowBits)&&(b.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new k,this.strm.avail_out=0;var c=f.inflateInit2(this.strm,b.windowBits);if(c!==i.Z_OK)throw new Error(j[c]);this.header=new l,f.inflateGetHeader(this.strm,this.header)};m.prototype.push=function(a,b){var c,d,e,j,k,l=this.strm,m=this.options.chunkSize;if(this.ended)return!1;d=b===~~b?b:b===!0?i.Z_FINISH:i.Z_NO_FLUSH,l.input="string"==typeof a?h.binstring2buf(a):a,l.next_in=0,l.avail_in=l.input.length;do{if(0===l.avail_out&&(l.output=new g.Buf8(m),l.next_out=0,l.avail_out=m),c=f.inflate(l,i.Z_NO_FLUSH),c!==i.Z_STREAM_END&&c!==i.Z_OK)return this.onEnd(c),this.ended=!0,!1;l.next_out&&(0===l.avail_out||c===i.Z_STREAM_END||0===l.avail_in&&d===i.Z_FINISH)&&("string"===this.options.to?(e=h.utf8border(l.output,l.next_out),j=l.next_out-e,k=h.buf2string(l.output,e),l.next_out=j,l.avail_out=m-j,j&&g.arraySet(l.output,l.output,e,j,0),this.onData(k)):this.onData(g.shrinkBuf(l.output,l.next_out)))}while(l.avail_in>0&&c!==i.Z_STREAM_END);return c===i.Z_STREAM_END&&(d=i.Z_FINISH),d===i.Z_FINISH?(c=f.inflateEnd(this.strm),this.onEnd(c),this.ended=!0,c===i.Z_OK):!0},m.prototype.onData=function(a){this.chunks.push(a)},m.prototype.onEnd=function(a){a===i.Z_OK&&(this.result="string"===this.options.to?this.chunks.join(""):g.flattenChunks(this.chunks)),this.chunks=[],this.err=a,this.msg=this.strm.msg},c.Inflate=m,c.inflate=d,c.inflateRaw=e,c.ungzip=d},{"./utils/common":27,"./utils/strings":28,"./zlib/constants":30,"./zlib/gzheader":33,"./zlib/inflate.js":35,"./zlib/messages":37,"./zlib/zstream":39}],27:[function(a,b,c){"use strict";var d="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;c.assign=function(a){for(var b=Array.prototype.slice.call(arguments,1);b.length;){var c=b.shift();if(c){if("object"!=typeof c)throw new TypeError(c+"must be non-object");for(var d in c)c.hasOwnProperty(d)&&(a[d]=c[d])}}return a},c.shrinkBuf=function(a,b){return a.length===b?a:a.subarray?a.subarray(0,b):(a.length=b,a)};var e={arraySet:function(a,b,c,d,e){if(b.subarray&&a.subarray)return void a.set(b.subarray(c,c+d),e);for(var f=0;d>f;f++)a[e+f]=b[c+f]},flattenChunks:function(a){var b,c,d,e,f,g;for(d=0,b=0,c=a.length;c>b;b++)d+=a[b].length;for(g=new Uint8Array(d),e=0,b=0,c=a.length;c>b;b++)f=a[b],g.set(f,e),e+=f.length;return g}},f={arraySet:function(a,b,c,d,e){for(var f=0;d>f;f++)a[e+f]=b[c+f]},flattenChunks:function(a){return[].concat.apply([],a)}};c.setTyped=function(a){a?(c.Buf8=Uint8Array,c.Buf16=Uint16Array,c.Buf32=Int32Array,c.assign(c,e)):(c.Buf8=Array,c.Buf16=Array,c.Buf32=Array,c.assign(c,f))},c.setTyped(d)},{}],28:[function(a,b,c){"use strict";function d(a,b){if(65537>b&&(a.subarray&&g||!a.subarray&&f))return String.fromCharCode.apply(null,e.shrinkBuf(a,b));for(var c="",d=0;b>d;d++)c+=String.fromCharCode(a[d]);return c}var e=a("./common"),f=!0,g=!0;try{String.fromCharCode.apply(null,[0])}catch(h){f=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(h){g=!1}for(var i=new e.Buf8(256),j=0;256>j;j++)i[j]=j>=252?6:j>=248?5:j>=240?4:j>=224?3:j>=192?2:1;i[254]=i[254]=1,c.string2buf=function(a){var b,c,d,f,g,h=a.length,i=0;for(f=0;h>f;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),i+=128>c?1:2048>c?2:65536>c?3:4;for(b=new e.Buf8(i),g=0,f=0;i>g;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),128>c?b[g++]=c:2048>c?(b[g++]=192|c>>>6,b[g++]=128|63&c):65536>c?(b[g++]=224|c>>>12,b[g++]=128|c>>>6&63,b[g++]=128|63&c):(b[g++]=240|c>>>18,b[g++]=128|c>>>12&63,b[g++]=128|c>>>6&63,b[g++]=128|63&c);return b},c.buf2binstring=function(a){return d(a,a.length)},c.binstring2buf=function(a){for(var b=new e.Buf8(a.length),c=0,d=b.length;d>c;c++)b[c]=a.charCodeAt(c);return b},c.buf2string=function(a,b){var c,e,f,g,h=b||a.length,j=new Array(2*h);for(e=0,c=0;h>c;)if(f=a[c++],128>f)j[e++]=f;else if(g=i[f],g>4)j[e++]=65533,c+=g-1;else{for(f&=2===g?31:3===g?15:7;g>1&&h>c;)f=f<<6|63&a[c++],g--;g>1?j[e++]=65533:65536>f?j[e++]=f:(f-=65536,j[e++]=55296|f>>10&1023,j[e++]=56320|1023&f)}return d(j,e)},c.utf8border=function(a,b){var c;for(b=b||a.length,b>a.length&&(b=a.length),c=b-1;c>=0&&128===(192&a[c]);)c--;return 0>c?b:0===c?b:c+i[a[c]]>b?c:b}},{"./common":27}],29:[function(a,b){"use strict";function c(a,b,c,d){for(var e=65535&a|0,f=a>>>16&65535|0,g=0;0!==c;){g=c>2e3?2e3:c,c-=g;do e=e+b[d++]|0,f=f+e|0;while(--g);e%=65521,f%=65521}return e|f<<16|0}b.exports=c},{}],30:[function(a,b){b.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},{}],31:[function(a,b){"use strict";function c(){for(var a,b=[],c=0;256>c;c++){a=c;for(var d=0;8>d;d++)a=1&a?3988292384^a>>>1:a>>>1;b[c]=a}return b}function d(a,b,c,d){var f=e,g=d+c;a=-1^a;for(var h=d;g>h;h++)a=a>>>8^f[255&(a^b[h])];return-1^a}var e=c();b.exports=d},{}],32:[function(a,b,c){"use strict";function d(a,b){return a.msg=G[b],b}function e(a){return(a<<1)-(a>4?9:0)}function f(a){for(var b=a.length;--b>=0;)a[b]=0}function g(a){var b=a.state,c=b.pending;c>a.avail_out&&(c=a.avail_out),0!==c&&(C.arraySet(a.output,b.pending_buf,b.pending_out,c,a.next_out),a.next_out+=c,b.pending_out+=c,a.total_out+=c,a.avail_out-=c,b.pending-=c,0===b.pending&&(b.pending_out=0))}function h(a,b){D._tr_flush_block(a,a.block_start>=0?a.block_start:-1,a.strstart-a.block_start,b),a.block_start=a.strstart,g(a.strm)}function i(a,b){a.pending_buf[a.pending++]=b}function j(a,b){a.pending_buf[a.pending++]=b>>>8&255,a.pending_buf[a.pending++]=255&b}function k(a,b,c,d){var e=a.avail_in;return e>d&&(e=d),0===e?0:(a.avail_in-=e,C.arraySet(b,a.input,a.next_in,e,c),1===a.state.wrap?a.adler=E(a.adler,b,e,c):2===a.state.wrap&&(a.adler=F(a.adler,b,e,c)),a.next_in+=e,a.total_in+=e,e)}function l(a,b){var c,d,e=a.max_chain_length,f=a.strstart,g=a.prev_length,h=a.nice_match,i=a.strstart>a.w_size-jb?a.strstart-(a.w_size-jb):0,j=a.window,k=a.w_mask,l=a.prev,m=a.strstart+ib,n=j[f+g-1],o=j[f+g];a.prev_length>=a.good_match&&(e>>=2),h>a.lookahead&&(h=a.lookahead);do if(c=b,j[c+g]===o&&j[c+g-1]===n&&j[c]===j[f]&&j[++c]===j[f+1]){f+=2,c++;do;while(j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&m>f);if(d=ib-(m-f),f=m-ib,d>g){if(a.match_start=b,g=d,d>=h)break;n=j[f+g-1],o=j[f+g]}}while((b=l[b&k])>i&&0!==--e);return g<=a.lookahead?g:a.lookahead}function m(a){var b,c,d,e,f,g=a.w_size;do{if(e=a.window_size-a.lookahead-a.strstart,a.strstart>=g+(g-jb)){C.arraySet(a.window,a.window,g,g,0),a.match_start-=g,a.strstart-=g,a.block_start-=g,c=a.hash_size,b=c;do d=a.head[--b],a.head[b]=d>=g?d-g:0;while(--c);c=g,b=c;do d=a.prev[--b],a.prev[b]=d>=g?d-g:0;while(--c);e+=g}if(0===a.strm.avail_in)break;if(c=k(a.strm,a.window,a.strstart+a.lookahead,e),a.lookahead+=c,a.lookahead+a.insert>=hb)for(f=a.strstart-a.insert,a.ins_h=a.window[f],a.ins_h=(a.ins_h<<a.hash_shift^a.window[f+1])&a.hash_mask;a.insert&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[f+hb-1])&a.hash_mask,a.prev[f&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=f,f++,a.insert--,!(a.lookahead+a.insert<hb)););}while(a.lookahead<jb&&0!==a.strm.avail_in)}function n(a,b){var c=65535;for(c>a.pending_buf_size-5&&(c=a.pending_buf_size-5);;){if(a.lookahead<=1){if(m(a),0===a.lookahead&&b===H)return sb;if(0===a.lookahead)break}a.strstart+=a.lookahead,a.lookahead=0;var d=a.block_start+c;if((0===a.strstart||a.strstart>=d)&&(a.lookahead=a.strstart-d,a.strstart=d,h(a,!1),0===a.strm.avail_out))return sb;if(a.strstart-a.block_start>=a.w_size-jb&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.strstart>a.block_start&&(h(a,!1),0===a.strm.avail_out)?sb:sb}function o(a,b){for(var c,d;;){if(a.lookahead<jb){if(m(a),a.lookahead<jb&&b===H)return sb;if(0===a.lookahead)break}if(c=0,a.lookahead>=hb&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart),0!==c&&a.strstart-c<=a.w_size-jb&&(a.match_length=l(a,c)),a.match_length>=hb)if(d=D._tr_tally(a,a.strstart-a.match_start,a.match_length-hb),a.lookahead-=a.match_length,a.match_length<=a.max_lazy_match&&a.lookahead>=hb){a.match_length--;do a.strstart++,a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart;while(0!==--a.match_length);a.strstart++}else a.strstart+=a.match_length,a.match_length=0,a.ins_h=a.window[a.strstart],a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+1])&a.hash_mask;else d=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++;if(d&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=a.strstart<hb-1?a.strstart:hb-1,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function p(a,b){for(var c,d,e;;){if(a.lookahead<jb){if(m(a),a.lookahead<jb&&b===H)return sb;if(0===a.lookahead)break}if(c=0,a.lookahead>=hb&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart),a.prev_length=a.match_length,a.prev_match=a.match_start,a.match_length=hb-1,0!==c&&a.prev_length<a.max_lazy_match&&a.strstart-c<=a.w_size-jb&&(a.match_length=l(a,c),a.match_length<=5&&(a.strategy===S||a.match_length===hb&&a.strstart-a.match_start>4096)&&(a.match_length=hb-1)),a.prev_length>=hb&&a.match_length<=a.prev_length){e=a.strstart+a.lookahead-hb,d=D._tr_tally(a,a.strstart-1-a.prev_match,a.prev_length-hb),a.lookahead-=a.prev_length-1,a.prev_length-=2;do++a.strstart<=e&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart);while(0!==--a.prev_length);if(a.match_available=0,a.match_length=hb-1,a.strstart++,d&&(h(a,!1),0===a.strm.avail_out))return sb}else if(a.match_available){if(d=D._tr_tally(a,0,a.window[a.strstart-1]),d&&h(a,!1),a.strstart++,a.lookahead--,0===a.strm.avail_out)return sb}else a.match_available=1,a.strstart++,a.lookahead--}return a.match_available&&(d=D._tr_tally(a,0,a.window[a.strstart-1]),a.match_available=0),a.insert=a.strstart<hb-1?a.strstart:hb-1,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function q(a,b){for(var c,d,e,f,g=a.window;;){if(a.lookahead<=ib){if(m(a),a.lookahead<=ib&&b===H)return sb;if(0===a.lookahead)break}if(a.match_length=0,a.lookahead>=hb&&a.strstart>0&&(e=a.strstart-1,d=g[e],d===g[++e]&&d===g[++e]&&d===g[++e])){f=a.strstart+ib;do;while(d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&f>e);a.match_length=ib-(f-e),a.match_length>a.lookahead&&(a.match_length=a.lookahead)}if(a.match_length>=hb?(c=D._tr_tally(a,1,a.match_length-hb),a.lookahead-=a.match_length,a.strstart+=a.match_length,a.match_length=0):(c=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++),c&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function r(a,b){for(var c;;){if(0===a.lookahead&&(m(a),0===a.lookahead)){if(b===H)return sb;break}if(a.match_length=0,c=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++,c&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function s(a){a.window_size=2*a.w_size,f(a.head),a.max_lazy_match=B[a.level].max_lazy,a.good_match=B[a.level].good_length,a.nice_match=B[a.level].nice_length,a.max_chain_length=B[a.level].max_chain,a.strstart=0,a.block_start=0,a.lookahead=0,a.insert=0,a.match_length=a.prev_length=hb-1,a.match_available=0,a.ins_h=0}function t(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=Y,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new C.Buf16(2*fb),this.dyn_dtree=new C.Buf16(2*(2*db+1)),this.bl_tree=new C.Buf16(2*(2*eb+1)),f(this.dyn_ltree),f(this.dyn_dtree),f(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new C.Buf16(gb+1),this.heap=new C.Buf16(2*cb+1),f(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new C.Buf16(2*cb+1),f(this.depth),this.l_buf=0,this.lit_bufsize=0,this.last_lit=0,this.d_buf=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}function u(a){var b;return a&&a.state?(a.total_in=a.total_out=0,a.data_type=X,b=a.state,b.pending=0,b.pending_out=0,b.wrap<0&&(b.wrap=-b.wrap),b.status=b.wrap?lb:qb,a.adler=2===b.wrap?0:1,b.last_flush=H,D._tr_init(b),M):d(a,O)}function v(a){var b=u(a);return b===M&&s(a.state),b}function w(a,b){return a&&a.state?2!==a.state.wrap?O:(a.state.gzhead=b,M):O}function x(a,b,c,e,f,g){if(!a)return O;var h=1;if(b===R&&(b=6),0>e?(h=0,e=-e):e>15&&(h=2,e-=16),1>f||f>Z||c!==Y||8>e||e>15||0>b||b>9||0>g||g>V)return d(a,O);8===e&&(e=9);var i=new t;return a.state=i,i.strm=a,i.wrap=h,i.gzhead=null,i.w_bits=e,i.w_size=1<<i.w_bits,i.w_mask=i.w_size-1,i.hash_bits=f+7,i.hash_size=1<<i.hash_bits,i.hash_mask=i.hash_size-1,i.hash_shift=~~((i.hash_bits+hb-1)/hb),i.window=new C.Buf8(2*i.w_size),i.head=new C.Buf16(i.hash_size),i.prev=new C.Buf16(i.w_size),i.lit_bufsize=1<<f+6,i.pending_buf_size=4*i.lit_bufsize,i.pending_buf=new C.Buf8(i.pending_buf_size),i.d_buf=i.lit_bufsize>>1,i.l_buf=3*i.lit_bufsize,i.level=b,i.strategy=g,i.method=c,v(a)}function y(a,b){return x(a,b,Y,$,_,W)}function z(a,b){var c,h,k,l;if(!a||!a.state||b>L||0>b)return a?d(a,O):O;if(h=a.state,!a.output||!a.input&&0!==a.avail_in||h.status===rb&&b!==K)return d(a,0===a.avail_out?Q:O);if(h.strm=a,c=h.last_flush,h.last_flush=b,h.status===lb)if(2===h.wrap)a.adler=0,i(h,31),i(h,139),i(h,8),h.gzhead?(i(h,(h.gzhead.text?1:0)+(h.gzhead.hcrc?2:0)+(h.gzhead.extra?4:0)+(h.gzhead.name?8:0)+(h.gzhead.comment?16:0)),i(h,255&h.gzhead.time),i(h,h.gzhead.time>>8&255),i(h,h.gzhead.time>>16&255),i(h,h.gzhead.time>>24&255),i(h,9===h.level?2:h.strategy>=T||h.level<2?4:0),i(h,255&h.gzhead.os),h.gzhead.extra&&h.gzhead.extra.length&&(i(h,255&h.gzhead.extra.length),i(h,h.gzhead.extra.length>>8&255)),h.gzhead.hcrc&&(a.adler=F(a.adler,h.pending_buf,h.pending,0)),h.gzindex=0,h.status=mb):(i(h,0),i(h,0),i(h,0),i(h,0),i(h,0),i(h,9===h.level?2:h.strategy>=T||h.level<2?4:0),i(h,wb),h.status=qb);else{var m=Y+(h.w_bits-8<<4)<<8,n=-1;n=h.strategy>=T||h.level<2?0:h.level<6?1:6===h.level?2:3,m|=n<<6,0!==h.strstart&&(m|=kb),m+=31-m%31,h.status=qb,j(h,m),0!==h.strstart&&(j(h,a.adler>>>16),j(h,65535&a.adler)),a.adler=1}if(h.status===mb)if(h.gzhead.extra){for(k=h.pending;h.gzindex<(65535&h.gzhead.extra.length)&&(h.pending!==h.pending_buf_size||(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending!==h.pending_buf_size));)i(h,255&h.gzhead.extra[h.gzindex]),h.gzindex++;h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),h.gzindex===h.gzhead.extra.length&&(h.gzindex=0,h.status=nb)}else h.status=nb;if(h.status===nb)if(h.gzhead.name){k=h.pending;do{if(h.pending===h.pending_buf_size&&(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending===h.pending_buf_size)){l=1;break}l=h.gzindex<h.gzhead.name.length?255&h.gzhead.name.charCodeAt(h.gzindex++):0,i(h,l)}while(0!==l);h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),0===l&&(h.gzindex=0,h.status=ob)}else h.status=ob;if(h.status===ob)if(h.gzhead.comment){k=h.pending;do{if(h.pending===h.pending_buf_size&&(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending===h.pending_buf_size)){l=1;break}l=h.gzindex<h.gzhead.comment.length?255&h.gzhead.comment.charCodeAt(h.gzindex++):0,i(h,l)}while(0!==l);h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),0===l&&(h.status=pb)}else h.status=pb;if(h.status===pb&&(h.gzhead.hcrc?(h.pending+2>h.pending_buf_size&&g(a),h.pending+2<=h.pending_buf_size&&(i(h,255&a.adler),i(h,a.adler>>8&255),a.adler=0,h.status=qb)):h.status=qb),0!==h.pending){if(g(a),0===a.avail_out)return h.last_flush=-1,M}else if(0===a.avail_in&&e(b)<=e(c)&&b!==K)return d(a,Q);if(h.status===rb&&0!==a.avail_in)return d(a,Q);if(0!==a.avail_in||0!==h.lookahead||b!==H&&h.status!==rb){var o=h.strategy===T?r(h,b):h.strategy===U?q(h,b):B[h.level].func(h,b);if((o===ub||o===vb)&&(h.status=rb),o===sb||o===ub)return 0===a.avail_out&&(h.last_flush=-1),M;if(o===tb&&(b===I?D._tr_align(h):b!==L&&(D._tr_stored_block(h,0,0,!1),b===J&&(f(h.head),0===h.lookahead&&(h.strstart=0,h.block_start=0,h.insert=0))),g(a),0===a.avail_out))return h.last_flush=-1,M}return b!==K?M:h.wrap<=0?N:(2===h.wrap?(i(h,255&a.adler),i(h,a.adler>>8&255),i(h,a.adler>>16&255),i(h,a.adler>>24&255),i(h,255&a.total_in),i(h,a.total_in>>8&255),i(h,a.total_in>>16&255),i(h,a.total_in>>24&255)):(j(h,a.adler>>>16),j(h,65535&a.adler)),g(a),h.wrap>0&&(h.wrap=-h.wrap),0!==h.pending?M:N)}function A(a){var b;return a&&a.state?(b=a.state.status,b!==lb&&b!==mb&&b!==nb&&b!==ob&&b!==pb&&b!==qb&&b!==rb?d(a,O):(a.state=null,b===qb?d(a,P):M)):O}var B,C=a("../utils/common"),D=a("./trees"),E=a("./adler32"),F=a("./crc32"),G=a("./messages"),H=0,I=1,J=3,K=4,L=5,M=0,N=1,O=-2,P=-3,Q=-5,R=-1,S=1,T=2,U=3,V=4,W=0,X=2,Y=8,Z=9,$=15,_=8,ab=29,bb=256,cb=bb+1+ab,db=30,eb=19,fb=2*cb+1,gb=15,hb=3,ib=258,jb=ib+hb+1,kb=32,lb=42,mb=69,nb=73,ob=91,pb=103,qb=113,rb=666,sb=1,tb=2,ub=3,vb=4,wb=3,xb=function(a,b,c,d,e){this.good_length=a,this.max_lazy=b,this.nice_length=c,this.max_chain=d,this.func=e};B=[new xb(0,0,0,0,n),new xb(4,4,8,4,o),new xb(4,5,16,8,o),new xb(4,6,32,32,o),new xb(4,4,16,16,p),new xb(8,16,32,32,p),new xb(8,16,128,128,p),new xb(8,32,128,256,p),new xb(32,128,258,1024,p),new xb(32,258,258,4096,p)],c.deflateInit=y,c.deflateInit2=x,c.deflateReset=v,c.deflateResetKeep=u,c.deflateSetHeader=w,c.deflate=z,c.deflateEnd=A,c.deflateInfo="pako deflate (from Nodeca project)"},{"../utils/common":27,"./adler32":29,"./crc32":31,"./messages":37,"./trees":38}],33:[function(a,b){"use strict";function c(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}b.exports=c},{}],34:[function(a,b){"use strict";var c=30,d=12;b.exports=function(a,b){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C;e=a.state,f=a.next_in,B=a.input,g=f+(a.avail_in-5),h=a.next_out,C=a.output,i=h-(b-a.avail_out),j=h+(a.avail_out-257),k=e.dmax,l=e.wsize,m=e.whave,n=e.wnext,o=e.window,p=e.hold,q=e.bits,r=e.lencode,s=e.distcode,t=(1<<e.lenbits)-1,u=(1<<e.distbits)-1;a:do{15>q&&(p+=B[f++]<<q,q+=8,p+=B[f++]<<q,q+=8),v=r[p&t];b:for(;;){if(w=v>>>24,p>>>=w,q-=w,w=v>>>16&255,0===w)C[h++]=65535&v;else{if(!(16&w)){if(0===(64&w)){v=r[(65535&v)+(p&(1<<w)-1)];continue b}if(32&w){e.mode=d;break a}a.msg="invalid literal/length code",e.mode=c;break a}x=65535&v,w&=15,w&&(w>q&&(p+=B[f++]<<q,q+=8),x+=p&(1<<w)-1,p>>>=w,q-=w),15>q&&(p+=B[f++]<<q,q+=8,p+=B[f++]<<q,q+=8),v=s[p&u];c:for(;;){if(w=v>>>24,p>>>=w,q-=w,w=v>>>16&255,!(16&w)){if(0===(64&w)){v=s[(65535&v)+(p&(1<<w)-1)];continue c}a.msg="invalid distance code",e.mode=c;break a}if(y=65535&v,w&=15,w>q&&(p+=B[f++]<<q,q+=8,w>q&&(p+=B[f++]<<q,q+=8)),y+=p&(1<<w)-1,y>k){a.msg="invalid distance too far back",e.mode=c;break a}if(p>>>=w,q-=w,w=h-i,y>w){if(w=y-w,w>m&&e.sane){a.msg="invalid distance too far back",e.mode=c;break a}if(z=0,A=o,0===n){if(z+=l-w,x>w){x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}}else if(w>n){if(z+=l+n-w,w-=n,x>w){x-=w;do C[h++]=o[z++];while(--w);if(z=0,x>n){w=n,x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}}}else if(z+=n-w,x>w){x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}for(;x>2;)C[h++]=A[z++],C[h++]=A[z++],C[h++]=A[z++],x-=3;x&&(C[h++]=A[z++],x>1&&(C[h++]=A[z++]))}else{z=h-y;do C[h++]=C[z++],C[h++]=C[z++],C[h++]=C[z++],x-=3;while(x>2);x&&(C[h++]=C[z++],x>1&&(C[h++]=C[z++]))}break}}break}}while(g>f&&j>h);x=q>>3,f-=x,q-=x<<3,p&=(1<<q)-1,a.next_in=f,a.next_out=h,a.avail_in=g>f?5+(g-f):5-(f-g),a.avail_out=j>h?257+(j-h):257-(h-j),e.hold=p,e.bits=q}},{}],35:[function(a,b,c){"use strict";function d(a){return(a>>>24&255)+(a>>>8&65280)+((65280&a)<<8)+((255&a)<<24)}function e(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new r.Buf16(320),this.work=new r.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function f(a){var b;return a&&a.state?(b=a.state,a.total_in=a.total_out=b.total=0,a.msg="",b.wrap&&(a.adler=1&b.wrap),b.mode=K,b.last=0,b.havedict=0,b.dmax=32768,b.head=null,b.hold=0,b.bits=0,b.lencode=b.lendyn=new r.Buf32(ob),b.distcode=b.distdyn=new r.Buf32(pb),b.sane=1,b.back=-1,C):F}function g(a){var b;return a&&a.state?(b=a.state,b.wsize=0,b.whave=0,b.wnext=0,f(a)):F}function h(a,b){var c,d;return a&&a.state?(d=a.state,0>b?(c=0,b=-b):(c=(b>>4)+1,48>b&&(b&=15)),b&&(8>b||b>15)?F:(null!==d.window&&d.wbits!==b&&(d.window=null),d.wrap=c,d.wbits=b,g(a))):F}function i(a,b){var c,d;return a?(d=new e,a.state=d,d.window=null,c=h(a,b),c!==C&&(a.state=null),c):F}function j(a){return i(a,rb)}function k(a){if(sb){var b;for(p=new r.Buf32(512),q=new r.Buf32(32),b=0;144>b;)a.lens[b++]=8;for(;256>b;)a.lens[b++]=9;for(;280>b;)a.lens[b++]=7;for(;288>b;)a.lens[b++]=8;for(v(x,a.lens,0,288,p,0,a.work,{bits:9}),b=0;32>b;)a.lens[b++]=5;v(y,a.lens,0,32,q,0,a.work,{bits:5}),sb=!1}a.lencode=p,a.lenbits=9,a.distcode=q,a.distbits=5}function l(a,b,c,d){var e,f=a.state;return null===f.window&&(f.wsize=1<<f.wbits,f.wnext=0,f.whave=0,f.window=new r.Buf8(f.wsize)),d>=f.wsize?(r.arraySet(f.window,b,c-f.wsize,f.wsize,0),f.wnext=0,f.whave=f.wsize):(e=f.wsize-f.wnext,e>d&&(e=d),r.arraySet(f.window,b,c-d,e,f.wnext),d-=e,d?(r.arraySet(f.window,b,c-d,d,0),f.wnext=d,f.whave=f.wsize):(f.wnext+=e,f.wnext===f.wsize&&(f.wnext=0),f.whave<f.wsize&&(f.whave+=e))),0}function m(a,b){var c,e,f,g,h,i,j,m,n,o,p,q,ob,pb,qb,rb,sb,tb,ub,vb,wb,xb,yb,zb,Ab=0,Bb=new r.Buf8(4),Cb=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];if(!a||!a.state||!a.output||!a.input&&0!==a.avail_in)return F;c=a.state,c.mode===V&&(c.mode=W),h=a.next_out,f=a.output,j=a.avail_out,g=a.next_in,e=a.input,i=a.avail_in,m=c.hold,n=c.bits,o=i,p=j,xb=C;a:for(;;)switch(c.mode){case K:if(0===c.wrap){c.mode=W;break}for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(2&c.wrap&&35615===m){c.check=0,Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0),m=0,n=0,c.mode=L;break}if(c.flags=0,c.head&&(c.head.done=!1),!(1&c.wrap)||(((255&m)<<8)+(m>>8))%31){a.msg="incorrect header check",c.mode=lb;break}if((15&m)!==J){a.msg="unknown compression method",c.mode=lb;break}if(m>>>=4,n-=4,wb=(15&m)+8,0===c.wbits)c.wbits=wb;else if(wb>c.wbits){a.msg="invalid window size",c.mode=lb;break}c.dmax=1<<wb,a.adler=c.check=1,c.mode=512&m?T:V,m=0,n=0;break;case L:for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(c.flags=m,(255&c.flags)!==J){a.msg="unknown compression method",c.mode=lb;break}if(57344&c.flags){a.msg="unknown header flags set",c.mode=lb;break}c.head&&(c.head.text=m>>8&1),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0,c.mode=M;case M:for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.head&&(c.head.time=m),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,Bb[2]=m>>>16&255,Bb[3]=m>>>24&255,c.check=t(c.check,Bb,4,0)),m=0,n=0,c.mode=N;case N:for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.head&&(c.head.xflags=255&m,c.head.os=m>>8),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0,c.mode=O;case O:if(1024&c.flags){for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.length=m,c.head&&(c.head.extra_len=m),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0}else c.head&&(c.head.extra=null);c.mode=P;case P:if(1024&c.flags&&(q=c.length,q>i&&(q=i),q&&(c.head&&(wb=c.head.extra_len-c.length,c.head.extra||(c.head.extra=new Array(c.head.extra_len)),r.arraySet(c.head.extra,e,g,q,wb)),512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,c.length-=q),c.length))break a;c.length=0,c.mode=Q;case Q:if(2048&c.flags){if(0===i)break a;q=0;do wb=e[g+q++],c.head&&wb&&c.length<65536&&(c.head.name+=String.fromCharCode(wb));while(wb&&i>q);if(512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,wb)break a}else c.head&&(c.head.name=null);c.length=0,c.mode=R;case R:if(4096&c.flags){if(0===i)break a;q=0;do wb=e[g+q++],c.head&&wb&&c.length<65536&&(c.head.comment+=String.fromCharCode(wb));while(wb&&i>q);if(512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,wb)break a}else c.head&&(c.head.comment=null);c.mode=S;case S:if(512&c.flags){for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m!==(65535&c.check)){a.msg="header crc mismatch",c.mode=lb;break}m=0,n=0}c.head&&(c.head.hcrc=c.flags>>9&1,c.head.done=!0),a.adler=c.check=0,c.mode=V;break;case T:for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}a.adler=c.check=d(m),m=0,n=0,c.mode=U;case U:if(0===c.havedict)return a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,E;a.adler=c.check=1,c.mode=V;case V:if(b===A||b===B)break a;case W:if(c.last){m>>>=7&n,n-=7&n,c.mode=ib;break}for(;3>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}switch(c.last=1&m,m>>>=1,n-=1,3&m){case 0:c.mode=X;break;case 1:if(k(c),c.mode=bb,b===B){m>>>=2,n-=2;break a}break;case 2:c.mode=$;break;case 3:a.msg="invalid block type",c.mode=lb}m>>>=2,n-=2;break;case X:for(m>>>=7&n,n-=7&n;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if((65535&m)!==(m>>>16^65535)){a.msg="invalid stored block lengths",c.mode=lb;break}if(c.length=65535&m,m=0,n=0,c.mode=Y,b===B)break a;case Y:c.mode=Z;case Z:if(q=c.length){if(q>i&&(q=i),q>j&&(q=j),0===q)break a;r.arraySet(f,e,g,q,h),i-=q,g+=q,j-=q,h+=q,c.length-=q;break}c.mode=V;break;case $:for(;14>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(c.nlen=(31&m)+257,m>>>=5,n-=5,c.ndist=(31&m)+1,m>>>=5,n-=5,c.ncode=(15&m)+4,m>>>=4,n-=4,c.nlen>286||c.ndist>30){a.msg="too many length or distance symbols",c.mode=lb;break}c.have=0,c.mode=_;case _:for(;c.have<c.ncode;){for(;3>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.lens[Cb[c.have++]]=7&m,m>>>=3,n-=3}for(;c.have<19;)c.lens[Cb[c.have++]]=0;if(c.lencode=c.lendyn,c.lenbits=7,yb={bits:c.lenbits},xb=v(w,c.lens,0,19,c.lencode,0,c.work,yb),c.lenbits=yb.bits,xb){a.msg="invalid code lengths set",c.mode=lb;break}c.have=0,c.mode=ab;case ab:for(;c.have<c.nlen+c.ndist;){for(;Ab=c.lencode[m&(1<<c.lenbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(16>sb)m>>>=qb,n-=qb,c.lens[c.have++]=sb;else{if(16===sb){for(zb=qb+2;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m>>>=qb,n-=qb,0===c.have){a.msg="invalid bit length repeat",c.mode=lb;break}wb=c.lens[c.have-1],q=3+(3&m),m>>>=2,n-=2}else if(17===sb){for(zb=qb+3;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=qb,n-=qb,wb=0,q=3+(7&m),m>>>=3,n-=3}else{for(zb=qb+7;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=qb,n-=qb,wb=0,q=11+(127&m),m>>>=7,n-=7}if(c.have+q>c.nlen+c.ndist){a.msg="invalid bit length repeat",c.mode=lb;break}for(;q--;)c.lens[c.have++]=wb}}if(c.mode===lb)break;if(0===c.lens[256]){a.msg="invalid code -- missing end-of-block",c.mode=lb;break}if(c.lenbits=9,yb={bits:c.lenbits},xb=v(x,c.lens,0,c.nlen,c.lencode,0,c.work,yb),c.lenbits=yb.bits,xb){a.msg="invalid literal/lengths set",c.mode=lb;break}if(c.distbits=6,c.distcode=c.distdyn,yb={bits:c.distbits},xb=v(y,c.lens,c.nlen,c.ndist,c.distcode,0,c.work,yb),c.distbits=yb.bits,xb){a.msg="invalid distances set",c.mode=lb;break}if(c.mode=bb,b===B)break a;case bb:c.mode=cb;case cb:if(i>=6&&j>=258){a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,u(a,p),h=a.next_out,f=a.output,j=a.avail_out,g=a.next_in,e=a.input,i=a.avail_in,m=c.hold,n=c.bits,c.mode===V&&(c.back=-1);break}for(c.back=0;Ab=c.lencode[m&(1<<c.lenbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(rb&&0===(240&rb)){for(tb=qb,ub=rb,vb=sb;Ab=c.lencode[vb+((m&(1<<tb+ub)-1)>>tb)],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=tb+qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=tb,n-=tb,c.back+=tb}if(m>>>=qb,n-=qb,c.back+=qb,c.length=sb,0===rb){c.mode=hb;break}if(32&rb){c.back=-1,c.mode=V;break}if(64&rb){a.msg="invalid literal/length code",c.mode=lb;break}c.extra=15&rb,c.mode=db;case db:if(c.extra){for(zb=c.extra;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.length+=m&(1<<c.extra)-1,m>>>=c.extra,n-=c.extra,c.back+=c.extra}c.was=c.length,c.mode=eb;case eb:for(;Ab=c.distcode[m&(1<<c.distbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(0===(240&rb)){for(tb=qb,ub=rb,vb=sb;Ab=c.distcode[vb+((m&(1<<tb+ub)-1)>>tb)],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=tb+qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=tb,n-=tb,c.back+=tb}if(m>>>=qb,n-=qb,c.back+=qb,64&rb){a.msg="invalid distance code",c.mode=lb;break}c.offset=sb,c.extra=15&rb,c.mode=fb;case fb:if(c.extra){for(zb=c.extra;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.offset+=m&(1<<c.extra)-1,m>>>=c.extra,n-=c.extra,c.back+=c.extra}if(c.offset>c.dmax){a.msg="invalid distance too far back",c.mode=lb;break}c.mode=gb;case gb:if(0===j)break a;if(q=p-j,c.offset>q){if(q=c.offset-q,q>c.whave&&c.sane){a.msg="invalid distance too far back",c.mode=lb;break}q>c.wnext?(q-=c.wnext,ob=c.wsize-q):ob=c.wnext-q,q>c.length&&(q=c.length),pb=c.window}else pb=f,ob=h-c.offset,q=c.length;q>j&&(q=j),j-=q,c.length-=q;do f[h++]=pb[ob++];while(--q);0===c.length&&(c.mode=cb);break;case hb:if(0===j)break a;f[h++]=c.length,j--,c.mode=cb;break;case ib:if(c.wrap){for(;32>n;){if(0===i)break a;i--,m|=e[g++]<<n,n+=8}if(p-=j,a.total_out+=p,c.total+=p,p&&(a.adler=c.check=c.flags?t(c.check,f,p,h-p):s(c.check,f,p,h-p)),p=j,(c.flags?m:d(m))!==c.check){a.msg="incorrect data check",c.mode=lb;break}m=0,n=0}c.mode=jb;case jb:if(c.wrap&&c.flags){for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m!==(4294967295&c.total)){a.msg="incorrect length check",c.mode=lb;break}m=0,n=0}c.mode=kb;case kb:xb=D;break a;case lb:xb=G;break a;case mb:return H;case nb:default:return F}return a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,(c.wsize||p!==a.avail_out&&c.mode<lb&&(c.mode<ib||b!==z))&&l(a,a.output,a.next_out,p-a.avail_out)?(c.mode=mb,H):(o-=a.avail_in,p-=a.avail_out,a.total_in+=o,a.total_out+=p,c.total+=p,c.wrap&&p&&(a.adler=c.check=c.flags?t(c.check,f,p,a.next_out-p):s(c.check,f,p,a.next_out-p)),a.data_type=c.bits+(c.last?64:0)+(c.mode===V?128:0)+(c.mode===bb||c.mode===Y?256:0),(0===o&&0===p||b===z)&&xb===C&&(xb=I),xb)}function n(a){if(!a||!a.state)return F;var b=a.state;return b.window&&(b.window=null),a.state=null,C}function o(a,b){var c;return a&&a.state?(c=a.state,0===(2&c.wrap)?F:(c.head=b,b.done=!1,C)):F}var p,q,r=a("../utils/common"),s=a("./adler32"),t=a("./crc32"),u=a("./inffast"),v=a("./inftrees"),w=0,x=1,y=2,z=4,A=5,B=6,C=0,D=1,E=2,F=-2,G=-3,H=-4,I=-5,J=8,K=1,L=2,M=3,N=4,O=5,P=6,Q=7,R=8,S=9,T=10,U=11,V=12,W=13,X=14,Y=15,Z=16,$=17,_=18,ab=19,bb=20,cb=21,db=22,eb=23,fb=24,gb=25,hb=26,ib=27,jb=28,kb=29,lb=30,mb=31,nb=32,ob=852,pb=592,qb=15,rb=qb,sb=!0;c.inflateReset=g,c.inflateReset2=h,c.inflateResetKeep=f,c.inflateInit=j,c.inflateInit2=i,c.inflate=m,c.inflateEnd=n,c.inflateGetHeader=o,c.inflateInfo="pako inflate (from Nodeca project)"},{"../utils/common":27,"./adler32":29,"./crc32":31,"./inffast":34,"./inftrees":36}],36:[function(a,b){"use strict";var c=a("../utils/common"),d=15,e=852,f=592,g=0,h=1,i=2,j=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],k=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],l=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],m=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];b.exports=function(a,b,n,o,p,q,r,s){var t,u,v,w,x,y,z,A,B,C=s.bits,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=null,O=0,P=new c.Buf16(d+1),Q=new c.Buf16(d+1),R=null,S=0;for(D=0;d>=D;D++)P[D]=0;for(E=0;o>E;E++)P[b[n+E]]++;for(H=C,G=d;G>=1&&0===P[G];G--);if(H>G&&(H=G),0===G)return p[q++]=20971520,p[q++]=20971520,s.bits=1,0;for(F=1;G>F&&0===P[F];F++);for(F>H&&(H=F),K=1,D=1;d>=D;D++)if(K<<=1,K-=P[D],0>K)return-1;if(K>0&&(a===g||1!==G))return-1;for(Q[1]=0,D=1;d>D;D++)Q[D+1]=Q[D]+P[D];for(E=0;o>E;E++)0!==b[n+E]&&(r[Q[b[n+E]]++]=E);if(a===g?(N=R=r,y=19):a===h?(N=j,O-=257,R=k,S-=257,y=256):(N=l,R=m,y=-1),M=0,E=0,D=F,x=q,I=H,J=0,v=-1,L=1<<H,w=L-1,a===h&&L>e||a===i&&L>f)return 1;for(var T=0;;){T++,z=D-J,r[E]<y?(A=0,B=r[E]):r[E]>y?(A=R[S+r[E]],B=N[O+r[E]]):(A=96,B=0),t=1<<D-J,u=1<<I,F=u;do u-=t,p[x+(M>>J)+u]=z<<24|A<<16|B|0;while(0!==u);for(t=1<<D-1;M&t;)t>>=1;if(0!==t?(M&=t-1,M+=t):M=0,E++,0===--P[D]){if(D===G)break;D=b[n+r[E]]}if(D>H&&(M&w)!==v){for(0===J&&(J=H),x+=F,I=D-J,K=1<<I;G>I+J&&(K-=P[I+J],!(0>=K));)I++,K<<=1;if(L+=1<<I,a===h&&L>e||a===i&&L>f)return 1;v=M&w,p[v]=H<<24|I<<16|x-q|0}}return 0!==M&&(p[x+M]=D-J<<24|64<<16|0),s.bits=H,0}},{"../utils/common":27}],37:[function(a,b){"use strict";b.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],38:[function(a,b,c){"use strict";function d(a){for(var b=a.length;--b>=0;)a[b]=0}function e(a){return 256>a?gb[a]:gb[256+(a>>>7)]}function f(a,b){a.pending_buf[a.pending++]=255&b,a.pending_buf[a.pending++]=b>>>8&255}function g(a,b,c){a.bi_valid>V-c?(a.bi_buf|=b<<a.bi_valid&65535,f(a,a.bi_buf),a.bi_buf=b>>V-a.bi_valid,a.bi_valid+=c-V):(a.bi_buf|=b<<a.bi_valid&65535,a.bi_valid+=c)}function h(a,b,c){g(a,c[2*b],c[2*b+1])}function i(a,b){var c=0;do c|=1&a,a>>>=1,c<<=1;while(--b>0);return c>>>1}function j(a){16===a.bi_valid?(f(a,a.bi_buf),a.bi_buf=0,a.bi_valid=0):a.bi_valid>=8&&(a.pending_buf[a.pending++]=255&a.bi_buf,a.bi_buf>>=8,a.bi_valid-=8)}function k(a,b){var c,d,e,f,g,h,i=b.dyn_tree,j=b.max_code,k=b.stat_desc.static_tree,l=b.stat_desc.has_stree,m=b.stat_desc.extra_bits,n=b.stat_desc.extra_base,o=b.stat_desc.max_length,p=0;for(f=0;U>=f;f++)a.bl_count[f]=0;for(i[2*a.heap[a.heap_max]+1]=0,c=a.heap_max+1;T>c;c++)d=a.heap[c],f=i[2*i[2*d+1]+1]+1,f>o&&(f=o,p++),i[2*d+1]=f,d>j||(a.bl_count[f]++,g=0,d>=n&&(g=m[d-n]),h=i[2*d],a.opt_len+=h*(f+g),l&&(a.static_len+=h*(k[2*d+1]+g)));if(0!==p){do{for(f=o-1;0===a.bl_count[f];)f--;a.bl_count[f]--,a.bl_count[f+1]+=2,a.bl_count[o]--,p-=2}while(p>0);for(f=o;0!==f;f--)for(d=a.bl_count[f];0!==d;)e=a.heap[--c],e>j||(i[2*e+1]!==f&&(a.opt_len+=(f-i[2*e+1])*i[2*e],i[2*e+1]=f),d--)}}function l(a,b,c){var d,e,f=new Array(U+1),g=0;for(d=1;U>=d;d++)f[d]=g=g+c[d-1]<<1;for(e=0;b>=e;e++){var h=a[2*e+1];0!==h&&(a[2*e]=i(f[h]++,h))}}function m(){var a,b,c,d,e,f=new Array(U+1);for(c=0,d=0;O-1>d;d++)for(ib[d]=c,a=0;a<1<<_[d];a++)hb[c++]=d;for(hb[c-1]=d,e=0,d=0;16>d;d++)for(jb[d]=e,a=0;a<1<<ab[d];a++)gb[e++]=d;for(e>>=7;R>d;d++)for(jb[d]=e<<7,a=0;a<1<<ab[d]-7;a++)gb[256+e++]=d;for(b=0;U>=b;b++)f[b]=0;for(a=0;143>=a;)eb[2*a+1]=8,a++,f[8]++;for(;255>=a;)eb[2*a+1]=9,a++,f[9]++;for(;279>=a;)eb[2*a+1]=7,a++,f[7]++;for(;287>=a;)eb[2*a+1]=8,a++,f[8]++;for(l(eb,Q+1,f),a=0;R>a;a++)fb[2*a+1]=5,fb[2*a]=i(a,5);kb=new nb(eb,_,P+1,Q,U),lb=new nb(fb,ab,0,R,U),mb=new nb(new Array(0),bb,0,S,W)}function n(a){var b;for(b=0;Q>b;b++)a.dyn_ltree[2*b]=0;for(b=0;R>b;b++)a.dyn_dtree[2*b]=0;for(b=0;S>b;b++)a.bl_tree[2*b]=0;a.dyn_ltree[2*X]=1,a.opt_len=a.static_len=0,a.last_lit=a.matches=0}function o(a){a.bi_valid>8?f(a,a.bi_buf):a.bi_valid>0&&(a.pending_buf[a.pending++]=a.bi_buf),a.bi_buf=0,a.bi_valid=0}function p(a,b,c,d){o(a),d&&(f(a,c),f(a,~c)),E.arraySet(a.pending_buf,a.window,b,c,a.pending),a.pending+=c}function q(a,b,c,d){var e=2*b,f=2*c;return a[e]<a[f]||a[e]===a[f]&&d[b]<=d[c]}function r(a,b,c){for(var d=a.heap[c],e=c<<1;e<=a.heap_len&&(e<a.heap_len&&q(b,a.heap[e+1],a.heap[e],a.depth)&&e++,!q(b,d,a.heap[e],a.depth));)a.heap[c]=a.heap[e],c=e,e<<=1;a.heap[c]=d}function s(a,b,c){var d,f,i,j,k=0;if(0!==a.last_lit)do d=a.pending_buf[a.d_buf+2*k]<<8|a.pending_buf[a.d_buf+2*k+1],f=a.pending_buf[a.l_buf+k],k++,0===d?h(a,f,b):(i=hb[f],h(a,i+P+1,b),j=_[i],0!==j&&(f-=ib[i],g(a,f,j)),d--,i=e(d),h(a,i,c),j=ab[i],0!==j&&(d-=jb[i],g(a,d,j)));while(k<a.last_lit);h(a,X,b)}function t(a,b){var c,d,e,f=b.dyn_tree,g=b.stat_desc.static_tree,h=b.stat_desc.has_stree,i=b.stat_desc.elems,j=-1;for(a.heap_len=0,a.heap_max=T,c=0;i>c;c++)0!==f[2*c]?(a.heap[++a.heap_len]=j=c,a.depth[c]=0):f[2*c+1]=0;for(;a.heap_len<2;)e=a.heap[++a.heap_len]=2>j?++j:0,f[2*e]=1,a.depth[e]=0,a.opt_len--,h&&(a.static_len-=g[2*e+1]);for(b.max_code=j,c=a.heap_len>>1;c>=1;c--)r(a,f,c);e=i;do c=a.heap[1],a.heap[1]=a.heap[a.heap_len--],r(a,f,1),d=a.heap[1],a.heap[--a.heap_max]=c,a.heap[--a.heap_max]=d,f[2*e]=f[2*c]+f[2*d],a.depth[e]=(a.depth[c]>=a.depth[d]?a.depth[c]:a.depth[d])+1,f[2*c+1]=f[2*d+1]=e,a.heap[1]=e++,r(a,f,1);while(a.heap_len>=2);a.heap[--a.heap_max]=a.heap[1],k(a,b),l(f,j,a.bl_count)}function u(a,b,c){var d,e,f=-1,g=b[1],h=0,i=7,j=4;for(0===g&&(i=138,j=3),b[2*(c+1)+1]=65535,d=0;c>=d;d++)e=g,g=b[2*(d+1)+1],++h<i&&e===g||(j>h?a.bl_tree[2*e]+=h:0!==e?(e!==f&&a.bl_tree[2*e]++,a.bl_tree[2*Y]++):10>=h?a.bl_tree[2*Z]++:a.bl_tree[2*$]++,h=0,f=e,0===g?(i=138,j=3):e===g?(i=6,j=3):(i=7,j=4))}function v(a,b,c){var d,e,f=-1,i=b[1],j=0,k=7,l=4;for(0===i&&(k=138,l=3),d=0;c>=d;d++)if(e=i,i=b[2*(d+1)+1],!(++j<k&&e===i)){if(l>j){do h(a,e,a.bl_tree);while(0!==--j)}else 0!==e?(e!==f&&(h(a,e,a.bl_tree),j--),h(a,Y,a.bl_tree),g(a,j-3,2)):10>=j?(h(a,Z,a.bl_tree),g(a,j-3,3)):(h(a,$,a.bl_tree),g(a,j-11,7));j=0,f=e,0===i?(k=138,l=3):e===i?(k=6,l=3):(k=7,l=4)}}function w(a){var b;for(u(a,a.dyn_ltree,a.l_desc.max_code),u(a,a.dyn_dtree,a.d_desc.max_code),t(a,a.bl_desc),b=S-1;b>=3&&0===a.bl_tree[2*cb[b]+1];b--);return a.opt_len+=3*(b+1)+5+5+4,b}function x(a,b,c,d){var e;for(g(a,b-257,5),g(a,c-1,5),g(a,d-4,4),e=0;d>e;e++)g(a,a.bl_tree[2*cb[e]+1],3);v(a,a.dyn_ltree,b-1),v(a,a.dyn_dtree,c-1)}function y(a){var b,c=4093624447;for(b=0;31>=b;b++,c>>>=1)if(1&c&&0!==a.dyn_ltree[2*b])return G;if(0!==a.dyn_ltree[18]||0!==a.dyn_ltree[20]||0!==a.dyn_ltree[26])return H;for(b=32;P>b;b++)if(0!==a.dyn_ltree[2*b])return H;return G}function z(a){pb||(m(),pb=!0),a.l_desc=new ob(a.dyn_ltree,kb),a.d_desc=new ob(a.dyn_dtree,lb),a.bl_desc=new ob(a.bl_tree,mb),a.bi_buf=0,a.bi_valid=0,n(a)}function A(a,b,c,d){g(a,(J<<1)+(d?1:0),3),p(a,b,c,!0)}function B(a){g(a,K<<1,3),h(a,X,eb),j(a)}function C(a,b,c,d){var e,f,h=0;a.level>0?(a.strm.data_type===I&&(a.strm.data_type=y(a)),t(a,a.l_desc),t(a,a.d_desc),h=w(a),e=a.opt_len+3+7>>>3,f=a.static_len+3+7>>>3,e>=f&&(e=f)):e=f=c+5,e>=c+4&&-1!==b?A(a,b,c,d):a.strategy===F||f===e?(g(a,(K<<1)+(d?1:0),3),s(a,eb,fb)):(g(a,(L<<1)+(d?1:0),3),x(a,a.l_desc.max_code+1,a.d_desc.max_code+1,h+1),s(a,a.dyn_ltree,a.dyn_dtree)),n(a),d&&o(a)}function D(a,b,c){return a.pending_buf[a.d_buf+2*a.last_lit]=b>>>8&255,a.pending_buf[a.d_buf+2*a.last_lit+1]=255&b,a.pending_buf[a.l_buf+a.last_lit]=255&c,a.last_lit++,0===b?a.dyn_ltree[2*c]++:(a.matches++,b--,a.dyn_ltree[2*(hb[c]+P+1)]++,a.dyn_dtree[2*e(b)]++),a.last_lit===a.lit_bufsize-1}var E=a("../utils/common"),F=4,G=0,H=1,I=2,J=0,K=1,L=2,M=3,N=258,O=29,P=256,Q=P+1+O,R=30,S=19,T=2*Q+1,U=15,V=16,W=7,X=256,Y=16,Z=17,$=18,_=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],ab=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],bb=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],cb=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],db=512,eb=new Array(2*(Q+2));d(eb);var fb=new Array(2*R);d(fb);var gb=new Array(db);d(gb);var hb=new Array(N-M+1);d(hb);var ib=new Array(O);d(ib);var jb=new Array(R);d(jb);var kb,lb,mb,nb=function(a,b,c,d,e){this.static_tree=a,this.extra_bits=b,this.extra_base=c,this.elems=d,this.max_length=e,this.has_stree=a&&a.length},ob=function(a,b){this.dyn_tree=a,this.max_code=0,this.stat_desc=b},pb=!1;c._tr_init=z,c._tr_stored_block=A,c._tr_flush_block=C,c._tr_tally=D,c._tr_align=B},{"../utils/common":27}],39:[function(a,b){"use strict";function c(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}b.exports=c},{}]},{},[9])(9)});'use strict';if(tr.isVinn){global.window={};}'use strict';if(tr.isVinn){global.JSZip=global.window.JSZip;global.window=undefined;}else if(tr.isNode){var jsZipAbsPath=HTMLImportsLoader.hrefToAbsolutePath('/jszip.min.js');var jsZipModule=require(jsZipAbsPath);global.JSZip=jsZipModule;}'use strict';tr.exportTo('tr.e.importer',function(){var GZIP_MEMBER_HEADER_ID_SIZE=3;var GZIP_HEADER_ID1=0x1f;var GZIP_HEADER_ID2=0x8b;var GZIP_DEFLATE_COMPRESSION=8;function GzipImporter(model,eventData){if(typeof(eventData)==='string'||eventData instanceof String){eventData=JSZip.utils.transformTo('uint8array',eventData);}else if(eventData instanceof ArrayBuffer){eventData=new Uint8Array(eventData);}else
-throw new Error('Unknown gzip data format');this.model_=model;this.gzipData_=eventData;}
-GzipImporter.canImport=function(eventData){var header;if(eventData instanceof ArrayBuffer)
-header=new Uint8Array(eventData.slice(0,GZIP_MEMBER_HEADER_ID_SIZE));else if(typeof(eventData)==='string'||eventData instanceof String){header=eventData.substring(0,GZIP_MEMBER_HEADER_ID_SIZE);header=JSZip.utils.transformTo('uint8array',header);}else
-return false;return header[0]==GZIP_HEADER_ID1&&header[1]==GZIP_HEADER_ID2&&header[2]==GZIP_DEFLATE_COMPRESSION;};GzipImporter.inflateGzipData_=function(data){var position=0;function getByte(){if(position>=data.length)
-throw new Error('Unexpected end of gzip data');return data[position++];}
-function getWord(){var low=getByte();var high=getByte();return(high<<8)+low;}
+return true;};EtwImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'EtwImporter';},get model(){return this.model_;},createThreadIfNeeded(pid,tid){this.tidsToPid_[tid]=pid;},removeThreadIfPresent(tid){this.tidsToPid_[tid]=undefined;},getPidFromWindowsTid(tid){if(tid===0)return 0;const pid=this.tidsToPid_[tid];if(pid===undefined){return 0;}
+return pid;},getThreadFromWindowsTid(tid){const pid=this.getPidFromWindowsTid(tid);const process=this.model_.getProcess(pid);if(!process)return undefined;return process.getThread(tid);},getOrCreateCpu(cpuNumber){const cpu=this.model_.kernel.getOrCreateCpu(cpuNumber);return cpu;},importEvents(){this.events_.content.forEach(this.parseInfo.bind(this));if(this.walltime_===undefined||this.ticks_===undefined){throw Error('Cannot find clock sync information in the system trace.');}
+if(this.is64bit_===undefined){throw Error('Cannot determine pointer size of the system trace.'+'Consider deselecting "System tracing" or disabling the "Paging '+'Executive" feature of Windows');}
+this.events_.content.forEach(this.parseEvent.bind(this));},importTimestamp(timestamp){const ts=parseInt(timestamp,16);return(ts-this.walltime_+this.ticks_)/1000.;},parseInfo(event){if(event.hasOwnProperty('guid')&&event.hasOwnProperty('walltime')&&event.hasOwnProperty('tick')&&event.guid==='ClockSync'){this.walltime_=parseInt(event.walltime,16);this.ticks_=parseInt(event.tick,16);}
+if(this.is64bit_===undefined&&event.hasOwnProperty('guid')&&event.hasOwnProperty('op')&&event.hasOwnProperty('ver')&&event.hasOwnProperty('payload')&&event.guid===kThreadGuid&&event.op===kThreadDCStartOpcode){const decodedSize=tr.b.Base64.getDecodedBufferLength(event.payload);if(event.ver===1){if(decodedSize>=52){this.is64bit_=true;}else{this.is64bit_=false;}}else if(event.ver===2){if(decodedSize>=64){this.is64bit_=true;}else{this.is64bit_=false;}}else if(event.ver===3){if(decodedSize>=60){this.is64bit_=true;}else{this.is64bit_=false;}}}
+return true;},parseEvent(event){if(!event.hasOwnProperty('guid')||!event.hasOwnProperty('op')||!event.hasOwnProperty('ver')||!event.hasOwnProperty('cpu')||!event.hasOwnProperty('ts')||!event.hasOwnProperty('payload')){return false;}
+const timestamp=this.importTimestamp(event.ts);const header={guid:event.guid,opcode:event.op,version:event.ver,cpu:event.cpu,timestamp,is64:this.is64bit_};const decoder=this.decoder_;decoder.reset(event.payload);const handler=this.getEventHandler(header.guid,header.opcode);if(!handler)return false;if(!handler(header,decoder)){this.model_.importWarning({type:'parse_error',message:'Malformed '+header.guid+' event ('+event.payload+')'});return false;}
+return true;},registerEventHandler(guid,opcode,handler){if(this.handlers_[guid]===undefined){this.handlers_[guid]=[];}
+this.handlers_[guid][opcode]=handler;},getEventHandler(guid,opcode){if(this.handlers_[guid]===undefined){return undefined;}
+return this.handlers_[guid][opcode];}};tr.importer.Importer.register(EtwImporter);return{EtwImporter,};});'use strict';tr.exportTo('tr.b',function(){class TraceStream{static get HEADER_SIZE(){return Math.pow(2,10);}
+static get CHUNK_SIZE(){return Math.pow(2,20);}
+get isBinary(){throw new Error('Not implemented');}
+get hasData(){throw new Error('Not implemented');}
+get header(){throw new Error('Not implemented');}
+readUntilDelimiter(delim){throw new Error('Not implemented');}
+readNumBytes(opt_size){throw new Error('Not implemented');}
+rewind(){throw new Error('Not implemented');}
+substream(offset,opt_length,opt_headerSize){throw new Error('Not implemented');}}
+return{TraceStream,};});'use strict';tr.exportTo('tr.e.importer.fuchsia',function(){const IMPORT_PRIORITY=0;const IDLE_THREAD_THRESHOLD=6444000000;const ZX_THREAD_STATE_NEW=0;const ZX_THREAD_STATE_RUNNING=1;const ZX_THREAD_STATE_SUSPENDED=2;const ZX_THREAD_STATE_BLOCKED=3;const ZX_THREAD_STATE_DYING=4;const ZX_THREAD_STATE_DEAD=5;class FuchsiaImporter extends tr.importer.Importer{constructor(model,eventData){super(model,eventData);this.importPriority=IMPORT_PRIORITY;this.model_=model;this.events_=eventData.events;this.parsers_=[];this.threadInfo_=new Map();this.processNames_=new Map();this.threadStates_=new Map();}
+static canImport(eventData){if(eventData instanceof tr.b.TraceStream){if(eventData.isBinary)return false;eventData=eventData.header;}
+if(eventData instanceof Object&&eventData.type==='fuchsia'){return true;}
+return false;}
+get importerName(){return'FuchsiaImporter';}
+get model(){return this.model_;}
+importClockSyncMarkers(){}
+finalizeImport(){}
+isIdleThread(prio,tid){if(prio===undefined){return tid>IDLE_THREAD_THRESHOLD;}
+return prio===0;}
+recordThreadState_(tid,timestamp,state,prio){if(this.isIdleThread(prio,tid)){return;}
+const states=this.threadStates_.has(tid)?this.threadStates_.get(tid):[];states.push({'ts':timestamp,state});this.threadStates_.set(tid,states);}
+processContextSwitchEvent_(event){let tid=event.in.tid;let threadName=tid.toString();let procName='';const prio=event.in.prio;if(this.threadInfo_.has(tid)){const threadInfo=this.threadInfo_.get(tid);threadName=threadInfo.name;const pid=threadInfo.pid;if(this.processNames_.has(pid)){procName=this.processNames_.get(pid)+':';}}
+const name=procName+threadName;if(this.isIdleThread(prio,tid)){tid=undefined;}
+const cpu=this.model_.kernel.getOrCreateCpu(event.cpu);const timestamp=tr.b.Unit.timestampFromUs(event.ts);cpu.switchActiveThread(timestamp,{},tid,name,tid);const SCHEDULING_STATE=tr.model.SCHEDULING_STATE;this.recordThreadState_(tid,timestamp,SCHEDULING_STATE.RUNNING,prio);let outState=SCHEDULING_STATE.UNKNOWN;switch(event.out.state){case ZX_THREAD_STATE_NEW:outState=SCHEDULING_STATE.RUNNABLE;break;case ZX_THREAD_STATE_RUNNING:outState=SCHEDULING_STATE.RUNNABLE;break;case ZX_THREAD_STATE_BLOCKED:outState=SCHEDULING_STATE.SLEEPING;break;case ZX_THREAD_STATE_SUSPENDED:outState=SCHEDULING_STATE.STOPPED;break;case ZX_THREAD_STATE_DEAD:outState=SCHEDULING_STATE.TASK_DEAD;break;}
+this.recordThreadState_(event.out.tid,timestamp,outState,event.out.prio);}
+processProcessInfoEvent_(event){const process=this.model_.getOrCreateProcess(event.pid);process.name=event.name;this.processNames_.set(event.pid,event.name);if('sort_index'in event){process.sortIndex=event.sort_index;}}
+processThreadInfoEvent_(event){const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);thread.name=event.name;this.threadInfo_.set(event.tid,{'name':event.name,'pid':event.pid});if('sort_index'in event){const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);thread.sortIndex=event.sort_index;}}
+processEvent_(event){switch(event.ph){case'k':this.processContextSwitchEvent_(event);break;case'p':this.processProcessInfoEvent_(event);break;case't':this.processThreadInfoEvent_(event);break;}}
+postProcessStates_(){for(const[tid,states]of this.threadStates_){if(!this.threadInfo_.has(tid)){continue;}
+const pid=this.threadInfo_.get(tid).pid;const thread=this.model_.getOrCreateProcess(pid).getOrCreateThread(tid);const slices=[];for(let i=0;i<states.length-1;i++){slices.push(new tr.model.ThreadTimeSlice(thread,states[i].state,'',states[i].ts,{},states[i+1].ts-states[i].ts));}
+thread.timeSlices=slices;}}
+importEvents(){for(const event of this.events_){this.processEvent_(event);}
+this.postProcessStates_();}}
+tr.importer.Importer.register(FuchsiaImporter);return{FuchsiaImporter,IMPORT_PRIORITY,};});'use strict';tr.exportTo('tr.b',function(){const MAX_FUNCTION_ARGS_COUNT=Math.pow(2,15)-1;class InMemoryTraceStream extends tr.b.TraceStream{constructor(buffer,isBinary,opt_headerSize){super();if(!buffer instanceof Uint8Array){throw new Error('buffer should be a Uint8Array');}
+const headerSize=opt_headerSize||tr.b.TraceStream.HEADER_SIZE;this.data_=buffer;this.isBinary_=isBinary;this.header_=InMemoryTraceStream.uint8ArrayToString_(this.data_.subarray(0,headerSize));this.cursor_=0;}
+get isBinary(){return this.isBinary_;}
+get hasData(){return this.cursor_<this.data_.length;}
+get header(){return this.header_;}
+get data(){return this.data_;}
+toString(){this.rewind();return this.readNumBytes(Number.MAX_VALUE);}
+readUntilDelimiter(delim){if(delim.length!==1){throw new Error('delim must be exactly one character');}
+const offset=this.data_.indexOf(delim.charCodeAt(0),this.cursor_)+1;return this.readToOffset_(offset>0?Math.min(offset,this.data_.length):this.data_.length);}
+readNumBytes(opt_size){if(opt_size!==undefined&&opt_size<=0){throw new Error(`readNumBytes expects a positive size (${opt_size} given)`);}
+const size=opt_size||tr.b.TraceStream.CHUNK_SIZE;const offset=Math.min(this.cursor_+size,this.data_.length);return this.readToOffset_(offset);}
+rewind(){this.cursor_=0;}
+substream(startOffset,opt_endOffset,opt_headerSize){return new InMemoryTraceStream(this.data_.subarray(startOffset,opt_endOffset),this.isBinary_,opt_headerSize);}
+readToOffset_(offset){const out=InMemoryTraceStream.uint8ArrayToString_(this.data_.subarray(this.cursor_,offset));this.cursor_=offset;return out;}
+static uint8ArrayToString_(arr){if(typeof TextDecoder!=='undefined'){const decoder=new TextDecoder('utf-8');return decoder.decode(arr);}
+const c=[];for(let i=0;i<arr.length;i+=MAX_FUNCTION_ARGS_COUNT){c.push(String.fromCharCode(...arr.subarray(i,i+MAX_FUNCTION_ARGS_COUNT)));}
+return c.join('');}}
+return{InMemoryTraceStream,};});!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).pako=t()}}(function(){return function t(e,a,i){function n(s,o){if(!a[s]){if(!e[s]){var l="function"==typeof require&&require;if(!o&&l)return l(s,!0);if(r)return r(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var d=a[s]={exports:{}};e[s][0].call(d.exports,function(t){var a=e[s][1][t];return n(a||t)},d,d.exports,t,e,a,i)}return a[s].exports}for(var r="function"==typeof require&&require,s=0;s<i.length;s++)n(i[s]);return n}({1:[function(t,e,a){"use strict";function i(t){if(!(this instanceof i))return new i(t);this.options=s.assign({level:_,method:c,chunkSize:16384,windowBits:15,memLevel:8,strategy:u,to:""},t||{});var e=this.options;e.raw&&e.windowBits>0?e.windowBits=-e.windowBits:e.gzip&&e.windowBits>0&&e.windowBits<16&&(e.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new h,this.strm.avail_out=0;var a=r.deflateInit2(this.strm,e.level,e.method,e.windowBits,e.memLevel,e.strategy);if(a!==f)throw new Error(l[a]);if(e.header&&r.deflateSetHeader(this.strm,e.header),e.dictionary){var n;if(n="string"==typeof e.dictionary?o.string2buf(e.dictionary):"[object ArrayBuffer]"===d.call(e.dictionary)?new Uint8Array(e.dictionary):e.dictionary,(a=r.deflateSetDictionary(this.strm,n))!==f)throw new Error(l[a]);this._dict_set=!0}}function n(t,e){var a=new i(e);if(a.push(t,!0),a.err)throw a.msg||l[a.err];return a.result}var r=t("./zlib/deflate"),s=t("./utils/common"),o=t("./utils/strings"),l=t("./zlib/messages"),h=t("./zlib/zstream"),d=Object.prototype.toString,f=0,_=-1,u=0,c=8;i.prototype.push=function(t,e){var a,i,n=this.strm,l=this.options.chunkSize;if(this.ended)return!1;i=e===~~e?e:!0===e?4:0,"string"==typeof t?n.input=o.string2buf(t):"[object ArrayBuffer]"===d.call(t)?n.input=new Uint8Array(t):n.input=t,n.next_in=0,n.avail_in=n.input.length;do{if(0===n.avail_out&&(n.output=new s.Buf8(l),n.next_out=0,n.avail_out=l),1!==(a=r.deflate(n,i))&&a!==f)return this.onEnd(a),this.ended=!0,!1;0!==n.avail_out&&(0!==n.avail_in||4!==i&&2!==i)||("string"===this.options.to?this.onData(o.buf2binstring(s.shrinkBuf(n.output,n.next_out))):this.onData(s.shrinkBuf(n.output,n.next_out)))}while((n.avail_in>0||0===n.avail_out)&&1!==a);return 4===i?(a=r.deflateEnd(this.strm),this.onEnd(a),this.ended=!0,a===f):2!==i||(this.onEnd(f),n.avail_out=0,!0)},i.prototype.onData=function(t){this.chunks.push(t)},i.prototype.onEnd=function(t){t===f&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=s.flattenChunks(this.chunks)),this.chunks=[],this.err=t,this.msg=this.strm.msg},a.Deflate=i,a.deflate=n,a.deflateRaw=function(t,e){return e=e||{},e.raw=!0,n(t,e)},a.gzip=function(t,e){return e=e||{},e.gzip=!0,n(t,e)}},{"./utils/common":3,"./utils/strings":4,"./zlib/deflate":8,"./zlib/messages":13,"./zlib/zstream":15}],2:[function(t,e,a){"use strict";function i(t){if(!(this instanceof i))return new i(t);this.options=s.assign({chunkSize:16384,windowBits:0,to:""},t||{});var e=this.options;e.raw&&e.windowBits>=0&&e.windowBits<16&&(e.windowBits=-e.windowBits,0===e.windowBits&&(e.windowBits=-15)),!(e.windowBits>=0&&e.windowBits<16)||t&&t.windowBits||(e.windowBits+=32),e.windowBits>15&&e.windowBits<48&&0==(15&e.windowBits)&&(e.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new d,this.strm.avail_out=0;var a=r.inflateInit2(this.strm,e.windowBits);if(a!==l.Z_OK)throw new Error(h[a]);this.header=new f,r.inflateGetHeader(this.strm,this.header)}function n(t,e){var a=new i(e);if(a.push(t,!0),a.err)throw a.msg||h[a.err];return a.result}var r=t("./zlib/inflate"),s=t("./utils/common"),o=t("./utils/strings"),l=t("./zlib/constants"),h=t("./zlib/messages"),d=t("./zlib/zstream"),f=t("./zlib/gzheader"),_=Object.prototype.toString;i.prototype.push=function(t,e){var a,i,n,h,d,f,u=this.strm,c=this.options.chunkSize,b=this.options.dictionary,g=!1;if(this.ended)return!1;i=e===~~e?e:!0===e?l.Z_FINISH:l.Z_NO_FLUSH,"string"==typeof t?u.input=o.binstring2buf(t):"[object ArrayBuffer]"===_.call(t)?u.input=new Uint8Array(t):u.input=t,u.next_in=0,u.avail_in=u.input.length;do{if(0===u.avail_out&&(u.output=new s.Buf8(c),u.next_out=0,u.avail_out=c),(a=r.inflate(u,l.Z_NO_FLUSH))===l.Z_NEED_DICT&&b&&(f="string"==typeof b?o.string2buf(b):"[object ArrayBuffer]"===_.call(b)?new Uint8Array(b):b,a=r.inflateSetDictionary(this.strm,f)),a===l.Z_BUF_ERROR&&!0===g&&(a=l.Z_OK,g=!1),a!==l.Z_STREAM_END&&a!==l.Z_OK)return this.onEnd(a),this.ended=!0,!1;u.next_out&&(0!==u.avail_out&&a!==l.Z_STREAM_END&&(0!==u.avail_in||i!==l.Z_FINISH&&i!==l.Z_SYNC_FLUSH)||("string"===this.options.to?(n=o.utf8border(u.output,u.next_out),h=u.next_out-n,d=o.buf2string(u.output,n),u.next_out=h,u.avail_out=c-h,h&&s.arraySet(u.output,u.output,n,h,0),this.onData(d)):this.onData(s.shrinkBuf(u.output,u.next_out)))),0===u.avail_in&&0===u.avail_out&&(g=!0)}while((u.avail_in>0||0===u.avail_out)&&a!==l.Z_STREAM_END);return a===l.Z_STREAM_END&&(i=l.Z_FINISH),i===l.Z_FINISH?(a=r.inflateEnd(this.strm),this.onEnd(a),this.ended=!0,a===l.Z_OK):i!==l.Z_SYNC_FLUSH||(this.onEnd(l.Z_OK),u.avail_out=0,!0)},i.prototype.onData=function(t){this.chunks.push(t)},i.prototype.onEnd=function(t){t===l.Z_OK&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=s.flattenChunks(this.chunks)),this.chunks=[],this.err=t,this.msg=this.strm.msg},a.Inflate=i,a.inflate=n,a.inflateRaw=function(t,e){return e=e||{},e.raw=!0,n(t,e)},a.ungzip=n},{"./utils/common":3,"./utils/strings":4,"./zlib/constants":6,"./zlib/gzheader":9,"./zlib/inflate":11,"./zlib/messages":13,"./zlib/zstream":15}],3:[function(t,e,a){"use strict";function i(t,e){return Object.prototype.hasOwnProperty.call(t,e)}var n="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;a.assign=function(t){for(var e=Array.prototype.slice.call(arguments,1);e.length;){var a=e.shift();if(a){if("object"!=typeof a)throw new TypeError(a+"must be non-object");for(var n in a)i(a,n)&&(t[n]=a[n])}}return t},a.shrinkBuf=function(t,e){return t.length===e?t:t.subarray?t.subarray(0,e):(t.length=e,t)};var r={arraySet:function(t,e,a,i,n){if(e.subarray&&t.subarray)t.set(e.subarray(a,a+i),n);else for(var r=0;r<i;r++)t[n+r]=e[a+r]},flattenChunks:function(t){var e,a,i,n,r,s;for(i=0,e=0,a=t.length;e<a;e++)i+=t[e].length;for(s=new Uint8Array(i),n=0,e=0,a=t.length;e<a;e++)r=t[e],s.set(r,n),n+=r.length;return s}},s={arraySet:function(t,e,a,i,n){for(var r=0;r<i;r++)t[n+r]=e[a+r]},flattenChunks:function(t){return[].concat.apply([],t)}};a.setTyped=function(t){t?(a.Buf8=Uint8Array,a.Buf16=Uint16Array,a.Buf32=Int32Array,a.assign(a,r)):(a.Buf8=Array,a.Buf16=Array,a.Buf32=Array,a.assign(a,s))},a.setTyped(n)},{}],4:[function(t,e,a){"use strict";function i(t,e){if(e<65537&&(t.subarray&&s||!t.subarray&&r))return String.fromCharCode.apply(null,n.shrinkBuf(t,e));for(var a="",i=0;i<e;i++)a+=String.fromCharCode(t[i]);return a}var n=t("./common"),r=!0,s=!0;try{String.fromCharCode.apply(null,[0])}catch(t){r=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(t){s=!1}for(var o=new n.Buf8(256),l=0;l<256;l++)o[l]=l>=252?6:l>=248?5:l>=240?4:l>=224?3:l>=192?2:1;o[254]=o[254]=1,a.string2buf=function(t){var e,a,i,r,s,o=t.length,l=0;for(r=0;r<o;r++)55296==(64512&(a=t.charCodeAt(r)))&&r+1<o&&56320==(64512&(i=t.charCodeAt(r+1)))&&(a=65536+(a-55296<<10)+(i-56320),r++),l+=a<128?1:a<2048?2:a<65536?3:4;for(e=new n.Buf8(l),s=0,r=0;s<l;r++)55296==(64512&(a=t.charCodeAt(r)))&&r+1<o&&56320==(64512&(i=t.charCodeAt(r+1)))&&(a=65536+(a-55296<<10)+(i-56320),r++),a<128?e[s++]=a:a<2048?(e[s++]=192|a>>>6,e[s++]=128|63&a):a<65536?(e[s++]=224|a>>>12,e[s++]=128|a>>>6&63,e[s++]=128|63&a):(e[s++]=240|a>>>18,e[s++]=128|a>>>12&63,e[s++]=128|a>>>6&63,e[s++]=128|63&a);return e},a.buf2binstring=function(t){return i(t,t.length)},a.binstring2buf=function(t){for(var e=new n.Buf8(t.length),a=0,i=e.length;a<i;a++)e[a]=t.charCodeAt(a);return e},a.buf2string=function(t,e){var a,n,r,s,l=e||t.length,h=new Array(2*l);for(n=0,a=0;a<l;)if((r=t[a++])<128)h[n++]=r;else if((s=o[r])>4)h[n++]=65533,a+=s-1;else{for(r&=2===s?31:3===s?15:7;s>1&&a<l;)r=r<<6|63&t[a++],s--;s>1?h[n++]=65533:r<65536?h[n++]=r:(r-=65536,h[n++]=55296|r>>10&1023,h[n++]=56320|1023&r)}return i(h,n)},a.utf8border=function(t,e){var a;for((e=e||t.length)>t.length&&(e=t.length),a=e-1;a>=0&&128==(192&t[a]);)a--;return a<0?e:0===a?e:a+o[t[a]]>e?a:e}},{"./common":3}],5:[function(t,e,a){"use strict";e.exports=function(t,e,a,i){for(var n=65535&t|0,r=t>>>16&65535|0,s=0;0!==a;){a-=s=a>2e3?2e3:a;do{r=r+(n=n+e[i++]|0)|0}while(--s);n%=65521,r%=65521}return n|r<<16|0}},{}],6:[function(t,e,a){"use strict";e.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},{}],7:[function(t,e,a){"use strict";var i=function(){for(var t,e=[],a=0;a<256;a++){t=a;for(var i=0;i<8;i++)t=1&t?3988292384^t>>>1:t>>>1;e[a]=t}return e}();e.exports=function(t,e,a,n){var r=i,s=n+a;t^=-1;for(var o=n;o<s;o++)t=t>>>8^r[255&(t^e[o])];return-1^t}},{}],8:[function(t,e,a){"use strict";function i(t,e){return t.msg=A[e],e}function n(t){return(t<<1)-(t>4?9:0)}function r(t){for(var e=t.length;--e>=0;)t[e]=0}function s(t){var e=t.state,a=e.pending;a>t.avail_out&&(a=t.avail_out),0!==a&&(z.arraySet(t.output,e.pending_buf,e.pending_out,a,t.next_out),t.next_out+=a,e.pending_out+=a,t.total_out+=a,t.avail_out-=a,e.pending-=a,0===e.pending&&(e.pending_out=0))}function o(t,e){B._tr_flush_block(t,t.block_start>=0?t.block_start:-1,t.strstart-t.block_start,e),t.block_start=t.strstart,s(t.strm)}function l(t,e){t.pending_buf[t.pending++]=e}function h(t,e){t.pending_buf[t.pending++]=e>>>8&255,t.pending_buf[t.pending++]=255&e}function d(t,e,a,i){var n=t.avail_in;return n>i&&(n=i),0===n?0:(t.avail_in-=n,z.arraySet(e,t.input,t.next_in,n,a),1===t.state.wrap?t.adler=S(t.adler,e,n,a):2===t.state.wrap&&(t.adler=E(t.adler,e,n,a)),t.next_in+=n,t.total_in+=n,n)}function f(t,e){var a,i,n=t.max_chain_length,r=t.strstart,s=t.prev_length,o=t.nice_match,l=t.strstart>t.w_size-it?t.strstart-(t.w_size-it):0,h=t.window,d=t.w_mask,f=t.prev,_=t.strstart+at,u=h[r+s-1],c=h[r+s];t.prev_length>=t.good_match&&(n>>=2),o>t.lookahead&&(o=t.lookahead);do{if(a=e,h[a+s]===c&&h[a+s-1]===u&&h[a]===h[r]&&h[++a]===h[r+1]){r+=2,a++;do{}while(h[++r]===h[++a]&&h[++r]===h[++a]&&h[++r]===h[++a]&&h[++r]===h[++a]&&h[++r]===h[++a]&&h[++r]===h[++a]&&h[++r]===h[++a]&&h[++r]===h[++a]&&r<_);if(i=at-(_-r),r=_-at,i>s){if(t.match_start=e,s=i,i>=o)break;u=h[r+s-1],c=h[r+s]}}}while((e=f[e&d])>l&&0!=--n);return s<=t.lookahead?s:t.lookahead}function _(t){var e,a,i,n,r,s=t.w_size;do{if(n=t.window_size-t.lookahead-t.strstart,t.strstart>=s+(s-it)){z.arraySet(t.window,t.window,s,s,0),t.match_start-=s,t.strstart-=s,t.block_start-=s,e=a=t.hash_size;do{i=t.head[--e],t.head[e]=i>=s?i-s:0}while(--a);e=a=s;do{i=t.prev[--e],t.prev[e]=i>=s?i-s:0}while(--a);n+=s}if(0===t.strm.avail_in)break;if(a=d(t.strm,t.window,t.strstart+t.lookahead,n),t.lookahead+=a,t.lookahead+t.insert>=et)for(r=t.strstart-t.insert,t.ins_h=t.window[r],t.ins_h=(t.ins_h<<t.hash_shift^t.window[r+1])&t.hash_mask;t.insert&&(t.ins_h=(t.ins_h<<t.hash_shift^t.window[r+et-1])&t.hash_mask,t.prev[r&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=r,r++,t.insert--,!(t.lookahead+t.insert<et)););}while(t.lookahead<it&&0!==t.strm.avail_in)}function u(t,e){for(var a,i;;){if(t.lookahead<it){if(_(t),t.lookahead<it&&e===Z)return _t;if(0===t.lookahead)break}if(a=0,t.lookahead>=et&&(t.ins_h=(t.ins_h<<t.hash_shift^t.window[t.strstart+et-1])&t.hash_mask,a=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart),0!==a&&t.strstart-a<=t.w_size-it&&(t.match_length=f(t,a)),t.match_length>=et)if(i=B._tr_tally(t,t.strstart-t.match_start,t.match_length-et),t.lookahead-=t.match_length,t.match_length<=t.max_lazy_match&&t.lookahead>=et){t.match_length--;do{t.strstart++,t.ins_h=(t.ins_h<<t.hash_shift^t.window[t.strstart+et-1])&t.hash_mask,a=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart}while(0!=--t.match_length);t.strstart++}else t.strstart+=t.match_length,t.match_length=0,t.ins_h=t.window[t.strstart],t.ins_h=(t.ins_h<<t.hash_shift^t.window[t.strstart+1])&t.hash_mask;else i=B._tr_tally(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++;if(i&&(o(t,!1),0===t.strm.avail_out))return _t}return t.insert=t.strstart<et-1?t.strstart:et-1,e===N?(o(t,!0),0===t.strm.avail_out?ct:bt):t.last_lit&&(o(t,!1),0===t.strm.avail_out)?_t:ut}function c(t,e){for(var a,i,n;;){if(t.lookahead<it){if(_(t),t.lookahead<it&&e===Z)return _t;if(0===t.lookahead)break}if(a=0,t.lookahead>=et&&(t.ins_h=(t.ins_h<<t.hash_shift^t.window[t.strstart+et-1])&t.hash_mask,a=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart),t.prev_length=t.match_length,t.prev_match=t.match_start,t.match_length=et-1,0!==a&&t.prev_length<t.max_lazy_match&&t.strstart-a<=t.w_size-it&&(t.match_length=f(t,a),t.match_length<=5&&(t.strategy===H||t.match_length===et&&t.strstart-t.match_start>4096)&&(t.match_length=et-1)),t.prev_length>=et&&t.match_length<=t.prev_length){n=t.strstart+t.lookahead-et,i=B._tr_tally(t,t.strstart-1-t.prev_match,t.prev_length-et),t.lookahead-=t.prev_length-1,t.prev_length-=2;do{++t.strstart<=n&&(t.ins_h=(t.ins_h<<t.hash_shift^t.window[t.strstart+et-1])&t.hash_mask,a=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart)}while(0!=--t.prev_length);if(t.match_available=0,t.match_length=et-1,t.strstart++,i&&(o(t,!1),0===t.strm.avail_out))return _t}else if(t.match_available){if((i=B._tr_tally(t,0,t.window[t.strstart-1]))&&o(t,!1),t.strstart++,t.lookahead--,0===t.strm.avail_out)return _t}else t.match_available=1,t.strstart++,t.lookahead--}return t.match_available&&(i=B._tr_tally(t,0,t.window[t.strstart-1]),t.match_available=0),t.insert=t.strstart<et-1?t.strstart:et-1,e===N?(o(t,!0),0===t.strm.avail_out?ct:bt):t.last_lit&&(o(t,!1),0===t.strm.avail_out)?_t:ut}function b(t,e){for(var a,i,n,r,s=t.window;;){if(t.lookahead<=at){if(_(t),t.lookahead<=at&&e===Z)return _t;if(0===t.lookahead)break}if(t.match_length=0,t.lookahead>=et&&t.strstart>0&&(n=t.strstart-1,(i=s[n])===s[++n]&&i===s[++n]&&i===s[++n])){r=t.strstart+at;do{}while(i===s[++n]&&i===s[++n]&&i===s[++n]&&i===s[++n]&&i===s[++n]&&i===s[++n]&&i===s[++n]&&i===s[++n]&&n<r);t.match_length=at-(r-n),t.match_length>t.lookahead&&(t.match_length=t.lookahead)}if(t.match_length>=et?(a=B._tr_tally(t,1,t.match_length-et),t.lookahead-=t.match_length,t.strstart+=t.match_length,t.match_length=0):(a=B._tr_tally(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++),a&&(o(t,!1),0===t.strm.avail_out))return _t}return t.insert=0,e===N?(o(t,!0),0===t.strm.avail_out?ct:bt):t.last_lit&&(o(t,!1),0===t.strm.avail_out)?_t:ut}function g(t,e){for(var a;;){if(0===t.lookahead&&(_(t),0===t.lookahead)){if(e===Z)return _t;break}if(t.match_length=0,a=B._tr_tally(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++,a&&(o(t,!1),0===t.strm.avail_out))return _t}return t.insert=0,e===N?(o(t,!0),0===t.strm.avail_out?ct:bt):t.last_lit&&(o(t,!1),0===t.strm.avail_out)?_t:ut}function m(t,e,a,i,n){this.good_length=t,this.max_lazy=e,this.nice_length=a,this.max_chain=i,this.func=n}function w(t){t.window_size=2*t.w_size,r(t.head),t.max_lazy_match=x[t.level].max_lazy,t.good_match=x[t.level].good_length,t.nice_match=x[t.level].nice_length,t.max_chain_length=x[t.level].max_chain,t.strstart=0,t.block_start=0,t.lookahead=0,t.insert=0,t.match_length=t.prev_length=et-1,t.match_available=0,t.ins_h=0}function p(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=q,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new z.Buf16(2*$),this.dyn_dtree=new z.Buf16(2*(2*Q+1)),this.bl_tree=new z.Buf16(2*(2*V+1)),r(this.dyn_ltree),r(this.dyn_dtree),r(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new z.Buf16(tt+1),this.heap=new z.Buf16(2*J+1),r(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new z.Buf16(2*J+1),r(this.depth),this.l_buf=0,this.lit_bufsize=0,this.last_lit=0,this.d_buf=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}function v(t){var e;return t&&t.state?(t.total_in=t.total_out=0,t.data_type=Y,e=t.state,e.pending=0,e.pending_out=0,e.wrap<0&&(e.wrap=-e.wrap),e.status=e.wrap?rt:dt,t.adler=2===e.wrap?0:1,e.last_flush=Z,B._tr_init(e),D):i(t,U)}function k(t){var e=v(t);return e===D&&w(t.state),e}function y(t,e,a,n,r,s){if(!t)return U;var o=1;if(e===L&&(e=6),n<0?(o=0,n=-n):n>15&&(o=2,n-=16),r<1||r>G||a!==q||n<8||n>15||e<0||e>9||s<0||s>M)return i(t,U);8===n&&(n=9);var l=new p;return t.state=l,l.strm=t,l.wrap=o,l.gzhead=null,l.w_bits=n,l.w_size=1<<l.w_bits,l.w_mask=l.w_size-1,l.hash_bits=r+7,l.hash_size=1<<l.hash_bits,l.hash_mask=l.hash_size-1,l.hash_shift=~~((l.hash_bits+et-1)/et),l.window=new z.Buf8(2*l.w_size),l.head=new z.Buf16(l.hash_size),l.prev=new z.Buf16(l.w_size),l.lit_bufsize=1<<r+6,l.pending_buf_size=4*l.lit_bufsize,l.pending_buf=new z.Buf8(l.pending_buf_size),l.d_buf=1*l.lit_bufsize,l.l_buf=3*l.lit_bufsize,l.level=e,l.strategy=s,l.method=a,k(t)}var x,z=t("../utils/common"),B=t("./trees"),S=t("./adler32"),E=t("./crc32"),A=t("./messages"),Z=0,R=1,C=3,N=4,O=5,D=0,I=1,U=-2,T=-3,F=-5,L=-1,H=1,j=2,K=3,M=4,P=0,Y=2,q=8,G=9,X=15,W=8,J=286,Q=30,V=19,$=2*J+1,tt=15,et=3,at=258,it=at+et+1,nt=32,rt=42,st=69,ot=73,lt=91,ht=103,dt=113,ft=666,_t=1,ut=2,ct=3,bt=4,gt=3;x=[new m(0,0,0,0,function(t,e){var a=65535;for(a>t.pending_buf_size-5&&(a=t.pending_buf_size-5);;){if(t.lookahead<=1){if(_(t),0===t.lookahead&&e===Z)return _t;if(0===t.lookahead)break}t.strstart+=t.lookahead,t.lookahead=0;var i=t.block_start+a;if((0===t.strstart||t.strstart>=i)&&(t.lookahead=t.strstart-i,t.strstart=i,o(t,!1),0===t.strm.avail_out))return _t;if(t.strstart-t.block_start>=t.w_size-it&&(o(t,!1),0===t.strm.avail_out))return _t}return t.insert=0,e===N?(o(t,!0),0===t.strm.avail_out?ct:bt):(t.strstart>t.block_start&&(o(t,!1),t.strm.avail_out),_t)}),new m(4,4,8,4,u),new m(4,5,16,8,u),new m(4,6,32,32,u),new m(4,4,16,16,c),new m(8,16,32,32,c),new m(8,16,128,128,c),new m(8,32,128,256,c),new m(32,128,258,1024,c),new m(32,258,258,4096,c)],a.deflateInit=function(t,e){return y(t,e,q,X,W,P)},a.deflateInit2=y,a.deflateReset=k,a.deflateResetKeep=v,a.deflateSetHeader=function(t,e){return t&&t.state?2!==t.state.wrap?U:(t.state.gzhead=e,D):U},a.deflate=function(t,e){var a,o,d,f;if(!t||!t.state||e>O||e<0)return t?i(t,U):U;if(o=t.state,!t.output||!t.input&&0!==t.avail_in||o.status===ft&&e!==N)return i(t,0===t.avail_out?F:U);if(o.strm=t,a=o.last_flush,o.last_flush=e,o.status===rt)if(2===o.wrap)t.adler=0,l(o,31),l(o,139),l(o,8),o.gzhead?(l(o,(o.gzhead.text?1:0)+(o.gzhead.hcrc?2:0)+(o.gzhead.extra?4:0)+(o.gzhead.name?8:0)+(o.gzhead.comment?16:0)),l(o,255&o.gzhead.time),l(o,o.gzhead.time>>8&255),l(o,o.gzhead.time>>16&255),l(o,o.gzhead.time>>24&255),l(o,9===o.level?2:o.strategy>=j||o.level<2?4:0),l(o,255&o.gzhead.os),o.gzhead.extra&&o.gzhead.extra.length&&(l(o,255&o.gzhead.extra.length),l(o,o.gzhead.extra.length>>8&255)),o.gzhead.hcrc&&(t.adler=E(t.adler,o.pending_buf,o.pending,0)),o.gzindex=0,o.status=st):(l(o,0),l(o,0),l(o,0),l(o,0),l(o,0),l(o,9===o.level?2:o.strategy>=j||o.level<2?4:0),l(o,gt),o.status=dt);else{var _=q+(o.w_bits-8<<4)<<8;_|=(o.strategy>=j||o.level<2?0:o.level<6?1:6===o.level?2:3)<<6,0!==o.strstart&&(_|=nt),_+=31-_%31,o.status=dt,h(o,_),0!==o.strstart&&(h(o,t.adler>>>16),h(o,65535&t.adler)),t.adler=1}if(o.status===st)if(o.gzhead.extra){for(d=o.pending;o.gzindex<(65535&o.gzhead.extra.length)&&(o.pending!==o.pending_buf_size||(o.gzhead.hcrc&&o.pending>d&&(t.adler=E(t.adler,o.pending_buf,o.pending-d,d)),s(t),d=o.pending,o.pending!==o.pending_buf_size));)l(o,255&o.gzhead.extra[o.gzindex]),o.gzindex++;o.gzhead.hcrc&&o.pending>d&&(t.adler=E(t.adler,o.pending_buf,o.pending-d,d)),o.gzindex===o.gzhead.extra.length&&(o.gzindex=0,o.status=ot)}else o.status=ot;if(o.status===ot)if(o.gzhead.name){d=o.pending;do{if(o.pending===o.pending_buf_size&&(o.gzhead.hcrc&&o.pending>d&&(t.adler=E(t.adler,o.pending_buf,o.pending-d,d)),s(t),d=o.pending,o.pending===o.pending_buf_size)){f=1;break}f=o.gzindex<o.gzhead.name.length?255&o.gzhead.name.charCodeAt(o.gzindex++):0,l(o,f)}while(0!==f);o.gzhead.hcrc&&o.pending>d&&(t.adler=E(t.adler,o.pending_buf,o.pending-d,d)),0===f&&(o.gzindex=0,o.status=lt)}else o.status=lt;if(o.status===lt)if(o.gzhead.comment){d=o.pending;do{if(o.pending===o.pending_buf_size&&(o.gzhead.hcrc&&o.pending>d&&(t.adler=E(t.adler,o.pending_buf,o.pending-d,d)),s(t),d=o.pending,o.pending===o.pending_buf_size)){f=1;break}f=o.gzindex<o.gzhead.comment.length?255&o.gzhead.comment.charCodeAt(o.gzindex++):0,l(o,f)}while(0!==f);o.gzhead.hcrc&&o.pending>d&&(t.adler=E(t.adler,o.pending_buf,o.pending-d,d)),0===f&&(o.status=ht)}else o.status=ht;if(o.status===ht&&(o.gzhead.hcrc?(o.pending+2>o.pending_buf_size&&s(t),o.pending+2<=o.pending_buf_size&&(l(o,255&t.adler),l(o,t.adler>>8&255),t.adler=0,o.status=dt)):o.status=dt),0!==o.pending){if(s(t),0===t.avail_out)return o.last_flush=-1,D}else if(0===t.avail_in&&n(e)<=n(a)&&e!==N)return i(t,F);if(o.status===ft&&0!==t.avail_in)return i(t,F);if(0!==t.avail_in||0!==o.lookahead||e!==Z&&o.status!==ft){var u=o.strategy===j?g(o,e):o.strategy===K?b(o,e):x[o.level].func(o,e);if(u!==ct&&u!==bt||(o.status=ft),u===_t||u===ct)return 0===t.avail_out&&(o.last_flush=-1),D;if(u===ut&&(e===R?B._tr_align(o):e!==O&&(B._tr_stored_block(o,0,0,!1),e===C&&(r(o.head),0===o.lookahead&&(o.strstart=0,o.block_start=0,o.insert=0))),s(t),0===t.avail_out))return o.last_flush=-1,D}return e!==N?D:o.wrap<=0?I:(2===o.wrap?(l(o,255&t.adler),l(o,t.adler>>8&255),l(o,t.adler>>16&255),l(o,t.adler>>24&255),l(o,255&t.total_in),l(o,t.total_in>>8&255),l(o,t.total_in>>16&255),l(o,t.total_in>>24&255)):(h(o,t.adler>>>16),h(o,65535&t.adler)),s(t),o.wrap>0&&(o.wrap=-o.wrap),0!==o.pending?D:I)},a.deflateEnd=function(t){var e;return t&&t.state?(e=t.state.status)!==rt&&e!==st&&e!==ot&&e!==lt&&e!==ht&&e!==dt&&e!==ft?i(t,U):(t.state=null,e===dt?i(t,T):D):U},a.deflateSetDictionary=function(t,e){var a,i,n,s,o,l,h,d,f=e.length;if(!t||!t.state)return U;if(a=t.state,2===(s=a.wrap)||1===s&&a.status!==rt||a.lookahead)return U;for(1===s&&(t.adler=S(t.adler,e,f,0)),a.wrap=0,f>=a.w_size&&(0===s&&(r(a.head),a.strstart=0,a.block_start=0,a.insert=0),d=new z.Buf8(a.w_size),z.arraySet(d,e,f-a.w_size,a.w_size,0),e=d,f=a.w_size),o=t.avail_in,l=t.next_in,h=t.input,t.avail_in=f,t.next_in=0,t.input=e,_(a);a.lookahead>=et;){i=a.strstart,n=a.lookahead-(et-1);do{a.ins_h=(a.ins_h<<a.hash_shift^a.window[i+et-1])&a.hash_mask,a.prev[i&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=i,i++}while(--n);a.strstart=i,a.lookahead=et-1,_(a)}return a.strstart+=a.lookahead,a.block_start=a.strstart,a.insert=a.lookahead,a.lookahead=0,a.match_length=a.prev_length=et-1,a.match_available=0,t.next_in=l,t.input=h,t.avail_in=o,a.wrap=s,D},a.deflateInfo="pako deflate (from Nodeca project)"},{"../utils/common":3,"./adler32":5,"./crc32":7,"./messages":13,"./trees":14}],9:[function(t,e,a){"use strict";e.exports=function(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}},{}],10:[function(t,e,a){"use strict";e.exports=function(t,e){var a,i,n,r,s,o,l,h,d,f,_,u,c,b,g,m,w,p,v,k,y,x,z,B,S;a=t.state,i=t.next_in,B=t.input,n=i+(t.avail_in-5),r=t.next_out,S=t.output,s=r-(e-t.avail_out),o=r+(t.avail_out-257),l=a.dmax,h=a.wsize,d=a.whave,f=a.wnext,_=a.window,u=a.hold,c=a.bits,b=a.lencode,g=a.distcode,m=(1<<a.lenbits)-1,w=(1<<a.distbits)-1;t:do{c<15&&(u+=B[i++]<<c,c+=8,u+=B[i++]<<c,c+=8),p=b[u&m];e:for(;;){if(v=p>>>24,u>>>=v,c-=v,0===(v=p>>>16&255))S[r++]=65535&p;else{if(!(16&v)){if(0==(64&v)){p=b[(65535&p)+(u&(1<<v)-1)];continue e}if(32&v){a.mode=12;break t}t.msg="invalid literal/length code",a.mode=30;break t}k=65535&p,(v&=15)&&(c<v&&(u+=B[i++]<<c,c+=8),k+=u&(1<<v)-1,u>>>=v,c-=v),c<15&&(u+=B[i++]<<c,c+=8,u+=B[i++]<<c,c+=8),p=g[u&w];a:for(;;){if(v=p>>>24,u>>>=v,c-=v,!(16&(v=p>>>16&255))){if(0==(64&v)){p=g[(65535&p)+(u&(1<<v)-1)];continue a}t.msg="invalid distance code",a.mode=30;break t}if(y=65535&p,v&=15,c<v&&(u+=B[i++]<<c,(c+=8)<v&&(u+=B[i++]<<c,c+=8)),(y+=u&(1<<v)-1)>l){t.msg="invalid distance too far back",a.mode=30;break t}if(u>>>=v,c-=v,v=r-s,y>v){if((v=y-v)>d&&a.sane){t.msg="invalid distance too far back",a.mode=30;break t}if(x=0,z=_,0===f){if(x+=h-v,v<k){k-=v;do{S[r++]=_[x++]}while(--v);x=r-y,z=S}}else if(f<v){if(x+=h+f-v,(v-=f)<k){k-=v;do{S[r++]=_[x++]}while(--v);if(x=0,f<k){k-=v=f;do{S[r++]=_[x++]}while(--v);x=r-y,z=S}}}else if(x+=f-v,v<k){k-=v;do{S[r++]=_[x++]}while(--v);x=r-y,z=S}for(;k>2;)S[r++]=z[x++],S[r++]=z[x++],S[r++]=z[x++],k-=3;k&&(S[r++]=z[x++],k>1&&(S[r++]=z[x++]))}else{x=r-y;do{S[r++]=S[x++],S[r++]=S[x++],S[r++]=S[x++],k-=3}while(k>2);k&&(S[r++]=S[x++],k>1&&(S[r++]=S[x++]))}break}}break}}while(i<n&&r<o);i-=k=c>>3,u&=(1<<(c-=k<<3))-1,t.next_in=i,t.next_out=r,t.avail_in=i<n?n-i+5:5-(i-n),t.avail_out=r<o?o-r+257:257-(r-o),a.hold=u,a.bits=c}},{}],11:[function(t,e,a){"use strict";function i(t){return(t>>>24&255)+(t>>>8&65280)+((65280&t)<<8)+((255&t)<<24)}function n(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new u.Buf16(320),this.work=new u.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function r(t){var e;return t&&t.state?(e=t.state,t.total_in=t.total_out=e.total=0,t.msg="",e.wrap&&(t.adler=1&e.wrap),e.mode=N,e.last=0,e.havedict=0,e.dmax=32768,e.head=null,e.hold=0,e.bits=0,e.lencode=e.lendyn=new u.Buf32(dt),e.distcode=e.distdyn=new u.Buf32(ft),e.sane=1,e.back=-1,z):E}function s(t){var e;return t&&t.state?(e=t.state,e.wsize=0,e.whave=0,e.wnext=0,r(t)):E}function o(t,e){var a,i;return t&&t.state?(i=t.state,e<0?(a=0,e=-e):(a=1+(e>>4),e<48&&(e&=15)),e&&(e<8||e>15)?E:(null!==i.window&&i.wbits!==e&&(i.window=null),i.wrap=a,i.wbits=e,s(t))):E}function l(t,e){var a,i;return t?(i=new n,t.state=i,i.window=null,(a=o(t,e))!==z&&(t.state=null),a):E}function h(t){if(ut){var e;for(f=new u.Buf32(512),_=new u.Buf32(32),e=0;e<144;)t.lens[e++]=8;for(;e<256;)t.lens[e++]=9;for(;e<280;)t.lens[e++]=7;for(;e<288;)t.lens[e++]=8;for(m(p,t.lens,0,288,f,0,t.work,{bits:9}),e=0;e<32;)t.lens[e++]=5;m(v,t.lens,0,32,_,0,t.work,{bits:5}),ut=!1}t.lencode=f,t.lenbits=9,t.distcode=_,t.distbits=5}function d(t,e,a,i){var n,r=t.state;return null===r.window&&(r.wsize=1<<r.wbits,r.wnext=0,r.whave=0,r.window=new u.Buf8(r.wsize)),i>=r.wsize?(u.arraySet(r.window,e,a-r.wsize,r.wsize,0),r.wnext=0,r.whave=r.wsize):((n=r.wsize-r.wnext)>i&&(n=i),u.arraySet(r.window,e,a-i,n,r.wnext),(i-=n)?(u.arraySet(r.window,e,a-i,i,0),r.wnext=i,r.whave=r.wsize):(r.wnext+=n,r.wnext===r.wsize&&(r.wnext=0),r.whave<r.wsize&&(r.whave+=n))),0}var f,_,u=t("../utils/common"),c=t("./adler32"),b=t("./crc32"),g=t("./inffast"),m=t("./inftrees"),w=0,p=1,v=2,k=4,y=5,x=6,z=0,B=1,S=2,E=-2,A=-3,Z=-4,R=-5,C=8,N=1,O=2,D=3,I=4,U=5,T=6,F=7,L=8,H=9,j=10,K=11,M=12,P=13,Y=14,q=15,G=16,X=17,W=18,J=19,Q=20,V=21,$=22,tt=23,et=24,at=25,it=26,nt=27,rt=28,st=29,ot=30,lt=31,ht=32,dt=852,ft=592,_t=15,ut=!0;a.inflateReset=s,a.inflateReset2=o,a.inflateResetKeep=r,a.inflateInit=function(t){return l(t,_t)},a.inflateInit2=l,a.inflate=function(t,e){var a,n,r,s,o,l,f,_,dt,ft,_t,ut,ct,bt,gt,mt,wt,pt,vt,kt,yt,xt,zt,Bt,St=0,Et=new u.Buf8(4),At=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];if(!t||!t.state||!t.output||!t.input&&0!==t.avail_in)return E;(a=t.state).mode===M&&(a.mode=P),o=t.next_out,r=t.output,f=t.avail_out,s=t.next_in,n=t.input,l=t.avail_in,_=a.hold,dt=a.bits,ft=l,_t=f,xt=z;t:for(;;)switch(a.mode){case N:if(0===a.wrap){a.mode=P;break}for(;dt<16;){if(0===l)break t;l--,_+=n[s++]<<dt,dt+=8}if(2&a.wrap&&35615===_){a.check=0,Et[0]=255&_,Et[1]=_>>>8&255,a.check=b(a.check,Et,2,0),_=0,dt=0,a.mode=O;break}if(a.flags=0,a.head&&(a.head.done=!1),!(1&a.wrap)||(((255&_)<<8)+(_>>8))%31){t.msg="incorrect header check",a.mode=ot;break}if((15&_)!==C){t.msg="unknown compression method",a.mode=ot;break}if(_>>>=4,dt-=4,yt=8+(15&_),0===a.wbits)a.wbits=yt;else if(yt>a.wbits){t.msg="invalid window size",a.mode=ot;break}a.dmax=1<<yt,t.adler=a.check=1,a.mode=512&_?j:M,_=0,dt=0;break;case O:for(;dt<16;){if(0===l)break t;l--,_+=n[s++]<<dt,dt+=8}if(a.flags=_,(255&a.flags)!==C){t.msg="unknown compression method",a.mode=ot;break}if(57344&a.flags){t.msg="unknown header flags set",a.mode=ot;break}a.head&&(a.head.text=_>>8&1),512&a.flags&&(Et[0]=255&_,Et[1]=_>>>8&255,a.check=b(a.check,Et,2,0)),_=0,dt=0,a.mode=D;case D:for(;dt<32;){if(0===l)break t;l--,_+=n[s++]<<dt,dt+=8}a.head&&(a.head.time=_),512&a.flags&&(Et[0]=255&_,Et[1]=_>>>8&255,Et[2]=_>>>16&255,Et[3]=_>>>24&255,a.check=b(a.check,Et,4,0)),_=0,dt=0,a.mode=I;case I:for(;dt<16;){if(0===l)break t;l--,_+=n[s++]<<dt,dt+=8}a.head&&(a.head.xflags=255&_,a.head.os=_>>8),512&a.flags&&(Et[0]=255&_,Et[1]=_>>>8&255,a.check=b(a.check,Et,2,0)),_=0,dt=0,a.mode=U;case U:if(1024&a.flags){for(;dt<16;){if(0===l)break t;l--,_+=n[s++]<<dt,dt+=8}a.length=_,a.head&&(a.head.extra_len=_),512&a.flags&&(Et[0]=255&_,Et[1]=_>>>8&255,a.check=b(a.check,Et,2,0)),_=0,dt=0}else a.head&&(a.head.extra=null);a.mode=T;case T:if(1024&a.flags&&((ut=a.length)>l&&(ut=l),ut&&(a.head&&(yt=a.head.extra_len-a.length,a.head.extra||(a.head.extra=new Array(a.head.extra_len)),u.arraySet(a.head.extra,n,s,ut,yt)),512&a.flags&&(a.check=b(a.check,n,ut,s)),l-=ut,s+=ut,a.length-=ut),a.length))break t;a.length=0,a.mode=F;case F:if(2048&a.flags){if(0===l)break t;ut=0;do{yt=n[s+ut++],a.head&&yt&&a.length<65536&&(a.head.name+=String.fromCharCode(yt))}while(yt&&ut<l);if(512&a.flags&&(a.check=b(a.check,n,ut,s)),l-=ut,s+=ut,yt)break t}else a.head&&(a.head.name=null);a.length=0,a.mode=L;case L:if(4096&a.flags){if(0===l)break t;ut=0;do{yt=n[s+ut++],a.head&&yt&&a.length<65536&&(a.head.comment+=String.fromCharCode(yt))}while(yt&&ut<l);if(512&a.flags&&(a.check=b(a.check,n,ut,s)),l-=ut,s+=ut,yt)break t}else a.head&&(a.head.comment=null);a.mode=H;case H:if(512&a.flags){for(;dt<16;){if(0===l)break t;l--,_+=n[s++]<<dt,dt+=8}if(_!==(65535&a.check)){t.msg="header crc mismatch",a.mode=ot;break}_=0,dt=0}a.head&&(a.head.hcrc=a.flags>>9&1,a.head.done=!0),t.adler=a.check=0,a.mode=M;break;case j:for(;dt<32;){if(0===l)break t;l--,_+=n[s++]<<dt,dt+=8}t.adler=a.check=i(_),_=0,dt=0,a.mode=K;case K:if(0===a.havedict)return t.next_out=o,t.avail_out=f,t.next_in=s,t.avail_in=l,a.hold=_,a.bits=dt,S;t.adler=a.check=1,a.mode=M;case M:if(e===y||e===x)break t;case P:if(a.last){_>>>=7&dt,dt-=7&dt,a.mode=nt;break}for(;dt<3;){if(0===l)break t;l--,_+=n[s++]<<dt,dt+=8}switch(a.last=1&_,_>>>=1,dt-=1,3&_){case 0:a.mode=Y;break;case 1:if(h(a),a.mode=Q,e===x){_>>>=2,dt-=2;break t}break;case 2:a.mode=X;break;case 3:t.msg="invalid block type",a.mode=ot}_>>>=2,dt-=2;break;case Y:for(_>>>=7&dt,dt-=7&dt;dt<32;){if(0===l)break t;l--,_+=n[s++]<<dt,dt+=8}if((65535&_)!=(_>>>16^65535)){t.msg="invalid stored block lengths",a.mode=ot;break}if(a.length=65535&_,_=0,dt=0,a.mode=q,e===x)break t;case q:a.mode=G;case G:if(ut=a.length){if(ut>l&&(ut=l),ut>f&&(ut=f),0===ut)break t;u.arraySet(r,n,s,ut,o),l-=ut,s+=ut,f-=ut,o+=ut,a.length-=ut;break}a.mode=M;break;case X:for(;dt<14;){if(0===l)break t;l--,_+=n[s++]<<dt,dt+=8}if(a.nlen=257+(31&_),_>>>=5,dt-=5,a.ndist=1+(31&_),_>>>=5,dt-=5,a.ncode=4+(15&_),_>>>=4,dt-=4,a.nlen>286||a.ndist>30){t.msg="too many length or distance symbols",a.mode=ot;break}a.have=0,a.mode=W;case W:for(;a.have<a.ncode;){for(;dt<3;){if(0===l)break t;l--,_+=n[s++]<<dt,dt+=8}a.lens[At[a.have++]]=7&_,_>>>=3,dt-=3}for(;a.have<19;)a.lens[At[a.have++]]=0;if(a.lencode=a.lendyn,a.lenbits=7,zt={bits:a.lenbits},xt=m(w,a.lens,0,19,a.lencode,0,a.work,zt),a.lenbits=zt.bits,xt){t.msg="invalid code lengths set",a.mode=ot;break}a.have=0,a.mode=J;case J:for(;a.have<a.nlen+a.ndist;){for(;St=a.lencode[_&(1<<a.lenbits)-1],gt=St>>>24,mt=St>>>16&255,wt=65535&St,!(gt<=dt);){if(0===l)break t;l--,_+=n[s++]<<dt,dt+=8}if(wt<16)_>>>=gt,dt-=gt,a.lens[a.have++]=wt;else{if(16===wt){for(Bt=gt+2;dt<Bt;){if(0===l)break t;l--,_+=n[s++]<<dt,dt+=8}if(_>>>=gt,dt-=gt,0===a.have){t.msg="invalid bit length repeat",a.mode=ot;break}yt=a.lens[a.have-1],ut=3+(3&_),_>>>=2,dt-=2}else if(17===wt){for(Bt=gt+3;dt<Bt;){if(0===l)break t;l--,_+=n[s++]<<dt,dt+=8}dt-=gt,yt=0,ut=3+(7&(_>>>=gt)),_>>>=3,dt-=3}else{for(Bt=gt+7;dt<Bt;){if(0===l)break t;l--,_+=n[s++]<<dt,dt+=8}dt-=gt,yt=0,ut=11+(127&(_>>>=gt)),_>>>=7,dt-=7}if(a.have+ut>a.nlen+a.ndist){t.msg="invalid bit length repeat",a.mode=ot;break}for(;ut--;)a.lens[a.have++]=yt}}if(a.mode===ot)break;if(0===a.lens[256]){t.msg="invalid code -- missing end-of-block",a.mode=ot;break}if(a.lenbits=9,zt={bits:a.lenbits},xt=m(p,a.lens,0,a.nlen,a.lencode,0,a.work,zt),a.lenbits=zt.bits,xt){t.msg="invalid literal/lengths set",a.mode=ot;break}if(a.distbits=6,a.distcode=a.distdyn,zt={bits:a.distbits},xt=m(v,a.lens,a.nlen,a.ndist,a.distcode,0,a.work,zt),a.distbits=zt.bits,xt){t.msg="invalid distances set",a.mode=ot;break}if(a.mode=Q,e===x)break t;case Q:a.mode=V;case V:if(l>=6&&f>=258){t.next_out=o,t.avail_out=f,t.next_in=s,t.avail_in=l,a.hold=_,a.bits=dt,g(t,_t),o=t.next_out,r=t.output,f=t.avail_out,s=t.next_in,n=t.input,l=t.avail_in,_=a.hold,dt=a.bits,a.mode===M&&(a.back=-1);break}for(a.back=0;St=a.lencode[_&(1<<a.lenbits)-1],gt=St>>>24,mt=St>>>16&255,wt=65535&St,!(gt<=dt);){if(0===l)break t;l--,_+=n[s++]<<dt,dt+=8}if(mt&&0==(240&mt)){for(pt=gt,vt=mt,kt=wt;St=a.lencode[kt+((_&(1<<pt+vt)-1)>>pt)],gt=St>>>24,mt=St>>>16&255,wt=65535&St,!(pt+gt<=dt);){if(0===l)break t;l--,_+=n[s++]<<dt,dt+=8}_>>>=pt,dt-=pt,a.back+=pt}if(_>>>=gt,dt-=gt,a.back+=gt,a.length=wt,0===mt){a.mode=it;break}if(32&mt){a.back=-1,a.mode=M;break}if(64&mt){t.msg="invalid literal/length code",a.mode=ot;break}a.extra=15&mt,a.mode=$;case $:if(a.extra){for(Bt=a.extra;dt<Bt;){if(0===l)break t;l--,_+=n[s++]<<dt,dt+=8}a.length+=_&(1<<a.extra)-1,_>>>=a.extra,dt-=a.extra,a.back+=a.extra}a.was=a.length,a.mode=tt;case tt:for(;St=a.distcode[_&(1<<a.distbits)-1],gt=St>>>24,mt=St>>>16&255,wt=65535&St,!(gt<=dt);){if(0===l)break t;l--,_+=n[s++]<<dt,dt+=8}if(0==(240&mt)){for(pt=gt,vt=mt,kt=wt;St=a.distcode[kt+((_&(1<<pt+vt)-1)>>pt)],gt=St>>>24,mt=St>>>16&255,wt=65535&St,!(pt+gt<=dt);){if(0===l)break t;l--,_+=n[s++]<<dt,dt+=8}_>>>=pt,dt-=pt,a.back+=pt}if(_>>>=gt,dt-=gt,a.back+=gt,64&mt){t.msg="invalid distance code",a.mode=ot;break}a.offset=wt,a.extra=15&mt,a.mode=et;case et:if(a.extra){for(Bt=a.extra;dt<Bt;){if(0===l)break t;l--,_+=n[s++]<<dt,dt+=8}a.offset+=_&(1<<a.extra)-1,_>>>=a.extra,dt-=a.extra,a.back+=a.extra}if(a.offset>a.dmax){t.msg="invalid distance too far back",a.mode=ot;break}a.mode=at;case at:if(0===f)break t;if(ut=_t-f,a.offset>ut){if((ut=a.offset-ut)>a.whave&&a.sane){t.msg="invalid distance too far back",a.mode=ot;break}ut>a.wnext?(ut-=a.wnext,ct=a.wsize-ut):ct=a.wnext-ut,ut>a.length&&(ut=a.length),bt=a.window}else bt=r,ct=o-a.offset,ut=a.length;ut>f&&(ut=f),f-=ut,a.length-=ut;do{r[o++]=bt[ct++]}while(--ut);0===a.length&&(a.mode=V);break;case it:if(0===f)break t;r[o++]=a.length,f--,a.mode=V;break;case nt:if(a.wrap){for(;dt<32;){if(0===l)break t;l--,_|=n[s++]<<dt,dt+=8}if(_t-=f,t.total_out+=_t,a.total+=_t,_t&&(t.adler=a.check=a.flags?b(a.check,r,_t,o-_t):c(a.check,r,_t,o-_t)),_t=f,(a.flags?_:i(_))!==a.check){t.msg="incorrect data check",a.mode=ot;break}_=0,dt=0}a.mode=rt;case rt:if(a.wrap&&a.flags){for(;dt<32;){if(0===l)break t;l--,_+=n[s++]<<dt,dt+=8}if(_!==(4294967295&a.total)){t.msg="incorrect length check",a.mode=ot;break}_=0,dt=0}a.mode=st;case st:xt=B;break t;case ot:xt=A;break t;case lt:return Z;case ht:default:return E}return t.next_out=o,t.avail_out=f,t.next_in=s,t.avail_in=l,a.hold=_,a.bits=dt,(a.wsize||_t!==t.avail_out&&a.mode<ot&&(a.mode<nt||e!==k))&&d(t,t.output,t.next_out,_t-t.avail_out)?(a.mode=lt,Z):(ft-=t.avail_in,_t-=t.avail_out,t.total_in+=ft,t.total_out+=_t,a.total+=_t,a.wrap&&_t&&(t.adler=a.check=a.flags?b(a.check,r,_t,t.next_out-_t):c(a.check,r,_t,t.next_out-_t)),t.data_type=a.bits+(a.last?64:0)+(a.mode===M?128:0)+(a.mode===Q||a.mode===q?256:0),(0===ft&&0===_t||e===k)&&xt===z&&(xt=R),xt)},a.inflateEnd=function(t){if(!t||!t.state)return E;var e=t.state;return e.window&&(e.window=null),t.state=null,z},a.inflateGetHeader=function(t,e){var a;return t&&t.state?0==(2&(a=t.state).wrap)?E:(a.head=e,e.done=!1,z):E},a.inflateSetDictionary=function(t,e){var a,i,n=e.length;return t&&t.state?0!==(a=t.state).wrap&&a.mode!==K?E:a.mode===K&&(i=1,(i=c(i,e,n,0))!==a.check)?A:d(t,e,n,n)?(a.mode=lt,Z):(a.havedict=1,z):E},a.inflateInfo="pako inflate (from Nodeca project)"},{"../utils/common":3,"./adler32":5,"./crc32":7,"./inffast":10,"./inftrees":12}],12:[function(t,e,a){"use strict";var i=t("../utils/common"),n=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],r=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],s=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],o=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];e.exports=function(t,e,a,l,h,d,f,_){var u,c,b,g,m,w,p,v,k,y=_.bits,x=0,z=0,B=0,S=0,E=0,A=0,Z=0,R=0,C=0,N=0,O=null,D=0,I=new i.Buf16(16),U=new i.Buf16(16),T=null,F=0;for(x=0;x<=15;x++)I[x]=0;for(z=0;z<l;z++)I[e[a+z]]++;for(E=y,S=15;S>=1&&0===I[S];S--);if(E>S&&(E=S),0===S)return h[d++]=20971520,h[d++]=20971520,_.bits=1,0;for(B=1;B<S&&0===I[B];B++);for(E<B&&(E=B),R=1,x=1;x<=15;x++)if(R<<=1,(R-=I[x])<0)return-1;if(R>0&&(0===t||1!==S))return-1;for(U[1]=0,x=1;x<15;x++)U[x+1]=U[x]+I[x];for(z=0;z<l;z++)0!==e[a+z]&&(f[U[e[a+z]]++]=z);if(0===t?(O=T=f,w=19):1===t?(O=n,D-=257,T=r,F-=257,w=256):(O=s,T=o,w=-1),N=0,z=0,x=B,m=d,A=E,Z=0,b=-1,C=1<<E,g=C-1,1===t&&C>852||2===t&&C>592)return 1;for(;;){p=x-Z,f[z]<w?(v=0,k=f[z]):f[z]>w?(v=T[F+f[z]],k=O[D+f[z]]):(v=96,k=0),u=1<<x-Z,B=c=1<<A;do{h[m+(N>>Z)+(c-=u)]=p<<24|v<<16|k|0}while(0!==c);for(u=1<<x-1;N&u;)u>>=1;if(0!==u?(N&=u-1,N+=u):N=0,z++,0==--I[x]){if(x===S)break;x=e[a+f[z]]}if(x>E&&(N&g)!==b){for(0===Z&&(Z=E),m+=B,R=1<<(A=x-Z);A+Z<S&&!((R-=I[A+Z])<=0);)A++,R<<=1;if(C+=1<<A,1===t&&C>852||2===t&&C>592)return 1;h[b=N&g]=E<<24|A<<16|m-d|0}}return 0!==N&&(h[m+N]=x-Z<<24|64<<16|0),_.bits=E,0}},{"../utils/common":3}],13:[function(t,e,a){"use strict";e.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],14:[function(t,e,a){"use strict";function i(t){for(var e=t.length;--e>=0;)t[e]=0}function n(t,e,a,i,n){this.static_tree=t,this.extra_bits=e,this.extra_base=a,this.elems=i,this.max_length=n,this.has_stree=t&&t.length}function r(t,e){this.dyn_tree=t,this.max_code=0,this.stat_desc=e}function s(t){return t<256?et[t]:et[256+(t>>>7)]}function o(t,e){t.pending_buf[t.pending++]=255&e,t.pending_buf[t.pending++]=e>>>8&255}function l(t,e,a){t.bi_valid>M-a?(t.bi_buf|=e<<t.bi_valid&65535,o(t,t.bi_buf),t.bi_buf=e>>M-t.bi_valid,t.bi_valid+=a-M):(t.bi_buf|=e<<t.bi_valid&65535,t.bi_valid+=a)}function h(t,e,a){l(t,a[2*e],a[2*e+1])}function d(t,e){var a=0;do{a|=1&t,t>>>=1,a<<=1}while(--e>0);return a>>>1}function f(t){16===t.bi_valid?(o(t,t.bi_buf),t.bi_buf=0,t.bi_valid=0):t.bi_valid>=8&&(t.pending_buf[t.pending++]=255&t.bi_buf,t.bi_buf>>=8,t.bi_valid-=8)}function _(t,e){var a,i,n,r,s,o,l=e.dyn_tree,h=e.max_code,d=e.stat_desc.static_tree,f=e.stat_desc.has_stree,_=e.stat_desc.extra_bits,u=e.stat_desc.extra_base,c=e.stat_desc.max_length,b=0;for(r=0;r<=K;r++)t.bl_count[r]=0;for(l[2*t.heap[t.heap_max]+1]=0,a=t.heap_max+1;a<j;a++)(r=l[2*l[2*(i=t.heap[a])+1]+1]+1)>c&&(r=c,b++),l[2*i+1]=r,i>h||(t.bl_count[r]++,s=0,i>=u&&(s=_[i-u]),o=l[2*i],t.opt_len+=o*(r+s),f&&(t.static_len+=o*(d[2*i+1]+s)));if(0!==b){do{for(r=c-1;0===t.bl_count[r];)r--;t.bl_count[r]--,t.bl_count[r+1]+=2,t.bl_count[c]--,b-=2}while(b>0);for(r=c;0!==r;r--)for(i=t.bl_count[r];0!==i;)(n=t.heap[--a])>h||(l[2*n+1]!==r&&(t.opt_len+=(r-l[2*n+1])*l[2*n],l[2*n+1]=r),i--)}}function u(t,e,a){var i,n,r=new Array(K+1),s=0;for(i=1;i<=K;i++)r[i]=s=s+a[i-1]<<1;for(n=0;n<=e;n++){var o=t[2*n+1];0!==o&&(t[2*n]=d(r[o]++,o))}}function c(){var t,e,a,i,r,s=new Array(K+1);for(a=0,i=0;i<U-1;i++)for(it[i]=a,t=0;t<1<<W[i];t++)at[a++]=i;for(at[a-1]=i,r=0,i=0;i<16;i++)for(nt[i]=r,t=0;t<1<<J[i];t++)et[r++]=i;for(r>>=7;i<L;i++)for(nt[i]=r<<7,t=0;t<1<<J[i]-7;t++)et[256+r++]=i;for(e=0;e<=K;e++)s[e]=0;for(t=0;t<=143;)$[2*t+1]=8,t++,s[8]++;for(;t<=255;)$[2*t+1]=9,t++,s[9]++;for(;t<=279;)$[2*t+1]=7,t++,s[7]++;for(;t<=287;)$[2*t+1]=8,t++,s[8]++;for(u($,F+1,s),t=0;t<L;t++)tt[2*t+1]=5,tt[2*t]=d(t,5);rt=new n($,W,T+1,F,K),st=new n(tt,J,0,L,K),ot=new n(new Array(0),Q,0,H,P)}function b(t){var e;for(e=0;e<F;e++)t.dyn_ltree[2*e]=0;for(e=0;e<L;e++)t.dyn_dtree[2*e]=0;for(e=0;e<H;e++)t.bl_tree[2*e]=0;t.dyn_ltree[2*Y]=1,t.opt_len=t.static_len=0,t.last_lit=t.matches=0}function g(t){t.bi_valid>8?o(t,t.bi_buf):t.bi_valid>0&&(t.pending_buf[t.pending++]=t.bi_buf),t.bi_buf=0,t.bi_valid=0}function m(t,e,a,i){g(t),i&&(o(t,a),o(t,~a)),A.arraySet(t.pending_buf,t.window,e,a,t.pending),t.pending+=a}function w(t,e,a,i){var n=2*e,r=2*a;return t[n]<t[r]||t[n]===t[r]&&i[e]<=i[a]}function p(t,e,a){for(var i=t.heap[a],n=a<<1;n<=t.heap_len&&(n<t.heap_len&&w(e,t.heap[n+1],t.heap[n],t.depth)&&n++,!w(e,i,t.heap[n],t.depth));)t.heap[a]=t.heap[n],a=n,n<<=1;t.heap[a]=i}function v(t,e,a){var i,n,r,o,d=0;if(0!==t.last_lit)do{i=t.pending_buf[t.d_buf+2*d]<<8|t.pending_buf[t.d_buf+2*d+1],n=t.pending_buf[t.l_buf+d],d++,0===i?h(t,n,e):(h(t,(r=at[n])+T+1,e),0!==(o=W[r])&&l(t,n-=it[r],o),h(t,r=s(--i),a),0!==(o=J[r])&&l(t,i-=nt[r],o))}while(d<t.last_lit);h(t,Y,e)}function k(t,e){var a,i,n,r=e.dyn_tree,s=e.stat_desc.static_tree,o=e.stat_desc.has_stree,l=e.stat_desc.elems,h=-1;for(t.heap_len=0,t.heap_max=j,a=0;a<l;a++)0!==r[2*a]?(t.heap[++t.heap_len]=h=a,t.depth[a]=0):r[2*a+1]=0;for(;t.heap_len<2;)r[2*(n=t.heap[++t.heap_len]=h<2?++h:0)]=1,t.depth[n]=0,t.opt_len--,o&&(t.static_len-=s[2*n+1]);for(e.max_code=h,a=t.heap_len>>1;a>=1;a--)p(t,r,a);n=l;do{a=t.heap[1],t.heap[1]=t.heap[t.heap_len--],p(t,r,1),i=t.heap[1],t.heap[--t.heap_max]=a,t.heap[--t.heap_max]=i,r[2*n]=r[2*a]+r[2*i],t.depth[n]=(t.depth[a]>=t.depth[i]?t.depth[a]:t.depth[i])+1,r[2*a+1]=r[2*i+1]=n,t.heap[1]=n++,p(t,r,1)}while(t.heap_len>=2);t.heap[--t.heap_max]=t.heap[1],_(t,e),u(r,h,t.bl_count)}function y(t,e,a){var i,n,r=-1,s=e[1],o=0,l=7,h=4;for(0===s&&(l=138,h=3),e[2*(a+1)+1]=65535,i=0;i<=a;i++)n=s,s=e[2*(i+1)+1],++o<l&&n===s||(o<h?t.bl_tree[2*n]+=o:0!==n?(n!==r&&t.bl_tree[2*n]++,t.bl_tree[2*q]++):o<=10?t.bl_tree[2*G]++:t.bl_tree[2*X]++,o=0,r=n,0===s?(l=138,h=3):n===s?(l=6,h=3):(l=7,h=4))}function x(t,e,a){var i,n,r=-1,s=e[1],o=0,d=7,f=4;for(0===s&&(d=138,f=3),i=0;i<=a;i++)if(n=s,s=e[2*(i+1)+1],!(++o<d&&n===s)){if(o<f)do{h(t,n,t.bl_tree)}while(0!=--o);else 0!==n?(n!==r&&(h(t,n,t.bl_tree),o--),h(t,q,t.bl_tree),l(t,o-3,2)):o<=10?(h(t,G,t.bl_tree),l(t,o-3,3)):(h(t,X,t.bl_tree),l(t,o-11,7));o=0,r=n,0===s?(d=138,f=3):n===s?(d=6,f=3):(d=7,f=4)}}function z(t){var e;for(y(t,t.dyn_ltree,t.l_desc.max_code),y(t,t.dyn_dtree,t.d_desc.max_code),k(t,t.bl_desc),e=H-1;e>=3&&0===t.bl_tree[2*V[e]+1];e--);return t.opt_len+=3*(e+1)+5+5+4,e}function B(t,e,a,i){var n;for(l(t,e-257,5),l(t,a-1,5),l(t,i-4,4),n=0;n<i;n++)l(t,t.bl_tree[2*V[n]+1],3);x(t,t.dyn_ltree,e-1),x(t,t.dyn_dtree,a-1)}function S(t){var e,a=4093624447;for(e=0;e<=31;e++,a>>>=1)if(1&a&&0!==t.dyn_ltree[2*e])return R;if(0!==t.dyn_ltree[18]||0!==t.dyn_ltree[20]||0!==t.dyn_ltree[26])return C;for(e=32;e<T;e++)if(0!==t.dyn_ltree[2*e])return C;return R}function E(t,e,a,i){l(t,(O<<1)+(i?1:0),3),m(t,e,a,!0)}var A=t("../utils/common"),Z=4,R=0,C=1,N=2,O=0,D=1,I=2,U=29,T=256,F=T+1+U,L=30,H=19,j=2*F+1,K=15,M=16,P=7,Y=256,q=16,G=17,X=18,W=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],J=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],Q=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],V=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],$=new Array(2*(F+2));i($);var tt=new Array(2*L);i(tt);var et=new Array(512);i(et);var at=new Array(256);i(at);var it=new Array(U);i(it);var nt=new Array(L);i(nt);var rt,st,ot,lt=!1;a._tr_init=function(t){lt||(c(),lt=!0),t.l_desc=new r(t.dyn_ltree,rt),t.d_desc=new r(t.dyn_dtree,st),t.bl_desc=new r(t.bl_tree,ot),t.bi_buf=0,t.bi_valid=0,b(t)},a._tr_stored_block=E,a._tr_flush_block=function(t,e,a,i){var n,r,s=0;t.level>0?(t.strm.data_type===N&&(t.strm.data_type=S(t)),k(t,t.l_desc),k(t,t.d_desc),s=z(t),n=t.opt_len+3+7>>>3,(r=t.static_len+3+7>>>3)<=n&&(n=r)):n=r=a+5,a+4<=n&&-1!==e?E(t,e,a,i):t.strategy===Z||r===n?(l(t,(D<<1)+(i?1:0),3),v(t,$,tt)):(l(t,(I<<1)+(i?1:0),3),B(t,t.l_desc.max_code+1,t.d_desc.max_code+1,s+1),v(t,t.dyn_ltree,t.dyn_dtree)),b(t),i&&g(t)},a._tr_tally=function(t,e,a){return t.pending_buf[t.d_buf+2*t.last_lit]=e>>>8&255,t.pending_buf[t.d_buf+2*t.last_lit+1]=255&e,t.pending_buf[t.l_buf+t.last_lit]=255&a,t.last_lit++,0===e?t.dyn_ltree[2*a]++:(t.matches++,e--,t.dyn_ltree[2*(at[a]+T+1)]++,t.dyn_dtree[2*s(e)]++),t.last_lit===t.lit_bufsize-1},a._tr_align=function(t){l(t,D<<1,3),h(t,Y,$),f(t)}},{"../utils/common":3}],15:[function(t,e,a){"use strict";e.exports=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}},{}],"/":[function(t,e,a){"use strict";var i={};(0,t("./lib/utils/common").assign)(i,t("./lib/deflate"),t("./lib/inflate"),t("./lib/zlib/constants")),e.exports=i},{"./lib/deflate":1,"./lib/inflate":2,"./lib/utils/common":3,"./lib/zlib/constants":6}]},{},[])("/")});'use strict';tr.exportTo('tr.e.importer',function(){const GZIP_MEMBER_HEADER_ID_SIZE=3;const GZIP_HEADER_ID1=0x1f;const GZIP_HEADER_ID2=0x8b;const GZIP_DEFLATE_COMPRESSION=8;function _stringToUInt8Array(str){const array=new Uint8Array(str.length);for(let i=0;i<str.length;++i){array[i]=str.charCodeAt(i);}
+return array;}
+function GzipImporter(model,eventData){this.inflateAsTraceStream=false;if(typeof(eventData)==='string'||eventData instanceof String){eventData=_stringToUInt8Array(eventData);}else if(eventData instanceof ArrayBuffer){eventData=new Uint8Array(eventData);}else if(eventData instanceof tr.b.InMemoryTraceStream){eventData=eventData.data;this.inflateAsTraceStream_=true;}else{throw new Error('Unknown gzip data format');}
+this.model_=model;this.gzipData_=eventData;}
+GzipImporter.canImport=function(eventData){if(eventData instanceof tr.b.InMemoryTraceStream){eventData=eventData.header;}
+let header;if(eventData instanceof ArrayBuffer){header=new Uint8Array(eventData.slice(0,GZIP_MEMBER_HEADER_ID_SIZE));}else if(typeof(eventData)==='string'||eventData instanceof String){header=eventData.substring(0,GZIP_MEMBER_HEADER_ID_SIZE);header=_stringToUInt8Array(header);}else{return false;}
+return header[0]===GZIP_HEADER_ID1&&header[1]===GZIP_HEADER_ID2&&header[2]===GZIP_DEFLATE_COMPRESSION;};GzipImporter.inflateGzipData_=function(data){let position=0;function getByte(){if(position>=data.length){throw new Error('Unexpected end of gzip data');}
+return data[position++];}
+function getWord(){const low=getByte();const high=getByte();return(high<<8)+low;}
 function skipBytes(amount){position+=amount;}
-function skipZeroTerminatedString(){while(getByte()!=0){}}
-var id1=getByte();var id2=getByte();if(id1!==GZIP_HEADER_ID1||id2!==GZIP_HEADER_ID2)
-throw new Error('Not gzip data');var compression_method=getByte();if(compression_method!==GZIP_DEFLATE_COMPRESSION)
-throw new Error('Unsupported compression method: '+compression_method);var flags=getByte();var have_header_crc=flags&(1<<1);var have_extra_fields=flags&(1<<2);var have_file_name=flags&(1<<3);var have_comment=flags&(1<<4);skipBytes(4+1+1);if(have_extra_fields){var bytes_to_skip=getWord();skipBytes(bytes_to_skip);}
-if(have_file_name)
-skipZeroTerminatedString();if(have_comment)
-skipZeroTerminatedString();if(have_header_crc)
-getWord();var inflated_data=JSZip.compressions['DEFLATE'].uncompress(data.subarray(position));var string=GzipImporter.transformToString(inflated_data);if(inflated_data.length>0&&string.length===0){throw new RangeError('Inflated gzip data too long to fit into a string'+' ('+inflated_data.length+').');}
-return string;};GzipImporter.transformToString=function(data){if(typeof TextDecoder==='undefined'){return JSZip.utils.transformTo('string',data);}
-var type=JSZip.utils.getTypeOf(data);if(type==='string')
-return data;if(type==='array'){data=new Uint8Array(data);}
-var decoder=new TextDecoder('utf-8');return decoder.decode(data);};GzipImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'GzipImporter';},isTraceDataContainer:function(){return true;},extractSubtraces:function(){var eventData=GzipImporter.inflateGzipData_(this.gzipData_);return eventData?[eventData]:[];}};tr.importer.Importer.register(GzipImporter);return{GzipImporter:GzipImporter};});'use strict';tr.exportTo('tr.importer',function(){function SimpleLineReader(text){this.lines_=text.split('\n');this.curLine_=0;this.savedLines_=undefined;}
-SimpleLineReader.prototype={advanceToLineMatching:function(regex){for(;this.curLine_<this.lines_.length;this.curLine_++){var line=this.lines_[this.curLine_];if(this.savedLines_!==undefined)
-this.savedLines_.push(line);if(regex.test(line))
-return true;}
-return false;},get curLineNumber(){return this.curLine_;},beginSavingLines:function(){this.savedLines_=[];},endSavingLinesAndGetResult:function(){var tmp=this.savedLines_;this.savedLines_=undefined;return tmp;}};return{SimpleLineReader:SimpleLineReader};});'use strict';tr.exportTo('tr.e.importer',function(){function Trace2HTMLImporter(model,events){this.importPriority=0;}
-Trace2HTMLImporter.subtraces_=[];function _extractEventsFromHTML(text){Trace2HTMLImporter.subtraces_=[];var r=new tr.importer.SimpleLineReader(text);while(true){if(!r.advanceToLineMatching(new RegExp('^<\s*script id="viewer-data" '+'type="(application\/json|text\/plain)">$')))
-break;r.beginSavingLines();if(!r.advanceToLineMatching(/^<\/\s*script>$/))
-return failure;var raw_events=r.endSavingLinesAndGetResult();raw_events=raw_events.slice(1,raw_events.length-1);var data64=raw_events.join('\n');var buffer=new ArrayBuffer(tr.b.Base64.getDecodedBufferLength(data64));var len=tr.b.Base64.DecodeToTypedArray(data64,new DataView(buffer));Trace2HTMLImporter.subtraces_.push(buffer.slice(0,len));}}
-function _canImportFromHTML(text){if(/^<!DOCTYPE html>/.test(text)===false)
-return false;_extractEventsFromHTML(text);if(Trace2HTMLImporter.subtraces_.length===0)
-return false;return true;}
-Trace2HTMLImporter.canImport=function(events){return _canImportFromHTML(events);};Trace2HTMLImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'Trace2HTMLImporter';},isTraceDataContainer:function(){return true;},extractSubtraces:function(){return Trace2HTMLImporter.subtraces_;},importEvents:function(){}};tr.importer.Importer.register(Trace2HTMLImporter);return{Trace2HTMLImporter:Trace2HTMLImporter};});'use strict';tr.exportTo('tr.e.importer.v8',function(){function SplayTree(){};SplayTree.prototype.root_=null;SplayTree.prototype.isEmpty=function(){return!this.root_;};SplayTree.prototype.insert=function(key,value){if(this.isEmpty()){this.root_=new SplayTree.Node(key,value);return;}
-this.splay_(key);if(this.root_.key==key){return;}
-var node=new SplayTree.Node(key,value);if(key>this.root_.key){node.left=this.root_;node.right=this.root_.right;this.root_.right=null;}else{node.right=this.root_;node.left=this.root_.left;this.root_.left=null;}
+function skipZeroTerminatedString(){while(getByte()!==0){}}
+const id1=getByte();const id2=getByte();if(id1!==GZIP_HEADER_ID1||id2!==GZIP_HEADER_ID2){throw new Error('Not gzip data');}
+const compressionMethod=getByte();if(compressionMethod!==GZIP_DEFLATE_COMPRESSION){throw new Error('Unsupported compression method: '+compressionMethod);}
+const flags=getByte();const haveHeaderCrc=flags&(1<<1);const haveExtraFields=flags&(1<<2);const haveFileName=flags&(1<<3);const haveComment=flags&(1<<4);skipBytes(4+1+1);if(haveExtraFields){const bytesToSkip=getWord();skipBytes(bytesToSkip);}
+if(haveFileName)skipZeroTerminatedString();if(haveComment)skipZeroTerminatedString();if(haveHeaderCrc)getWord();const inflatedData=pako.inflateRaw(data.subarray(position));if(this.inflateAsTraceStream_){return GzipImporter.transformToStream(inflatedData);}
+let string;try{string=GzipImporter.transformToString(inflatedData);}catch(err){return GzipImporter.transformToStream(inflatedData);}
+if(inflatedData.length>0&&string.length===0){return GzipImporter.transformToStream(inflatedData);}
+return string;};GzipImporter.transformToStream=function(data){if(data instanceof Uint8Array){return new tr.b.InMemoryTraceStream(data,false);}
+throw new Error(`Cannot transform ${type} to TraceStream.`);};GzipImporter.transformToString=function(data){if(typeof(data)==='string')return data;if(typeof TextDecoder==='undefined'){if(data instanceof ArrayBuffer){data=new Uint8Array(data);}
+const result=[];let chunk=65536;let k=0;const len=data.length;while(k<len&&chunk>1){try{const chunklen=Math.min(k+chunk,len);let dataslice;if(data instanceof Array){dataslice=data.slice(k,chunklen);}else{dataslice=data.subarray(k,chunklen);}
+result.push(String.fromCharCode.apply(null,dataslice));k+=chunk;}catch(e){chunk=Math.floor(chunk/2);}}
+return result.join('');}
+if(data instanceof Array){data=new Uint8Array(data);}
+return new TextDecoder('utf-8').decode(data);};GzipImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'GzipImporter';},isTraceDataContainer(){return true;},extractSubtraces(){const eventData=GzipImporter.inflateGzipData_(this.gzipData_);return eventData?[eventData]:[];}};tr.importer.Importer.register(GzipImporter);return{GzipImporter,};});'use strict';tr.exportTo('tr.importer',function(){class SimpleLineReader{constructor(text){this.data_=text instanceof tr.b.TraceStream?text:text.split(new RegExp('\r?\n'));this.curLine_=0;this.readLastLine_=false;this.savedLines_=undefined;}*[Symbol.iterator](){let lastLine=undefined;while(this.hasData_){if(this.readLastLine_){this.curLine_++;this.readLastLine_=false;}else if(this.data_ instanceof tr.b.TraceStream){this.curLine_++;const line=this.data_.readUntilDelimiter('\n');if(line.endsWith('\r\n')){lastLine=line.slice(0,-2);}else if(line.endsWith('\n')){lastLine=line.slice(0,-1);}else{lastLine=line;}}else{this.curLine_++;lastLine=this.data_[this.curLine_-1];}
+yield lastLine;}}
+get curLineNumber(){return this.curLine_;}
+get hasData_(){if(this.data_ instanceof tr.b.TraceStream)return this.data_.hasData;return this.curLine_<this.data_.length;}
+advanceToLineMatching(regex){for(const line of this){if(this.savedLines_!==undefined)this.savedLines_.push(line);if(regex.test(line)){this.goBack_();return true;}}
+return false;}
+goBack_(){if(this.readLastLine_){throw new Error('There should be at least one nextLine call between '+'any two goBack calls.');}
+if(this.curLine_===0){throw new Error('There should be at least one nextLine call before '+'the first goBack call.');}
+this.readLastLine_=true;this.curLine_--;}
+beginSavingLines(){this.savedLines_=[];}
+endSavingLinesAndGetResult(){const tmp=this.savedLines_;this.savedLines_=undefined;return tmp;}}
+return{SimpleLineReader,};});'use strict';tr.exportTo('tr.e.importer',function(){function Trace2HTMLImporter(model,events){this.importPriority=0;}
+Trace2HTMLImporter.subtraces_=[];function _extractEventsFromHTML(text){Trace2HTMLImporter.subtraces_=[];const r=new tr.importer.SimpleLineReader(text);while(true){if(!r.advanceToLineMatching(new RegExp('^<\s*script id="viewer-data" '+'type="(application\/json|text\/plain)">\r?$'))){break;}
+r.beginSavingLines();if(!r.advanceToLineMatching(/^<\/\s*script>\r?$/))return;let rawEvents=r.endSavingLinesAndGetResult();rawEvents=rawEvents.slice(1,rawEvents.length-1);const data64=rawEvents.join('\n');const buffer=new ArrayBuffer(tr.b.Base64.getDecodedBufferLength(data64));const len=tr.b.Base64.DecodeToTypedArray(data64,new DataView(buffer));Trace2HTMLImporter.subtraces_.push(buffer.slice(0,len));}}
+function _canImportFromHTML(text){if(!/^<!DOCTYPE html>/.test(text))return false;_extractEventsFromHTML(text);if(Trace2HTMLImporter.subtraces_.length===0)return false;return true;}
+Trace2HTMLImporter.canImport=function(events){if(events instanceof tr.b.TraceStream)return false;return _canImportFromHTML(events);};Trace2HTMLImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'Trace2HTMLImporter';},isTraceDataContainer(){return true;},extractSubtraces(){return Trace2HTMLImporter.subtraces_;},importEvents(){}};tr.importer.Importer.register(Trace2HTMLImporter);return{Trace2HTMLImporter,};});'use strict';tr.exportTo('tr.e.importer.v8',function(){function SplayTree(){}
+SplayTree.prototype.root_=null;SplayTree.prototype.isEmpty=function(){return!this.root_;};SplayTree.prototype.insert=function(key,value){if(this.isEmpty()){this.root_=new SplayTree.Node(key,value);return;}
+this.splay_(key);if(this.root_.key===key){return;}
+const node=new SplayTree.Node(key,value);if(key>this.root_.key){node.left=this.root_;node.right=this.root_.right;this.root_.right=null;}else{node.right=this.root_;node.left=this.root_.left;this.root_.left=null;}
 this.root_=node;};SplayTree.prototype.remove=function(key){if(this.isEmpty()){throw Error('Key not found: '+key);}
-this.splay_(key);if(this.root_.key!=key){throw Error('Key not found: '+key);}
-var removed=this.root_;if(!this.root_.left){this.root_=this.root_.right;}else{var right=this.root_.right;this.root_=this.root_.left;this.splay_(key);this.root_.right=right;}
-return removed;};SplayTree.prototype.find=function(key){if(this.isEmpty()){return null;}
-this.splay_(key);return this.root_.key==key?this.root_:null;};SplayTree.prototype.findMin=function(){if(this.isEmpty()){return null;}
-var current=this.root_;while(current.left){current=current.left;}
-return current;};SplayTree.prototype.findMax=function(opt_startNode){if(this.isEmpty()){return null;}
-var current=opt_startNode||this.root_;while(current.right){current=current.right;}
-return current;};SplayTree.prototype.findGreatestLessThan=function(key){if(this.isEmpty()){return null;}
-this.splay_(key);if(this.root_.key<=key){return this.root_;}else if(this.root_.left){return this.findMax(this.root_.left);}else{return null;}};SplayTree.prototype.exportKeysAndValues=function(){var result=[];this.traverse_(function(node){result.push([node.key,node.value]);});return result;};SplayTree.prototype.exportValues=function(){var result=[];this.traverse_(function(node){result.push(node.value);});return result;};SplayTree.prototype.splay_=function(key){if(this.isEmpty()){return;}
-var dummy,left,right;dummy=left=right=new SplayTree.Node(null,null);var current=this.root_;while(true){if(key<current.key){if(!current.left){break;}
-if(key<current.left.key){var tmp=current.left;current.left=tmp.right;tmp.right=current;current=tmp;if(!current.left){break;}}
+this.splay_(key);if(this.root_.key!==key){throw Error('Key not found: '+key);}
+const removed=this.root_;if(!this.root_.left){this.root_=this.root_.right;}else{const right=this.root_.right;this.root_=this.root_.left;this.splay_(key);this.root_.right=right;}
+return removed;};SplayTree.prototype.find=function(key){if(this.isEmpty())return null;this.splay_(key);return this.root_.key===key?this.root_:null;};SplayTree.prototype.findMin=function(){if(this.isEmpty())return null;let current=this.root_;while(current.left){current=current.left;}
+return current;};SplayTree.prototype.findMax=function(opt_startNode){if(this.isEmpty())return null;let current=opt_startNode||this.root_;while(current.right){current=current.right;}
+return current;};SplayTree.prototype.findGreatestLessThan=function(key){if(this.isEmpty())return null;this.splay_(key);if(this.root_.key<=key){return this.root_;}
+if(this.root_.left){return this.findMax(this.root_.left);}
+return null;};SplayTree.prototype.exportKeysAndValues=function(){const result=[];this.traverse_(function(node){result.push([node.key,node.value]);});return result;};SplayTree.prototype.exportValues=function(){const result=[];this.traverse_(function(node){result.push(node.value);});return result;};SplayTree.prototype.splay_=function(key){if(this.isEmpty())return;const dummy=new SplayTree.Node(null,null);let left=dummy;let right=dummy;let current=this.root_;while(true){if(key<current.key){if(!current.left){break;}
+if(key<current.left.key){const tmp=current.left;current.left=tmp.right;tmp.right=current;current=tmp;if(!current.left){break;}}
 right.left=current;right=current;current=current.left;}else if(key>current.key){if(!current.right){break;}
-if(key>current.right.key){var tmp=current.right;current.right=tmp.left;tmp.left=current;current=tmp;if(!current.right){break;}}
+if(key>current.right.key){const tmp=current.right;current.right=tmp.left;tmp.left=current;current=tmp;if(!current.right){break;}}
 left.right=current;left=current;current=current.right;}else{break;}}
-left.right=current.left;right.left=current.right;current.left=dummy.right;current.right=dummy.left;this.root_=current;};SplayTree.prototype.traverse_=function(f){var nodesToVisit=[this.root_];while(nodesToVisit.length>0){var node=nodesToVisit.shift();if(node==null){continue;}
-f(node);nodesToVisit.push(node.left);nodesToVisit.push(node.right);}};SplayTree.Node=function(key,value){this.key=key;this.value=value;};SplayTree.Node.prototype.left=null;SplayTree.Node.prototype.right=null;return{SplayTree:SplayTree};});'use strict';tr.exportTo('tr.e.importer.v8',function(){function CodeMap(){this.dynamics_=new tr.e.importer.v8.SplayTree();this.dynamicsNameGen_=new tr.e.importer.v8.CodeMap.NameGenerator();this.statics_=new tr.e.importer.v8.SplayTree();this.libraries_=new tr.e.importer.v8.SplayTree();this.pages_=[];};CodeMap.PAGE_ALIGNMENT=12;CodeMap.PAGE_SIZE=1<<CodeMap.PAGE_ALIGNMENT;CodeMap.prototype.addCode=function(start,codeEntry){this.deleteAllCoveredNodes_(this.dynamics_,start,start+codeEntry.size);this.dynamics_.insert(start,codeEntry);};CodeMap.prototype.moveCode=function(from,to){var removedNode=this.dynamics_.remove(from);this.deleteAllCoveredNodes_(this.dynamics_,to,to+removedNode.value.size);this.dynamics_.insert(to,removedNode.value);};CodeMap.prototype.deleteCode=function(start){var removedNode=this.dynamics_.remove(start);};CodeMap.prototype.addLibrary=function(start,codeEntry){this.markPages_(start,start+codeEntry.size);this.libraries_.insert(start,codeEntry);};CodeMap.prototype.addStaticCode=function(start,codeEntry){this.statics_.insert(start,codeEntry);};CodeMap.prototype.markPages_=function(start,end){for(var addr=start;addr<=end;addr+=CodeMap.PAGE_SIZE){this.pages_[addr>>>CodeMap.PAGE_ALIGNMENT]=1;}};CodeMap.prototype.deleteAllCoveredNodes_=function(tree,start,end){var to_delete=[];var addr=end-1;while(addr>=start){var node=tree.findGreatestLessThan(addr);if(!node)break;var start2=node.key,end2=start2+node.value.size;if(start2<end&&start<end2)to_delete.push(start2);addr=start2-1;}
-for(var i=0,l=to_delete.length;i<l;++i)tree.remove(to_delete[i]);};CodeMap.prototype.isAddressBelongsTo_=function(addr,node){return addr>=node.key&&addr<(node.key+node.value.size);};CodeMap.prototype.findInTree_=function(tree,addr){var node=tree.findGreatestLessThan(addr);return node&&this.isAddressBelongsTo_(addr,node)?node.value:null;};CodeMap.prototype.findEntry=function(addr){var pageAddr=addr>>>CodeMap.PAGE_ALIGNMENT;if(pageAddr in this.pages_){return this.findInTree_(this.statics_,addr)||this.findInTree_(this.libraries_,addr);}
-var min=this.dynamics_.findMin();var max=this.dynamics_.findMax();if(max!=null&&addr<(max.key+max.value.size)&&addr>=min.key){var dynaEntry=this.findInTree_(this.dynamics_,addr);if(dynaEntry==null)return null;if(!dynaEntry.nameUpdated_){dynaEntry.name=this.dynamicsNameGen_.getName(dynaEntry.name);dynaEntry.nameUpdated_=true;}
+left.right=current.left;right.left=current.right;current.left=dummy.right;current.right=dummy.left;this.root_=current;};SplayTree.prototype.traverse_=function(f){const nodesToVisit=[this.root_];while(nodesToVisit.length>0){const node=nodesToVisit.shift();if(node===null)continue;f(node);nodesToVisit.push(node.left);nodesToVisit.push(node.right);}};SplayTree.Node=function(key,value){this.key=key;this.value=value;};SplayTree.Node.prototype.left=null;SplayTree.Node.prototype.right=null;return{SplayTree,};});'use strict';tr.exportTo('tr.e.importer.v8',function(){function CodeMap(){this.dynamics_=new tr.e.importer.v8.SplayTree();this.dynamicsNameGen_=new tr.e.importer.v8.CodeMap.NameGenerator();this.statics_=new tr.e.importer.v8.SplayTree();this.libraries_=new tr.e.importer.v8.SplayTree();this.pages_=[];}
+CodeMap.PAGE_ALIGNMENT=12;CodeMap.PAGE_SIZE=1<<CodeMap.PAGE_ALIGNMENT;CodeMap.prototype.addCode=function(start,codeEntry){this.deleteAllCoveredNodes_(this.dynamics_,start,start+codeEntry.size);this.dynamics_.insert(start,codeEntry);};CodeMap.prototype.moveCode=function(from,to){const removedNode=this.dynamics_.remove(from);this.deleteAllCoveredNodes_(this.dynamics_,to,to+removedNode.value.size);this.dynamics_.insert(to,removedNode.value);};CodeMap.prototype.deleteCode=function(start){const removedNode=this.dynamics_.remove(start);};CodeMap.prototype.addLibrary=function(start,codeEntry){this.markPages_(start,start+codeEntry.size);this.libraries_.insert(start,codeEntry);};CodeMap.prototype.addStaticCode=function(start,codeEntry){this.statics_.insert(start,codeEntry);};CodeMap.prototype.markPages_=function(start,end){for(let addr=start;addr<=end;addr+=CodeMap.PAGE_SIZE){this.pages_[addr>>>CodeMap.PAGE_ALIGNMENT]=1;}};CodeMap.prototype.deleteAllCoveredNodes_=function(tree,start,end){const toDelete=[];let addr=end-1;while(addr>=start){const node=tree.findGreatestLessThan(addr);if(!node)break;const start2=node.key;const end2=start2+node.value.size;if(start2<end&&start<end2)toDelete.push(start2);addr=start2-1;}
+for(let i=0,l=toDelete.length;i<l;++i)tree.remove(toDelete[i]);};CodeMap.prototype.isAddressBelongsTo_=function(addr,node){return addr>=node.key&&addr<(node.key+node.value.size);};CodeMap.prototype.findInTree_=function(tree,addr){const node=tree.findGreatestLessThan(addr);return node&&this.isAddressBelongsTo_(addr,node)?node.value:null;};CodeMap.prototype.findEntryInLibraries=function(addr){const pageAddr=addr>>>CodeMap.PAGE_ALIGNMENT;if(pageAddr in this.pages_){return this.findInTree_(this.libraries_,addr);}
+return undefined;};CodeMap.prototype.findEntry=function(addr){const pageAddr=addr>>>CodeMap.PAGE_ALIGNMENT;if(pageAddr in this.pages_){return this.findInTree_(this.statics_,addr)||this.findInTree_(this.libraries_,addr);}
+const min=this.dynamics_.findMin();const max=this.dynamics_.findMax();if(max!==null&&addr<(max.key+max.value.size)&&addr>=min.key){const dynaEntry=this.findInTree_(this.dynamics_,addr);if(dynaEntry===null)return null;if(!dynaEntry.nameUpdated_){dynaEntry.name=this.dynamicsNameGen_.getName(dynaEntry.name);dynaEntry.nameUpdated_=true;}
 return dynaEntry;}
-return null;};CodeMap.prototype.findDynamicEntryByStartAddress=function(addr){var node=this.dynamics_.find(addr);return node?node.value:null;};CodeMap.prototype.getAllDynamicEntries=function(){return this.dynamics_.exportValues();};CodeMap.prototype.getAllDynamicEntriesWithAddresses=function(){return this.dynamics_.exportKeysAndValues();};CodeMap.prototype.getAllStaticEntries=function(){return this.statics_.exportValues();};CodeMap.prototype.getAllLibrariesEntries=function(){return this.libraries_.exportValues();};CodeMap.CodeEntry=function(size,opt_name){this.id=tr.b.GUID.allocate();this.size=size;this.name=opt_name||'';this.nameUpdated_=false;};CodeMap.CodeEntry.prototype.getName=function(){return this.name;};CodeMap.CodeEntry.prototype.toString=function(){return this.name+': '+this.size.toString(16);};CodeMap.NameGenerator=function(){this.knownNames_={};};CodeMap.NameGenerator.prototype.getName=function(name){if(!(name in this.knownNames_)){this.knownNames_[name]=0;return name;}
-var count=++this.knownNames_[name];return name+' {'+count+'}';};return{CodeMap:CodeMap};});'use strict';tr.exportTo('tr.e.importer.v8',function(){function CsvParser(){};CsvParser.CSV_FIELD_RE_=/^"((?:[^"]|"")*)"|([^,]*)/;CsvParser.DOUBLE_QUOTE_RE_=/""/g;CsvParser.prototype.parseLine=function(line){var fieldRe=CsvParser.CSV_FIELD_RE_;var doubleQuoteRe=CsvParser.DOUBLE_QUOTE_RE_;var pos=0;var endPos=line.length;var fields=[];if(endPos>0){do{var fieldMatch=fieldRe.exec(line.substr(pos));if(typeof fieldMatch[1]==='string'){var field=fieldMatch[1];pos+=field.length+3;fields.push(field.replace(doubleQuoteRe,'"'));}else{var field=fieldMatch[2];pos+=field.length+1;fields.push(field);}}while(pos<=endPos);}
-return fields;};function LogReader(dispatchTable){this.dispatchTable_=dispatchTable;this.lineNum_=0;this.csvParser_=new CsvParser();};LogReader.prototype.printError=function(str){};LogReader.prototype.processLogChunk=function(chunk){this.processLog_(chunk.split('\n'));};LogReader.prototype.processLogLine=function(line){this.processLog_([line]);};LogReader.prototype.processStack=function(pc,func,stack){var fullStack=func?[pc,func]:[pc];var prevFrame=pc;for(var i=0,n=stack.length;i<n;++i){var frame=stack[i];var firstChar=frame.charAt(0);if(firstChar=='+'||firstChar=='-'){prevFrame+=parseInt(frame,16);fullStack.push(prevFrame);}else if(firstChar!='o'){fullStack.push(parseInt(frame,16));}}
-return fullStack;};LogReader.prototype.skipDispatch=function(dispatch){return false;};LogReader.prototype.dispatchLogRow_=function(fields){var command=fields[0];if(!(command in this.dispatchTable_))return;var dispatch=this.dispatchTable_[command];if(dispatch===null||this.skipDispatch(dispatch)){return;}
-var parsedFields=[];for(var i=0;i<dispatch.parsers.length;++i){var parser=dispatch.parsers[i];if(parser===null){parsedFields.push(fields[1+i]);}else if(typeof parser=='function'){parsedFields.push(parser(fields[1+i]));}else{parsedFields.push(fields.slice(1+i));break;}}
-dispatch.processor.apply(this,parsedFields);};LogReader.prototype.processLog_=function(lines){for(var i=0,n=lines.length;i<n;++i,++this.lineNum_){var line=lines[i];if(!line){continue;}
-try{var fields=this.csvParser_.parseLine(line);this.dispatchLogRow_(fields);}catch(e){this.printError('line '+(this.lineNum_+1)+': '+
-(e.message||e));}}};return{LogReader:LogReader};});'use strict';tr.exportTo('tr.e.importer.v8',function(){var ColorScheme=tr.b.ColorScheme;function V8LogImporter(model,eventData){this.importPriority=3;this.model_=model;this.logData_=eventData;this.code_map_=new tr.e.importer.v8.CodeMap();this.v8_timer_thread_=undefined;this.v8_thread_=undefined;this.root_stack_frame_=new tr.model.StackFrame(undefined,'v8-root-stack-frame','v8-root-stack-frame',0);this.v8_stack_timeline_=new Array();}
-var kV8BinarySuffixes=['/d8','/libv8.so'];var TimerEventDefaultArgs={'V8.Execute':{pause:false,no_execution:false},'V8.External':{pause:false,no_execution:true},'V8.CompileFullCode':{pause:true,no_execution:true},'V8.RecompileSynchronous':{pause:true,no_execution:true},'V8.RecompileParallel':{pause:false,no_execution:false},'V8.CompileEval':{pause:true,no_execution:true},'V8.Parse':{pause:true,no_execution:true},'V8.PreParse':{pause:true,no_execution:true},'V8.ParseLazy':{pause:true,no_execution:true},'V8.GCScavenger':{pause:true,no_execution:true},'V8.GCCompactor':{pause:true,no_execution:true},'V8.GCContext':{pause:true,no_execution:true}};V8LogImporter.canImport=function(eventData){if(typeof(eventData)!=='string'&&!(eventData instanceof String))
-return false;return eventData.substring(0,11)=='v8-version,'||eventData.substring(0,12)=='timer-event,'||eventData.substring(0,5)=='tick,'||eventData.substring(0,15)=='shared-library,'||eventData.substring(0,9)=='profiler,'||eventData.substring(0,14)=='code-creation,';};V8LogImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'V8LogImporter';},processTimerEvent_:function(name,start,length){var args=TimerEventDefaultArgs[name];if(args===undefined)return;start/=1000;length/=1000;var colorId=ColorScheme.getColorIdForGeneralPurposeString(name);var slice=new tr.model.Slice('v8',name,colorId,start,args,length);this.v8_timer_thread_.sliceGroup.pushSlice(slice);},processTimerEventStart_:function(name,start){var args=TimerEventDefaultArgs[name];if(args===undefined)return;start/=1000;this.v8_timer_thread_.sliceGroup.beginSlice('v8',name,start,args);},processTimerEventEnd_:function(name,end){end/=1000;this.v8_timer_thread_.sliceGroup.endSlice(end);},processCodeCreateEvent_:function(type,kind,address,size,name){var code_entry=new tr.e.importer.v8.CodeMap.CodeEntry(size,name);code_entry.kind=kind;this.code_map_.addCode(address,code_entry);},processCodeMoveEvent_:function(from,to){this.code_map_.moveCode(from,to);},processCodeDeleteEvent_:function(address){this.code_map_.deleteCode(address);},processSharedLibrary_:function(name,start,end){var code_entry=new tr.e.importer.v8.CodeMap.CodeEntry(end-start,name);code_entry.kind=-3;for(var i=0;i<kV8BinarySuffixes.length;i++){var suffix=kV8BinarySuffixes[i];if(name.indexOf(suffix,name.length-suffix.length)>=0){code_entry.kind=-1;break;}}
-this.code_map_.addLibrary(start,code_entry);},findCodeKind_:function(kind){for(name in CodeKinds){if(CodeKinds[name].kinds.indexOf(kind)>=0){return CodeKinds[name];}}},processTickEvent_:function(pc,start,unused_x,unused_y,vmstate,stack){start/=1000;function findChildWithEntryID(stackFrame,entryID){for(var i=0;i<stackFrame.children.length;i++){if(stackFrame.children[i].entryID==entryID)
-return stackFrame.children[i];}
+return null;};CodeMap.prototype.findDynamicEntryByStartAddress=function(addr){const node=this.dynamics_.find(addr);return node?node.value:null;};CodeMap.prototype.getAllDynamicEntries=function(){return this.dynamics_.exportValues();};CodeMap.prototype.getAllDynamicEntriesWithAddresses=function(){return this.dynamics_.exportKeysAndValues();};CodeMap.prototype.getAllStaticEntries=function(){return this.statics_.exportValues();};CodeMap.prototype.getAllLibrariesEntries=function(){return this.libraries_.exportValues();};CodeMap.CodeState={COMPILED:0,OPTIMIZABLE:1,OPTIMIZED:2};CodeMap.CodeEntry=function(size,opt_name,opt_type){this.id=tr.b.GUID.allocateSimple();this.size=size;this.name_=opt_name||'';this.type=opt_type||'';this.nameUpdated_=false;};CodeMap.CodeEntry.prototype={__proto__:Object.prototype,get name(){return this.name_;},set name(value){this.name_=value;},toString(){this.name_+': '+this.size.toString(16);}};CodeMap.CodeEntry.TYPE={SHARED_LIB:'SHARED_LIB',CPP:'CPP'};CodeMap.DynamicFuncCodeEntry=function(size,type,func,state){CodeMap.CodeEntry.call(this,size,'',type);this.func=func;this.state=state;};CodeMap.DynamicFuncCodeEntry.STATE_PREFIX=['','~','*'];CodeMap.DynamicFuncCodeEntry.prototype={__proto__:CodeMap.CodeEntry.prototype,get name(){return CodeMap.DynamicFuncCodeEntry.STATE_PREFIX[this.state]+
+this.func.name;},set name(value){this.name_=value;},getRawName(){return this.func.getName();},isJSFunction(){return true;},toString(){return this.type+': '+this.name+': '+this.size.toString(16);}};CodeMap.FunctionEntry=function(name){CodeMap.CodeEntry.call(this,0,name);};CodeMap.FunctionEntry.prototype={__proto__:CodeMap.CodeEntry.prototype,get name(){let name=this.name_;if(name.length===0){name='<anonymous>';}else if(name.charAt(0)===' '){name='<anonymous>'+name;}
+return name;},set name(value){this.name_=value;}};CodeMap.NameGenerator=function(){this.knownNames_={};};CodeMap.NameGenerator.prototype.getName=function(name){if(!(name in this.knownNames_)){this.knownNames_[name]=0;return name;}
+const count=++this.knownNames_[name];return name+' {'+count+'}';};return{CodeMap,};});'use strict';tr.exportTo('tr.e.importer.v8',function(){function CsvParser(){}
+CsvParser.CSV_FIELD_RE_=/^"((?:[^"]|"")*)"|([^,]*)/;CsvParser.DOUBLE_QUOTE_RE_=/""/g;CsvParser.prototype.parseLine=function(line){const fieldRe=CsvParser.CSV_FIELD_RE_;const doubleQuoteRe=CsvParser.DOUBLE_QUOTE_RE_;let pos=0;const endPos=line.length;const fields=[];if(endPos>0){do{const fieldMatch=fieldRe.exec(line.substr(pos));if(typeof fieldMatch[1]==='string'){const field=fieldMatch[1];pos+=field.length+3;fields.push(field.replace(doubleQuoteRe,'"'));}else{const field=fieldMatch[2];pos+=field.length+1;fields.push(field);}}while(pos<=endPos);}
+return fields;};function LogReader(dispatchTable){this.dispatchTable_=dispatchTable;this.lineNum_=0;this.csvParser_=new CsvParser();}
+LogReader.prototype.printError=function(str){};LogReader.prototype.processLogChunk=function(chunk){this.processLog_(chunk.split('\n'));};LogReader.prototype.processLogLine=function(line){this.processLog_([line]);};LogReader.prototype.processStack=function(pc,func,stack){const fullStack=func?[pc,func]:[pc];let prevFrame=pc;for(let i=0,n=stack.length;i<n;++i){const frame=stack[i];const firstChar=frame.charAt(0);if(firstChar==='+'||firstChar==='-'){prevFrame+=parseInt(frame,16);fullStack.push(prevFrame);}else if(firstChar!=='o'){fullStack.push(parseInt(frame,16));}}
+return fullStack;};LogReader.prototype.skipDispatch=function(dispatch){return false;};LogReader.prototype.dispatchLogRow_=function(fields){const command=fields[0];if(!(command in this.dispatchTable_))return;const dispatch=this.dispatchTable_[command];if(dispatch===null||this.skipDispatch(dispatch)){return;}
+const parsedFields=[];for(let i=0;i<dispatch.parsers.length;++i){const parser=dispatch.parsers[i];if(parser===null){parsedFields.push(fields[1+i]);}else if(typeof parser==='function'){parsedFields.push(parser(fields[1+i]));}else{parsedFields.push(fields.slice(1+i));break;}}
+dispatch.processor.apply(this,parsedFields);};LogReader.prototype.processLog_=function(lines){for(let i=0,n=lines.length;i<n;++i,++this.lineNum_){const line=lines[i];if(!line){continue;}
+try{const fields=this.csvParser_.parseLine(line);this.dispatchLogRow_(fields);}catch(e){this.printError('line '+(this.lineNum_+1)+': '+
+(e.message||e));}}};return{LogReader,};});'use strict';tr.exportTo('tr.model',function(){function ProfileNode(id,title,parentNode){this.id_=id;this.title_=title;this.parentNode_=parentNode;this.colorId_=-1;this.userFriendlyStack_=[];}
+ProfileNode.prototype={__proto__:Object.prototype,get title(){return this.title_;},get parentNode(){return this.parentNode_;},set parentNode(value){this.parentNode_=value;},get id(){return this.id_;},get colorId(){return this.colorId_;},set colorId(value){this.colorId_=value;},get userFriendlyName(){return this.title_;},get userFriendlyStack(){if(this.userFriendlyStack_.length===0){this.userFriendlyStack_=[this.userFriendlyName];if(this.parentNode_!==undefined){this.userFriendlyStack_=this.userFriendlyStack_.concat(this.parentNode_.userFriendlyStack);}}
+return this.userFriendlyStack_;},get sampleTitle(){throw new Error('Not implemented.');}};tr.model.EventRegistry.register(ProfileNode,{name:'Node',pluralName:'Nodes'});return{ProfileNode,};});'use strict';tr.exportTo('tr.e.v8',function(){const ProfileNode=tr.model.ProfileNode;function V8CpuProfileNode(id,callFrame,parentNode){ProfileNode.call(this,id,callFrame.functionName,parentNode);this.callFrame_=tr.b.deepCopy(callFrame);this.deoptReason_='';this.colorId_=tr.b.ColorScheme.getColorIdForGeneralPurposeString(callFrame.functionName);}
+V8CpuProfileNode.prototype={__proto__:ProfileNode.prototype,get functionName(){return this.callFrame_.functionName;},get scriptId(){return this.callFrame_.scriptId;},get url(){if(!this.callFrame_.url){return'unknown';}
+let url=this.callFrame_.url;if(this.callFrame_.lineNumber===undefined){return url;}
+url=url+':'+this.callFrame_.lineNumber;if(this.callFrame_.columnNumber===undefined){return url;}
+url=url+':'+this.callFrame_.columnNumber;return url;},get deoptReason(){return this.deoptReason_;},set deoptReason(value){this.deoptReason_=value;},get userFriendlyName(){const name=this.functionName+' url: '+this.url;return!this.deoptReason_?name:name+' Deoptimized reason: '+this.deoptReason_;},get sampleTitle(){return'V8 Sample';}};V8CpuProfileNode.constructFromObject=function(profileTree,node){const nodeId=node.id;if(nodeId===1){return undefined;}
+const parentNode=profileTree.getNode(node.parent);const profileNode=new V8CpuProfileNode(nodeId,node.callFrame,parentNode);if(node.deoptReason!==undefined){profileNode.deoptReason=node.deoptReason;}
+return profileNode;};ProfileNode.subTypes.register(V8CpuProfileNode,{typeName:'cpuProfile',name:'v8 cpu profile node',pluralName:'v8 cpu profile nodes'});ProfileNode.subTypes.register(V8CpuProfileNode,{typeName:'legacySample',name:'v8 cpu profile node',pluralName:'v8 cpu profile nodes'});return{ProfileNode,};});'use strict';tr.exportTo('tr.model',function(){function ProfileTree(){this.startTime_=undefined;this.endTime_=undefined;this.tree_=new Map();this.pid_=-1;this.tid_=-1;}
+ProfileTree.prototype={__proto__:Object.prototype,get pid(){return this.pid_;},set pid(value){this.pid_=value;},get tid(){return this.tid_;},set tid(value){this.tid_=value;},get tree(){return this.tree_;},get startTime(){return this.startTime_;},set startTime(value){this.startTime_=value;this.endTime_=value;},get endTime(){return this.endTime_;},set endTime(value){this.endTime_=value;},add(node){if(this.tree_.has(node.id)){throw new Error('Conflict id in the profile tree.');}
+this.tree_.set(node.id,node);return node;},getNode(nodeId){return this.tree_.get(nodeId);}};return{ProfileTree,};});'use strict';tr.exportTo('tr.e.importer.v8',function(){const CodeEntry=tr.e.importer.v8.CodeMap.CodeEntry;const CodeMap=tr.e.importer.v8.CodeMap;const ColorScheme=tr.b.ColorScheme;const DynamicFuncCodeEntry=tr.e.importer.v8.CodeMap.DynamicFuncCodeEntry;const FunctionEntry=tr.e.importer.v8.CodeMap.FunctionEntry;const ProfileNodeType=tr.model.ProfileNode.subTypes.getConstructor(undefined,'legacySample');function V8LogImporter(model,eventData){this.importPriority=3;this.model_=model;this.logData_=eventData;this.code_map_=new CodeMap();this.v8_timer_thread_=undefined;this.v8_thread_=undefined;this.profileTree_=new tr.model.ProfileTree();this.profileTree_.add(new ProfileNodeType(-1,{url:'',functionName:'unknown'}));this.v8_stack_timeline_=[];}
+const kV8BinarySuffixes=['/d8','/libv8.so'];const TimerEventDefaultArgs={'V8.Execute':{pause:false,no_execution:false},'V8.External':{pause:false,no_execution:true},'V8.CompileFullCode':{pause:true,no_execution:true},'V8.RecompileSynchronous':{pause:true,no_execution:true},'V8.RecompileParallel':{pause:false,no_execution:false},'V8.CompileEval':{pause:true,no_execution:true},'V8.Parse':{pause:true,no_execution:true},'V8.PreParse':{pause:true,no_execution:true},'V8.ParseLazy':{pause:true,no_execution:true},'V8.GCScavenger':{pause:true,no_execution:true},'V8.GCCompactor':{pause:true,no_execution:true},'V8.GCContext':{pause:true,no_execution:true}};V8LogImporter.canImport=function(eventData){if(typeof(eventData)!=='string'&&!(eventData instanceof String)){return false;}
+return eventData.substring(0,11)==='v8-version,'||eventData.substring(0,12)==='timer-event,'||eventData.substring(0,5)==='tick,'||eventData.substring(0,15)==='shared-library,'||eventData.substring(0,9)==='profiler,'||eventData.substring(0,14)==='code-creation,';};V8LogImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'V8LogImporter';},processTimerEvent_(name,startInUs,lengthInUs){const args=TimerEventDefaultArgs[name];if(args===undefined)return;const startInMs=tr.b.convertUnit(startInUs,tr.b.UnitPrefixScale.METRIC.MICRO,tr.b.UnitPrefixScale.METRIC.MILLI);const lengthInMs=tr.b.convertUnit(lengthInUs,tr.b.UnitPrefixScale.METRIC.MICRO,tr.b.UnitPrefixScale.METRIC.MILLI);const colorId=ColorScheme.getColorIdForGeneralPurposeString(name);const slice=new tr.model.ThreadSlice('v8',name,colorId,startInMs,args,lengthInMs);this.v8_timer_thread_.sliceGroup.pushSlice(slice);},processTimerEventStart_(name,startInUs){const args=TimerEventDefaultArgs[name];if(args===undefined)return;const startInMs=tr.b.convertUnit(startInUs,tr.b.UnitPrefixScale.METRIC.MICRO,tr.b.UnitPrefixScale.METRIC.MILLI);this.v8_timer_thread_.sliceGroup.beginSlice('v8',name,startInMs,args);},processTimerEventEnd_(name,endInUs){const endInMs=tr.b.convertUnit(endInUs,tr.b.UnitPrefixScale.METRIC.MICRO,tr.b.UnitPrefixScale.METRIC.MILLI);this.v8_timer_thread_.sliceGroup.endSlice(endInMs);},processCodeCreateEvent_(type,kind,address,size,name,maybeFunc){function parseState(s){switch(s){case'':return CodeMap.CodeState.COMPILED;case'~':return CodeMap.CodeState.OPTIMIZABLE;case'*':return CodeMap.CodeState.OPTIMIZED;}
+throw new Error('unknown code state: '+s);}
+if(maybeFunc.length){const funcAddr=parseInt(maybeFunc[0]);const state=parseState(maybeFunc[1]);let func=this.code_map_.findDynamicEntryByStartAddress(funcAddr);if(!func){func=new FunctionEntry(name);func.kind=kind;this.code_map_.addCode(funcAddr,func);}else if(func.name!==name){func.name=name;}
+let entry=this.code_map_.findDynamicEntryByStartAddress(address);if(entry){if(entry.size===size&&entry.func===func){entry.state=state;}}else{entry=new DynamicFuncCodeEntry(size,type,func,state);entry.kind=kind;this.code_map_.addCode(address,entry);}}else{const codeEntry=new CodeEntry(size,name);codeEntry.kind=kind;this.code_map_.addCode(address,codeEntry);}},processCodeMoveEvent_(from,to){this.code_map_.moveCode(from,to);},processCodeDeleteEvent_(address){this.code_map_.deleteCode(address);},processSharedLibrary_(name,start,end){const codeEntry=new CodeEntry(end-start,name,CodeEntry.TYPE.SHARED_LIB);codeEntry.kind=-3;for(let i=0;i<kV8BinarySuffixes.length;i++){const suffix=kV8BinarySuffixes[i];if(name.indexOf(suffix,name.length-suffix.length)>=0){codeEntry.kind=-1;break;}}
+this.code_map_.addLibrary(start,codeEntry);},processCppSymbol_(address,size,name){const codeEntry=new CodeEntry(size,name,CodeEntry.TYPE.CPP);codeEntry.kind=-1;this.code_map_.addStaticCode(address,codeEntry);},processTickEvent_(pc,startInUs,isExternalCallback,tosOrExternalCallback,vmstate,stack){const startInMs=tr.b.convertUnit(startInUs,tr.b.UnitPrefixScale.METRIC.MICRO,tr.b.UnitPrefixScale.METRIC.MILLI);function findChildWithEntryID(stackFrame,entryID){for(let i=0;i<stackFrame.children.length;i++){if(stackFrame.children[i].entryID===entryID){return stackFrame.children[i];}}
 return undefined;}
-var lastStackFrame;if(stack&&stack.length){lastStackFrame=this.root_stack_frame_;stack=stack.reverse();for(var i=0;i<stack.length;i++){if(!stack[i])
-break;var entry=this.code_map_.findEntry(stack[i]);var entryID=entry?entry.id:'Unknown';var childFrame=findChildWithEntryID(lastStackFrame,entryID);if(childFrame===undefined){var entryName=entry?entry.name:'Unknown';lastStackFrame=new tr.model.StackFrame(lastStackFrame,'v8sf-'+tr.b.GUID.allocate(),entryName,ColorScheme.getColorIdForGeneralPurposeString(entryName));lastStackFrame.entryID=entryID;this.model_.addStackFrame(lastStackFrame);}else{lastStackFrame=childFrame;}}}else{var pcEntry=this.code_map_.findEntry(pc);var pcEntryID='v8pc-'+(pcEntry?pcEntry.id:'Unknown');if(this.model_.stackFrames[pcEntryID]===undefined){var pcEntryName=pcEntry?pcEntry.name:'Unknown';lastStackFrame=new tr.model.StackFrame(undefined,pcEntryID,pcEntryName,ColorScheme.getColorIdForGeneralPurposeString(pcEntryName));this.model_.addStackFrame(lastStackFrame);}
-lastStackFrame=this.model_.stackFrames[pcEntryID];}
-var sample=new tr.model.Sample(undefined,this.v8_thread_,'V8 PC',start,lastStackFrame,1);this.model_.samples.push(sample);},processDistortion_:function(distortion_in_picoseconds){distortion_per_entry=distortion_in_picoseconds/1000000;},processPlotRange_:function(start,end){xrange_start_override=start;xrange_end_override=end;},processV8Version_:function(major,minor,build,patch,candidate){},importEvents:function(){var logreader=new tr.e.importer.v8.LogReader({'timer-event':{parsers:[null,parseInt,parseInt],processor:this.processTimerEvent_.bind(this)},'shared-library':{parsers:[null,parseInt,parseInt],processor:this.processSharedLibrary_.bind(this)},'timer-event-start':{parsers:[null,parseInt],processor:this.processTimerEventStart_.bind(this)},'timer-event-end':{parsers:[null,parseInt],processor:this.processTimerEventEnd_.bind(this)},'code-creation':{parsers:[null,parseInt,parseInt,parseInt,null],processor:this.processCodeCreateEvent_.bind(this)},'code-move':{parsers:[parseInt,parseInt],processor:this.processCodeMoveEvent_.bind(this)},'code-delete':{parsers:[parseInt],processor:this.processCodeDeleteEvent_.bind(this)},'tick':{parsers:[parseInt,parseInt,null,null,parseInt,'var-args'],processor:this.processTickEvent_.bind(this)},'distortion':{parsers:[parseInt],processor:this.processDistortion_.bind(this)},'plot-range':{parsers:[parseInt,parseInt],processor:this.processPlotRange_.bind(this)},'v8-version':{parsers:[parseInt,parseInt,parseInt,parseInt,parseInt],processor:this.processV8Version_.bind(this)}});this.v8_timer_thread_=this.model_.getOrCreateProcess(-32).getOrCreateThread(1);this.v8_timer_thread_.name='V8 Timers';this.v8_thread_=this.model_.getOrCreateProcess(-32).getOrCreateThread(2);this.v8_thread_.name='V8';var lines=this.logData_.split('\n');for(var i=0;i<lines.length;i++){logreader.processLogLine(lines[i]);}
-this.root_stack_frame_.removeAllChildren();function addSlices(slices,thread){for(var i=0;i<slices.length;i++){var duration=slices[i].end-slices[i].start;var slice=new tr.model.Slice('v8',slices[i].name,ColorScheme.getColorIdForGeneralPurposeString(slices[i].name),slices[i].start,{},duration);thread.sliceGroup.pushSlice(slice);addSlices(slices[i].children,thread);}}
-addSlices(this.v8_stack_timeline_,this.v8_thread_);}};tr.importer.Importer.register(V8LogImporter);return{V8LogImporter:V8LogImporter};});'use strict';tr.exportTo('tr.e.importer',function(){function ZipImporter(model,eventData){if(eventData instanceof ArrayBuffer)
-eventData=new Uint8Array(eventData);this.model_=model;this.eventData_=eventData;}
-ZipImporter.canImport=function(eventData){var header;if(eventData instanceof ArrayBuffer)
-header=new Uint8Array(eventData.slice(0,2));else if(typeof(eventData)==='string'||eventData instanceof String)
-header=[eventData.charCodeAt(0),eventData.charCodeAt(1)];else
-return false;return header[0]==='P'.charCodeAt(0)&&header[1]==='K'.charCodeAt(0);};ZipImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'ZipImporter';},isTraceDataContainer:function(){return true;},extractSubtraces:function(){var zip=new JSZip(this.eventData_);var subtraces=[];for(var idx in zip.files)
-subtraces.push(zip.files[idx].asBinary());return subtraces;}};tr.importer.Importer.register(ZipImporter);return{ZipImporter:ZipImporter};});'use strict';tr.exportTo('tr.model.source_info',function(){function SourceInfo(file,opt_line,opt_column){this.file_=file;this.line_=opt_line||-1;this.column_=opt_column||-1;}
-SourceInfo.prototype={get file(){return this.file_;},get line(){return this.line_;},get column(){return this.column_;},get domain(){if(!this.file_)
-return undefined;var domain=this.file_.match(/(.*:\/\/[^:\/]*)/i);return domain?domain[1]:undefined;},toString:function(){var str='';if(this.file_)
-str+=this.file_;if(this.line_>0)
-str+=':'+this.line_;if(this.column_>0)
-str+=':'+this.column_;return str;}};return{SourceInfo:SourceInfo};});'use strict';tr.exportTo('tr.model.source_info',function(){function JSSourceInfo(file,line,column,isNative,scriptId,state){tr.model.source_info.SourceInfo.call(this,file,line,column);this.isNative_=isNative;this.scriptId_=scriptId;this.state_=state;}
-JSSourceInfo.prototype={__proto__:tr.model.source_info.SourceInfo.prototype,get state(){return this.state_;},get isNative(){return this.isNative_;},get scriptId(){return this.scriptId_;},toString:function(){var str=this.isNative_?'[native v8] ':'';return str+
-tr.model.source_info.SourceInfo.prototype.toString.call(this);}};return{JSSourceInfo:JSSourceInfo,JSSourceState:{COMPILED:'compiled',OPTIMIZABLE:'optimizable',OPTIMIZED:'optimized',UNKNOWN:'unknown'}};});'use strict';tr.exportTo('tr.e.importer',function(){function TraceCodeEntry(address,size,name,scriptId){this.id_=tr.b.GUID.allocate();this.address_=address;this.size_=size;var rePrefix=/^(\w*:)?([*~]?)(.*)$/m;var tokens=rePrefix.exec(name);var prefix=tokens[1];var state=tokens[2];var body=tokens[3];if(state==='*'){state=tr.model.source_info.JSSourceState.OPTIMIZED;}else if(state==='~'){state=tr.model.source_info.JSSourceState.OPTIMIZABLE;}else if(state===''){state=tr.model.source_info.JSSourceState.COMPILED;}else{console.warning('Unknown v8 code state '+state);state=tr.model.source_info.JSSourceState.UNKNOWN;}
-var rawName;var rawUrl;if(prefix==='Script:'){rawName='';rawUrl=body;}else{var spacePos=body.lastIndexOf(' ');rawName=spacePos!==-1?body.substr(0,spacePos):body;rawUrl=spacePos!==-1?body.substr(spacePos+1):'';}
-function splitLineAndColumn(url){var lineColumnRegEx=/(?::(\d+))?(?::(\d+))?$/;var lineColumnMatch=lineColumnRegEx.exec(url);var lineNumber;var columnNumber;if(typeof(lineColumnMatch[1])==='string'){lineNumber=parseInt(lineColumnMatch[1],10);lineNumber=isNaN(lineNumber)?undefined:lineNumber-1;}
+function processStack(pc,func,stack){const fullStack=func?[pc,func]:[pc];let prevFrame=pc;for(let i=0,n=stack.length;i<n;++i){const frame=stack[i];const firstChar=frame.charAt(0);if(firstChar==='+'||firstChar==='-'){prevFrame+=parseInt(frame,16);fullStack.push(prevFrame);}else if(firstChar!=='o'){fullStack.push(parseInt(frame,16));}}
+return fullStack;}
+if(isExternalCallback){pc=tosOrExternalCallback;tosOrExternalCallback=0;}else if(tosOrExternalCallback){const funcEntry=this.code_map_.findEntry(tosOrExternalCallback);if(!funcEntry||!funcEntry.isJSFunction||!funcEntry.isJSFunction()){tosOrExternalCallback=0;}}
+let processedStack=processStack(pc,tosOrExternalCallback,stack);let node=undefined;let lastNode=undefined;processedStack=processedStack.reverse();for(let i=0,n=processedStack.length;i<n;i++){const frame=processedStack[i];if(!frame)break;const entry=this.code_map_.findEntry(frame);if(!entry&&i!==0){continue;}
+let sourceInfo=undefined;if(entry&&entry.type===CodeEntry.TYPE.CPP){const libEntry=this.code_map_.findEntryInLibraries(frame);if(libEntry){sourceInfo={file:libEntry.name};}}
+const entryId=entry?entry.id:-1;node=this.profileTree_.getNode(entryId);if(node===undefined){node=this.profileTree_.add(new ProfileNodeType(entryId,{functionName:entry.name,url:sourceInfo?sourceInfo.file:'',lineNumber:sourceInfo?sourceInfo.line:undefined,columnNumber:sourceInfo?sourceInfo.column:undefined,scriptId:sourceInfo?sourceInfo.scriptId:undefined},lastNode));}
+lastNode=node;}
+this.model_.samples.push(new tr.model.Sample(startInMs,'V8 PC',node,this.v8_thread_,undefined,1));},processDistortion_(distortionInPicoseconds){},processPlotRange_(start,end){},processV8Version_(major,minor,build,patch,candidate){},importEvents(){const logreader=new tr.e.importer.v8.LogReader({'timer-event':{parsers:[null,parseInt,parseInt],processor:this.processTimerEvent_.bind(this)},'shared-library':{parsers:[null,parseInt,parseInt],processor:this.processSharedLibrary_.bind(this)},'timer-event-start':{parsers:[null,parseInt],processor:this.processTimerEventStart_.bind(this)},'timer-event-end':{parsers:[null,parseInt],processor:this.processTimerEventEnd_.bind(this)},'code-creation':{parsers:[null,parseInt,parseInt,parseInt,null,'var-args'],processor:this.processCodeCreateEvent_.bind(this)},'code-move':{parsers:[parseInt,parseInt],processor:this.processCodeMoveEvent_.bind(this)},'code-delete':{parsers:[parseInt],processor:this.processCodeDeleteEvent_.bind(this)},'cpp':{parsers:[parseInt,parseInt,null],processor:this.processCppSymbol_.bind(this)},'tick':{parsers:[parseInt,parseInt,parseInt,parseInt,parseInt,'var-args'],processor:this.processTickEvent_.bind(this)},'distortion':{parsers:[parseInt],processor:this.processDistortion_.bind(this)},'plot-range':{parsers:[parseInt,parseInt],processor:this.processPlotRange_.bind(this)},'v8-version':{parsers:[parseInt,parseInt,parseInt,parseInt,parseInt],processor:this.processV8Version_.bind(this)}});this.v8_timer_thread_=this.model_.getOrCreateProcess(-32).getOrCreateThread(1);this.v8_timer_thread_.name='V8 Timers';this.v8_thread_=this.model_.getOrCreateProcess(-32).getOrCreateThread(2);this.v8_thread_.name='V8';const lines=this.logData_.split('\n');for(let i=0;i<lines.length;i++){logreader.processLogLine(lines[i]);}
+function addSlices(slices,thread){for(let i=0;i<slices.length;i++){const duration=slices[i].end-slices[i].start;const slice=new tr.model.ThreadSlice('v8',slices[i].name,ColorScheme.getColorIdForGeneralPurposeString(slices[i].name),slices[i].start,{},duration);thread.sliceGroup.pushSlice(slice);addSlices(slices[i].children,thread);}}
+addSlices(this.v8_stack_timeline_,this.v8_thread_);}};tr.importer.Importer.register(V8LogImporter);return{V8LogImporter,};});'use strict';if(tr.isVinn){global.window={};}
+!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;"undefined"!=typeof window?b=window:"undefined"!=typeof global?b=global:"undefined"!=typeof self&&(b=self),b.JSZip=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}({1:[function(a,b,c){"use strict";var d="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";c.encode=function(a){for(var b,c,e,f,g,h,i,j="",k=0;k<a.length;)b=a.charCodeAt(k++),c=a.charCodeAt(k++),e=a.charCodeAt(k++),f=b>>2,g=(3&b)<<4|c>>4,h=(15&c)<<2|e>>6,i=63&e,isNaN(c)?h=i=64:isNaN(e)&&(i=64),j=j+d.charAt(f)+d.charAt(g)+d.charAt(h)+d.charAt(i);return j},c.decode=function(a){var b,c,e,f,g,h,i,j="",k=0;for(a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");k<a.length;)f=d.indexOf(a.charAt(k++)),g=d.indexOf(a.charAt(k++)),h=d.indexOf(a.charAt(k++)),i=d.indexOf(a.charAt(k++)),b=f<<2|g>>4,c=(15&g)<<4|h>>2,e=(3&h)<<6|i,j+=String.fromCharCode(b),64!=h&&(j+=String.fromCharCode(c)),64!=i&&(j+=String.fromCharCode(e));return j}},{}],2:[function(a,b){"use strict";function c(){this.compressedSize=0,this.uncompressedSize=0,this.crc32=0,this.compressionMethod=null,this.compressedContent=null}c.prototype={getContent:function(){return null},getCompressedContent:function(){return null}},b.exports=c},{}],3:[function(a,b,c){"use strict";c.STORE={magic:"\x00\x00",compress:function(a){return a},uncompress:function(a){return a},compressInputType:null,uncompressInputType:null},c.DEFLATE=a("./flate")},{"./flate":8}],4:[function(a,b){"use strict";var c=a("./utils"),d=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117];b.exports=function(a,b){if("undefined"==typeof a||!a.length)return 0;var e="string"!==c.getTypeOf(a);"undefined"==typeof b&&(b=0);var f=0,g=0,h=0;b=-1^b;for(var i=0,j=a.length;j>i;i++)h=e?a[i]:a.charCodeAt(i),g=255&(b^h),f=d[g],b=b>>>8^f;return-1^b}},{"./utils":21}],5:[function(a,b){"use strict";function c(){this.data=null,this.length=0,this.index=0}var d=a("./utils");c.prototype={checkOffset:function(a){this.checkIndex(this.index+a)},checkIndex:function(a){if(this.length<a||0>a)throw new Error("End of data reached (data length = "+this.length+", asked index = "+a+"). Corrupted zip ?")},setIndex:function(a){this.checkIndex(a),this.index=a},skip:function(a){this.setIndex(this.index+a)},byteAt:function(){},readInt:function(a){var b,c=0;for(this.checkOffset(a),b=this.index+a-1;b>=this.index;b--)c=(c<<8)+this.byteAt(b);return this.index+=a,c},readString:function(a){return d.transformTo("string",this.readData(a))},readData:function(){},lastIndexOfSignature:function(){},readDate:function(){var a=this.readInt(4);return new Date((a>>25&127)+1980,(a>>21&15)-1,a>>16&31,a>>11&31,a>>5&63,(31&a)<<1)}},b.exports=c},{"./utils":21}],6:[function(a,b,c){"use strict";c.base64=!1,c.binary=!1,c.dir=!1,c.createFolders=!1,c.date=null,c.compression=null,c.comment=null},{}],7:[function(a,b,c){"use strict";var d=a("./utils");c.string2binary=function(a){return d.string2binary(a)},c.string2Uint8Array=function(a){return d.transformTo("uint8array",a)},c.uint8Array2String=function(a){return d.transformTo("string",a)},c.string2Blob=function(a){var b=d.transformTo("arraybuffer",a);return d.arrayBuffer2Blob(b)},c.arrayBuffer2Blob=function(a){return d.arrayBuffer2Blob(a)},c.transformTo=function(a,b){return d.transformTo(a,b)},c.getTypeOf=function(a){return d.getTypeOf(a)},c.checkSupport=function(a){return d.checkSupport(a)},c.MAX_VALUE_16BITS=d.MAX_VALUE_16BITS,c.MAX_VALUE_32BITS=d.MAX_VALUE_32BITS,c.pretty=function(a){return d.pretty(a)},c.findCompression=function(a){return d.findCompression(a)},c.isRegExp=function(a){return d.isRegExp(a)}},{"./utils":21}],8:[function(a,b,c){"use strict";var d="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Uint32Array,e=a("pako");c.uncompressInputType=d?"uint8array":"array",c.compressInputType=d?"uint8array":"array",c.magic="\b\x00",c.compress=function(a){return e.deflateRaw(a)},c.uncompress=function(a){return e.inflateRaw(a)}},{pako:24}],9:[function(a,b){"use strict";function c(a,b){return this instanceof c?(this.files={},this.comment=null,this.root="",a&&this.load(a,b),void(this.clone=function(){var a=new c;for(var b in this)"function"!=typeof this[b]&&(a[b]=this[b]);return a})):new c(a,b)}var d=a("./base64");c.prototype=a("./object"),c.prototype.load=a("./load"),c.support=a("./support"),c.defaults=a("./defaults"),c.utils=a("./deprecatedPublicUtils"),c.base64={encode:function(a){return d.encode(a)},decode:function(a){return d.decode(a)}},c.compressions=a("./compressions"),b.exports=c},{"./base64":1,"./compressions":3,"./defaults":6,"./deprecatedPublicUtils":7,"./load":10,"./object":13,"./support":17}],10:[function(a,b){"use strict";var c=a("./base64"),d=a("./zipEntries");b.exports=function(a,b){var e,f,g,h;for(b=b||{},b.base64&&(a=c.decode(a)),f=new d(a,b),e=f.files,g=0;g<e.length;g++)h=e[g],this.file(h.fileName,h.decompressed,{binary:!0,optimizedBinaryString:!0,date:h.date,dir:h.dir,comment:h.fileComment.length?h.fileComment:null,createFolders:b.createFolders});return f.zipComment.length&&(this.comment=f.zipComment),this}},{"./base64":1,"./zipEntries":22}],11:[function(a,b){(function(a){"use strict";b.exports=function(b,c){return new a(b,c)},b.exports.test=function(b){return a.isBuffer(b)}}).call(this,"undefined"!=typeof Buffer?Buffer:void 0)},{}],12:[function(a,b){"use strict";function c(a){this.data=a,this.length=this.data.length,this.index=0}var d=a("./uint8ArrayReader");c.prototype=new d,c.prototype.readData=function(a){this.checkOffset(a);var b=this.data.slice(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./uint8ArrayReader":18}],13:[function(a,b){"use strict";var c=a("./support"),d=a("./utils"),e=a("./crc32"),f=a("./signature"),g=a("./defaults"),h=a("./base64"),i=a("./compressions"),j=a("./compressedObject"),k=a("./nodeBuffer"),l=a("./utf8"),m=a("./stringWriter"),n=a("./uint8ArrayWriter"),o=function(a){if(a._data instanceof j&&(a._data=a._data.getContent(),a.options.binary=!0,a.options.base64=!1,"uint8array"===d.getTypeOf(a._data))){var b=a._data;a._data=new Uint8Array(b.length),0!==b.length&&a._data.set(b,0)}return a._data},p=function(a){var b=o(a),e=d.getTypeOf(b);return"string"===e?!a.options.binary&&c.nodebuffer?k(b,"utf-8"):a.asBinary():b},q=function(a){var b=o(this);return null===b||"undefined"==typeof b?"":(this.options.base64&&(b=h.decode(b)),b=a&&this.options.binary?A.utf8decode(b):d.transformTo("string",b),a||this.options.binary||(b=d.transformTo("string",A.utf8encode(b))),b)},r=function(a,b,c){this.name=a,this.dir=c.dir,this.date=c.date,this.comment=c.comment,this._data=b,this.options=c,this._initialMetadata={dir:c.dir,date:c.date}};r.prototype={asText:function(){return q.call(this,!0)},asBinary:function(){return q.call(this,!1)},asNodeBuffer:function(){var a=p(this);return d.transformTo("nodebuffer",a)},asUint8Array:function(){var a=p(this);return d.transformTo("uint8array",a)},asArrayBuffer:function(){return this.asUint8Array().buffer}};var s=function(a,b){var c,d="";for(c=0;b>c;c++)d+=String.fromCharCode(255&a),a>>>=8;return d},t=function(){var a,b,c={};for(a=0;a<arguments.length;a++)for(b in arguments[a])arguments[a].hasOwnProperty(b)&&"undefined"==typeof c[b]&&(c[b]=arguments[a][b]);return c},u=function(a){return a=a||{},a.base64!==!0||null!==a.binary&&void 0!==a.binary||(a.binary=!0),a=t(a,g),a.date=a.date||new Date,null!==a.compression&&(a.compression=a.compression.toUpperCase()),a},v=function(a,b,c){var e,f=d.getTypeOf(b);if(c=u(c),c.createFolders&&(e=w(a))&&x.call(this,e,!0),c.dir||null===b||"undefined"==typeof b)c.base64=!1,c.binary=!1,b=null;else if("string"===f)c.binary&&!c.base64&&c.optimizedBinaryString!==!0&&(b=d.string2binary(b));else{if(c.base64=!1,c.binary=!0,!(f||b instanceof j))throw new Error("The data of '"+a+"' is in an unsupported format !");"arraybuffer"===f&&(b=d.transformTo("uint8array",b))}var g=new r(a,b,c);return this.files[a]=g,g},w=function(a){"/"==a.slice(-1)&&(a=a.substring(0,a.length-1));var b=a.lastIndexOf("/");return b>0?a.substring(0,b):""},x=function(a,b){return"/"!=a.slice(-1)&&(a+="/"),b="undefined"!=typeof b?b:!1,this.files[a]||v.call(this,a,null,{dir:!0,createFolders:b}),this.files[a]},y=function(a,b){var c,f=new j;return a._data instanceof j?(f.uncompressedSize=a._data.uncompressedSize,f.crc32=a._data.crc32,0===f.uncompressedSize||a.dir?(b=i.STORE,f.compressedContent="",f.crc32=0):a._data.compressionMethod===b.magic?f.compressedContent=a._data.getCompressedContent():(c=a._data.getContent(),f.compressedContent=b.compress(d.transformTo(b.compressInputType,c)))):(c=p(a),(!c||0===c.length||a.dir)&&(b=i.STORE,c=""),f.uncompressedSize=c.length,f.crc32=e(c),f.compressedContent=b.compress(d.transformTo(b.compressInputType,c))),f.compressedSize=f.compressedContent.length,f.compressionMethod=b.magic,f},z=function(a,b,c,g){var h,i,j,k,m=(c.compressedContent,d.transformTo("string",l.utf8encode(b.name))),n=b.comment||"",o=d.transformTo("string",l.utf8encode(n)),p=m.length!==b.name.length,q=o.length!==n.length,r=b.options,t="",u="",v="";j=b._initialMetadata.dir!==b.dir?b.dir:r.dir,k=b._initialMetadata.date!==b.date?b.date:r.date,h=k.getHours(),h<<=6,h|=k.getMinutes(),h<<=5,h|=k.getSeconds()/2,i=k.getFullYear()-1980,i<<=4,i|=k.getMonth()+1,i<<=5,i|=k.getDate(),p&&(u=s(1,1)+s(e(m),4)+m,t+="up"+s(u.length,2)+u),q&&(v=s(1,1)+s(this.crc32(o),4)+o,t+="uc"+s(v.length,2)+v);var w="";w+="\n\x00",w+=p||q?"\x00\b":"\x00\x00",w+=c.compressionMethod,w+=s(h,2),w+=s(i,2),w+=s(c.crc32,4),w+=s(c.compressedSize,4),w+=s(c.uncompressedSize,4),w+=s(m.length,2),w+=s(t.length,2);var x=f.LOCAL_FILE_HEADER+w+m+t,y=f.CENTRAL_FILE_HEADER+"\x00"+w+s(o.length,2)+"\x00\x00\x00\x00"+(j===!0?"\x00\x00\x00":"\x00\x00\x00\x00")+s(g,4)+m+t+o;return{fileRecord:x,dirRecord:y,compressedObject:c}},A={load:function(){throw new Error("Load method is not defined. Is the file jszip-load.js included ?")},filter:function(a){var b,c,d,e,f=[];for(b in this.files)this.files.hasOwnProperty(b)&&(d=this.files[b],e=new r(d.name,d._data,t(d.options)),c=b.slice(this.root.length,b.length),b.slice(0,this.root.length)===this.root&&a(c,e)&&f.push(e));return f},file:function(a,b,c){if(1===arguments.length){if(d.isRegExp(a)){var e=a;return this.filter(function(a,b){return!b.dir&&e.test(a)})}return this.filter(function(b,c){return!c.dir&&b===a})[0]||null}return a=this.root+a,v.call(this,a,b,c),this},folder:function(a){if(!a)return this;if(d.isRegExp(a))return this.filter(function(b,c){return c.dir&&a.test(b)});var b=this.root+a,c=x.call(this,b),e=this.clone();return e.root=c.name,e},remove:function(a){a=this.root+a;var b=this.files[a];if(b||("/"!=a.slice(-1)&&(a+="/"),b=this.files[a]),b&&!b.dir)delete this.files[a];else for(var c=this.filter(function(b,c){return c.name.slice(0,a.length)===a}),d=0;d<c.length;d++)delete this.files[c[d].name];return this},generate:function(a){a=t(a||{},{base64:!0,compression:"STORE",type:"base64",comment:null}),d.checkSupport(a.type);var b,c,e=[],g=0,j=0,k=d.transformTo("string",this.utf8encode(a.comment||this.comment||""));for(var l in this.files)if(this.files.hasOwnProperty(l)){var o=this.files[l],p=o.options.compression||a.compression.toUpperCase(),q=i[p];if(!q)throw new Error(p+" is not a valid compression method !");var r=y.call(this,o,q),u=z.call(this,l,o,r,g);g+=u.fileRecord.length+r.compressedSize,j+=u.dirRecord.length,e.push(u)}var v="";v=f.CENTRAL_DIRECTORY_END+"\x00\x00\x00\x00"+s(e.length,2)+s(e.length,2)+s(j,4)+s(g,4)+s(k.length,2)+k;var w=a.type.toLowerCase();for(b="uint8array"===w||"arraybuffer"===w||"blob"===w||"nodebuffer"===w?new n(g+j+v.length):new m(g+j+v.length),c=0;c<e.length;c++)b.append(e[c].fileRecord),b.append(e[c].compressedObject.compressedContent);for(c=0;c<e.length;c++)b.append(e[c].dirRecord);b.append(v);var x=b.finalize();switch(a.type.toLowerCase()){case"uint8array":case"arraybuffer":case"nodebuffer":return d.transformTo(a.type.toLowerCase(),x);case"blob":return d.arrayBuffer2Blob(d.transformTo("arraybuffer",x));case"base64":return a.base64?h.encode(x):x;default:return x}},crc32:function(a,b){return e(a,b)},utf8encode:function(a){return d.transformTo("string",l.utf8encode(a))},utf8decode:function(a){return l.utf8decode(a)}};b.exports=A},{"./base64":1,"./compressedObject":2,"./compressions":3,"./crc32":4,"./defaults":6,"./nodeBuffer":11,"./signature":14,"./stringWriter":16,"./support":17,"./uint8ArrayWriter":19,"./utf8":20,"./utils":21}],14:[function(a,b,c){"use strict";c.LOCAL_FILE_HEADER="PK",c.CENTRAL_FILE_HEADER="PK",c.CENTRAL_DIRECTORY_END="PK",c.ZIP64_CENTRAL_DIRECTORY_LOCATOR="PK",c.ZIP64_CENTRAL_DIRECTORY_END="PK",c.DATA_DESCRIPTOR="PK\b"},{}],15:[function(a,b){"use strict";function c(a,b){this.data=a,b||(this.data=e.string2binary(this.data)),this.length=this.data.length,this.index=0}var d=a("./dataReader"),e=a("./utils");c.prototype=new d,c.prototype.byteAt=function(a){return this.data.charCodeAt(a)},c.prototype.lastIndexOfSignature=function(a){return this.data.lastIndexOf(a)},c.prototype.readData=function(a){this.checkOffset(a);var b=this.data.slice(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./dataReader":5,"./utils":21}],16:[function(a,b){"use strict";var c=a("./utils"),d=function(){this.data=[]};d.prototype={append:function(a){a=c.transformTo("string",a),this.data.push(a)},finalize:function(){return this.data.join("")}},b.exports=d},{"./utils":21}],17:[function(a,b,c){(function(a){"use strict";if(c.base64=!0,c.array=!0,c.string=!0,c.arraybuffer="undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array,c.nodebuffer="undefined"!=typeof a,c.uint8array="undefined"!=typeof Uint8Array,"undefined"==typeof ArrayBuffer)c.blob=!1;else{var b=new ArrayBuffer(0);try{c.blob=0===new Blob([b],{type:"application/zip"}).size}catch(d){try{var e=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,f=new e;f.append(b),c.blob=0===f.getBlob("application/zip").size}catch(d){c.blob=!1}}}}).call(this,"undefined"!=typeof Buffer?Buffer:void 0)},{}],18:[function(a,b){"use strict";function c(a){a&&(this.data=a,this.length=this.data.length,this.index=0)}var d=a("./dataReader");c.prototype=new d,c.prototype.byteAt=function(a){return this.data[a]},c.prototype.lastIndexOfSignature=function(a){for(var b=a.charCodeAt(0),c=a.charCodeAt(1),d=a.charCodeAt(2),e=a.charCodeAt(3),f=this.length-4;f>=0;--f)if(this.data[f]===b&&this.data[f+1]===c&&this.data[f+2]===d&&this.data[f+3]===e)return f;return-1},c.prototype.readData=function(a){if(this.checkOffset(a),0===a)return new Uint8Array(0);var b=this.data.subarray(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./dataReader":5}],19:[function(a,b){"use strict";var c=a("./utils"),d=function(a){this.data=new Uint8Array(a),this.index=0};d.prototype={append:function(a){0!==a.length&&(a=c.transformTo("uint8array",a),this.data.set(a,this.index),this.index+=a.length)},finalize:function(){return this.data}},b.exports=d},{"./utils":21}],20:[function(a,b,c){"use strict";for(var d=a("./utils"),e=a("./support"),f=a("./nodeBuffer"),g=new Array(256),h=0;256>h;h++)g[h]=h>=252?6:h>=248?5:h>=240?4:h>=224?3:h>=192?2:1;g[254]=g[254]=1;var i=function(a){var b,c,d,f,g,h=a.length,i=0;for(f=0;h>f;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),i+=128>c?1:2048>c?2:65536>c?3:4;for(b=e.uint8array?new Uint8Array(i):new Array(i),g=0,f=0;i>g;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),128>c?b[g++]=c:2048>c?(b[g++]=192|c>>>6,b[g++]=128|63&c):65536>c?(b[g++]=224|c>>>12,b[g++]=128|c>>>6&63,b[g++]=128|63&c):(b[g++]=240|c>>>18,b[g++]=128|c>>>12&63,b[g++]=128|c>>>6&63,b[g++]=128|63&c);return b},j=function(a,b){var c;for(b=b||a.length,b>a.length&&(b=a.length),c=b-1;c>=0&&128===(192&a[c]);)c--;return 0>c?b:0===c?b:c+g[a[c]]>b?c:b},k=function(a){var b,c,e,f,h=a.length,i=new Array(2*h);for(c=0,b=0;h>b;)if(e=a[b++],128>e)i[c++]=e;else if(f=g[e],f>4)i[c++]=65533,b+=f-1;else{for(e&=2===f?31:3===f?15:7;f>1&&h>b;)e=e<<6|63&a[b++],f--;f>1?i[c++]=65533:65536>e?i[c++]=e:(e-=65536,i[c++]=55296|e>>10&1023,i[c++]=56320|1023&e)}return i.length!==c&&(i.subarray?i=i.subarray(0,c):i.length=c),d.applyFromCharCode(i)};c.utf8encode=function(a){return e.nodebuffer?f(a,"utf-8"):i(a)},c.utf8decode=function(a){if(e.nodebuffer)return d.transformTo("nodebuffer",a).toString("utf-8");a=d.transformTo(e.uint8array?"uint8array":"array",a);for(var b=[],c=0,f=a.length,g=65536;f>c;){var h=j(a,Math.min(c+g,f));b.push(e.uint8array?k(a.subarray(c,h)):k(a.slice(c,h))),c=h}return b.join("")}},{"./nodeBuffer":11,"./support":17,"./utils":21}],21:[function(a,b,c){"use strict";function d(a){return a}function e(a,b){for(var c=0;c<a.length;++c)b[c]=255&a.charCodeAt(c);return b}function f(a){var b=65536,d=[],e=a.length,f=c.getTypeOf(a),g=0,h=!0;try{switch(f){case"uint8array":String.fromCharCode.apply(null,new Uint8Array(0));break;case"nodebuffer":String.fromCharCode.apply(null,j(0))}}catch(i){h=!1}if(!h){for(var k="",l=0;l<a.length;l++)k+=String.fromCharCode(a[l]);return k}for(;e>g&&b>1;)try{d.push("array"===f||"nodebuffer"===f?String.fromCharCode.apply(null,a.slice(g,Math.min(g+b,e))):String.fromCharCode.apply(null,a.subarray(g,Math.min(g+b,e)))),g+=b}catch(i){b=Math.floor(b/2)}return d.join("")}function g(a,b){for(var c=0;c<a.length;c++)b[c]=a[c];return b}var h=a("./support"),i=a("./compressions"),j=a("./nodeBuffer");c.string2binary=function(a){for(var b="",c=0;c<a.length;c++)b+=String.fromCharCode(255&a.charCodeAt(c));return b},c.arrayBuffer2Blob=function(a){c.checkSupport("blob");try{return new Blob([a],{type:"application/zip"})}catch(b){try{var d=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,e=new d;return e.append(a),e.getBlob("application/zip")}catch(b){throw new Error("Bug : can't construct the Blob.")}}},c.applyFromCharCode=f;var k={};k.string={string:d,array:function(a){return e(a,new Array(a.length))},arraybuffer:function(a){return k.string.uint8array(a).buffer},uint8array:function(a){return e(a,new Uint8Array(a.length))},nodebuffer:function(a){return e(a,j(a.length))}},k.array={string:f,array:d,arraybuffer:function(a){return new Uint8Array(a).buffer},uint8array:function(a){return new Uint8Array(a)},nodebuffer:function(a){return j(a)}},k.arraybuffer={string:function(a){return f(new Uint8Array(a))},array:function(a){return g(new Uint8Array(a),new Array(a.byteLength))},arraybuffer:d,uint8array:function(a){return new Uint8Array(a)},nodebuffer:function(a){return j(new Uint8Array(a))}},k.uint8array={string:f,array:function(a){return g(a,new Array(a.length))},arraybuffer:function(a){return a.buffer},uint8array:d,nodebuffer:function(a){return j(a)}},k.nodebuffer={string:f,array:function(a){return g(a,new Array(a.length))},arraybuffer:function(a){return k.nodebuffer.uint8array(a).buffer},uint8array:function(a){return g(a,new Uint8Array(a.length))},nodebuffer:d},c.transformTo=function(a,b){if(b||(b=""),!a)return b;c.checkSupport(a);var d=c.getTypeOf(b),e=k[d][a](b);return e},c.getTypeOf=function(a){return"string"==typeof a?"string":"[object Array]"===Object.prototype.toString.call(a)?"array":h.nodebuffer&&j.test(a)?"nodebuffer":h.uint8array&&a instanceof Uint8Array?"uint8array":h.arraybuffer&&a instanceof ArrayBuffer?"arraybuffer":void 0},c.checkSupport=function(a){var b=h[a.toLowerCase()];if(!b)throw new Error(a+" is not supported by this browser")},c.MAX_VALUE_16BITS=65535,c.MAX_VALUE_32BITS=-1,c.pretty=function(a){var b,c,d="";for(c=0;c<(a||"").length;c++)b=a.charCodeAt(c),d+="\\x"+(16>b?"0":"")+b.toString(16).toUpperCase();return d},c.findCompression=function(a){for(var b in i)if(i.hasOwnProperty(b)&&i[b].magic===a)return i[b];return null},c.isRegExp=function(a){return"[object RegExp]"===Object.prototype.toString.call(a)}},{"./compressions":3,"./nodeBuffer":11,"./support":17}],22:[function(a,b){"use strict";function c(a,b){this.files=[],this.loadOptions=b,a&&this.load(a)}var d=a("./stringReader"),e=a("./nodeBufferReader"),f=a("./uint8ArrayReader"),g=a("./utils"),h=a("./signature"),i=a("./zipEntry"),j=a("./support"),k=a("./object");c.prototype={checkSignature:function(a){var b=this.reader.readString(4);if(b!==a)throw new Error("Corrupted zip or bug : unexpected signature ("+g.pretty(b)+", expected "+g.pretty(a)+")")},readBlockEndOfCentral:function(){this.diskNumber=this.reader.readInt(2),this.diskWithCentralDirStart=this.reader.readInt(2),this.centralDirRecordsOnThisDisk=this.reader.readInt(2),this.centralDirRecords=this.reader.readInt(2),this.centralDirSize=this.reader.readInt(4),this.centralDirOffset=this.reader.readInt(4),this.zipCommentLength=this.reader.readInt(2),this.zipComment=this.reader.readString(this.zipCommentLength),this.zipComment=k.utf8decode(this.zipComment)},readBlockZip64EndOfCentral:function(){this.zip64EndOfCentralSize=this.reader.readInt(8),this.versionMadeBy=this.reader.readString(2),this.versionNeeded=this.reader.readInt(2),this.diskNumber=this.reader.readInt(4),this.diskWithCentralDirStart=this.reader.readInt(4),this.centralDirRecordsOnThisDisk=this.reader.readInt(8),this.centralDirRecords=this.reader.readInt(8),this.centralDirSize=this.reader.readInt(8),this.centralDirOffset=this.reader.readInt(8),this.zip64ExtensibleData={};for(var a,b,c,d=this.zip64EndOfCentralSize-44,e=0;d>e;)a=this.reader.readInt(2),b=this.reader.readInt(4),c=this.reader.readString(b),this.zip64ExtensibleData[a]={id:a,length:b,value:c}},readBlockZip64EndOfCentralLocator:function(){if(this.diskWithZip64CentralDirStart=this.reader.readInt(4),this.relativeOffsetEndOfZip64CentralDir=this.reader.readInt(8),this.disksCount=this.reader.readInt(4),this.disksCount>1)throw new Error("Multi-volumes zip are not supported")},readLocalFiles:function(){var a,b;for(a=0;a<this.files.length;a++)b=this.files[a],this.reader.setIndex(b.localHeaderOffset),this.checkSignature(h.LOCAL_FILE_HEADER),b.readLocalPart(this.reader),b.handleUTF8()},readCentralDir:function(){var a;for(this.reader.setIndex(this.centralDirOffset);this.reader.readString(4)===h.CENTRAL_FILE_HEADER;)a=new i({zip64:this.zip64},this.loadOptions),a.readCentralPart(this.reader),this.files.push(a)},readEndOfCentral:function(){var a=this.reader.lastIndexOfSignature(h.CENTRAL_DIRECTORY_END);if(-1===a)throw new Error("Corrupted zip : can't find end of central directory");if(this.reader.setIndex(a),this.checkSignature(h.CENTRAL_DIRECTORY_END),this.readBlockEndOfCentral(),this.diskNumber===g.MAX_VALUE_16BITS||this.diskWithCentralDirStart===g.MAX_VALUE_16BITS||this.centralDirRecordsOnThisDisk===g.MAX_VALUE_16BITS||this.centralDirRecords===g.MAX_VALUE_16BITS||this.centralDirSize===g.MAX_VALUE_32BITS||this.centralDirOffset===g.MAX_VALUE_32BITS){if(this.zip64=!0,a=this.reader.lastIndexOfSignature(h.ZIP64_CENTRAL_DIRECTORY_LOCATOR),-1===a)throw new Error("Corrupted zip : can't find the ZIP64 end of central directory locator");this.reader.setIndex(a),this.checkSignature(h.ZIP64_CENTRAL_DIRECTORY_LOCATOR),this.readBlockZip64EndOfCentralLocator(),this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir),this.checkSignature(h.ZIP64_CENTRAL_DIRECTORY_END),this.readBlockZip64EndOfCentral()}},prepareReader:function(a){var b=g.getTypeOf(a);this.reader="string"!==b||j.uint8array?"nodebuffer"===b?new e(a):new f(g.transformTo("uint8array",a)):new d(a,this.loadOptions.optimizedBinaryString)},load:function(a){this.prepareReader(a),this.readEndOfCentral(),this.readCentralDir(),this.readLocalFiles()}},b.exports=c},{"./nodeBufferReader":12,"./object":13,"./signature":14,"./stringReader":15,"./support":17,"./uint8ArrayReader":18,"./utils":21,"./zipEntry":23}],23:[function(a,b){"use strict";function c(a,b){this.options=a,this.loadOptions=b}var d=a("./stringReader"),e=a("./utils"),f=a("./compressedObject"),g=a("./object");c.prototype={isEncrypted:function(){return 1===(1&this.bitFlag)},useUTF8:function(){return 2048===(2048&this.bitFlag)},prepareCompressedContent:function(a,b,c){return function(){var d=a.index;a.setIndex(b);var e=a.readData(c);return a.setIndex(d),e}},prepareContent:function(a,b,c,d,f){return function(){var a=e.transformTo(d.uncompressInputType,this.getCompressedContent()),b=d.uncompress(a);if(b.length!==f)throw new Error("Bug : uncompressed data size mismatch");return b}},readLocalPart:function(a){var b,c;if(a.skip(22),this.fileNameLength=a.readInt(2),c=a.readInt(2),this.fileName=a.readString(this.fileNameLength),a.skip(c),-1==this.compressedSize||-1==this.uncompressedSize)throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory (compressedSize == -1 || uncompressedSize == -1)");if(b=e.findCompression(this.compressionMethod),null===b)throw new Error("Corrupted zip : compression "+e.pretty(this.compressionMethod)+" unknown (inner file : "+this.fileName+")");if(this.decompressed=new f,this.decompressed.compressedSize=this.compressedSize,this.decompressed.uncompressedSize=this.uncompressedSize,this.decompressed.crc32=this.crc32,this.decompressed.compressionMethod=this.compressionMethod,this.decompressed.getCompressedContent=this.prepareCompressedContent(a,a.index,this.compressedSize,b),this.decompressed.getContent=this.prepareContent(a,a.index,this.compressedSize,b,this.uncompressedSize),this.loadOptions.checkCRC32&&(this.decompressed=e.transformTo("string",this.decompressed.getContent()),g.crc32(this.decompressed)!==this.crc32))throw new Error("Corrupted zip : CRC32 mismatch")},readCentralPart:function(a){if(this.versionMadeBy=a.readString(2),this.versionNeeded=a.readInt(2),this.bitFlag=a.readInt(2),this.compressionMethod=a.readString(2),this.date=a.readDate(),this.crc32=a.readInt(4),this.compressedSize=a.readInt(4),this.uncompressedSize=a.readInt(4),this.fileNameLength=a.readInt(2),this.extraFieldsLength=a.readInt(2),this.fileCommentLength=a.readInt(2),this.diskNumberStart=a.readInt(2),this.internalFileAttributes=a.readInt(2),this.externalFileAttributes=a.readInt(4),this.localHeaderOffset=a.readInt(4),this.isEncrypted())throw new Error("Encrypted zip are not supported");this.fileName=a.readString(this.fileNameLength),this.readExtraFields(a),this.parseZIP64ExtraField(a),this.fileComment=a.readString(this.fileCommentLength),this.dir=16&this.externalFileAttributes?!0:!1},parseZIP64ExtraField:function(){if(this.extraFields[1]){var a=new d(this.extraFields[1].value);this.uncompressedSize===e.MAX_VALUE_32BITS&&(this.uncompressedSize=a.readInt(8)),this.compressedSize===e.MAX_VALUE_32BITS&&(this.compressedSize=a.readInt(8)),this.localHeaderOffset===e.MAX_VALUE_32BITS&&(this.localHeaderOffset=a.readInt(8)),this.diskNumberStart===e.MAX_VALUE_32BITS&&(this.diskNumberStart=a.readInt(4))}},readExtraFields:function(a){var b,c,d,e=a.index;for(this.extraFields=this.extraFields||{};a.index<e+this.extraFieldsLength;)b=a.readInt(2),c=a.readInt(2),d=a.readString(c),this.extraFields[b]={id:b,length:c,value:d}},handleUTF8:function(){if(this.useUTF8())this.fileName=g.utf8decode(this.fileName),this.fileComment=g.utf8decode(this.fileComment);else{var a=this.findExtraFieldUnicodePath();null!==a&&(this.fileName=a);var b=this.findExtraFieldUnicodeComment();null!==b&&(this.fileComment=b)}},findExtraFieldUnicodePath:function(){var a=this.extraFields[28789];if(a){var b=new d(a.value);return 1!==b.readInt(1)?null:g.crc32(this.fileName)!==b.readInt(4)?null:g.utf8decode(b.readString(a.length-5))}return null},findExtraFieldUnicodeComment:function(){var a=this.extraFields[25461];if(a){var b=new d(a.value);return 1!==b.readInt(1)?null:g.crc32(this.fileComment)!==b.readInt(4)?null:g.utf8decode(b.readString(a.length-5))}return null}},b.exports=c},{"./compressedObject":2,"./object":13,"./stringReader":15,"./utils":21}],24:[function(a,b){"use strict";var c=a("./lib/utils/common").assign,d=a("./lib/deflate"),e=a("./lib/inflate"),f=a("./lib/zlib/constants"),g={};c(g,d,e,f),b.exports=g},{"./lib/deflate":25,"./lib/inflate":26,"./lib/utils/common":27,"./lib/zlib/constants":30}],25:[function(a,b,c){"use strict";function d(a,b){var c=new s(b);if(c.push(a,!0),c.err)throw c.msg;return c.result}function e(a,b){return b=b||{},b.raw=!0,d(a,b)}function f(a,b){return b=b||{},b.gzip=!0,d(a,b)}var g=a("./zlib/deflate.js"),h=a("./utils/common"),i=a("./utils/strings"),j=a("./zlib/messages"),k=a("./zlib/zstream"),l=0,m=4,n=0,o=1,p=-1,q=0,r=8,s=function(a){this.options=h.assign({level:p,method:r,chunkSize:16384,windowBits:15,memLevel:8,strategy:q,to:""},a||{});var b=this.options;b.raw&&b.windowBits>0?b.windowBits=-b.windowBits:b.gzip&&b.windowBits>0&&b.windowBits<16&&(b.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new k,this.strm.avail_out=0;var c=g.deflateInit2(this.strm,b.level,b.method,b.windowBits,b.memLevel,b.strategy);if(c!==n)throw new Error(j[c]);b.header&&g.deflateSetHeader(this.strm,b.header)};s.prototype.push=function(a,b){var c,d,e=this.strm,f=this.options.chunkSize;if(this.ended)return!1;d=b===~~b?b:b===!0?m:l,e.input="string"==typeof a?i.string2buf(a):a,e.next_in=0,e.avail_in=e.input.length;do{if(0===e.avail_out&&(e.output=new h.Buf8(f),e.next_out=0,e.avail_out=f),c=g.deflate(e,d),c!==o&&c!==n)return this.onEnd(c),this.ended=!0,!1;(0===e.avail_out||0===e.avail_in&&d===m)&&this.onData("string"===this.options.to?i.buf2binstring(h.shrinkBuf(e.output,e.next_out)):h.shrinkBuf(e.output,e.next_out))}while((e.avail_in>0||0===e.avail_out)&&c!==o);return d===m?(c=g.deflateEnd(this.strm),this.onEnd(c),this.ended=!0,c===n):!0},s.prototype.onData=function(a){this.chunks.push(a)},s.prototype.onEnd=function(a){a===n&&(this.result="string"===this.options.to?this.chunks.join(""):h.flattenChunks(this.chunks)),this.chunks=[],this.err=a,this.msg=this.strm.msg},c.Deflate=s,c.deflate=d,c.deflateRaw=e,c.gzip=f},{"./utils/common":27,"./utils/strings":28,"./zlib/deflate.js":32,"./zlib/messages":37,"./zlib/zstream":39}],26:[function(a,b,c){"use strict";function d(a,b){var c=new m(b);if(c.push(a,!0),c.err)throw c.msg;return c.result}function e(a,b){return b=b||{},b.raw=!0,d(a,b)}var f=a("./zlib/inflate.js"),g=a("./utils/common"),h=a("./utils/strings"),i=a("./zlib/constants"),j=a("./zlib/messages"),k=a("./zlib/zstream"),l=a("./zlib/gzheader"),m=function(a){this.options=g.assign({chunkSize:16384,windowBits:0,to:""},a||{});var b=this.options;b.raw&&b.windowBits>=0&&b.windowBits<16&&(b.windowBits=-b.windowBits,0===b.windowBits&&(b.windowBits=-15)),!(b.windowBits>=0&&b.windowBits<16)||a&&a.windowBits||(b.windowBits+=32),b.windowBits>15&&b.windowBits<48&&0===(15&b.windowBits)&&(b.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new k,this.strm.avail_out=0;var c=f.inflateInit2(this.strm,b.windowBits);if(c!==i.Z_OK)throw new Error(j[c]);this.header=new l,f.inflateGetHeader(this.strm,this.header)};m.prototype.push=function(a,b){var c,d,e,j,k,l=this.strm,m=this.options.chunkSize;if(this.ended)return!1;d=b===~~b?b:b===!0?i.Z_FINISH:i.Z_NO_FLUSH,l.input="string"==typeof a?h.binstring2buf(a):a,l.next_in=0,l.avail_in=l.input.length;do{if(0===l.avail_out&&(l.output=new g.Buf8(m),l.next_out=0,l.avail_out=m),c=f.inflate(l,i.Z_NO_FLUSH),c!==i.Z_STREAM_END&&c!==i.Z_OK)return this.onEnd(c),this.ended=!0,!1;l.next_out&&(0===l.avail_out||c===i.Z_STREAM_END||0===l.avail_in&&d===i.Z_FINISH)&&("string"===this.options.to?(e=h.utf8border(l.output,l.next_out),j=l.next_out-e,k=h.buf2string(l.output,e),l.next_out=j,l.avail_out=m-j,j&&g.arraySet(l.output,l.output,e,j,0),this.onData(k)):this.onData(g.shrinkBuf(l.output,l.next_out)))}while(l.avail_in>0&&c!==i.Z_STREAM_END);return c===i.Z_STREAM_END&&(d=i.Z_FINISH),d===i.Z_FINISH?(c=f.inflateEnd(this.strm),this.onEnd(c),this.ended=!0,c===i.Z_OK):!0},m.prototype.onData=function(a){this.chunks.push(a)},m.prototype.onEnd=function(a){a===i.Z_OK&&(this.result="string"===this.options.to?this.chunks.join(""):g.flattenChunks(this.chunks)),this.chunks=[],this.err=a,this.msg=this.strm.msg},c.Inflate=m,c.inflate=d,c.inflateRaw=e,c.ungzip=d},{"./utils/common":27,"./utils/strings":28,"./zlib/constants":30,"./zlib/gzheader":33,"./zlib/inflate.js":35,"./zlib/messages":37,"./zlib/zstream":39}],27:[function(a,b,c){"use strict";var d="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;c.assign=function(a){for(var b=Array.prototype.slice.call(arguments,1);b.length;){var c=b.shift();if(c){if("object"!=typeof c)throw new TypeError(c+"must be non-object");for(var d in c)c.hasOwnProperty(d)&&(a[d]=c[d])}}return a},c.shrinkBuf=function(a,b){return a.length===b?a:a.subarray?a.subarray(0,b):(a.length=b,a)};var e={arraySet:function(a,b,c,d,e){if(b.subarray&&a.subarray)return void a.set(b.subarray(c,c+d),e);for(var f=0;d>f;f++)a[e+f]=b[c+f]},flattenChunks:function(a){var b,c,d,e,f,g;for(d=0,b=0,c=a.length;c>b;b++)d+=a[b].length;for(g=new Uint8Array(d),e=0,b=0,c=a.length;c>b;b++)f=a[b],g.set(f,e),e+=f.length;return g}},f={arraySet:function(a,b,c,d,e){for(var f=0;d>f;f++)a[e+f]=b[c+f]},flattenChunks:function(a){return[].concat.apply([],a)}};c.setTyped=function(a){a?(c.Buf8=Uint8Array,c.Buf16=Uint16Array,c.Buf32=Int32Array,c.assign(c,e)):(c.Buf8=Array,c.Buf16=Array,c.Buf32=Array,c.assign(c,f))},c.setTyped(d)},{}],28:[function(a,b,c){"use strict";function d(a,b){if(65537>b&&(a.subarray&&g||!a.subarray&&f))return String.fromCharCode.apply(null,e.shrinkBuf(a,b));for(var c="",d=0;b>d;d++)c+=String.fromCharCode(a[d]);return c}var e=a("./common"),f=!0,g=!0;try{String.fromCharCode.apply(null,[0])}catch(h){f=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(h){g=!1}for(var i=new e.Buf8(256),j=0;256>j;j++)i[j]=j>=252?6:j>=248?5:j>=240?4:j>=224?3:j>=192?2:1;i[254]=i[254]=1,c.string2buf=function(a){var b,c,d,f,g,h=a.length,i=0;for(f=0;h>f;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),i+=128>c?1:2048>c?2:65536>c?3:4;for(b=new e.Buf8(i),g=0,f=0;i>g;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),128>c?b[g++]=c:2048>c?(b[g++]=192|c>>>6,b[g++]=128|63&c):65536>c?(b[g++]=224|c>>>12,b[g++]=128|c>>>6&63,b[g++]=128|63&c):(b[g++]=240|c>>>18,b[g++]=128|c>>>12&63,b[g++]=128|c>>>6&63,b[g++]=128|63&c);return b},c.buf2binstring=function(a){return d(a,a.length)},c.binstring2buf=function(a){for(var b=new e.Buf8(a.length),c=0,d=b.length;d>c;c++)b[c]=a.charCodeAt(c);return b},c.buf2string=function(a,b){var c,e,f,g,h=b||a.length,j=new Array(2*h);for(e=0,c=0;h>c;)if(f=a[c++],128>f)j[e++]=f;else if(g=i[f],g>4)j[e++]=65533,c+=g-1;else{for(f&=2===g?31:3===g?15:7;g>1&&h>c;)f=f<<6|63&a[c++],g--;g>1?j[e++]=65533:65536>f?j[e++]=f:(f-=65536,j[e++]=55296|f>>10&1023,j[e++]=56320|1023&f)}return d(j,e)},c.utf8border=function(a,b){var c;for(b=b||a.length,b>a.length&&(b=a.length),c=b-1;c>=0&&128===(192&a[c]);)c--;return 0>c?b:0===c?b:c+i[a[c]]>b?c:b}},{"./common":27}],29:[function(a,b){"use strict";function c(a,b,c,d){for(var e=65535&a|0,f=a>>>16&65535|0,g=0;0!==c;){g=c>2e3?2e3:c,c-=g;do e=e+b[d++]|0,f=f+e|0;while(--g);e%=65521,f%=65521}return e|f<<16|0}b.exports=c},{}],30:[function(a,b){b.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},{}],31:[function(a,b){"use strict";function c(){for(var a,b=[],c=0;256>c;c++){a=c;for(var d=0;8>d;d++)a=1&a?3988292384^a>>>1:a>>>1;b[c]=a}return b}function d(a,b,c,d){var f=e,g=d+c;a=-1^a;for(var h=d;g>h;h++)a=a>>>8^f[255&(a^b[h])];return-1^a}var e=c();b.exports=d},{}],32:[function(a,b,c){"use strict";function d(a,b){return a.msg=G[b],b}function e(a){return(a<<1)-(a>4?9:0)}function f(a){for(var b=a.length;--b>=0;)a[b]=0}function g(a){var b=a.state,c=b.pending;c>a.avail_out&&(c=a.avail_out),0!==c&&(C.arraySet(a.output,b.pending_buf,b.pending_out,c,a.next_out),a.next_out+=c,b.pending_out+=c,a.total_out+=c,a.avail_out-=c,b.pending-=c,0===b.pending&&(b.pending_out=0))}function h(a,b){D._tr_flush_block(a,a.block_start>=0?a.block_start:-1,a.strstart-a.block_start,b),a.block_start=a.strstart,g(a.strm)}function i(a,b){a.pending_buf[a.pending++]=b}function j(a,b){a.pending_buf[a.pending++]=b>>>8&255,a.pending_buf[a.pending++]=255&b}function k(a,b,c,d){var e=a.avail_in;return e>d&&(e=d),0===e?0:(a.avail_in-=e,C.arraySet(b,a.input,a.next_in,e,c),1===a.state.wrap?a.adler=E(a.adler,b,e,c):2===a.state.wrap&&(a.adler=F(a.adler,b,e,c)),a.next_in+=e,a.total_in+=e,e)}function l(a,b){var c,d,e=a.max_chain_length,f=a.strstart,g=a.prev_length,h=a.nice_match,i=a.strstart>a.w_size-jb?a.strstart-(a.w_size-jb):0,j=a.window,k=a.w_mask,l=a.prev,m=a.strstart+ib,n=j[f+g-1],o=j[f+g];a.prev_length>=a.good_match&&(e>>=2),h>a.lookahead&&(h=a.lookahead);do if(c=b,j[c+g]===o&&j[c+g-1]===n&&j[c]===j[f]&&j[++c]===j[f+1]){f+=2,c++;do;while(j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&m>f);if(d=ib-(m-f),f=m-ib,d>g){if(a.match_start=b,g=d,d>=h)break;n=j[f+g-1],o=j[f+g]}}while((b=l[b&k])>i&&0!==--e);return g<=a.lookahead?g:a.lookahead}function m(a){var b,c,d,e,f,g=a.w_size;do{if(e=a.window_size-a.lookahead-a.strstart,a.strstart>=g+(g-jb)){C.arraySet(a.window,a.window,g,g,0),a.match_start-=g,a.strstart-=g,a.block_start-=g,c=a.hash_size,b=c;do d=a.head[--b],a.head[b]=d>=g?d-g:0;while(--c);c=g,b=c;do d=a.prev[--b],a.prev[b]=d>=g?d-g:0;while(--c);e+=g}if(0===a.strm.avail_in)break;if(c=k(a.strm,a.window,a.strstart+a.lookahead,e),a.lookahead+=c,a.lookahead+a.insert>=hb)for(f=a.strstart-a.insert,a.ins_h=a.window[f],a.ins_h=(a.ins_h<<a.hash_shift^a.window[f+1])&a.hash_mask;a.insert&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[f+hb-1])&a.hash_mask,a.prev[f&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=f,f++,a.insert--,!(a.lookahead+a.insert<hb)););}while(a.lookahead<jb&&0!==a.strm.avail_in)}function n(a,b){var c=65535;for(c>a.pending_buf_size-5&&(c=a.pending_buf_size-5);;){if(a.lookahead<=1){if(m(a),0===a.lookahead&&b===H)return sb;if(0===a.lookahead)break}a.strstart+=a.lookahead,a.lookahead=0;var d=a.block_start+c;if((0===a.strstart||a.strstart>=d)&&(a.lookahead=a.strstart-d,a.strstart=d,h(a,!1),0===a.strm.avail_out))return sb;if(a.strstart-a.block_start>=a.w_size-jb&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.strstart>a.block_start&&(h(a,!1),0===a.strm.avail_out)?sb:sb}function o(a,b){for(var c,d;;){if(a.lookahead<jb){if(m(a),a.lookahead<jb&&b===H)return sb;if(0===a.lookahead)break}if(c=0,a.lookahead>=hb&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart),0!==c&&a.strstart-c<=a.w_size-jb&&(a.match_length=l(a,c)),a.match_length>=hb)if(d=D._tr_tally(a,a.strstart-a.match_start,a.match_length-hb),a.lookahead-=a.match_length,a.match_length<=a.max_lazy_match&&a.lookahead>=hb){a.match_length--;do a.strstart++,a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart;while(0!==--a.match_length);a.strstart++}else a.strstart+=a.match_length,a.match_length=0,a.ins_h=a.window[a.strstart],a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+1])&a.hash_mask;else d=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++;if(d&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=a.strstart<hb-1?a.strstart:hb-1,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function p(a,b){for(var c,d,e;;){if(a.lookahead<jb){if(m(a),a.lookahead<jb&&b===H)return sb;if(0===a.lookahead)break}if(c=0,a.lookahead>=hb&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart),a.prev_length=a.match_length,a.prev_match=a.match_start,a.match_length=hb-1,0!==c&&a.prev_length<a.max_lazy_match&&a.strstart-c<=a.w_size-jb&&(a.match_length=l(a,c),a.match_length<=5&&(a.strategy===S||a.match_length===hb&&a.strstart-a.match_start>4096)&&(a.match_length=hb-1)),a.prev_length>=hb&&a.match_length<=a.prev_length){e=a.strstart+a.lookahead-hb,d=D._tr_tally(a,a.strstart-1-a.prev_match,a.prev_length-hb),a.lookahead-=a.prev_length-1,a.prev_length-=2;do++a.strstart<=e&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart);while(0!==--a.prev_length);if(a.match_available=0,a.match_length=hb-1,a.strstart++,d&&(h(a,!1),0===a.strm.avail_out))return sb}else if(a.match_available){if(d=D._tr_tally(a,0,a.window[a.strstart-1]),d&&h(a,!1),a.strstart++,a.lookahead--,0===a.strm.avail_out)return sb}else a.match_available=1,a.strstart++,a.lookahead--}return a.match_available&&(d=D._tr_tally(a,0,a.window[a.strstart-1]),a.match_available=0),a.insert=a.strstart<hb-1?a.strstart:hb-1,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function q(a,b){for(var c,d,e,f,g=a.window;;){if(a.lookahead<=ib){if(m(a),a.lookahead<=ib&&b===H)return sb;if(0===a.lookahead)break}if(a.match_length=0,a.lookahead>=hb&&a.strstart>0&&(e=a.strstart-1,d=g[e],d===g[++e]&&d===g[++e]&&d===g[++e])){f=a.strstart+ib;do;while(d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&f>e);a.match_length=ib-(f-e),a.match_length>a.lookahead&&(a.match_length=a.lookahead)}if(a.match_length>=hb?(c=D._tr_tally(a,1,a.match_length-hb),a.lookahead-=a.match_length,a.strstart+=a.match_length,a.match_length=0):(c=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++),c&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function r(a,b){for(var c;;){if(0===a.lookahead&&(m(a),0===a.lookahead)){if(b===H)return sb;break}if(a.match_length=0,c=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++,c&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function s(a){a.window_size=2*a.w_size,f(a.head),a.max_lazy_match=B[a.level].max_lazy,a.good_match=B[a.level].good_length,a.nice_match=B[a.level].nice_length,a.max_chain_length=B[a.level].max_chain,a.strstart=0,a.block_start=0,a.lookahead=0,a.insert=0,a.match_length=a.prev_length=hb-1,a.match_available=0,a.ins_h=0}function t(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=Y,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new C.Buf16(2*fb),this.dyn_dtree=new C.Buf16(2*(2*db+1)),this.bl_tree=new C.Buf16(2*(2*eb+1)),f(this.dyn_ltree),f(this.dyn_dtree),f(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new C.Buf16(gb+1),this.heap=new C.Buf16(2*cb+1),f(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new C.Buf16(2*cb+1),f(this.depth),this.l_buf=0,this.lit_bufsize=0,this.last_lit=0,this.d_buf=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}function u(a){var b;return a&&a.state?(a.total_in=a.total_out=0,a.data_type=X,b=a.state,b.pending=0,b.pending_out=0,b.wrap<0&&(b.wrap=-b.wrap),b.status=b.wrap?lb:qb,a.adler=2===b.wrap?0:1,b.last_flush=H,D._tr_init(b),M):d(a,O)}function v(a){var b=u(a);return b===M&&s(a.state),b}function w(a,b){return a&&a.state?2!==a.state.wrap?O:(a.state.gzhead=b,M):O}function x(a,b,c,e,f,g){if(!a)return O;var h=1;if(b===R&&(b=6),0>e?(h=0,e=-e):e>15&&(h=2,e-=16),1>f||f>Z||c!==Y||8>e||e>15||0>b||b>9||0>g||g>V)return d(a,O);8===e&&(e=9);var i=new t;return a.state=i,i.strm=a,i.wrap=h,i.gzhead=null,i.w_bits=e,i.w_size=1<<i.w_bits,i.w_mask=i.w_size-1,i.hash_bits=f+7,i.hash_size=1<<i.hash_bits,i.hash_mask=i.hash_size-1,i.hash_shift=~~((i.hash_bits+hb-1)/hb),i.window=new C.Buf8(2*i.w_size),i.head=new C.Buf16(i.hash_size),i.prev=new C.Buf16(i.w_size),i.lit_bufsize=1<<f+6,i.pending_buf_size=4*i.lit_bufsize,i.pending_buf=new C.Buf8(i.pending_buf_size),i.d_buf=i.lit_bufsize>>1,i.l_buf=3*i.lit_bufsize,i.level=b,i.strategy=g,i.method=c,v(a)}function y(a,b){return x(a,b,Y,$,_,W)}function z(a,b){var c,h,k,l;if(!a||!a.state||b>L||0>b)return a?d(a,O):O;if(h=a.state,!a.output||!a.input&&0!==a.avail_in||h.status===rb&&b!==K)return d(a,0===a.avail_out?Q:O);if(h.strm=a,c=h.last_flush,h.last_flush=b,h.status===lb)if(2===h.wrap)a.adler=0,i(h,31),i(h,139),i(h,8),h.gzhead?(i(h,(h.gzhead.text?1:0)+(h.gzhead.hcrc?2:0)+(h.gzhead.extra?4:0)+(h.gzhead.name?8:0)+(h.gzhead.comment?16:0)),i(h,255&h.gzhead.time),i(h,h.gzhead.time>>8&255),i(h,h.gzhead.time>>16&255),i(h,h.gzhead.time>>24&255),i(h,9===h.level?2:h.strategy>=T||h.level<2?4:0),i(h,255&h.gzhead.os),h.gzhead.extra&&h.gzhead.extra.length&&(i(h,255&h.gzhead.extra.length),i(h,h.gzhead.extra.length>>8&255)),h.gzhead.hcrc&&(a.adler=F(a.adler,h.pending_buf,h.pending,0)),h.gzindex=0,h.status=mb):(i(h,0),i(h,0),i(h,0),i(h,0),i(h,0),i(h,9===h.level?2:h.strategy>=T||h.level<2?4:0),i(h,wb),h.status=qb);else{var m=Y+(h.w_bits-8<<4)<<8,n=-1;n=h.strategy>=T||h.level<2?0:h.level<6?1:6===h.level?2:3,m|=n<<6,0!==h.strstart&&(m|=kb),m+=31-m%31,h.status=qb,j(h,m),0!==h.strstart&&(j(h,a.adler>>>16),j(h,65535&a.adler)),a.adler=1}if(h.status===mb)if(h.gzhead.extra){for(k=h.pending;h.gzindex<(65535&h.gzhead.extra.length)&&(h.pending!==h.pending_buf_size||(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending!==h.pending_buf_size));)i(h,255&h.gzhead.extra[h.gzindex]),h.gzindex++;h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),h.gzindex===h.gzhead.extra.length&&(h.gzindex=0,h.status=nb)}else h.status=nb;if(h.status===nb)if(h.gzhead.name){k=h.pending;do{if(h.pending===h.pending_buf_size&&(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending===h.pending_buf_size)){l=1;break}l=h.gzindex<h.gzhead.name.length?255&h.gzhead.name.charCodeAt(h.gzindex++):0,i(h,l)}while(0!==l);h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),0===l&&(h.gzindex=0,h.status=ob)}else h.status=ob;if(h.status===ob)if(h.gzhead.comment){k=h.pending;do{if(h.pending===h.pending_buf_size&&(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending===h.pending_buf_size)){l=1;break}l=h.gzindex<h.gzhead.comment.length?255&h.gzhead.comment.charCodeAt(h.gzindex++):0,i(h,l)}while(0!==l);h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),0===l&&(h.status=pb)}else h.status=pb;if(h.status===pb&&(h.gzhead.hcrc?(h.pending+2>h.pending_buf_size&&g(a),h.pending+2<=h.pending_buf_size&&(i(h,255&a.adler),i(h,a.adler>>8&255),a.adler=0,h.status=qb)):h.status=qb),0!==h.pending){if(g(a),0===a.avail_out)return h.last_flush=-1,M}else if(0===a.avail_in&&e(b)<=e(c)&&b!==K)return d(a,Q);if(h.status===rb&&0!==a.avail_in)return d(a,Q);if(0!==a.avail_in||0!==h.lookahead||b!==H&&h.status!==rb){var o=h.strategy===T?r(h,b):h.strategy===U?q(h,b):B[h.level].func(h,b);if((o===ub||o===vb)&&(h.status=rb),o===sb||o===ub)return 0===a.avail_out&&(h.last_flush=-1),M;if(o===tb&&(b===I?D._tr_align(h):b!==L&&(D._tr_stored_block(h,0,0,!1),b===J&&(f(h.head),0===h.lookahead&&(h.strstart=0,h.block_start=0,h.insert=0))),g(a),0===a.avail_out))return h.last_flush=-1,M}return b!==K?M:h.wrap<=0?N:(2===h.wrap?(i(h,255&a.adler),i(h,a.adler>>8&255),i(h,a.adler>>16&255),i(h,a.adler>>24&255),i(h,255&a.total_in),i(h,a.total_in>>8&255),i(h,a.total_in>>16&255),i(h,a.total_in>>24&255)):(j(h,a.adler>>>16),j(h,65535&a.adler)),g(a),h.wrap>0&&(h.wrap=-h.wrap),0!==h.pending?M:N)}function A(a){var b;return a&&a.state?(b=a.state.status,b!==lb&&b!==mb&&b!==nb&&b!==ob&&b!==pb&&b!==qb&&b!==rb?d(a,O):(a.state=null,b===qb?d(a,P):M)):O}var B,C=a("../utils/common"),D=a("./trees"),E=a("./adler32"),F=a("./crc32"),G=a("./messages"),H=0,I=1,J=3,K=4,L=5,M=0,N=1,O=-2,P=-3,Q=-5,R=-1,S=1,T=2,U=3,V=4,W=0,X=2,Y=8,Z=9,$=15,_=8,ab=29,bb=256,cb=bb+1+ab,db=30,eb=19,fb=2*cb+1,gb=15,hb=3,ib=258,jb=ib+hb+1,kb=32,lb=42,mb=69,nb=73,ob=91,pb=103,qb=113,rb=666,sb=1,tb=2,ub=3,vb=4,wb=3,xb=function(a,b,c,d,e){this.good_length=a,this.max_lazy=b,this.nice_length=c,this.max_chain=d,this.func=e};B=[new xb(0,0,0,0,n),new xb(4,4,8,4,o),new xb(4,5,16,8,o),new xb(4,6,32,32,o),new xb(4,4,16,16,p),new xb(8,16,32,32,p),new xb(8,16,128,128,p),new xb(8,32,128,256,p),new xb(32,128,258,1024,p),new xb(32,258,258,4096,p)],c.deflateInit=y,c.deflateInit2=x,c.deflateReset=v,c.deflateResetKeep=u,c.deflateSetHeader=w,c.deflate=z,c.deflateEnd=A,c.deflateInfo="pako deflate (from Nodeca project)"},{"../utils/common":27,"./adler32":29,"./crc32":31,"./messages":37,"./trees":38}],33:[function(a,b){"use strict";function c(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}b.exports=c},{}],34:[function(a,b){"use strict";var c=30,d=12;b.exports=function(a,b){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C;e=a.state,f=a.next_in,B=a.input,g=f+(a.avail_in-5),h=a.next_out,C=a.output,i=h-(b-a.avail_out),j=h+(a.avail_out-257),k=e.dmax,l=e.wsize,m=e.whave,n=e.wnext,o=e.window,p=e.hold,q=e.bits,r=e.lencode,s=e.distcode,t=(1<<e.lenbits)-1,u=(1<<e.distbits)-1;a:do{15>q&&(p+=B[f++]<<q,q+=8,p+=B[f++]<<q,q+=8),v=r[p&t];b:for(;;){if(w=v>>>24,p>>>=w,q-=w,w=v>>>16&255,0===w)C[h++]=65535&v;else{if(!(16&w)){if(0===(64&w)){v=r[(65535&v)+(p&(1<<w)-1)];continue b}if(32&w){e.mode=d;break a}a.msg="invalid literal/length code",e.mode=c;break a}x=65535&v,w&=15,w&&(w>q&&(p+=B[f++]<<q,q+=8),x+=p&(1<<w)-1,p>>>=w,q-=w),15>q&&(p+=B[f++]<<q,q+=8,p+=B[f++]<<q,q+=8),v=s[p&u];c:for(;;){if(w=v>>>24,p>>>=w,q-=w,w=v>>>16&255,!(16&w)){if(0===(64&w)){v=s[(65535&v)+(p&(1<<w)-1)];continue c}a.msg="invalid distance code",e.mode=c;break a}if(y=65535&v,w&=15,w>q&&(p+=B[f++]<<q,q+=8,w>q&&(p+=B[f++]<<q,q+=8)),y+=p&(1<<w)-1,y>k){a.msg="invalid distance too far back",e.mode=c;break a}if(p>>>=w,q-=w,w=h-i,y>w){if(w=y-w,w>m&&e.sane){a.msg="invalid distance too far back",e.mode=c;break a}if(z=0,A=o,0===n){if(z+=l-w,x>w){x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}}else if(w>n){if(z+=l+n-w,w-=n,x>w){x-=w;do C[h++]=o[z++];while(--w);if(z=0,x>n){w=n,x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}}}else if(z+=n-w,x>w){x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}for(;x>2;)C[h++]=A[z++],C[h++]=A[z++],C[h++]=A[z++],x-=3;x&&(C[h++]=A[z++],x>1&&(C[h++]=A[z++]))}else{z=h-y;do C[h++]=C[z++],C[h++]=C[z++],C[h++]=C[z++],x-=3;while(x>2);x&&(C[h++]=C[z++],x>1&&(C[h++]=C[z++]))}break}}break}}while(g>f&&j>h);x=q>>3,f-=x,q-=x<<3,p&=(1<<q)-1,a.next_in=f,a.next_out=h,a.avail_in=g>f?5+(g-f):5-(f-g),a.avail_out=j>h?257+(j-h):257-(h-j),e.hold=p,e.bits=q}},{}],35:[function(a,b,c){"use strict";function d(a){return(a>>>24&255)+(a>>>8&65280)+((65280&a)<<8)+((255&a)<<24)}function e(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new r.Buf16(320),this.work=new r.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function f(a){var b;return a&&a.state?(b=a.state,a.total_in=a.total_out=b.total=0,a.msg="",b.wrap&&(a.adler=1&b.wrap),b.mode=K,b.last=0,b.havedict=0,b.dmax=32768,b.head=null,b.hold=0,b.bits=0,b.lencode=b.lendyn=new r.Buf32(ob),b.distcode=b.distdyn=new r.Buf32(pb),b.sane=1,b.back=-1,C):F}function g(a){var b;return a&&a.state?(b=a.state,b.wsize=0,b.whave=0,b.wnext=0,f(a)):F}function h(a,b){var c,d;return a&&a.state?(d=a.state,0>b?(c=0,b=-b):(c=(b>>4)+1,48>b&&(b&=15)),b&&(8>b||b>15)?F:(null!==d.window&&d.wbits!==b&&(d.window=null),d.wrap=c,d.wbits=b,g(a))):F}function i(a,b){var c,d;return a?(d=new e,a.state=d,d.window=null,c=h(a,b),c!==C&&(a.state=null),c):F}function j(a){return i(a,rb)}function k(a){if(sb){var b;for(p=new r.Buf32(512),q=new r.Buf32(32),b=0;144>b;)a.lens[b++]=8;for(;256>b;)a.lens[b++]=9;for(;280>b;)a.lens[b++]=7;for(;288>b;)a.lens[b++]=8;for(v(x,a.lens,0,288,p,0,a.work,{bits:9}),b=0;32>b;)a.lens[b++]=5;v(y,a.lens,0,32,q,0,a.work,{bits:5}),sb=!1}a.lencode=p,a.lenbits=9,a.distcode=q,a.distbits=5}function l(a,b,c,d){var e,f=a.state;return null===f.window&&(f.wsize=1<<f.wbits,f.wnext=0,f.whave=0,f.window=new r.Buf8(f.wsize)),d>=f.wsize?(r.arraySet(f.window,b,c-f.wsize,f.wsize,0),f.wnext=0,f.whave=f.wsize):(e=f.wsize-f.wnext,e>d&&(e=d),r.arraySet(f.window,b,c-d,e,f.wnext),d-=e,d?(r.arraySet(f.window,b,c-d,d,0),f.wnext=d,f.whave=f.wsize):(f.wnext+=e,f.wnext===f.wsize&&(f.wnext=0),f.whave<f.wsize&&(f.whave+=e))),0}function m(a,b){var c,e,f,g,h,i,j,m,n,o,p,q,ob,pb,qb,rb,sb,tb,ub,vb,wb,xb,yb,zb,Ab=0,Bb=new r.Buf8(4),Cb=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];if(!a||!a.state||!a.output||!a.input&&0!==a.avail_in)return F;c=a.state,c.mode===V&&(c.mode=W),h=a.next_out,f=a.output,j=a.avail_out,g=a.next_in,e=a.input,i=a.avail_in,m=c.hold,n=c.bits,o=i,p=j,xb=C;a:for(;;)switch(c.mode){case K:if(0===c.wrap){c.mode=W;break}for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(2&c.wrap&&35615===m){c.check=0,Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0),m=0,n=0,c.mode=L;break}if(c.flags=0,c.head&&(c.head.done=!1),!(1&c.wrap)||(((255&m)<<8)+(m>>8))%31){a.msg="incorrect header check",c.mode=lb;break}if((15&m)!==J){a.msg="unknown compression method",c.mode=lb;break}if(m>>>=4,n-=4,wb=(15&m)+8,0===c.wbits)c.wbits=wb;else if(wb>c.wbits){a.msg="invalid window size",c.mode=lb;break}c.dmax=1<<wb,a.adler=c.check=1,c.mode=512&m?T:V,m=0,n=0;break;case L:for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(c.flags=m,(255&c.flags)!==J){a.msg="unknown compression method",c.mode=lb;break}if(57344&c.flags){a.msg="unknown header flags set",c.mode=lb;break}c.head&&(c.head.text=m>>8&1),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0,c.mode=M;case M:for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.head&&(c.head.time=m),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,Bb[2]=m>>>16&255,Bb[3]=m>>>24&255,c.check=t(c.check,Bb,4,0)),m=0,n=0,c.mode=N;case N:for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.head&&(c.head.xflags=255&m,c.head.os=m>>8),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0,c.mode=O;case O:if(1024&c.flags){for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.length=m,c.head&&(c.head.extra_len=m),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0}else c.head&&(c.head.extra=null);c.mode=P;case P:if(1024&c.flags&&(q=c.length,q>i&&(q=i),q&&(c.head&&(wb=c.head.extra_len-c.length,c.head.extra||(c.head.extra=new Array(c.head.extra_len)),r.arraySet(c.head.extra,e,g,q,wb)),512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,c.length-=q),c.length))break a;c.length=0,c.mode=Q;case Q:if(2048&c.flags){if(0===i)break a;q=0;do wb=e[g+q++],c.head&&wb&&c.length<65536&&(c.head.name+=String.fromCharCode(wb));while(wb&&i>q);if(512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,wb)break a}else c.head&&(c.head.name=null);c.length=0,c.mode=R;case R:if(4096&c.flags){if(0===i)break a;q=0;do wb=e[g+q++],c.head&&wb&&c.length<65536&&(c.head.comment+=String.fromCharCode(wb));while(wb&&i>q);if(512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,wb)break a}else c.head&&(c.head.comment=null);c.mode=S;case S:if(512&c.flags){for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m!==(65535&c.check)){a.msg="header crc mismatch",c.mode=lb;break}m=0,n=0}c.head&&(c.head.hcrc=c.flags>>9&1,c.head.done=!0),a.adler=c.check=0,c.mode=V;break;case T:for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}a.adler=c.check=d(m),m=0,n=0,c.mode=U;case U:if(0===c.havedict)return a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,E;a.adler=c.check=1,c.mode=V;case V:if(b===A||b===B)break a;case W:if(c.last){m>>>=7&n,n-=7&n,c.mode=ib;break}for(;3>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}switch(c.last=1&m,m>>>=1,n-=1,3&m){case 0:c.mode=X;break;case 1:if(k(c),c.mode=bb,b===B){m>>>=2,n-=2;break a}break;case 2:c.mode=$;break;case 3:a.msg="invalid block type",c.mode=lb}m>>>=2,n-=2;break;case X:for(m>>>=7&n,n-=7&n;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if((65535&m)!==(m>>>16^65535)){a.msg="invalid stored block lengths",c.mode=lb;break}if(c.length=65535&m,m=0,n=0,c.mode=Y,b===B)break a;case Y:c.mode=Z;case Z:if(q=c.length){if(q>i&&(q=i),q>j&&(q=j),0===q)break a;r.arraySet(f,e,g,q,h),i-=q,g+=q,j-=q,h+=q,c.length-=q;break}c.mode=V;break;case $:for(;14>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(c.nlen=(31&m)+257,m>>>=5,n-=5,c.ndist=(31&m)+1,m>>>=5,n-=5,c.ncode=(15&m)+4,m>>>=4,n-=4,c.nlen>286||c.ndist>30){a.msg="too many length or distance symbols",c.mode=lb;break}c.have=0,c.mode=_;case _:for(;c.have<c.ncode;){for(;3>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.lens[Cb[c.have++]]=7&m,m>>>=3,n-=3}for(;c.have<19;)c.lens[Cb[c.have++]]=0;if(c.lencode=c.lendyn,c.lenbits=7,yb={bits:c.lenbits},xb=v(w,c.lens,0,19,c.lencode,0,c.work,yb),c.lenbits=yb.bits,xb){a.msg="invalid code lengths set",c.mode=lb;break}c.have=0,c.mode=ab;case ab:for(;c.have<c.nlen+c.ndist;){for(;Ab=c.lencode[m&(1<<c.lenbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(16>sb)m>>>=qb,n-=qb,c.lens[c.have++]=sb;else{if(16===sb){for(zb=qb+2;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m>>>=qb,n-=qb,0===c.have){a.msg="invalid bit length repeat",c.mode=lb;break}wb=c.lens[c.have-1],q=3+(3&m),m>>>=2,n-=2}else if(17===sb){for(zb=qb+3;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=qb,n-=qb,wb=0,q=3+(7&m),m>>>=3,n-=3}else{for(zb=qb+7;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=qb,n-=qb,wb=0,q=11+(127&m),m>>>=7,n-=7}if(c.have+q>c.nlen+c.ndist){a.msg="invalid bit length repeat",c.mode=lb;break}for(;q--;)c.lens[c.have++]=wb}}if(c.mode===lb)break;if(0===c.lens[256]){a.msg="invalid code -- missing end-of-block",c.mode=lb;break}if(c.lenbits=9,yb={bits:c.lenbits},xb=v(x,c.lens,0,c.nlen,c.lencode,0,c.work,yb),c.lenbits=yb.bits,xb){a.msg="invalid literal/lengths set",c.mode=lb;break}if(c.distbits=6,c.distcode=c.distdyn,yb={bits:c.distbits},xb=v(y,c.lens,c.nlen,c.ndist,c.distcode,0,c.work,yb),c.distbits=yb.bits,xb){a.msg="invalid distances set",c.mode=lb;break}if(c.mode=bb,b===B)break a;case bb:c.mode=cb;case cb:if(i>=6&&j>=258){a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,u(a,p),h=a.next_out,f=a.output,j=a.avail_out,g=a.next_in,e=a.input,i=a.avail_in,m=c.hold,n=c.bits,c.mode===V&&(c.back=-1);break}for(c.back=0;Ab=c.lencode[m&(1<<c.lenbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(rb&&0===(240&rb)){for(tb=qb,ub=rb,vb=sb;Ab=c.lencode[vb+((m&(1<<tb+ub)-1)>>tb)],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=tb+qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=tb,n-=tb,c.back+=tb}if(m>>>=qb,n-=qb,c.back+=qb,c.length=sb,0===rb){c.mode=hb;break}if(32&rb){c.back=-1,c.mode=V;break}if(64&rb){a.msg="invalid literal/length code",c.mode=lb;break}c.extra=15&rb,c.mode=db;case db:if(c.extra){for(zb=c.extra;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.length+=m&(1<<c.extra)-1,m>>>=c.extra,n-=c.extra,c.back+=c.extra}c.was=c.length,c.mode=eb;case eb:for(;Ab=c.distcode[m&(1<<c.distbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(0===(240&rb)){for(tb=qb,ub=rb,vb=sb;Ab=c.distcode[vb+((m&(1<<tb+ub)-1)>>tb)],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=tb+qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=tb,n-=tb,c.back+=tb}if(m>>>=qb,n-=qb,c.back+=qb,64&rb){a.msg="invalid distance code",c.mode=lb;break}c.offset=sb,c.extra=15&rb,c.mode=fb;case fb:if(c.extra){for(zb=c.extra;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.offset+=m&(1<<c.extra)-1,m>>>=c.extra,n-=c.extra,c.back+=c.extra}if(c.offset>c.dmax){a.msg="invalid distance too far back",c.mode=lb;break}c.mode=gb;case gb:if(0===j)break a;if(q=p-j,c.offset>q){if(q=c.offset-q,q>c.whave&&c.sane){a.msg="invalid distance too far back",c.mode=lb;break}q>c.wnext?(q-=c.wnext,ob=c.wsize-q):ob=c.wnext-q,q>c.length&&(q=c.length),pb=c.window}else pb=f,ob=h-c.offset,q=c.length;q>j&&(q=j),j-=q,c.length-=q;do f[h++]=pb[ob++];while(--q);0===c.length&&(c.mode=cb);break;case hb:if(0===j)break a;f[h++]=c.length,j--,c.mode=cb;break;case ib:if(c.wrap){for(;32>n;){if(0===i)break a;i--,m|=e[g++]<<n,n+=8}if(p-=j,a.total_out+=p,c.total+=p,p&&(a.adler=c.check=c.flags?t(c.check,f,p,h-p):s(c.check,f,p,h-p)),p=j,(c.flags?m:d(m))!==c.check){a.msg="incorrect data check",c.mode=lb;break}m=0,n=0}c.mode=jb;case jb:if(c.wrap&&c.flags){for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m!==(4294967295&c.total)){a.msg="incorrect length check",c.mode=lb;break}m=0,n=0}c.mode=kb;case kb:xb=D;break a;case lb:xb=G;break a;case mb:return H;case nb:default:return F}return a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,(c.wsize||p!==a.avail_out&&c.mode<lb&&(c.mode<ib||b!==z))&&l(a,a.output,a.next_out,p-a.avail_out)?(c.mode=mb,H):(o-=a.avail_in,p-=a.avail_out,a.total_in+=o,a.total_out+=p,c.total+=p,c.wrap&&p&&(a.adler=c.check=c.flags?t(c.check,f,p,a.next_out-p):s(c.check,f,p,a.next_out-p)),a.data_type=c.bits+(c.last?64:0)+(c.mode===V?128:0)+(c.mode===bb||c.mode===Y?256:0),(0===o&&0===p||b===z)&&xb===C&&(xb=I),xb)}function n(a){if(!a||!a.state)return F;var b=a.state;return b.window&&(b.window=null),a.state=null,C}function o(a,b){var c;return a&&a.state?(c=a.state,0===(2&c.wrap)?F:(c.head=b,b.done=!1,C)):F}var p,q,r=a("../utils/common"),s=a("./adler32"),t=a("./crc32"),u=a("./inffast"),v=a("./inftrees"),w=0,x=1,y=2,z=4,A=5,B=6,C=0,D=1,E=2,F=-2,G=-3,H=-4,I=-5,J=8,K=1,L=2,M=3,N=4,O=5,P=6,Q=7,R=8,S=9,T=10,U=11,V=12,W=13,X=14,Y=15,Z=16,$=17,_=18,ab=19,bb=20,cb=21,db=22,eb=23,fb=24,gb=25,hb=26,ib=27,jb=28,kb=29,lb=30,mb=31,nb=32,ob=852,pb=592,qb=15,rb=qb,sb=!0;c.inflateReset=g,c.inflateReset2=h,c.inflateResetKeep=f,c.inflateInit=j,c.inflateInit2=i,c.inflate=m,c.inflateEnd=n,c.inflateGetHeader=o,c.inflateInfo="pako inflate (from Nodeca project)"},{"../utils/common":27,"./adler32":29,"./crc32":31,"./inffast":34,"./inftrees":36}],36:[function(a,b){"use strict";var c=a("../utils/common"),d=15,e=852,f=592,g=0,h=1,i=2,j=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],k=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],l=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],m=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];b.exports=function(a,b,n,o,p,q,r,s){var t,u,v,w,x,y,z,A,B,C=s.bits,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=null,O=0,P=new c.Buf16(d+1),Q=new c.Buf16(d+1),R=null,S=0;for(D=0;d>=D;D++)P[D]=0;for(E=0;o>E;E++)P[b[n+E]]++;for(H=C,G=d;G>=1&&0===P[G];G--);if(H>G&&(H=G),0===G)return p[q++]=20971520,p[q++]=20971520,s.bits=1,0;for(F=1;G>F&&0===P[F];F++);for(F>H&&(H=F),K=1,D=1;d>=D;D++)if(K<<=1,K-=P[D],0>K)return-1;if(K>0&&(a===g||1!==G))return-1;for(Q[1]=0,D=1;d>D;D++)Q[D+1]=Q[D]+P[D];for(E=0;o>E;E++)0!==b[n+E]&&(r[Q[b[n+E]]++]=E);if(a===g?(N=R=r,y=19):a===h?(N=j,O-=257,R=k,S-=257,y=256):(N=l,R=m,y=-1),M=0,E=0,D=F,x=q,I=H,J=0,v=-1,L=1<<H,w=L-1,a===h&&L>e||a===i&&L>f)return 1;for(var T=0;;){T++,z=D-J,r[E]<y?(A=0,B=r[E]):r[E]>y?(A=R[S+r[E]],B=N[O+r[E]]):(A=96,B=0),t=1<<D-J,u=1<<I,F=u;do u-=t,p[x+(M>>J)+u]=z<<24|A<<16|B|0;while(0!==u);for(t=1<<D-1;M&t;)t>>=1;if(0!==t?(M&=t-1,M+=t):M=0,E++,0===--P[D]){if(D===G)break;D=b[n+r[E]]}if(D>H&&(M&w)!==v){for(0===J&&(J=H),x+=F,I=D-J,K=1<<I;G>I+J&&(K-=P[I+J],!(0>=K));)I++,K<<=1;if(L+=1<<I,a===h&&L>e||a===i&&L>f)return 1;v=M&w,p[v]=H<<24|I<<16|x-q|0}}return 0!==M&&(p[x+M]=D-J<<24|64<<16|0),s.bits=H,0}},{"../utils/common":27}],37:[function(a,b){"use strict";b.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],38:[function(a,b,c){"use strict";function d(a){for(var b=a.length;--b>=0;)a[b]=0}function e(a){return 256>a?gb[a]:gb[256+(a>>>7)]}function f(a,b){a.pending_buf[a.pending++]=255&b,a.pending_buf[a.pending++]=b>>>8&255}function g(a,b,c){a.bi_valid>V-c?(a.bi_buf|=b<<a.bi_valid&65535,f(a,a.bi_buf),a.bi_buf=b>>V-a.bi_valid,a.bi_valid+=c-V):(a.bi_buf|=b<<a.bi_valid&65535,a.bi_valid+=c)}function h(a,b,c){g(a,c[2*b],c[2*b+1])}function i(a,b){var c=0;do c|=1&a,a>>>=1,c<<=1;while(--b>0);return c>>>1}function j(a){16===a.bi_valid?(f(a,a.bi_buf),a.bi_buf=0,a.bi_valid=0):a.bi_valid>=8&&(a.pending_buf[a.pending++]=255&a.bi_buf,a.bi_buf>>=8,a.bi_valid-=8)}function k(a,b){var c,d,e,f,g,h,i=b.dyn_tree,j=b.max_code,k=b.stat_desc.static_tree,l=b.stat_desc.has_stree,m=b.stat_desc.extra_bits,n=b.stat_desc.extra_base,o=b.stat_desc.max_length,p=0;for(f=0;U>=f;f++)a.bl_count[f]=0;for(i[2*a.heap[a.heap_max]+1]=0,c=a.heap_max+1;T>c;c++)d=a.heap[c],f=i[2*i[2*d+1]+1]+1,f>o&&(f=o,p++),i[2*d+1]=f,d>j||(a.bl_count[f]++,g=0,d>=n&&(g=m[d-n]),h=i[2*d],a.opt_len+=h*(f+g),l&&(a.static_len+=h*(k[2*d+1]+g)));if(0!==p){do{for(f=o-1;0===a.bl_count[f];)f--;a.bl_count[f]--,a.bl_count[f+1]+=2,a.bl_count[o]--,p-=2}while(p>0);for(f=o;0!==f;f--)for(d=a.bl_count[f];0!==d;)e=a.heap[--c],e>j||(i[2*e+1]!==f&&(a.opt_len+=(f-i[2*e+1])*i[2*e],i[2*e+1]=f),d--)}}function l(a,b,c){var d,e,f=new Array(U+1),g=0;for(d=1;U>=d;d++)f[d]=g=g+c[d-1]<<1;for(e=0;b>=e;e++){var h=a[2*e+1];0!==h&&(a[2*e]=i(f[h]++,h))}}function m(){var a,b,c,d,e,f=new Array(U+1);for(c=0,d=0;O-1>d;d++)for(ib[d]=c,a=0;a<1<<_[d];a++)hb[c++]=d;for(hb[c-1]=d,e=0,d=0;16>d;d++)for(jb[d]=e,a=0;a<1<<ab[d];a++)gb[e++]=d;for(e>>=7;R>d;d++)for(jb[d]=e<<7,a=0;a<1<<ab[d]-7;a++)gb[256+e++]=d;for(b=0;U>=b;b++)f[b]=0;for(a=0;143>=a;)eb[2*a+1]=8,a++,f[8]++;for(;255>=a;)eb[2*a+1]=9,a++,f[9]++;for(;279>=a;)eb[2*a+1]=7,a++,f[7]++;for(;287>=a;)eb[2*a+1]=8,a++,f[8]++;for(l(eb,Q+1,f),a=0;R>a;a++)fb[2*a+1]=5,fb[2*a]=i(a,5);kb=new nb(eb,_,P+1,Q,U),lb=new nb(fb,ab,0,R,U),mb=new nb(new Array(0),bb,0,S,W)}function n(a){var b;for(b=0;Q>b;b++)a.dyn_ltree[2*b]=0;for(b=0;R>b;b++)a.dyn_dtree[2*b]=0;for(b=0;S>b;b++)a.bl_tree[2*b]=0;a.dyn_ltree[2*X]=1,a.opt_len=a.static_len=0,a.last_lit=a.matches=0}function o(a){a.bi_valid>8?f(a,a.bi_buf):a.bi_valid>0&&(a.pending_buf[a.pending++]=a.bi_buf),a.bi_buf=0,a.bi_valid=0}function p(a,b,c,d){o(a),d&&(f(a,c),f(a,~c)),E.arraySet(a.pending_buf,a.window,b,c,a.pending),a.pending+=c}function q(a,b,c,d){var e=2*b,f=2*c;return a[e]<a[f]||a[e]===a[f]&&d[b]<=d[c]}function r(a,b,c){for(var d=a.heap[c],e=c<<1;e<=a.heap_len&&(e<a.heap_len&&q(b,a.heap[e+1],a.heap[e],a.depth)&&e++,!q(b,d,a.heap[e],a.depth));)a.heap[c]=a.heap[e],c=e,e<<=1;a.heap[c]=d}function s(a,b,c){var d,f,i,j,k=0;if(0!==a.last_lit)do d=a.pending_buf[a.d_buf+2*k]<<8|a.pending_buf[a.d_buf+2*k+1],f=a.pending_buf[a.l_buf+k],k++,0===d?h(a,f,b):(i=hb[f],h(a,i+P+1,b),j=_[i],0!==j&&(f-=ib[i],g(a,f,j)),d--,i=e(d),h(a,i,c),j=ab[i],0!==j&&(d-=jb[i],g(a,d,j)));while(k<a.last_lit);h(a,X,b)}function t(a,b){var c,d,e,f=b.dyn_tree,g=b.stat_desc.static_tree,h=b.stat_desc.has_stree,i=b.stat_desc.elems,j=-1;for(a.heap_len=0,a.heap_max=T,c=0;i>c;c++)0!==f[2*c]?(a.heap[++a.heap_len]=j=c,a.depth[c]=0):f[2*c+1]=0;for(;a.heap_len<2;)e=a.heap[++a.heap_len]=2>j?++j:0,f[2*e]=1,a.depth[e]=0,a.opt_len--,h&&(a.static_len-=g[2*e+1]);for(b.max_code=j,c=a.heap_len>>1;c>=1;c--)r(a,f,c);e=i;do c=a.heap[1],a.heap[1]=a.heap[a.heap_len--],r(a,f,1),d=a.heap[1],a.heap[--a.heap_max]=c,a.heap[--a.heap_max]=d,f[2*e]=f[2*c]+f[2*d],a.depth[e]=(a.depth[c]>=a.depth[d]?a.depth[c]:a.depth[d])+1,f[2*c+1]=f[2*d+1]=e,a.heap[1]=e++,r(a,f,1);while(a.heap_len>=2);a.heap[--a.heap_max]=a.heap[1],k(a,b),l(f,j,a.bl_count)}function u(a,b,c){var d,e,f=-1,g=b[1],h=0,i=7,j=4;for(0===g&&(i=138,j=3),b[2*(c+1)+1]=65535,d=0;c>=d;d++)e=g,g=b[2*(d+1)+1],++h<i&&e===g||(j>h?a.bl_tree[2*e]+=h:0!==e?(e!==f&&a.bl_tree[2*e]++,a.bl_tree[2*Y]++):10>=h?a.bl_tree[2*Z]++:a.bl_tree[2*$]++,h=0,f=e,0===g?(i=138,j=3):e===g?(i=6,j=3):(i=7,j=4))}function v(a,b,c){var d,e,f=-1,i=b[1],j=0,k=7,l=4;for(0===i&&(k=138,l=3),d=0;c>=d;d++)if(e=i,i=b[2*(d+1)+1],!(++j<k&&e===i)){if(l>j){do h(a,e,a.bl_tree);while(0!==--j)}else 0!==e?(e!==f&&(h(a,e,a.bl_tree),j--),h(a,Y,a.bl_tree),g(a,j-3,2)):10>=j?(h(a,Z,a.bl_tree),g(a,j-3,3)):(h(a,$,a.bl_tree),g(a,j-11,7));j=0,f=e,0===i?(k=138,l=3):e===i?(k=6,l=3):(k=7,l=4)}}function w(a){var b;for(u(a,a.dyn_ltree,a.l_desc.max_code),u(a,a.dyn_dtree,a.d_desc.max_code),t(a,a.bl_desc),b=S-1;b>=3&&0===a.bl_tree[2*cb[b]+1];b--);return a.opt_len+=3*(b+1)+5+5+4,b}function x(a,b,c,d){var e;for(g(a,b-257,5),g(a,c-1,5),g(a,d-4,4),e=0;d>e;e++)g(a,a.bl_tree[2*cb[e]+1],3);v(a,a.dyn_ltree,b-1),v(a,a.dyn_dtree,c-1)}function y(a){var b,c=4093624447;for(b=0;31>=b;b++,c>>>=1)if(1&c&&0!==a.dyn_ltree[2*b])return G;if(0!==a.dyn_ltree[18]||0!==a.dyn_ltree[20]||0!==a.dyn_ltree[26])return H;for(b=32;P>b;b++)if(0!==a.dyn_ltree[2*b])return H;return G}function z(a){pb||(m(),pb=!0),a.l_desc=new ob(a.dyn_ltree,kb),a.d_desc=new ob(a.dyn_dtree,lb),a.bl_desc=new ob(a.bl_tree,mb),a.bi_buf=0,a.bi_valid=0,n(a)}function A(a,b,c,d){g(a,(J<<1)+(d?1:0),3),p(a,b,c,!0)}function B(a){g(a,K<<1,3),h(a,X,eb),j(a)}function C(a,b,c,d){var e,f,h=0;a.level>0?(a.strm.data_type===I&&(a.strm.data_type=y(a)),t(a,a.l_desc),t(a,a.d_desc),h=w(a),e=a.opt_len+3+7>>>3,f=a.static_len+3+7>>>3,e>=f&&(e=f)):e=f=c+5,e>=c+4&&-1!==b?A(a,b,c,d):a.strategy===F||f===e?(g(a,(K<<1)+(d?1:0),3),s(a,eb,fb)):(g(a,(L<<1)+(d?1:0),3),x(a,a.l_desc.max_code+1,a.d_desc.max_code+1,h+1),s(a,a.dyn_ltree,a.dyn_dtree)),n(a),d&&o(a)}function D(a,b,c){return a.pending_buf[a.d_buf+2*a.last_lit]=b>>>8&255,a.pending_buf[a.d_buf+2*a.last_lit+1]=255&b,a.pending_buf[a.l_buf+a.last_lit]=255&c,a.last_lit++,0===b?a.dyn_ltree[2*c]++:(a.matches++,b--,a.dyn_ltree[2*(hb[c]+P+1)]++,a.dyn_dtree[2*e(b)]++),a.last_lit===a.lit_bufsize-1}var E=a("../utils/common"),F=4,G=0,H=1,I=2,J=0,K=1,L=2,M=3,N=258,O=29,P=256,Q=P+1+O,R=30,S=19,T=2*Q+1,U=15,V=16,W=7,X=256,Y=16,Z=17,$=18,_=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],ab=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],bb=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],cb=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],db=512,eb=new Array(2*(Q+2));d(eb);var fb=new Array(2*R);d(fb);var gb=new Array(db);d(gb);var hb=new Array(N-M+1);d(hb);var ib=new Array(O);d(ib);var jb=new Array(R);d(jb);var kb,lb,mb,nb=function(a,b,c,d,e){this.static_tree=a,this.extra_bits=b,this.extra_base=c,this.elems=d,this.max_length=e,this.has_stree=a&&a.length},ob=function(a,b){this.dyn_tree=a,this.max_code=0,this.stat_desc=b},pb=!1;c._tr_init=z,c._tr_stored_block=A,c._tr_flush_block=C,c._tr_tally=D,c._tr_align=B},{"../utils/common":27}],39:[function(a,b){"use strict";function c(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}b.exports=c},{}]},{},[9])(9)});'use strict';if(tr.isVinn){global.JSZip=global.window.JSZip;global.window=undefined;}else if(tr.isNode){const jsZipAbsPath=HTMLImportsLoader.hrefToAbsolutePath('/jszip.min.js');const jsZipModule=require(jsZipAbsPath);global.JSZip=jsZipModule;}'use strict';tr.exportTo('tr.e.importer',function(){function ZipImporter(model,eventData){if(eventData instanceof ArrayBuffer){eventData=new Uint8Array(eventData);}
+this.model_=model;this.eventData_=eventData;}
+ZipImporter.canImport=function(eventData){let header;if(eventData instanceof ArrayBuffer){header=new Uint8Array(eventData.slice(0,2));}else if(typeof(eventData)==='string'||eventData instanceof String){header=[eventData.charCodeAt(0),eventData.charCodeAt(1)];}else{return false;}
+return header[0]==='P'.charCodeAt(0)&&header[1]==='K'.charCodeAt(0);};ZipImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'ZipImporter';},isTraceDataContainer(){return true;},extractSubtraces(){const zip=new JSZip(this.eventData_);const subtraces=[];for(const idx in zip.files){subtraces.push(zip.files[idx].asBinary());}
+return subtraces;}};tr.importer.Importer.register(ZipImporter);return{ZipImporter,};});'use strict';tr.exportTo('tr.model',function(){function HeapEntry(heapDump,leafStackFrame,objectTypeName,size,count,valuesAreTotals){this.heapDump=heapDump;this.leafStackFrame=leafStackFrame;this.objectTypeName=objectTypeName;this.size=size;this.count=count;this.valuesAreTotals=valuesAreTotals;}
+function HeapDump(processMemoryDump,allocatorName,isComplete){this.processMemoryDump=processMemoryDump;this.allocatorName=allocatorName;this.isComplete=isComplete;this.entries=[];}
+HeapDump.prototype={addEntry(leafStackFrame,objectTypeName,size,count,opt_valuesAreTotals){if(opt_valuesAreTotals===undefined)opt_valuesAreTotals=true;const valuesAreTotals=opt_valuesAreTotals;const entry=new HeapEntry(this,leafStackFrame,objectTypeName,size,count,valuesAreTotals);this.entries.push(entry);return entry;}};return{HeapEntry,HeapDump,};});'use strict';tr.exportTo('tr.e.importer',function(){function HeapDumpTraceEventImporter(heapProfileExpander,stackFrames,processMemoryDump,idPrefix,model){this.expander=heapProfileExpander;this.stackFrames=stackFrames;this.processMemoryDump=processMemoryDump;this.idPrefix=idPrefix;this.model=model;}
+HeapDumpTraceEventImporter.prototype={getLeafStackFrame(stackFrameId){if(stackFrameId==='')return undefined;const parentId=this.idPrefix+stackFrameId;const id=parentId+':self';if(!this.stackFrames[id]){const parentStackFrame=this.stackFrames[parentId];const stackFrame=new tr.model.StackFrame(parentStackFrame,id,'<self>',undefined);this.model.addStackFrame(stackFrame);}
+return this.stackFrames[id];},parseEntry(entry,heapDump){const size=entry.size;const count=entry.count;const leafStackFrame=this.getLeafStackFrame(entry.node.id);const objectTypeName=entry.type.name;const valuesAreTotals=false;if(objectTypeName===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing object type name (ID '+typeId+')',});}
+heapDump.addEntry(leafStackFrame,objectTypeName,size,count,valuesAreTotals);},parse(){const heapDumps={};const inflated=this.expander.inflated;for(const[allocatorName,entries]of Object.entries(inflated)){const heapDump=new tr.model.HeapDump(this.processMemoryDump,allocatorName);for(const entry of entries){this.parseEntry(entry,heapDump);}
+heapDump.isComplete=true;heapDumps[allocatorName]=heapDump;}
+return heapDumps;},};return{HeapDumpTraceEventImporter,};});'use strict';tr.exportTo('tr.e.importer',function(){function LegacyHeapDumpTraceEventImporter(model,processMemoryDump,processObjectTypeNameMap,idPrefix,dumpId,rawHeapDumps){this.model_=model;this.processObjectTypeNameMap_=processObjectTypeNameMap;this.idPrefix_=idPrefix;this.processMemoryDump_=processMemoryDump;this.pid_=this.processMemoryDump_.process.pid;this.dumpId_=dumpId;this.rawHeapDumps_=rawHeapDumps;}
+LegacyHeapDumpTraceEventImporter.prototype={parseRawHeapDump(rawHeapDump,allocatorName){const model=this.model_;const processMemoryDump=this.processMemoryDump_;const heapDump=new tr.model.HeapDump(processMemoryDump,allocatorName);const entries=rawHeapDump.entries;if(entries===undefined||entries.length===0){this.model_.importWarning({type:'memory_dump_parse_error',message:'No heap entries in a '+allocatorName+' heap dump for PID='+this.pid_+' and dump ID='+this.dumpId_+'.'});return undefined;}
+const isOldFormat=entries[0].bt===undefined;if(!isOldFormat&&this.processObjectTypeNameMap_===undefined){return undefined;}
+for(let i=0;i<entries.length;i++){const entry=entries[i];const size=parseInt(entry.size,16);const leafStackFrameIndex=entry.bt;let leafStackFrame;if(isOldFormat){if(leafStackFrameIndex===undefined){leafStackFrame=undefined;}else{let leafStackFrameId=this.idPrefix_+leafStackFrameIndex;if(leafStackFrameIndex===''){leafStackFrame=undefined;}else{leafStackFrame=model.stackFrames[leafStackFrameId];if(leafStackFrame===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing leaf stack frame (ID '+
+leafStackFrameId+') of heap entry '+i+' (size '+
+size+') in a '+allocatorName+' heap dump for PID='+this.pid_+'.'});continue;}}
+leafStackFrameId+=':self';if(model.stackFrames[leafStackFrameId]!==undefined){leafStackFrame=model.stackFrames[leafStackFrameId];}else{leafStackFrame=new tr.model.StackFrame(leafStackFrame,leafStackFrameId,'<self>',undefined);model.addStackFrame(leafStackFrame);}}}else{if(leafStackFrameIndex===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing stack frame ID of heap entry '+i+' (size '+size+') in a '+allocatorName+' heap dump for PID='+this.pid_+'.'});continue;}
+const leafStackFrameId=this.idPrefix_+leafStackFrameIndex;if(leafStackFrameIndex===''){leafStackFrame=undefined;}else{leafStackFrame=model.stackFrames[leafStackFrameId];if(leafStackFrame===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing leaf stack frame (ID '+leafStackFrameId+') of heap entry '+i+' (size '+size+') in a '+
+allocatorName+' heap dump for PID='+this.pid_+'.'});continue;}}}
+const objectTypeId=entry.type;let objectTypeName;if(objectTypeId===undefined){objectTypeName=undefined;}else if(this.processObjectTypeNameMap_===undefined){continue;}else{objectTypeName=this.processObjectTypeNameMap_[objectTypeId];if(objectTypeName===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing object type name (ID '+objectTypeId+') of heap entry '+i+' (size '+size+') in a '+
+allocatorName+' heap dump for PID='+this.pid_+'.'});continue;}}
+const count=entry.count===undefined?undefined:parseInt(entry.count,16);heapDump.addEntry(leafStackFrame,objectTypeName,size,count);}
+return heapDump;},parse(){const heapDumps={};for(const allocatorName in this.rawHeapDumps_){const rawHeapDump=this.rawHeapDumps_[allocatorName];const heapDump=this.parseRawHeapDump(rawHeapDump,allocatorName);if(heapDump!==undefined&&heapDump.entries.length>0){heapDumps[allocatorName]=heapDump;}}
+return heapDumps;},};return{LegacyHeapDumpTraceEventImporter,};});'use strict';if(tr.isHeadless){global.window={};}
+(function(window,Object,Array,Error,JSON,undefined){var partialComplete=varArgs(function(fn,args){var numBoundArgs=args.length;return varArgs(function(callArgs){for(var i=0;i<callArgs.length;i++){args[numBoundArgs+i]=callArgs[i];}
+args.length=numBoundArgs+callArgs.length;return fn.apply(this,args);});}),compose=varArgs(function(fns){var fnsList=arrayAsList(fns);function next(params,curFn){return[apply(params,curFn)];}
+return varArgs(function(startParams){return foldR(next,startParams,fnsList)[0];});});function compose2(f1,f2){return function(){return f1.call(this,f2.apply(this,arguments));}}
+function attr(key){return function(o){return o[key];};}
+var lazyUnion=varArgs(function(fns){return varArgs(function(params){var maybeValue;for(var i=0;i<len(fns);i++){maybeValue=apply(params,fns[i]);if(maybeValue){return maybeValue;}}});});function apply(args,fn){return fn.apply(undefined,args);}
+function varArgs(fn){var numberOfFixedArguments=fn.length-1,slice=Array.prototype.slice;if(numberOfFixedArguments==0){return function(){return fn.call(this,slice.call(arguments));}}else if(numberOfFixedArguments==1){return function(){return fn.call(this,arguments[0],slice.call(arguments,1));}}
+var argsHolder=Array(fn.length);return function(){for(var i=0;i<numberOfFixedArguments;i++){argsHolder[i]=arguments[i];}
+argsHolder[numberOfFixedArguments]=slice.call(arguments,numberOfFixedArguments);return fn.apply(this,argsHolder);}}
+function flip(fn){return function(a,b){return fn(b,a);}}
+function lazyIntersection(fn1,fn2){return function(param){return fn1(param)&&fn2(param);};}
+function noop(){}
+function always(){return true}
+function functor(val){return function(){return val;}}
+function isOfType(T,maybeSomething){return maybeSomething&&maybeSomething.constructor===T;}
+var len=attr('length'),isString=partialComplete(isOfType,String);function defined(value){return value!==undefined;}
+function hasAllProperties(fieldList,o){return(o instanceof Object)&&all(function(field){return(field in o);},fieldList);}
+function cons(x,xs){return[x,xs];}
+var emptyList=null,head=attr(0),tail=attr(1);function arrayAsList(inputArray){return reverseList(inputArray.reduce(flip(cons),emptyList));}
+var list=varArgs(arrayAsList);function listAsArray(list){return foldR(function(arraySoFar,listItem){arraySoFar.unshift(listItem);return arraySoFar;},[],list);}
+function map(fn,list){return list?cons(fn(head(list)),map(fn,tail(list))):emptyList;}
+function foldR(fn,startValue,list){return list?fn(foldR(fn,startValue,tail(list)),head(list)):startValue;}
+function foldR1(fn,list){return tail(list)?fn(foldR1(fn,tail(list)),head(list)):head(list);}
+function without(list,test,removedFn){return withoutInner(list,removedFn||noop);function withoutInner(subList,removedFn){return subList?(test(head(subList))?(removedFn(head(subList)),tail(subList)):cons(head(subList),withoutInner(tail(subList),removedFn))):emptyList;}}
+function all(fn,list){return!list||(fn(head(list))&&all(fn,tail(list)));}
+function applyEach(fnList,args){if(fnList){head(fnList).apply(null,args);applyEach(tail(fnList),args);}}
+function reverseList(list){function reverseInner(list,reversedAlready){if(!list){return reversedAlready;}
+return reverseInner(tail(list),cons(head(list),reversedAlready))}
+return reverseInner(list,emptyList);}
+function first(test,list){return list&&(test(head(list))?head(list):first(test,tail(list)));}
+function clarinet(eventBus){"use strict";var
+emitSaxKey=eventBus(SAX_KEY).emit,emitValueOpen=eventBus(SAX_VALUE_OPEN).emit,emitValueClose=eventBus(SAX_VALUE_CLOSE).emit,emitFail=eventBus(FAIL_EVENT).emit,MAX_BUFFER_LENGTH=64*1024,stringTokenPattern=/[\\"\n]/g,_n=0,BEGIN=_n++,VALUE=_n++,OPEN_OBJECT=_n++,CLOSE_OBJECT=_n++,OPEN_ARRAY=_n++,CLOSE_ARRAY=_n++,STRING=_n++,OPEN_KEY=_n++,CLOSE_KEY=_n++,TRUE=_n++,TRUE2=_n++,TRUE3=_n++,FALSE=_n++,FALSE2=_n++,FALSE3=_n++,FALSE4=_n++,NULL=_n++,NULL2=_n++,NULL3=_n++,NUMBER_DECIMAL_POINT=_n++,NUMBER_DIGIT=_n,bufferCheckPosition=MAX_BUFFER_LENGTH,latestError,c,p,textNode=undefined,numberNode="",slashed=false,closed=false,state=BEGIN,stack=[],unicodeS=null,unicodeI=0,depth=0,position=0,column=0,line=1;function checkBufferLength(){var maxActual=0;if(textNode!==undefined&&textNode.length>MAX_BUFFER_LENGTH){emitError("Max buffer length exceeded: textNode");maxActual=Math.max(maxActual,textNode.length);}
+if(numberNode.length>MAX_BUFFER_LENGTH){emitError("Max buffer length exceeded: numberNode");maxActual=Math.max(maxActual,numberNode.length);}
+bufferCheckPosition=(MAX_BUFFER_LENGTH-maxActual)
++position;}
+eventBus(STREAM_DATA).on(handleData);eventBus(STREAM_END).on(handleStreamEnd);function emitError(errorString){if(textNode!==undefined){emitValueOpen(textNode);emitValueClose();textNode=undefined;}
+latestError=Error(errorString+"\nLn: "+line+"\nCol: "+column+"\nChr: "+c);emitFail(errorReport(undefined,undefined,latestError));}
+function handleStreamEnd(){if(state==BEGIN){emitValueOpen({});emitValueClose();closed=true;return;}
+if(state!==VALUE||depth!==0)
+emitError("Unexpected end");if(textNode!==undefined){emitValueOpen(textNode);emitValueClose();textNode=undefined;}
+closed=true;}
+function whitespace(c){return c=='\r'||c=='\n'||c==' '||c=='\t';}
+function handleData(chunk){if(latestError)
+return;if(closed){return emitError("Cannot write after close");}
+var i=0;c=chunk[0];while(c){p=c;c=chunk[i++];if(!c)break;position++;if(c=="\n"){line++;column=0;}else column++;switch(state){case BEGIN:if(c==="{")state=OPEN_OBJECT;else if(c==="[")state=OPEN_ARRAY;else if(!whitespace(c))
+return emitError("Non-whitespace before {[.");continue;case OPEN_KEY:case OPEN_OBJECT:if(whitespace(c))continue;if(state===OPEN_KEY)stack.push(CLOSE_KEY);else{if(c==='}'){emitValueOpen({});emitValueClose();state=stack.pop()||VALUE;continue;}else stack.push(CLOSE_OBJECT);}
+if(c==='"')
+state=STRING;else
+return emitError("Malformed object key should start with \" ");continue;case CLOSE_KEY:case CLOSE_OBJECT:if(whitespace(c))continue;if(c===':'){if(state===CLOSE_OBJECT){stack.push(CLOSE_OBJECT);if(textNode!==undefined){emitValueOpen({});emitSaxKey(textNode);textNode=undefined;}
+depth++;}else{if(textNode!==undefined){emitSaxKey(textNode);textNode=undefined;}}
+state=VALUE;}else if(c==='}'){if(textNode!==undefined){emitValueOpen(textNode);emitValueClose();textNode=undefined;}
+emitValueClose();depth--;state=stack.pop()||VALUE;}else if(c===','){if(state===CLOSE_OBJECT)
+stack.push(CLOSE_OBJECT);if(textNode!==undefined){emitValueOpen(textNode);emitValueClose();textNode=undefined;}
+state=OPEN_KEY;}else
+return emitError('Bad object');continue;case OPEN_ARRAY:case VALUE:if(whitespace(c))continue;if(state===OPEN_ARRAY){emitValueOpen([]);depth++;state=VALUE;if(c===']'){emitValueClose();depth--;state=stack.pop()||VALUE;continue;}else{stack.push(CLOSE_ARRAY);}}
+if(c==='"')state=STRING;else if(c==='{')state=OPEN_OBJECT;else if(c==='[')state=OPEN_ARRAY;else if(c==='t')state=TRUE;else if(c==='f')state=FALSE;else if(c==='n')state=NULL;else if(c==='-'){numberNode+=c;}else if(c==='0'){numberNode+=c;state=NUMBER_DIGIT;}else if('123456789'.indexOf(c)!==-1){numberNode+=c;state=NUMBER_DIGIT;}else
+return emitError("Bad value");continue;case CLOSE_ARRAY:if(c===','){stack.push(CLOSE_ARRAY);if(textNode!==undefined){emitValueOpen(textNode);emitValueClose();textNode=undefined;}
+state=VALUE;}else if(c===']'){if(textNode!==undefined){emitValueOpen(textNode);emitValueClose();textNode=undefined;}
+emitValueClose();depth--;state=stack.pop()||VALUE;}else if(whitespace(c))
+continue;else
+return emitError('Bad array');continue;case STRING:if(textNode===undefined){textNode="";}
+var starti=i-1;STRING_BIGLOOP:while(true){while(unicodeI>0){unicodeS+=c;c=chunk.charAt(i++);if(unicodeI===4){textNode+=String.fromCharCode(parseInt(unicodeS,16));unicodeI=0;starti=i-1;}else{unicodeI++;}
+if(!c)break STRING_BIGLOOP;}
+if(c==='"'&&!slashed){state=stack.pop()||VALUE;textNode+=chunk.substring(starti,i-1);break;}
+if(c==='\\'&&!slashed){slashed=true;textNode+=chunk.substring(starti,i-1);c=chunk.charAt(i++);if(!c)break;}
+if(slashed){slashed=false;if(c==='n'){textNode+='\n';}
+else if(c==='r'){textNode+='\r';}
+else if(c==='t'){textNode+='\t';}
+else if(c==='f'){textNode+='\f';}
+else if(c==='b'){textNode+='\b';}
+else if(c==='u'){unicodeI=1;unicodeS='';}else{textNode+=c;}
+c=chunk.charAt(i++);starti=i-1;if(!c)break;else continue;}
+stringTokenPattern.lastIndex=i;var reResult=stringTokenPattern.exec(chunk);if(!reResult){i=chunk.length+1;textNode+=chunk.substring(starti,i-1);break;}
+i=reResult.index+1;c=chunk.charAt(reResult.index);if(!c){textNode+=chunk.substring(starti,i-1);break;}}
+continue;case TRUE:if(!c)continue;if(c==='r')state=TRUE2;else
+return emitError('Invalid true started with t'+c);continue;case TRUE2:if(!c)continue;if(c==='u')state=TRUE3;else
+return emitError('Invalid true started with tr'+c);continue;case TRUE3:if(!c)continue;if(c==='e'){emitValueOpen(true);emitValueClose();state=stack.pop()||VALUE;}else
+return emitError('Invalid true started with tru'+c);continue;case FALSE:if(!c)continue;if(c==='a')state=FALSE2;else
+return emitError('Invalid false started with f'+c);continue;case FALSE2:if(!c)continue;if(c==='l')state=FALSE3;else
+return emitError('Invalid false started with fa'+c);continue;case FALSE3:if(!c)continue;if(c==='s')state=FALSE4;else
+return emitError('Invalid false started with fal'+c);continue;case FALSE4:if(!c)continue;if(c==='e'){emitValueOpen(false);emitValueClose();state=stack.pop()||VALUE;}else
+return emitError('Invalid false started with fals'+c);continue;case NULL:if(!c)continue;if(c==='u')state=NULL2;else
+return emitError('Invalid null started with n'+c);continue;case NULL2:if(!c)continue;if(c==='l')state=NULL3;else
+return emitError('Invalid null started with nu'+c);continue;case NULL3:if(!c)continue;if(c==='l'){emitValueOpen(null);emitValueClose();state=stack.pop()||VALUE;}else
+return emitError('Invalid null started with nul'+c);continue;case NUMBER_DECIMAL_POINT:if(c==='.'){numberNode+=c;state=NUMBER_DIGIT;}else
+return emitError('Leading zero not followed by .');continue;case NUMBER_DIGIT:if('0123456789'.indexOf(c)!==-1)numberNode+=c;else if(c==='.'){if(numberNode.indexOf('.')!==-1)
+return emitError('Invalid number has two dots');numberNode+=c;}else if(c==='e'||c==='E'){if(numberNode.indexOf('e')!==-1||numberNode.indexOf('E')!==-1)
+return emitError('Invalid number has two exponential');numberNode+=c;}else if(c==="+"||c==="-"){if(!(p==='e'||p==='E'))
+return emitError('Invalid symbol in number');numberNode+=c;}else{if(numberNode){emitValueOpen(parseFloat(numberNode));emitValueClose();numberNode="";}
+i--;state=stack.pop()||VALUE;}
+continue;default:return emitError("Unknown state: "+state);}}
+if(position>=bufferCheckPosition)
+checkBufferLength();}}
+function ascentManager(oboeBus,handlers){"use strict";var listenerId={},ascent;function stateAfter(handler){return function(param){ascent=handler(ascent,param);}}
+for(var eventName in handlers){oboeBus(eventName).on(stateAfter(handlers[eventName]),listenerId);}
+oboeBus(NODE_SWAP).on(function(newNode){var oldHead=head(ascent),key=keyOf(oldHead),ancestors=tail(ascent),parentNode;if(ancestors){parentNode=nodeOf(head(ancestors));parentNode[key]=newNode;}});oboeBus(NODE_DROP).on(function(){var oldHead=head(ascent),key=keyOf(oldHead),ancestors=tail(ascent),parentNode;if(ancestors){parentNode=nodeOf(head(ancestors));delete parentNode[key];}});oboeBus(ABORTING).on(function(){for(var eventName in handlers){oboeBus(eventName).un(listenerId);}});}
+function parseResponseHeaders(headerStr){var headers={};headerStr&&headerStr.split('\u000d\u000a').forEach(function(headerPair){var index=headerPair.indexOf('\u003a\u0020');headers[headerPair.substring(0,index)]=headerPair.substring(index+2);});return headers;}
+function isCrossOrigin(pageLocation,ajaxHost){function defaultPort(protocol){return{'http:':80,'https:':443}[protocol];}
+function portOf(location){return location.port||defaultPort(location.protocol||pageLocation.protocol);}
+return!!((ajaxHost.protocol&&(ajaxHost.protocol!=pageLocation.protocol))||(ajaxHost.host&&(ajaxHost.host!=pageLocation.host))||(ajaxHost.host&&(portOf(ajaxHost)!=portOf(pageLocation))));}
+function parseUrlOrigin(url){var URL_HOST_PATTERN=/(\w+:)?(?:\/\/)([\w.-]+)?(?::(\d+))?\/?/,urlHostMatch=URL_HOST_PATTERN.exec(url)||[];return{protocol:urlHostMatch[1]||'',host:urlHostMatch[2]||'',port:urlHostMatch[3]||''};}
+function httpTransport(){return new XMLHttpRequest();}
+function streamingHttp(oboeBus,xhr,method,url,data,headers,withCredentials){"use strict";var emitStreamData=oboeBus(STREAM_DATA).emit,emitFail=oboeBus(FAIL_EVENT).emit,numberOfCharsAlreadyGivenToCallback=0,stillToSendStartEvent=true;oboeBus(ABORTING).on(function(){xhr.onreadystatechange=null;xhr.abort();});function handleProgress(){var textSoFar=xhr.responseText,newText=textSoFar.substr(numberOfCharsAlreadyGivenToCallback);if(newText){emitStreamData(newText);}
+numberOfCharsAlreadyGivenToCallback=len(textSoFar);}
+if('onprogress'in xhr){xhr.onprogress=handleProgress;}
+xhr.onreadystatechange=function(){function sendStartIfNotAlready(){try{stillToSendStartEvent&&oboeBus(HTTP_START).emit(xhr.status,parseResponseHeaders(xhr.getAllResponseHeaders()));stillToSendStartEvent=false;}catch(e){}}
+switch(xhr.readyState){case 2:case 3:return sendStartIfNotAlready();case 4:sendStartIfNotAlready();var successful=String(xhr.status)[0]==2;if(successful){handleProgress();oboeBus(STREAM_END).emit();}else{emitFail(errorReport(xhr.status,xhr.responseText));}}};try{xhr.open(method,url,true);for(var headerName in headers){xhr.setRequestHeader(headerName,headers[headerName]);}
+if(!isCrossOrigin(window.location,parseUrlOrigin(url))){xhr.setRequestHeader('X-Requested-With','XMLHttpRequest');}
+xhr.withCredentials=withCredentials;xhr.send(data);}catch(e){window.setTimeout(partialComplete(emitFail,errorReport(undefined,undefined,e)),0);}}
+var jsonPathSyntax=(function(){var
+regexDescriptor=function regexDescriptor(regex){return regex.exec.bind(regex);},jsonPathClause=varArgs(function(componentRegexes){componentRegexes.unshift(/^/);return regexDescriptor(RegExp(componentRegexes.map(attr('source')).join('')));}),possiblyCapturing=/(\$?)/,namedNode=/([\w-_]+|\*)/,namePlaceholder=/()/,nodeInArrayNotation=/\["([^"]+)"\]/,numberedNodeInArrayNotation=/\[(\d+|\*)\]/,fieldList=/{([\w ]*?)}/,optionalFieldList=/(?:{([\w ]*?)})?/
+,jsonPathNamedNodeInObjectNotation=jsonPathClause(possiblyCapturing,namedNode,optionalFieldList),jsonPathNamedNodeInArrayNotation=jsonPathClause(possiblyCapturing,nodeInArrayNotation,optionalFieldList),jsonPathNumberedNodeInArrayNotation=jsonPathClause(possiblyCapturing,numberedNodeInArrayNotation,optionalFieldList),jsonPathPureDuckTyping=jsonPathClause(possiblyCapturing,namePlaceholder,fieldList),jsonPathDoubleDot=jsonPathClause(/\.\./),jsonPathDot=jsonPathClause(/\./),jsonPathBang=jsonPathClause(possiblyCapturing,/!/),emptyString=jsonPathClause(/$/);return function(fn){return fn(lazyUnion(jsonPathNamedNodeInObjectNotation,jsonPathNamedNodeInArrayNotation,jsonPathNumberedNodeInArrayNotation,jsonPathPureDuckTyping),jsonPathDoubleDot,jsonPathDot,jsonPathBang,emptyString);};}());function namedNode(key,node){return{key:key,node:node};}
+var keyOf=attr('key');var nodeOf=attr('node');var ROOT_PATH={};function incrementalContentBuilder(oboeBus){var emitNodeOpened=oboeBus(NODE_OPENED).emit,emitNodeClosed=oboeBus(NODE_CLOSED).emit,emitRootOpened=oboeBus(ROOT_PATH_FOUND).emit,emitRootClosed=oboeBus(ROOT_NODE_FOUND).emit;function arrayIndicesAreKeys(possiblyInconsistentAscent,newDeepestNode){var parentNode=nodeOf(head(possiblyInconsistentAscent));return isOfType(Array,parentNode)?keyFound(possiblyInconsistentAscent,len(parentNode),newDeepestNode):possiblyInconsistentAscent;}
+function nodeOpened(ascent,newDeepestNode){if(!ascent){emitRootOpened(newDeepestNode);return keyFound(ascent,ROOT_PATH,newDeepestNode);}
+var arrayConsistentAscent=arrayIndicesAreKeys(ascent,newDeepestNode),ancestorBranches=tail(arrayConsistentAscent),previouslyUnmappedName=keyOf(head(arrayConsistentAscent));appendBuiltContent(ancestorBranches,previouslyUnmappedName,newDeepestNode);return cons(namedNode(previouslyUnmappedName,newDeepestNode),ancestorBranches);}
+function appendBuiltContent(ancestorBranches,key,node){nodeOf(head(ancestorBranches))[key]=node;}
+function keyFound(ascent,newDeepestName,maybeNewDeepestNode){if(ascent){appendBuiltContent(ascent,newDeepestName,maybeNewDeepestNode);}
+var ascentWithNewPath=cons(namedNode(newDeepestName,maybeNewDeepestNode),ascent);emitNodeOpened(ascentWithNewPath);return ascentWithNewPath;}
+function nodeClosed(ascent){emitNodeClosed(ascent);return tail(ascent)||emitRootClosed(nodeOf(head(ascent)));}
+var contentBuilderHandlers={};contentBuilderHandlers[SAX_VALUE_OPEN]=nodeOpened;contentBuilderHandlers[SAX_VALUE_CLOSE]=nodeClosed;contentBuilderHandlers[SAX_KEY]=keyFound;return contentBuilderHandlers;}
+var jsonPathCompiler=jsonPathSyntax(function(pathNodeSyntax,doubleDotSyntax,dotSyntax,bangSyntax,emptySyntax){var CAPTURING_INDEX=1;var NAME_INDEX=2;var FIELD_LIST_INDEX=3;var headKey=compose2(keyOf,head),headNode=compose2(nodeOf,head);function nameClause(previousExpr,detection){var name=detection[NAME_INDEX],matchesName=(!name||name=='*')?always:function(ascent){return headKey(ascent)==name};return lazyIntersection(matchesName,previousExpr);}
+function duckTypeClause(previousExpr,detection){var fieldListStr=detection[FIELD_LIST_INDEX];if(!fieldListStr)
+return previousExpr;var hasAllrequiredFields=partialComplete(hasAllProperties,arrayAsList(fieldListStr.split(/\W+/))),isMatch=compose2(hasAllrequiredFields,headNode);return lazyIntersection(isMatch,previousExpr);}
+function capture(previousExpr,detection){var capturing=!!detection[CAPTURING_INDEX];if(!capturing)
+return previousExpr;return lazyIntersection(previousExpr,head);}
+function skip1(previousExpr){if(previousExpr==always){return always;}
+function notAtRoot(ascent){return headKey(ascent)!=ROOT_PATH;}
+return lazyIntersection(notAtRoot,compose2(previousExpr,tail));}
+function skipMany(previousExpr){if(previousExpr==always){return always;}
+var
+terminalCaseWhenArrivingAtRoot=rootExpr(),terminalCaseWhenPreviousExpressionIsSatisfied=previousExpr,recursiveCase=skip1(function(ascent){return cases(ascent);}),cases=lazyUnion(terminalCaseWhenArrivingAtRoot,terminalCaseWhenPreviousExpressionIsSatisfied,recursiveCase);return cases;}
+function rootExpr(){return function(ascent){return headKey(ascent)==ROOT_PATH;};}
+function statementExpr(lastClause){return function(ascent){var exprMatch=lastClause(ascent);return exprMatch===true?head(ascent):exprMatch;};}
+function expressionsReader(exprs,parserGeneratedSoFar,detection){return foldR(function(parserGeneratedSoFar,expr){return expr(parserGeneratedSoFar,detection);},parserGeneratedSoFar,exprs);}
+function generateClauseReaderIfTokenFound(tokenDetector,clauseEvaluatorGenerators,jsonPath,parserGeneratedSoFar,onSuccess){var detected=tokenDetector(jsonPath);if(detected){var compiledParser=expressionsReader(clauseEvaluatorGenerators,parserGeneratedSoFar,detected),remainingUnparsedJsonPath=jsonPath.substr(len(detected[0]));return onSuccess(remainingUnparsedJsonPath,compiledParser);}}
+function clauseMatcher(tokenDetector,exprs){return partialComplete(generateClauseReaderIfTokenFound,tokenDetector,exprs);}
+var clauseForJsonPath=lazyUnion(clauseMatcher(pathNodeSyntax,list(capture,duckTypeClause,nameClause,skip1)),clauseMatcher(doubleDotSyntax,list(skipMany)),clauseMatcher(dotSyntax,list()),clauseMatcher(bangSyntax,list(capture,rootExpr)),clauseMatcher(emptySyntax,list(statementExpr)),function(jsonPath){throw Error('"'+jsonPath+'" could not be tokenised')});function returnFoundParser(_remainingJsonPath,compiledParser){return compiledParser}
+function compileJsonPathToFunction(uncompiledJsonPath,parserGeneratedSoFar){var onFind=uncompiledJsonPath?compileJsonPathToFunction:returnFoundParser;return clauseForJsonPath(uncompiledJsonPath,parserGeneratedSoFar,onFind);}
+return function(jsonPath){try{return compileJsonPathToFunction(jsonPath,always);}catch(e){throw Error('Could not compile "'+jsonPath+'" because '+e.message);}}});function singleEventPubSub(eventType,newListener,removeListener){var listenerTupleList,listenerList;function hasId(id){return function(tuple){return tuple.id==id;};}
+return{on:function(listener,listenerId){var tuple={listener:listener,id:listenerId||listener};if(newListener){newListener.emit(eventType,listener,tuple.id);}
+listenerTupleList=cons(tuple,listenerTupleList);listenerList=cons(listener,listenerList);return this;},emit:function(){applyEach(listenerList,arguments);},un:function(listenerId){var removed;listenerTupleList=without(listenerTupleList,hasId(listenerId),function(tuple){removed=tuple;});if(removed){listenerList=without(listenerList,function(listener){return listener==removed.listener;});if(removeListener){removeListener.emit(eventType,removed.listener,removed.id);}}},listeners:function(){return listenerList;},hasListener:function(listenerId){var test=listenerId?hasId(listenerId):always;return defined(first(test,listenerTupleList));}};}
+function pubSub(){var singles={},newListener=newSingle('newListener'),removeListener=newSingle('removeListener');function newSingle(eventName){return singles[eventName]=singleEventPubSub(eventName,newListener,removeListener);}
+function pubSubInstance(eventName){return singles[eventName]||newSingle(eventName);}
+['emit','on','un'].forEach(function(methodName){pubSubInstance[methodName]=varArgs(function(eventName,parameters){apply(parameters,pubSubInstance(eventName)[methodName]);});});return pubSubInstance;}
+var
+_S=1,NODE_OPENED=_S++,NODE_CLOSED=_S++,NODE_SWAP=_S++,NODE_DROP=_S++,FAIL_EVENT='fail',ROOT_NODE_FOUND=_S++,ROOT_PATH_FOUND=_S++,HTTP_START='start',STREAM_DATA='data',STREAM_END='end',ABORTING=_S++,SAX_KEY=_S++,SAX_VALUE_OPEN=_S++,SAX_VALUE_CLOSE=_S++;function errorReport(statusCode,body,error){try{var jsonBody=JSON.parse(body);}catch(e){}
+return{statusCode:statusCode,body:body,jsonBody:jsonBody,thrown:error};}
+function patternAdapter(oboeBus,jsonPathCompiler){var predicateEventMap={node:oboeBus(NODE_CLOSED),path:oboeBus(NODE_OPENED)};function emitMatchingNode(emitMatch,node,ascent){var descent=reverseList(ascent);emitMatch(node,listAsArray(tail(map(keyOf,descent))),listAsArray(map(nodeOf,descent)));}
+function addUnderlyingListener(fullEventName,predicateEvent,compiledJsonPath){var emitMatch=oboeBus(fullEventName).emit;predicateEvent.on(function(ascent){var maybeMatchingMapping=compiledJsonPath(ascent);if(maybeMatchingMapping!==false){emitMatchingNode(emitMatch,nodeOf(maybeMatchingMapping),ascent);}},fullEventName);oboeBus('removeListener').on(function(removedEventName){if(removedEventName==fullEventName){if(!oboeBus(removedEventName).listeners()){predicateEvent.un(fullEventName);}}});}
+oboeBus('newListener').on(function(fullEventName){var match=/(node|path):(.*)/.exec(fullEventName);if(match){var predicateEvent=predicateEventMap[match[1]];if(!predicateEvent.hasListener(fullEventName)){addUnderlyingListener(fullEventName,predicateEvent,jsonPathCompiler(match[2]));}}})}
+function instanceApi(oboeBus,contentSource){var oboeApi,fullyQualifiedNamePattern=/^(node|path):./,rootNodeFinishedEvent=oboeBus(ROOT_NODE_FOUND),emitNodeDrop=oboeBus(NODE_DROP).emit,emitNodeSwap=oboeBus(NODE_SWAP).emit,addListener=varArgs(function(eventId,parameters){if(oboeApi[eventId]){apply(parameters,oboeApi[eventId]);}else{var event=oboeBus(eventId),listener=parameters[0];if(fullyQualifiedNamePattern.test(eventId)){addForgettableCallback(event,listener);}else{event.on(listener);}}
+return oboeApi;}),removeListener=function(eventId,p2,p3){if(eventId=='done'){rootNodeFinishedEvent.un(p2);}else if(eventId=='node'||eventId=='path'){oboeBus.un(eventId+':'+p2,p3);}else{var listener=p2;oboeBus(eventId).un(listener);}
+return oboeApi;};function addProtectedCallback(eventName,callback){oboeBus(eventName).on(protectedCallback(callback),callback);return oboeApi;}
+function addForgettableCallback(event,callback,listenerId){listenerId=listenerId||callback;var safeCallback=protectedCallback(callback);event.on(function(){var discard=false;oboeApi.forget=function(){discard=true;};apply(arguments,safeCallback);delete oboeApi.forget;if(discard){event.un(listenerId);}},listenerId);return oboeApi;}
+function protectedCallback(callback){return function(){try{return callback.apply(oboeApi,arguments);}catch(e){setTimeout(function(){throw new Error(e.message);});}}}
+function fullyQualifiedPatternMatchEvent(type,pattern){return oboeBus(type+':'+pattern);}
+function wrapCallbackToSwapNodeIfSomethingReturned(callback){return function(){var returnValueFromCallback=callback.apply(this,arguments);if(defined(returnValueFromCallback)){if(returnValueFromCallback==oboe.drop){emitNodeDrop();}else{emitNodeSwap(returnValueFromCallback);}}}}
+function addSingleNodeOrPathListener(eventId,pattern,callback){var effectiveCallback;if(eventId=='node'){effectiveCallback=wrapCallbackToSwapNodeIfSomethingReturned(callback);}else{effectiveCallback=callback;}
+addForgettableCallback(fullyQualifiedPatternMatchEvent(eventId,pattern),effectiveCallback,callback);}
+function addMultipleNodeOrPathListeners(eventId,listenerMap){for(var pattern in listenerMap){addSingleNodeOrPathListener(eventId,pattern,listenerMap[pattern]);}}
+function addNodeOrPathListenerApi(eventId,jsonPathOrListenerMap,callback){if(isString(jsonPathOrListenerMap)){addSingleNodeOrPathListener(eventId,jsonPathOrListenerMap,callback);}else{addMultipleNodeOrPathListeners(eventId,jsonPathOrListenerMap);}
+return oboeApi;}
+oboeBus(ROOT_PATH_FOUND).on(function(rootNode){oboeApi.root=functor(rootNode);});oboeBus(HTTP_START).on(function(_statusCode,headers){oboeApi.header=function(name){return name?headers[name]:headers;}});return oboeApi={on:addListener,addListener:addListener,removeListener:removeListener,emit:oboeBus.emit,node:partialComplete(addNodeOrPathListenerApi,'node'),path:partialComplete(addNodeOrPathListenerApi,'path'),done:partialComplete(addForgettableCallback,rootNodeFinishedEvent),start:partialComplete(addProtectedCallback,HTTP_START),fail:oboeBus(FAIL_EVENT).on,abort:oboeBus(ABORTING).emit,write:oboeBus(STREAM_DATA).emit,finish:oboeBus(STREAM_END).emit,header:noop,root:noop,source:contentSource};}
+function wire(httpMethodName,contentSource,body,headers,withCredentials){var oboeBus=pubSub();if(contentSource){streamingHttp(oboeBus,httpTransport(),httpMethodName,contentSource,body,headers,withCredentials);}
+clarinet(oboeBus);ascentManager(oboeBus,incrementalContentBuilder(oboeBus));patternAdapter(oboeBus,jsonPathCompiler);return instanceApi(oboeBus,contentSource);}
+function applyDefaults(passthrough,url,httpMethodName,body,headers,withCredentials,cached){headers=headers?JSON.parse(JSON.stringify(headers)):{};if(body){if(!isString(body)){body=JSON.stringify(body);headers['Content-Type']=headers['Content-Type']||'application/json';}}else{body=null;}
+function modifiedUrl(baseUrl,cached){if(cached===false){if(baseUrl.indexOf('?')==-1){baseUrl+='?';}else{baseUrl+='&';}
+baseUrl+='_='+new Date().getTime();}
+return baseUrl;}
+return passthrough(httpMethodName||'GET',modifiedUrl(url,cached),body,headers,withCredentials||false);}
+function oboe(arg1){var nodeStreamMethodNames=list('resume','pause','pipe'),isStream=partialComplete(hasAllProperties,nodeStreamMethodNames);if(arg1){if(isStream(arg1)||isString(arg1)){return applyDefaults(wire,arg1);}else{return applyDefaults(wire,arg1.url,arg1.method,arg1.body,arg1.headers,arg1.withCredentials,arg1.cached);}}else{return wire();}}
+oboe.drop=function(){return oboe.drop;};if(typeof define==="function"&&define.amd){define("oboe",[],function(){return oboe;});}else if(typeof exports==='object'){module.exports=oboe;}else{window.oboe=oboe;}})((function(){try{return window;}catch(e){return self;}}()),Object,Array,Error,JSON);'use strict';if(tr.isVinn){global.oboe=global.window.oboe;global.window=undefined;}else if(tr.isNode){global.window=undefined;const path=HTMLImportsLoader.hrefToAbsolutePath('/oboe/dist/oboe-node.js');global.oboe=require(path);}'use strict';tr.exportTo('tr.e.importer',function(){const STRING_ID_SUFFIX='_sid';const PLURAL_STRING_ID_SUFFIX='_sids';function isStringReference(s){return s.endsWith(STRING_ID_SUFFIX)||s.endsWith(PLURAL_STRING_ID_SUFFIX);}
+function getStringReferenceName(name){if(name.endsWith(PLURAL_STRING_ID_SUFFIX)){return name.slice(0,-PLURAL_STRING_ID_SUFFIX.length);}
+return name.slice(0,-STRING_ID_SUFFIX.length);}
+function deferenceStrings(idToString,o){const clone=Object.assign({},o);for(const[key,value]of Object.entries(clone)){if(isStringReference(key)){const name=getStringReferenceName(key);clone[name]=idToString(value);}}
+return clone;}
+function singularize(word){if(word.endsWith('s')){return word.slice(0,-1);}
+return word;}
+function getMetadataPairs(dataJson){const isMetadata=v=>typeof v!=='object'||Array.isArray(v);const pairs=Object.entries(dataJson);const metadataPairs=pairs.filter(([_,v])=>isMetadata(v));return metadataPairs;}
+function getGroupPairs(dataJson){const pairs=Object.entries(dataJson);const nonMapPairs=pairs.filter(([k,_])=>k!=='maps');const groupPairs=nonMapPairs.filter(([_,v])=>typeof v==='object');return groupPairs;}
+function createMap(mapJson){const map=new Map();for(const entry of mapJson){if(entry.id===undefined){throw new Error('Missing required key "id" in streaming event.');}
+map.set(entry.id,entry);}
+return map;}
+function createMaps(mapsJson){const maps=new Map();for(const[name,mapJson]of Object.entries(mapsJson)){maps.set(name,createMap(mapJson));}
+return maps;}
+function createGroup(groupJson,opt_startTime){const entries=[];const n=Object.values(groupJson)[0].length;for(let i=0;i<n;i++){const entry={};for(const name in groupJson){entry[name]=groupJson[name][i];}
+entries.push(entry);}
+const timeDelta=groupJson.timeDelta;if(opt_startTime===undefined&&timeDelta!==undefined){throw new Error('Missing required key "startTime" in streaming event.');}
+if(opt_startTime){let delta=0;for(const entry of entries){delta+=entry.timeDelta?entry.timeDelta:0;entry.time=opt_startTime+delta;}}
+return entries;}
+function createGroups(groupsJson,opt_startTime){const groups=new Map();for(const[name,groupJson]of Object.entries(groupsJson)){groups.set(name,createGroup(groupJson,opt_startTime));}
+return groups;}
+function createMetadata(metadataPairs){const metadata=new Map();for(const[name,value]of metadataPairs){metadata.set(name,value);}
+if(metadata.get('version')===undefined){throw new Error('Missing required key "version" in streaming event.');}
+return metadata;}
+class ProfilingDictionaryReader{constructor(opt_metadata,opt_maps,opt_groups,opt_parent){this.metadata=opt_metadata||new Map();this.maps=opt_maps||new Map();this.groups=opt_groups||new Map();this.parent_=opt_parent||undefined;this.inflated_=undefined;this.raw_=undefined;this.boundGetString_=this.getString.bind(this);this.deferenceStrings_=o=>deferenceStrings(this.boundGetString_,o);}
+static empty(){return new ProfilingDictionaryReader();}
+get parent(){return this.parent_;}
+get raw(){if(this.raw_)return this.raw_;this.raw_={};for(const[name,group]of this.groups.entries()){this.raw_[name]=group;}
+return this.raw_;}
+get inflated(){if(this.inflated_)return this.inflated_;this.inflated_={};for(const[name,group]of this.groups.entries()){this.inflated_[name]=this.inflateGroup(group);}
+return this.inflated_;}
+getNewMap(name){return this.maps.get(name)||new Map();}
+getMapValue(mapName,id){let value=this.getNewMap(mapName).get(id);if(value===undefined&&this.parent){value=this.parent.getMapValue(mapName,id);}
+return value;}
+getString(id){const value=this.getMapValue('strings',id);if(value===undefined)return undefined;return value.string;}
+hasMap(name){if(this.maps.has(name))return true;if(this.parent===undefined)return false;return this.parent.hasMap(name);}
+inflateGroup(group){return group.map(this.inflateEntry.bind(this));}
+inflateEntry(entry){const inflatedEntry={};for(const[name,value]of Object.entries(entry)){let inflatedValue;if(this.hasMap(name)){const id=value;inflatedValue=this.deferenceStrings_(this.getMapValue(name,id));}else{inflatedValue=value;}
+inflatedEntry[singularize(name)]=inflatedValue;}
+return this.deferenceStrings_(inflatedEntry);}
+expandData(data){const mapsJson=data.maps||{};const groupsJson=data.allocators||{};const metadataPairs=getMetadataPairs(data);const metadata=createMetadata(metadataPairs);const opt_startTime=metadata.get('startTime');const maps=createMaps(mapsJson);const groups=createGroups(groupsJson,opt_startTime);return new ProfilingDictionaryReader(metadata,maps,groups,this);}
+expandEvent(event){return this.expandData(event.args.data);}}
+return{ProfilingDictionaryReader,singularize,deferenceStringsForTest:deferenceStrings,};});'use strict';tr.exportTo('tr.model.source_info',function(){function SourceInfo(file,opt_line,opt_column){this.file_=file;this.line_=opt_line||-1;this.column_=opt_column||-1;}
+SourceInfo.prototype={get file(){return this.file_;},get line(){return this.line_;},get column(){return this.column_;},get domain(){if(!this.file_)return undefined;const domain=this.file_.match(/(.*:\/\/[^:\/]*)/i);return domain?domain[1]:undefined;},toString(){let str='';if(this.file_){str+=this.file_;}
+if(this.line_>0){str+=':'+this.line_;}
+if(this.column_>0){str+=':'+this.column_;}
+return str;}};return{SourceInfo,};});'use strict';tr.exportTo('tr.model.source_info',function(){function JSSourceInfo(file,line,column,isNative,scriptId,state){tr.model.source_info.SourceInfo.call(this,file,line,column);this.isNative_=isNative;this.scriptId_=scriptId;this.state_=state;}
+JSSourceInfo.prototype={__proto__:tr.model.source_info.SourceInfo.prototype,get state(){return this.state_;},get isNative(){return this.isNative_;},get scriptId(){return this.scriptId_;},toString(){const str=this.isNative_?'[native v8] ':'';return str+
+tr.model.source_info.SourceInfo.prototype.toString.call(this);}};const JSSourceState={COMPILED:'compiled',OPTIMIZABLE:'optimizable',OPTIMIZED:'optimized',UNKNOWN:'unknown',};return{JSSourceInfo,JSSourceState,};});'use strict';tr.exportTo('tr.e.importer',function(){function TraceCodeEntry(address,size,name,scriptId){this.id_=tr.b.GUID.allocateSimple();this.address_=address;this.size_=size;const rePrefix=/^(\w*:)?([*~]?)(.*)$/m;const tokens=rePrefix.exec(name);const prefix=tokens[1];let state=tokens[2];const body=tokens[3];if(state==='*'){state=tr.model.source_info.JSSourceState.OPTIMIZED;}else if(state==='~'){state=tr.model.source_info.JSSourceState.OPTIMIZABLE;}else if(state===''){state=tr.model.source_info.JSSourceState.COMPILED;}else{state=tr.model.source_info.JSSourceState.UNKNOWN;}
+let rawName;let rawUrl;if(prefix==='Script:'){rawName='';rawUrl=body;}else{const spacePos=body.lastIndexOf(' ');rawName=spacePos!==-1?body.substr(0,spacePos):body;rawUrl=spacePos!==-1?body.substr(spacePos+1):'';}
+function splitLineAndColumn(url){const lineColumnRegEx=/(?::(\d+))?(?::(\d+))?$/;const lineColumnMatch=lineColumnRegEx.exec(url);let lineNumber;let columnNumber;if(typeof(lineColumnMatch[1])==='string'){lineNumber=parseInt(lineColumnMatch[1],10);lineNumber=isNaN(lineNumber)?undefined:lineNumber-1;}
 if(typeof(lineColumnMatch[2])==='string'){columnNumber=parseInt(lineColumnMatch[2],10);columnNumber=isNaN(columnNumber)?undefined:columnNumber-1;}
-return{url:url.substring(0,url.length-lineColumnMatch[0].length),lineNumber:lineNumber,columnNumber:columnNumber};}
-var nativeSuffix=' native';var isNative=rawName.endsWith(nativeSuffix);this.name_=isNative?rawName.slice(0,-nativeSuffix.length):rawName;var urlData=splitLineAndColumn(rawUrl);var url=urlData.url||'';var line=urlData.lineNumber||0;var column=urlData.columnNumber||0;this.sourceInfo_=new tr.model.source_info.JSSourceInfo(url,line,column,isNative,scriptId,state);};TraceCodeEntry.prototype={get id(){return this.id_;},get sourceInfo(){return this.sourceInfo_;},get name(){return this.name_;},set address(address){this.address_=address;},get address(){return this.address_;},set size(size){this.size_=size;},get size(){return this.size_;}};return{TraceCodeEntry:TraceCodeEntry};});'use strict';tr.exportTo('tr.e.importer',function(){function TraceCodeMap(){this.banks_=new Map();}
-TraceCodeMap.prototype={addEntry:function(addressHex,size,name,scriptId){var entry=new tr.e.importer.TraceCodeEntry(this.getAddress_(addressHex),size,name,scriptId);this.addEntry_(addressHex,entry);},moveEntry:function(oldAddressHex,newAddressHex,size){var entry=this.getBank_(oldAddressHex).removeEntry(this.getAddress_(oldAddressHex));if(!entry)
-return;entry.address=this.getAddress_(newAddressHex);entry.size=size;this.addEntry_(newAddressHex,entry);},lookupEntry:function(addressHex){return this.getBank_(addressHex).lookupEntry(this.getAddress_(addressHex));},addEntry_:function(addressHex,entry){this.getBank_(addressHex).addEntry(entry);},getAddress_:function(addressHex){var bankSizeHexDigits=13;addressHex=addressHex.slice(2);return parseInt(addressHex.slice(-bankSizeHexDigits),16);},getBank_:function(addressHex){addressHex=addressHex.slice(2);var bankSizeHexDigits=13;var maxHexDigits=16;var bankName=addressHex.slice(-maxHexDigits,-bankSizeHexDigits);var bank=this.banks_.get(bankName);if(!bank){bank=new TraceCodeBank();this.banks_.set(bankName,bank);}
+return{url:url.substring(0,url.length-lineColumnMatch[0].length),lineNumber,columnNumber};}
+const nativeSuffix=' native';const isNative=rawName.endsWith(nativeSuffix);this.name_=isNative?rawName.slice(0,-nativeSuffix.length):rawName;const urlData=splitLineAndColumn(rawUrl);const url=urlData.url||'';const line=urlData.lineNumber||0;const column=urlData.columnNumber||0;this.sourceInfo_=new tr.model.source_info.JSSourceInfo(url,line,column,isNative,scriptId,state);}
+TraceCodeEntry.prototype={get id(){return this.id_;},get sourceInfo(){return this.sourceInfo_;},get name(){return this.name_;},set address(address){this.address_=address;},get address(){return this.address_;},set size(size){this.size_=size;},get size(){return this.size_;}};return{TraceCodeEntry,};});'use strict';tr.exportTo('tr.e.importer',function(){function TraceCodeMap(){this.banks_=new Map();}
+TraceCodeMap.prototype={addEntry(addressHex,size,name,scriptId){const entry=new tr.e.importer.TraceCodeEntry(this.getAddress_(addressHex),size,name,scriptId);this.addEntry_(addressHex,entry);},moveEntry(oldAddressHex,newAddressHex,size){const entry=this.getBank_(oldAddressHex).removeEntry(this.getAddress_(oldAddressHex));if(!entry)return;entry.address=this.getAddress_(newAddressHex);entry.size=size;this.addEntry_(newAddressHex,entry);},lookupEntry(addressHex){return this.getBank_(addressHex).lookupEntry(this.getAddress_(addressHex));},addEntry_(addressHex,entry){this.getBank_(addressHex).addEntry(entry);},getAddress_(addressHex){const bankSizeHexDigits=13;addressHex=addressHex.slice(2);return parseInt(addressHex.slice(-bankSizeHexDigits),16);},getBank_(addressHex){addressHex=addressHex.slice(2);const bankSizeHexDigits=13;const maxHexDigits=16;const bankName=addressHex.slice(-maxHexDigits,-bankSizeHexDigits);let bank=this.banks_.get(bankName);if(!bank){bank=new TraceCodeBank();this.banks_.set(bankName,bank);}
 return bank;}};function TraceCodeBank(){this.entries_=[];}
-TraceCodeBank.prototype={removeEntry:function(address){if(this.entries_.length===0)
-return undefined;var index=tr.b.findLowIndexInSortedArray(this.entries_,function(entry){return entry.address;},address);var entry=this.entries_[index];if(!entry||entry.address!==address)
-return undefined;this.entries_.splice(index,1);return entry;},lookupEntry:function(address){var index=tr.b.findHighIndexInSortedArray(this.entries_,function(e){return address-e.address;})-1;var entry=this.entries_[index];return entry&&address<entry.address+entry.size?entry:undefined;},addEntry:function(newEntry){if(this.entries_.length===0)
-this.entries_.push(newEntry);var endAddress=newEntry.address+newEntry.size;var lastIndex=tr.b.findLowIndexInSortedArray(this.entries_,function(entry){return entry.address;},endAddress);var index;for(index=lastIndex-1;index>=0;--index){var entry=this.entries_[index];var entryEndAddress=entry.address+entry.size;if(entryEndAddress<=newEntry.address)
-break;}
-++index;this.entries_.splice(index,lastIndex-index,newEntry);}};return{TraceCodeMap:TraceCodeMap};});'use strict';tr.exportTo('tr.model',function(){function ClockSyncRecord(syncId,start,args){this.syncId_=syncId;this.start_=start;this.args_=args;};ClockSyncRecord.prototype={get syncId(){return this.syncId_;},get start(){return this.start_;},set start(value){this.start_=value;},get args(){return this.args_;}};function InstantClockSyncRecord(syncId,start,args){ClockSyncRecord.call(this,syncId,start,args);};InstantClockSyncRecord.prototype={__proto__:ClockSyncRecord.prototype};function PingPongClockSyncRecord(syncId,start,duration,args){ClockSyncRecord.call(this,syncId,start,args);this.duration_=duration;};PingPongClockSyncRecord.prototype={__proto__:ClockSyncRecord.prototype,get duration(){return this.duration_;},set duration(value){this.duration_=value;},};return{InstantClockSyncRecord:InstantClockSyncRecord,PingPongClockSyncRecord:PingPongClockSyncRecord};});'use strict';tr.exportTo('tr.model',function(){function YComponent(stableId,yPercentOffset){this.stableId=stableId;this.yPercentOffset=yPercentOffset;}
-YComponent.prototype={toDict:function(){return{stableId:this.stableId,yPercentOffset:this.yPercentOffset};}};function Location(xWorld,yComponents){this.xWorld_=xWorld;this.yComponents_=yComponents;};Location.fromViewCoordinates=function(viewport,viewX,viewY){var dt=viewport.currentDisplayTransform;var xWorld=dt.xViewToWorld(viewX);var yComponents=[];var elem=document.elementFromPoint(viewX+viewport.modelTrackContainer.canvas.offsetLeft,viewY+viewport.modelTrackContainer.canvas.offsetTop);while(elem instanceof tr.ui.tracks.Track){if(elem.eventContainer){var boundRect=elem.getBoundingClientRect();var yPercentOffset=(viewY-boundRect.top)/boundRect.height;yComponents.push(new YComponent(elem.eventContainer.stableId,yPercentOffset));}
+TraceCodeBank.prototype={removeEntry(address){if(this.entries_.length===0)return undefined;const index=tr.b.findLowIndexInSortedArray(this.entries_,function(entry){return entry.address;},address);const entry=this.entries_[index];if(!entry||entry.address!==address)return undefined;this.entries_.splice(index,1);return entry;},lookupEntry(address){const index=tr.b.findFirstTrueIndexInSortedArray(this.entries_,e=>(address<e.address))-1;const entry=this.entries_[index];return entry&&address<entry.address+entry.size?entry:undefined;},addEntry(newEntry){if(this.entries_.length===0){this.entries_.push(newEntry);}
+const endAddress=newEntry.address+newEntry.size;const lastIndex=tr.b.findLowIndexInSortedArray(this.entries_,function(entry){return entry.address;},endAddress);let index;for(index=lastIndex-1;index>=0;--index){const entry=this.entries_[index];const entryEndAddress=entry.address+entry.size;if(entryEndAddress<=newEntry.address)break;}
+++index;this.entries_.splice(index,lastIndex-index,newEntry);}};return{TraceCodeMap,};});'use strict';tr.exportTo('tr.e.measure',function(){const AsyncSlice=tr.model.AsyncSlice;const MEASURE_NAME_REGEX=/([^\/:]+):(.*?)(?:\/([A-Za-z0-9+/]+=?=?))?$/;function MeasureAsyncSlice(){this.groupTitle_='Ungrouped Measure';const matched=MEASURE_NAME_REGEX.exec(arguments[1]);if(matched!==null){arguments[1]=matched[2];this.groupTitle_=matched[1];}
+AsyncSlice.apply(this,arguments);}
+MeasureAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get viewSubGroupTitle(){return this.groupTitle_;},get title(){return this.title_;},set title(title){this.title_=title;}};AsyncSlice.subTypes.register(MeasureAsyncSlice,{categoryParts:['blink.user_timing']});return{MEASURE_NAME_REGEX,MeasureAsyncSlice,};});'use strict';tr.exportTo('tr.importer',function(){function ContextProcessor(model){this.model_=model;this.activeContexts_=[];this.stackPerType_={};this.contextCache_={};this.contextSetCache_={};this.cachedEntryForActiveContexts_=undefined;this.seenSnapshots_={};}
+ContextProcessor.prototype={enterContext(contextType,scopedId){const newActiveContexts=[this.getOrCreateContext_(contextType,scopedId),];for(const oldContext of this.activeContexts_){if(oldContext.type===contextType){this.pushContext_(oldContext);}else{newActiveContexts.push(oldContext);}}
+this.activeContexts_=newActiveContexts;this.cachedEntryForActiveContexts_=undefined;},leaveContext(contextType,scopedId){this.leaveContextImpl_(context=>context.type===contextType&&context.snapshot.scope===scopedId.scope&&context.snapshot.idRef===scopedId.id);},destroyContext(scopedId){for(const stack of Object.values(this.stackPerType_)){let newLength=0;for(let i=0;i<stack.length;++i){if(stack[i].snapshot.scope!==scopedId.scope||stack[i].snapshot.idRef!==scopedId.id){stack[newLength++]=stack[i];}}
+stack.length=newLength;}
+this.leaveContextImpl_(context=>context.snapshot.scope===scopedId.scope&&context.snapshot.idRef===scopedId.id);},leaveContextImpl_(predicate){const newActiveContexts=[];for(const oldContext of this.activeContexts_){if(predicate(oldContext)){const previousContext=this.popContext_(oldContext.type);if(previousContext){newActiveContexts.push(previousContext);}}else{newActiveContexts.push(oldContext);}}
+this.activeContexts_=newActiveContexts;this.cachedEntryForActiveContexts_=undefined;},getOrCreateContext_(contextType,scopedId){const context={type:contextType,snapshot:{scope:scopedId.scope,idRef:scopedId.id}};const key=this.getContextKey_(context);if(key in this.contextCache_){return this.contextCache_[key];}
+this.contextCache_[key]=context;const snapshotKey=this.getSnapshotKey_(scopedId);this.seenSnapshots_[snapshotKey]=true;return context;},pushContext_(context){if(!(context.type in this.stackPerType_)){this.stackPerType_[context.type]=[];}
+this.stackPerType_[context.type].push(context);},popContext_(contextType){if(!(contextType in this.stackPerType_)){return undefined;}
+return this.stackPerType_[contextType].pop();},getContextKey_(context){return[context.type,context.snapshot.scope,context.snapshot.idRef].join('\x00');},getSnapshotKey_(scopedId){return[scopedId.scope,scopedId.idRef].join('\x00');},get activeContexts(){if(this.cachedEntryForActiveContexts_===undefined){let key=[];for(const context of this.activeContexts_){key.push(this.getContextKey_(context));}
+key.sort();key=key.join('\x00');if(key in this.contextSetCache_){this.cachedEntryForActiveContexts_=this.contextSetCache_[key];}else{this.activeContexts_.sort(function(a,b){const keyA=this.getContextKey_(a);const keyB=this.getContextKey_(b);if(keyA<keyB){return-1;}
+if(keyA>keyB){return 1;}
+return 0;}.bind(this));this.contextSetCache_[key]=Object.freeze(this.activeContexts_);this.cachedEntryForActiveContexts_=this.contextSetCache_[key];}}
+return this.cachedEntryForActiveContexts_;},invalidateContextCacheForSnapshot(scopedId){const snapshotKey=this.getSnapshotKey_(scopedId);if(!(snapshotKey in this.seenSnapshots_))return;this.contextCache_={};this.contextSetCache_={};this.cachedEntryForActiveContexts_=undefined;this.activeContexts_=this.activeContexts_.map(function(context){if(context.snapshot.scope!==scopedId.scope||context.snapshot.idRef!==scopedId.id){return context;}
+return{type:context.type,snapshot:{scope:context.snapshot.scope,idRef:context.snapshot.idRef}};});this.seenSnapshots_={};},};return{ContextProcessor,};});'use strict';tr.exportTo('tr.model',function(){function Annotation(){this.guid_=tr.b.GUID.allocateSimple();this.view_=undefined;}
+Annotation.fromDictIfPossible=function(args){if(args.typeName===undefined){throw new Error('Missing typeName argument');}
+const typeInfo=Annotation.findTypeInfoMatching(function(typeInfo){return typeInfo.metadata.typeName===args.typeName;});if(typeInfo===undefined)return undefined;return typeInfo.constructor.fromDict(args);};Annotation.fromDict=function(){throw new Error('Not implemented');};Annotation.prototype={get guid(){return this.guid_;},onRemove(){},toDict(){throw new Error('Not implemented');},getOrCreateView(viewport){if(!this.view_){this.view_=this.createView_(viewport);}
+return this.view_;},createView_(){throw new Error('Not implemented');}};const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(Annotation,options);Annotation.addEventListener('will-register',function(e){if(!e.typeInfo.constructor.hasOwnProperty('fromDict')){throw new Error('Must have fromDict method');}
+if(!e.typeInfo.metadata.typeName){throw new Error('Registered Annotations must provide typeName');}});return{Annotation,};});'use strict';tr.exportTo('tr.model',function(){function YComponent(stableId,yPercentOffset){this.stableId=stableId;this.yPercentOffset=yPercentOffset;}
+YComponent.prototype={toDict(){return{stableId:this.stableId,yPercentOffset:this.yPercentOffset};}};function Location(xWorld,yComponents){this.xWorld_=xWorld;this.yComponents_=yComponents;}
+Location.fromViewCoordinates=function(viewport,viewX,viewY){const dt=viewport.currentDisplayTransform;const xWorld=dt.xViewToWorld(viewX);const yComponents=[];let elem=document.elementFromPoint(viewX+viewport.modelTrackContainer.canvas.offsetLeft,viewY+viewport.modelTrackContainer.canvas.offsetTop);while(elem instanceof tr.ui.tracks.Track){if(elem.eventContainer){const boundRect=elem.getBoundingClientRect();const yPercentOffset=(viewY-boundRect.top)/boundRect.height;yComponents.push(new YComponent(elem.eventContainer.stableId,yPercentOffset));}
 elem=elem.parentElement;}
-if(yComponents.length==0)
-return;return new Location(xWorld,yComponents);}
-Location.fromStableIdAndTimestamp=function(viewport,stableId,ts){var xWorld=ts;var yComponents=[];var containerToTrack=viewport.containerToTrackMap;var elem=containerToTrack.getTrackByStableId(stableId);if(!elem)
-return;var firstY=elem.getBoundingClientRect().top;while(elem instanceof tr.ui.tracks.Track){if(elem.eventContainer){var boundRect=elem.getBoundingClientRect();var yPercentOffset=(firstY-boundRect.top)/boundRect.height;yComponents.push(new YComponent(elem.eventContainer.stableId,yPercentOffset));}
+if(yComponents.length===0)return;return new Location(xWorld,yComponents);};Location.fromStableIdAndTimestamp=function(viewport,stableId,ts){const xWorld=ts;const yComponents=[];const containerToTrack=viewport.containerToTrackMap;let elem=containerToTrack.getTrackByStableId(stableId);if(!elem)return;const firstY=elem.getBoundingClientRect().top;while(elem instanceof tr.ui.tracks.Track){if(elem.eventContainer){const boundRect=elem.getBoundingClientRect();const yPercentOffset=(firstY-boundRect.top)/boundRect.height;yComponents.push(new YComponent(elem.eventContainer.stableId,yPercentOffset));}
 elem=elem.parentElement;}
-if(yComponents.length==0)
-return;return new Location(xWorld,yComponents);}
-Location.prototype={get xWorld(){return this.xWorld_;},getContainingTrack:function(viewport){var containerToTrack=viewport.containerToTrackMap;for(var i in this.yComponents_){var yComponent=this.yComponents_[i];var track=containerToTrack.getTrackByStableId(yComponent.stableId);if(track!==undefined)
-return track;}},toViewCoordinates:function(viewport){var dt=viewport.currentDisplayTransform;var containerToTrack=viewport.containerToTrackMap;var viewX=dt.xWorldToView(this.xWorld_);var viewY=-1;for(var index in this.yComponents_){var yComponent=this.yComponents_[index];var track=containerToTrack.getTrackByStableId(yComponent.stableId);if(track!==undefined){var boundRect=track.getBoundingClientRect();viewY=yComponent.yPercentOffset*boundRect.height+boundRect.top;break;}}
-return{viewX:viewX,viewY:viewY};},toDict:function(){return{xWorld:this.xWorld_,yComponents:this.yComponents_};}};return{Location:Location};});'use strict';tr.exportTo('tr.model',function(){function Annotation(){this.guid_=tr.b.GUID.allocate();this.view_=undefined;};Annotation.fromDictIfPossible=function(args){if(args.typeName===undefined)
-throw new Error('Missing typeName argument');var typeInfo=Annotation.findTypeInfoMatching(function(typeInfo){return typeInfo.metadata.typeName===args.typeName;});if(typeInfo===undefined)
-return undefined;return typeInfo.constructor.fromDict(args);};Annotation.fromDict=function(){throw new Error('Not implemented');}
-Annotation.prototype={get guid(){return this.guid_;},onRemove:function(){},toDict:function(){throw new Error('Not implemented');},getOrCreateView:function(viewport){if(!this.view_)
-this.view_=this.createView_(viewport);return this.view_;},createView_:function(){throw new Error('Not implemented');}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(Annotation,options);Annotation.addEventListener('will-register',function(e){if(!e.typeInfo.constructor.hasOwnProperty('fromDict'))
-throw new Error('Must have fromDict method');if(!e.typeInfo.metadata.typeName)
-throw new Error('Registered Annotations must provide typeName');});return{Annotation:Annotation};});'use strict';tr.exportTo('tr.ui.annotations',function(){function AnnotationView(viewport,annotation){}
-AnnotationView.prototype={draw:function(ctx){throw new Error('Not implemented');}};return{AnnotationView:AnnotationView};});'use strict';tr.exportTo('tr.ui.annotations',function(){function RectAnnotationView(viewport,annotation){this.viewport_=viewport;this.annotation_=annotation;}
-RectAnnotationView.prototype={__proto__:tr.ui.annotations.AnnotationView.prototype,draw:function(ctx){var dt=this.viewport_.currentDisplayTransform;var startCoords=this.annotation_.startLocation.toViewCoordinates(this.viewport_);var endCoords=this.annotation_.endLocation.toViewCoordinates(this.viewport_);var startY=startCoords.viewY-ctx.canvas.getBoundingClientRect().top;var sizeY=endCoords.viewY-startCoords.viewY;if(startY+sizeY<0){startY=sizeY;}else if(startY<0){startY=0;}
-ctx.fillStyle=this.annotation_.fillStyle;ctx.fillRect(startCoords.viewX,startY,endCoords.viewX-startCoords.viewX,sizeY);}};return{RectAnnotationView:RectAnnotationView};});'use strict';tr.exportTo('tr.model',function(){function RectAnnotation(start,end){tr.model.Annotation.apply(this,arguments);this.startLocation_=start;this.endLocation_=end;this.fillStyle='rgba(255, 180, 0, 0.3)';}
-RectAnnotation.fromDict=function(dict){var args=dict.args;var startLoc=new tr.model.Location(args.start.xWorld,args.start.yComponents);var endLoc=new tr.model.Location(args.end.xWorld,args.end.yComponents);return new tr.model.RectAnnotation(startLoc,endLoc);}
-RectAnnotation.prototype={__proto__:tr.model.Annotation.prototype,get startLocation(){return this.startLocation_;},get endLocation(){return this.endLocation_;},toDict:function(){return{typeName:'rect',args:{start:this.startLocation.toDict(),end:this.endLocation.toDict()}};},createView_:function(viewport){return new tr.ui.annotations.RectAnnotationView(viewport,this);}};tr.model.Annotation.register(RectAnnotation,{typeName:'rect'});return{RectAnnotation:RectAnnotation};});'use strict';tr.exportTo('tr.ui.annotations',function(){function CommentBoxAnnotationView(viewport,annotation){this.viewport_=viewport;this.annotation_=annotation;this.textArea_=undefined;this.styleWidth=250;this.styleHeight=50;this.fontSize=10;this.rightOffset=50;this.topOffset=25;}
-CommentBoxAnnotationView.prototype={__proto__:tr.ui.annotations.AnnotationView.prototype,removeTextArea:function(){this.textArea_.parentNode.removeChild(this.textArea_);},draw:function(ctx){var coords=this.annotation_.location.toViewCoordinates(this.viewport_);if(coords.viewX<0){if(this.textArea_)
-this.textArea_.style.visibility='hidden';return;}
-if(!this.textArea_){this.textArea_=document.createElement('textarea');this.textArea_.style.position='absolute';this.textArea_.readOnly=true;this.textArea_.value=this.annotation_.text;this.textArea_.style.zIndex=1;ctx.canvas.parentNode.appendChild(this.textArea_);}
+if(yComponents.length===0)return;return new Location(xWorld,yComponents);};Location.prototype={get xWorld(){return this.xWorld_;},getContainingTrack(viewport){const containerToTrack=viewport.containerToTrackMap;for(const i in this.yComponents_){const yComponent=this.yComponents_[i];const track=containerToTrack.getTrackByStableId(yComponent.stableId);if(track!==undefined)return track;}},toViewCoordinates(viewport){const dt=viewport.currentDisplayTransform;const containerToTrack=viewport.containerToTrackMap;const viewX=dt.xWorldToView(this.xWorld_);let viewY=-1;for(const index in this.yComponents_){const yComponent=this.yComponents_[index];const track=containerToTrack.getTrackByStableId(yComponent.stableId);if(track!==undefined){const boundRect=track.getBoundingClientRect();viewY=yComponent.yPercentOffset*boundRect.height+boundRect.top;break;}}
+return{viewX,viewY};},toDict(){return{xWorld:this.xWorld_,yComponents:this.yComponents_};}};return{Location,};});'use strict';tr.exportTo('tr.ui.annotations',function(){function AnnotationView(viewport,annotation){}
+AnnotationView.prototype={draw(ctx){throw new Error('Not implemented');}};return{AnnotationView,};});'use strict';tr.exportTo('tr.ui.annotations',function(){function RectAnnotationView(viewport,annotation){this.viewport_=viewport;this.annotation_=annotation;}
+RectAnnotationView.prototype={__proto__:tr.ui.annotations.AnnotationView.prototype,draw(ctx){const dt=this.viewport_.currentDisplayTransform;const startCoords=this.annotation_.startLocation.toViewCoordinates(this.viewport_);const endCoords=this.annotation_.endLocation.toViewCoordinates(this.viewport_);let startY=startCoords.viewY-ctx.canvas.getBoundingClientRect().top;const sizeY=endCoords.viewY-startCoords.viewY;if(startY+sizeY<0){startY=sizeY;}else if(startY<0){startY=0;}
+ctx.fillStyle=this.annotation_.fillStyle;ctx.fillRect(startCoords.viewX,startY,endCoords.viewX-startCoords.viewX,sizeY);}};return{RectAnnotationView,};});'use strict';tr.exportTo('tr.model',function(){function RectAnnotation(start,end){tr.model.Annotation.apply(this,arguments);this.startLocation_=start;this.endLocation_=end;this.fillStyle='rgba(255, 180, 0, 0.3)';}
+RectAnnotation.fromDict=function(dict){const args=dict.args;const startLoc=new tr.model.Location(args.start.xWorld,args.start.yComponents);const endLoc=new tr.model.Location(args.end.xWorld,args.end.yComponents);return new tr.model.RectAnnotation(startLoc,endLoc);};RectAnnotation.prototype={__proto__:tr.model.Annotation.prototype,get startLocation(){return this.startLocation_;},get endLocation(){return this.endLocation_;},toDict(){return{typeName:'rect',args:{start:this.startLocation.toDict(),end:this.endLocation.toDict()}};},createView_(viewport){return new tr.ui.annotations.RectAnnotationView(viewport,this);}};tr.model.Annotation.register(RectAnnotation,{typeName:'rect'});return{RectAnnotation,};});'use strict';tr.exportTo('tr.ui.annotations',function(){function CommentBoxAnnotationView(viewport,annotation){this.viewport_=viewport;this.annotation_=annotation;this.textArea_=undefined;this.styleWidth=250;this.styleHeight=50;this.fontSize=10;this.rightOffset=50;this.topOffset=25;}
+CommentBoxAnnotationView.prototype={__proto__:tr.ui.annotations.AnnotationView.prototype,removeTextArea(){Polymer.dom(Polymer.dom(this.textArea_).parentNode).removeChild(this.textArea_);},draw(ctx){const coords=this.annotation_.location.toViewCoordinates(this.viewport_);if(coords.viewX<0){if(this.textArea_){this.textArea_.style.visibility='hidden';}
+return;}
+if(!this.textArea_){this.textArea_=document.createElement('textarea');this.textArea_.style.position='absolute';this.textArea_.readOnly=true;this.textArea_.value=this.annotation_.text;this.textArea_.style.zIndex=1;Polymer.dom(Polymer.dom(ctx.canvas).parentNode).appendChild(this.textArea_);}
 this.textArea_.style.width=this.styleWidth+'px';this.textArea_.style.height=this.styleHeight+'px';this.textArea_.style.fontSize=this.fontSize+'px';this.textArea_.style.visibility='visible';this.textArea_.style.left=coords.viewX+ctx.canvas.getBoundingClientRect().left+
 this.rightOffset+'px';this.textArea_.style.top=coords.viewY-ctx.canvas.getBoundingClientRect().top-
 this.topOffset+'px';ctx.strokeStyle='rgb(0, 0, 0)';ctx.lineWidth=2;ctx.beginPath();tr.ui.b.drawLine(ctx,coords.viewX,coords.viewY-ctx.canvas.getBoundingClientRect().top,coords.viewX+this.rightOffset,coords.viewY-this.topOffset-
-ctx.canvas.getBoundingClientRect().top);ctx.stroke();}};return{CommentBoxAnnotationView:CommentBoxAnnotationView};});'use strict';tr.exportTo('tr.model',function(){function CommentBoxAnnotation(location,text){tr.model.Annotation.apply(this,arguments);this.location=location;this.text=text;}
-CommentBoxAnnotation.fromDict=function(dict){var args=dict.args;var location=new tr.model.Location(args.location.xWorld,args.location.yComponents);return new tr.model.CommentBoxAnnotation(location,args.text);};CommentBoxAnnotation.prototype={__proto__:tr.model.Annotation.prototype,onRemove:function(){this.view_.removeTextArea();},toDict:function(){return{typeName:'comment_box',args:{text:this.text,location:this.location.toDict()}};},createView_:function(viewport){return new tr.ui.annotations.CommentBoxAnnotationView(viewport,this);}};tr.model.Annotation.register(CommentBoxAnnotation,{typeName:'comment_box'});return{CommentBoxAnnotation:CommentBoxAnnotation};});'use strict';tr.exportTo('tr.model',function(){function HeapEntry(heapDump,leafStackFrame,objectTypeName,size){this.heapDump=heapDump;this.leafStackFrame=leafStackFrame;this.objectTypeName=objectTypeName;this.size=size;}
-function HeapDump(processMemoryDump,allocatorName){this.processMemoryDump=processMemoryDump;this.allocatorName=allocatorName;this.entries=[];}
-HeapDump.prototype={addEntry:function(leafStackFrame,objectTypeName,size){var entry=new HeapEntry(this,leafStackFrame,objectTypeName,size);this.entries.push(entry);return entry;}};return{HeapEntry:HeapEntry,HeapDump:HeapDump};});'use strict';tr.exportTo('tr.model',function(){function ScopedId(scope,id){if(scope===undefined){throw new Error('Scope should be defined. Use \''+
+ctx.canvas.getBoundingClientRect().top);ctx.stroke();}};return{CommentBoxAnnotationView,};});'use strict';tr.exportTo('tr.model',function(){function CommentBoxAnnotation(location,text){tr.model.Annotation.apply(this,arguments);this.location=location;this.text=text;}
+CommentBoxAnnotation.fromDict=function(dict){const args=dict.args;const location=new tr.model.Location(args.location.xWorld,args.location.yComponents);return new tr.model.CommentBoxAnnotation(location,args.text);};CommentBoxAnnotation.prototype={__proto__:tr.model.Annotation.prototype,onRemove(){this.view_.removeTextArea();},toDict(){return{typeName:'comment_box',args:{text:this.text,location:this.location.toDict()}};},createView_(viewport){return new tr.ui.annotations.CommentBoxAnnotationView(viewport,this);}};tr.model.Annotation.register(CommentBoxAnnotation,{typeName:'comment_box'});return{CommentBoxAnnotation,};});'use strict';tr.exportTo('tr.model',function(){function ScopedId(scope,id,pid){if(scope===undefined){throw new Error('Scope should be defined. Use \''+
 tr.model.OBJECT_DEFAULT_SCOPE+'\' as the default scope.');}
-this.scope=scope;this.id=id;}
-ScopedId.prototype={toString:function(){return'{scope: '+this.scope+', id: '+this.id+'}';}};return{ScopedId:ScopedId};});'use strict';tr.exportTo('tr.ui.annotations',function(){function XMarkerAnnotationView(viewport,annotation){this.viewport_=viewport;this.annotation_=annotation;}
-XMarkerAnnotationView.prototype={__proto__:tr.ui.annotations.AnnotationView.prototype,draw:function(ctx){var dt=this.viewport_.currentDisplayTransform;var viewX=dt.xWorldToView(this.annotation_.timestamp);ctx.beginPath();tr.ui.b.drawLine(ctx,viewX,0,viewX,ctx.canvas.height);ctx.strokeStyle=this.annotation_.strokeStyle;ctx.stroke();}};return{XMarkerAnnotationView:XMarkerAnnotationView};});'use strict';tr.exportTo('tr.model',function(){function XMarkerAnnotation(timestamp){tr.model.Annotation.apply(this,arguments);this.timestamp=timestamp;this.strokeStyle='rgba(0, 0, 255, 0.5)';}
-XMarkerAnnotation.fromDict=function(dict){return new XMarkerAnnotation(dict.args.timestamp);}
-XMarkerAnnotation.prototype={__proto__:tr.model.Annotation.prototype,toDict:function(){return{typeName:'xmarker',args:{timestamp:this.timestamp}};},createView_:function(viewport){return new tr.ui.annotations.XMarkerAnnotationView(viewport,this);}};tr.model.Annotation.register(XMarkerAnnotation,{typeName:'xmarker'});return{XMarkerAnnotation:XMarkerAnnotation};});'use strict';tr.exportTo('tr.e.importer',function(){var Base64=tr.b.Base64;var deepCopy=tr.b.deepCopy;var ColorScheme=tr.b.ColorScheme;function getEventColor(event,opt_customName){if(event.cname)
-return ColorScheme.getColorIdForReservedName(event.cname);else if(opt_customName||event.name){return ColorScheme.getColorIdForGeneralPurposeString(opt_customName||event.name);}}
-var timestampFromUs=tr.v.Unit.timestampFromUs;var maybeTimestampFromUs=tr.v.Unit.maybeTimestampFromUs;var PRODUCER='producer';var CONSUMER='consumer';var STEP='step';var LIGHT=tr.model.ContainerMemoryDump.LevelOfDetail.LIGHT;var DETAILED=tr.model.ContainerMemoryDump.LevelOfDetail.DETAILED;var MEMORY_DUMP_LEVEL_OF_DETAIL_ORDER=[undefined,LIGHT,DETAILED];var GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX='global/';var BYTE_STAT_NAME_MAP={'pc':'privateCleanResident','pd':'privateDirtyResident','sc':'sharedCleanResident','sd':'sharedDirtyResident','pss':'proportionalResident','sw':'swapped'};var WEAK_MEMORY_ALLOCATOR_DUMP_FLAG=1<<0;var OBJECT_TYPE_NAME_PATTERNS=[{prefix:'const char *WTF::getStringWithTypeName() [T = ',suffix:']'},{prefix:'const char* WTF::getStringWithTypeName() [with T = ',suffix:']'},{prefix:'const char *__cdecl WTF::getStringWithTypeName<',suffix:'>(void)'}];function TraceEventImporter(model,eventData){this.importPriority=1;this.model_=model;this.events_=undefined;this.sampleEvents_=undefined;this.stackFrameEvents_=undefined;this.systemTraceEvents_=undefined;this.battorData_=undefined;this.eventsWereFromString_=false;this.softwareMeasuredCpuCount_=undefined;this.allAsyncEvents_=[];this.allFlowEvents_=[];this.allObjectEvents_=[];this.traceEventSampleStackFramesByName_={};this.v8ProcessCodeMaps_={};this.v8ProcessRootStackFrame_={};this.v8SamplingData_=[];this.allMemoryDumpEvents_={};this.objectTypeNameMap_={};this.clockDomainId_=tr.model.ClockDomainId.TRACE_EVENT_IMPORTER;if(typeof(eventData)==='string'||eventData instanceof String){eventData=eventData.trim();if(eventData[0]==='['){eventData=eventData.replace(/\s*,\s*$/,'');if(eventData[eventData.length-1]!==']')
-eventData=eventData+']';}
+this.scope=scope;this.id=id;this.pid=pid;}
+ScopedId.prototype={toString(){const pidStr=this.pid===undefined?'':'pid: '+this.pid+', ';return'{'+pidStr+'scope: '+this.scope+', id: '+this.id+'}';},toStringWithDelimiter(delim){return(this.pid===undefined?'':this.pid)+delim+
+this.scope+delim+this.id;}};return{ScopedId,};});'use strict';tr.exportTo('tr.ui.annotations',function(){function XMarkerAnnotationView(viewport,annotation){this.viewport_=viewport;this.annotation_=annotation;}
+XMarkerAnnotationView.prototype={__proto__:tr.ui.annotations.AnnotationView.prototype,draw(ctx){const dt=this.viewport_.currentDisplayTransform;const viewX=dt.xWorldToView(this.annotation_.timestamp);ctx.beginPath();tr.ui.b.drawLine(ctx,viewX,0,viewX,ctx.canvas.height);ctx.strokeStyle=this.annotation_.strokeStyle;ctx.stroke();}};return{XMarkerAnnotationView,};});'use strict';tr.exportTo('tr.model',function(){function XMarkerAnnotation(timestamp){tr.model.Annotation.apply(this,arguments);this.timestamp=timestamp;this.strokeStyle='rgba(0, 0, 255, 0.5)';}
+XMarkerAnnotation.fromDict=function(dict){return new XMarkerAnnotation(dict.args.timestamp);};XMarkerAnnotation.prototype={__proto__:tr.model.Annotation.prototype,toDict(){return{typeName:'xmarker',args:{timestamp:this.timestamp}};},createView_(viewport){return new tr.ui.annotations.XMarkerAnnotationView(viewport,this);}};tr.model.Annotation.register(XMarkerAnnotation,{typeName:'xmarker'});return{XMarkerAnnotation,};});'use strict';tr.exportTo('tr.e.importer',function(){const Base64=tr.b.Base64;const deepCopy=tr.b.deepCopy;const ColorScheme=tr.b.ColorScheme;const HeapDumpTraceEventImporter=tr.e.importer.HeapDumpTraceEventImporter;const LegacyHeapDumpTraceEventImporter=tr.e.importer.LegacyHeapDumpTraceEventImporter;const StreamingEventExpander=tr.e.importer.StreamingEventExpander;const ProfilingDictionaryReader=tr.e.importer.ProfilingDictionaryReader;const MEASURE_NAME_REGEX=tr.e.measure.MEASURE_NAME_REGEX;function getEventColor(event,opt_customName){if(event.cname){return ColorScheme.getColorIdForReservedName(event.cname);}else if(opt_customName||event.name){return ColorScheme.getColorIdForGeneralPurposeString(opt_customName||event.name);}}
+function isLegacyChromeClockSyncEvent(event){return event.name!==undefined&&event.name.startsWith(LEGACY_CHROME_CLOCK_SYNC_EVENT_NAME_PREFIX)&&((event.ph==='S')||(event.ph==='F'));}
+const PRODUCER='producer';const CONSUMER='consumer';const STEP='step';const BACKGROUND=tr.model.ContainerMemoryDump.LevelOfDetail.BACKGROUND;const LIGHT=tr.model.ContainerMemoryDump.LevelOfDetail.LIGHT;const DETAILED=tr.model.ContainerMemoryDump.LevelOfDetail.DETAILED;const MEMORY_DUMP_LEVEL_OF_DETAIL_ORDER=[undefined,BACKGROUND,LIGHT,DETAILED];const GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX='global/';const LEGACY_CHROME_CLOCK_SYNC_EVENT_NAME_PREFIX='ClockSyncEvent.';const BYTE_STAT_NAME_MAP={'pc':'privateCleanResident','pd':'privateDirtyResident','sc':'sharedCleanResident','sd':'sharedDirtyResident','pss':'proportionalResident','sw':'swapped'};const WEAK_MEMORY_ALLOCATOR_DUMP_FLAG=1<<0;const OBJECT_TYPE_NAME_PATTERNS=[{prefix:'const char *WTF::getStringWithTypeName() [T = ',suffix:']'},{prefix:'const char* WTF::getStringWithTypeName() [with T = ',suffix:']'},{prefix:'const char *__cdecl WTF::getStringWithTypeName<',suffix:'>(void)'}];const SUBTRACE_FIELDS=new Set(['powerTraceAsString','systemTraceEvents','androidProcessDump',]);const NON_METADATA_FIELDS=new Set(['displayTimeUnit','samples','stackFrames','traceAnnotations','traceEvents',...SUBTRACE_FIELDS]);function TraceEventImporter(model,eventData){this.hasEvents_=undefined;this.importPriority=1;this.model_=model;this.events_=undefined;this.sampleEvents_=undefined;this.stackFrameEvents_=undefined;this.stackFrameTree_=new tr.model.ProfileTree();this.subtraces_=[];this.eventsWereFromString_=false;this.softwareMeasuredCpuCount_=undefined;this.allAsyncEvents_=[];this.allFlowEvents_=[];this.allObjectEvents_=[];this.contextProcessorPerThread={};this.traceEventSampleStackFramesByName_={};this.v8ProcessCodeMaps_={};this.v8ProcessRootStackFrame_={};this.v8SamplingData_=[];this.profileTrees_=new Map();this.profileInfo_=new Map();this.legacyChromeClockSyncStartEvent_=undefined;this.legacyChromeClockSyncFinishEvent_=undefined;this.allMemoryDumpEvents_={};this.heapProfileExpander=new ProfilingDictionaryReader();this.objectTypeNameMap_={};this.clockDomainId_=tr.model.ClockDomainId.UNKNOWN_CHROME_LEGACY;this.toModelTime_=undefined;if(typeof(eventData)==='string'||eventData instanceof String){eventData=eventData.trim();if(eventData[0]==='['){eventData=eventData.replace(/\s*,\s*$/,'');if(eventData[eventData.length-1]!==']'){eventData=eventData+']';}}
 this.events_=JSON.parse(eventData);this.eventsWereFromString_=true;}else{this.events_=eventData;}
-this.traceAnnotations_=this.events_.traceAnnotations;if(this.events_.traceEvents){var container=this.events_;this.events_=this.events_.traceEvents;this.systemTraceEvents_=container.systemTraceEvents;this.battorData_=container.powerTraceAsString;this.sampleEvents_=container.samples;this.stackFrameEvents_=container.stackFrames;if(container.displayTimeUnit){var unitName=container.displayTimeUnit;var unit=tr.v.TimeDisplayModes[unitName];if(unit===undefined){throw new Error('Unit '+unitName+' is not supported.');}
-this.model_.intrinsicTimeUnit=unit;}
-var knownFieldNames={powerTraceAsString:true,samples:true,stackFrames:true,systemTraceEvents:true,traceAnnotations:true,traceEvents:true};for(var fieldName in container){if(fieldName in knownFieldNames)
-continue;this.model_.metadata.push({name:fieldName,value:container[fieldName]});if(fieldName==='metadata'){var metadata=container[fieldName];if(metadata['highres-ticks'])
-this.model_.isTimeHighResolution=metadata['highres-ticks'];if(metadata['clock-domain'])
-this.clockDomainId_=metadata['clock-domain'];}}}}
-TraceEventImporter.canImport=function(eventData){if(typeof(eventData)==='string'||eventData instanceof String){eventData=eventData.trim();return eventData[0]==='{'||eventData[0]==='[';}
-if(eventData instanceof Array&&eventData.length&&eventData[0].ph)
-return true;if(eventData.traceEvents){if(eventData.traceEvents instanceof Array){if(eventData.traceEvents.length&&eventData.traceEvents[0].ph)
-return true;if(eventData.samples.length&&eventData.stackFrames!==undefined)
-return true;}}
-return false;};TraceEventImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'TraceEventImporter';},extractSubtraces:function(){var systemEventsTmp=this.systemTraceEvents_;var battorDataTmp=this.battorData_;this.systemTraceEvents_=undefined;this.battorData_=undefined;var subTraces=systemEventsTmp?[systemEventsTmp]:[];if(battorDataTmp)
-subTraces.push(battorDataTmp);return subTraces;},deepCopyIfNeeded_:function(obj){if(obj===undefined)
-obj={};if(this.eventsWereFromString_)
-return obj;return deepCopy(obj);},deepCopyAlways_:function(obj){if(obj===undefined)
-obj={};return deepCopy(obj);},processAsyncEvent:function(event){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.allAsyncEvents_.push({sequenceNumber:this.allAsyncEvents_.length,event:event,thread:thread});},processFlowEvent:function(event,opt_slice){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.allFlowEvents_.push({refGuid:tr.b.GUID.getLastGuid(),sequenceNumber:this.allFlowEvents_.length,event:event,slice:opt_slice,thread:thread});},processCounterEvent:function(event){var ctr_name;if(event.id!==undefined)
-ctr_name=event.name+'['+event.id+']';else
-ctr_name=event.name;var ctr=this.model_.getOrCreateProcess(event.pid).getOrCreateCounter(event.cat,ctr_name);var reservedColorId=event.cname?getEventColor(event):undefined;if(ctr.numSeries===0){for(var seriesName in event.args){var colorId=reservedColorId||getEventColor(event,ctr.name+'.'+seriesName);ctr.addSeries(new tr.model.CounterSeries(seriesName,colorId));}
+if(this.events_.traceEvents){const container=this.events_;this.events_=this.events_.traceEvents;for(const subtraceField of SUBTRACE_FIELDS){if(container[subtraceField]){this.storeSubtrace_(container[subtraceField]);}}
+this.storeSamples_(container.samples);this.storeStackFrames_(container.stackFrames);this.storeDisplayTimeUnit_(container.displayTimeUnit);this.storeTraceAnnotations_(container.traceAnnotations);this.storeMetadata_(container);}else if(this.events_ instanceof tr.b.TraceStream){const parser=oboe().node('{cat ph}',function(e){return oboe.drop;}).node('!.powerTraceAsString',this.storeSubtrace_.bind(this)).node('!.systemTraceEvents',this.storeSubtrace_.bind(this)).node('!.samples',this.storeSamples_.bind(this)).node('!.stackFrames',this.storeStackFrames_.bind(this)).node('!.displayTimeUnit',this.storeDisplayTimeUnit_.bind(this)).node('!.traceAnnotations',this.storeTraceAnnotations_.bind(this)).done(this.storeMetadata_.bind(this));this.events_.rewind();while(this.events_.hasData){parser.write(this.events_.readNumBytes());}
+parser.finish();}}
+TraceEventImporter.canImport=function(eventData){if(eventData instanceof tr.b.TraceStream){if(eventData.isBinary)return false;eventData=eventData.header;}
+if(typeof(eventData)==='string'||eventData instanceof String){eventData=eventData.trim();return eventData[0]==='{'||eventData[0]==='[';}
+if(eventData instanceof Array&&eventData.length&&eventData[0].ph){return true;}
+if(eventData.traceEvents){if(eventData.traceEvents instanceof Array){if(eventData.traceEvents.length&&eventData.traceEvents[0].ph){return true;}
+if(eventData.samples&&eventData.samples.length&&eventData.stackFrames!==undefined){return true;}}}
+return false;};TraceEventImporter.scopedIdForEvent_=function(event){const scope=event.scope||tr.model.OBJECT_DEFAULT_SCOPE;let pid=undefined;if(event.id!==undefined){if(event.id2!==undefined){throw new Error('Event has both id and id2');}
+pid=tr.model.LOCAL_ID_PHASES.has(event.ph)?event.pid:undefined;return new tr.model.ScopedId(scope,event.id,pid);}else if(event.id2!==undefined){if(event.id2.global!==undefined){return new tr.model.ScopedId(scope,event.id2.global);}else if(event.id2.local!==undefined){return new tr.model.ScopedId(scope,event.id2.local,event.pid);}
+throw new Error('Event that uses id2 must have either a global or local ID');}
+return undefined;};TraceEventImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'TraceEventImporter';},extractSubtraces(){const subtraces=this.subtraces_;this.subtraces_=[];return subtraces;},deepCopyIfNeeded_(obj){if(obj===undefined)obj={};if(this.eventsWereFromString_)return obj;return deepCopy(obj);},deepCopyAlways_(obj){if(obj===undefined)obj={};return deepCopy(obj);},processAsyncEvent(event){const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.allAsyncEvents_.push({sequenceNumber:this.allAsyncEvents_.length,event,thread});},processFlowEvent(event,opt_slice){const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.allFlowEvents_.push({refGuid:tr.b.GUID.getLastSimpleGuid(),sequenceNumber:this.allFlowEvents_.length,event,slice:opt_slice,thread});},processCounterEvent(event){let ctrName;if(event.id!==undefined){ctrName=event.name+'['+event.id+']';}else{ctrName=event.name;}
+const ctr=this.model_.getOrCreateProcess(event.pid).getOrCreateCounter(event.cat,ctrName);const reservedColorId=event.cname?getEventColor(event):undefined;if(ctr.numSeries===0){for(const seriesName in event.args){const colorId=reservedColorId||getEventColor(event,ctr.name+'.'+seriesName);ctr.addSeries(new tr.model.CounterSeries(seriesName,colorId));}
 if(ctr.numSeries===0){this.model_.importWarning({type:'counter_parse_error',message:'Expected counter '+event.name+' to have at least one argument to use as a value.'});delete ctr.parent.counters[ctr.name];return;}}
-var ts=timestampFromUs(event.ts);ctr.series.forEach(function(series){var val=event.args[series.name]?event.args[series.name]:0;series.addCounterSample(ts,val);});},processObjectEvent:function(event){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.allObjectEvents_.push({sequenceNumber:this.allObjectEvents_.length,event:event,thread:thread});},processDurationEvent:function(event){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);var ts=timestampFromUs(event.ts);if(!thread.sliceGroup.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'duration_parse_error',message:'Timestamps are moving backward.'});return;}
-if(event.ph==='B'){var slice=thread.sliceGroup.beginSlice(event.cat,event.name,timestampFromUs(event.ts),this.deepCopyIfNeeded_(event.args),timestampFromUs(event.tts),event.argsStripped,getEventColor(event));slice.startStackFrame=this.getStackFrameForEvent_(event);}else if(event.ph==='I'||event.ph==='i'||event.ph==='R'){if(event.s!==undefined&&event.s!=='t')
-throw new Error('This should never happen');thread.sliceGroup.beginSlice(event.cat,event.name,timestampFromUs(event.ts),this.deepCopyIfNeeded_(event.args),timestampFromUs(event.tts),event.argsStripped,getEventColor(event));var slice=thread.sliceGroup.endSlice(timestampFromUs(event.ts),timestampFromUs(event.tts));slice.startStackFrame=this.getStackFrameForEvent_(event);slice.endStackFrame=undefined;}else{if(!thread.sliceGroup.openSliceCount){this.model_.importWarning({type:'duration_parse_error',message:'E phase event without a matching B phase event.'});return;}
-var slice=thread.sliceGroup.endSlice(timestampFromUs(event.ts),timestampFromUs(event.tts),getEventColor(event));if(event.name&&slice.title!=event.name){this.model_.importWarning({type:'title_match_error',message:'Titles do not match. Title is '+
+const ts=this.toModelTimeFromUs_(event.ts);ctr.series.forEach(function(series){const val=event.args[series.name]?event.args[series.name]:0;series.addCounterSample(ts,val);});},processObjectEvent(event){const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.allObjectEvents_.push({sequenceNumber:this.allObjectEvents_.length,event,thread});if(thread.guid in this.contextProcessorPerThread){const processor=this.contextProcessorPerThread[thread.guid];const scopedId=TraceEventImporter.scopedIdForEvent_(event);if(event.ph==='D'){processor.destroyContext(scopedId);}
+processor.invalidateContextCacheForSnapshot(scopedId);}},processContextEvent(event){const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);if(!(thread.guid in this.contextProcessorPerThread)){this.contextProcessorPerThread[thread.guid]=new tr.importer.ContextProcessor(this.model_);}
+const scopedId=TraceEventImporter.scopedIdForEvent_(event);const contextType=event.name;const processor=this.contextProcessorPerThread[thread.guid];if(event.ph==='('){processor.enterContext(contextType,scopedId);}else if(event.ph===')'){processor.leaveContext(contextType,scopedId);}else{this.model_.importWarning({type:'unknown_context_phase',message:'Unknown context event phase: '+event.ph+'.'});}},setContextsFromThread_(thread,slice){if(thread.guid in this.contextProcessorPerThread){slice.contexts=this.contextProcessorPerThread[thread.guid].activeContexts;}},processDurationEvent(event){const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);const ts=this.toModelTimeFromUs_(event.ts);if(event.dur===0&&!thread.sliceGroup.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'duration_parse_error',message:'Timestamps are moving backward.'});return;}
+if(event.ph==='B'){const slice=thread.sliceGroup.beginSlice(event.cat,event.name,this.toModelTimeFromUs_(event.ts),this.deepCopyIfNeeded_(event.args),this.toModelTimeFromUs_(event.tts),event.argsStripped,getEventColor(event),event.bind_id);slice.startStackFrame=this.getStackFrameForEvent_(event);this.setContextsFromThread_(thread,slice);}else if(event.ph==='I'||event.ph==='i'||event.ph==='R'){if(event.s!==undefined&&event.s!=='t'){throw new Error('This should never happen');}
+thread.sliceGroup.beginSlice(event.cat,event.name,this.toModelTimeFromUs_(event.ts),this.deepCopyIfNeeded_(event.args),this.toModelTimeFromUs_(event.tts),event.argsStripped,getEventColor(event),event.bind_id);const slice=thread.sliceGroup.endSlice(this.toModelTimeFromUs_(event.ts),this.toModelTimeFromUs_(event.tts));slice.startStackFrame=this.getStackFrameForEvent_(event);slice.endStackFrame=undefined;}else{if(!thread.sliceGroup.openSliceCount){this.model_.importWarning({type:'duration_parse_error',message:'E phase event without a matching B phase event.'});return;}
+const slice=thread.sliceGroup.endSlice(this.toModelTimeFromUs_(event.ts),this.toModelTimeFromUs_(event.tts),getEventColor(event));if(event.name&&slice.title!==event.name){this.model_.importWarning({type:'title_match_error',message:'Titles do not match. Title is '+
 slice.title+' in openSlice, and is '+
 event.name+' in endSlice'});}
-slice.endStackFrame=this.getStackFrameForEvent_(event);this.mergeArgsInto_(slice.args,event.args,slice.title);}},mergeArgsInto_:function(dstArgs,srcArgs,eventName){for(var arg in srcArgs){if(dstArgs[arg]!==undefined){this.model_.importWarning({type:'arg_merge_error',message:'Different phases of '+eventName+' provided values for argument '+arg+'.'+' The last provided value will be used.'});}
-dstArgs[arg]=this.deepCopyIfNeeded_(srcArgs[arg]);}},processCompleteEvent:function(event){if(event.cat!==undefined&&event.cat.indexOf('trace_event_overhead')>-1)
-return undefined;var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);if(event.flow_out){if(event.flow_in)
-event.flowPhase=STEP;else
-event.flowPhase=PRODUCER;}else if(event.flow_in){event.flowPhase=CONSUMER;}
-var slice=thread.sliceGroup.pushCompleteSlice(event.cat,event.name,timestampFromUs(event.ts),maybeTimestampFromUs(event.dur),maybeTimestampFromUs(event.tts),maybeTimestampFromUs(event.tdur),this.deepCopyIfNeeded_(event.args),event.argsStripped,getEventColor(event),event.bind_id);slice.startStackFrame=this.getStackFrameForEvent_(event);slice.endStackFrame=this.getStackFrameForEvent_(event,true);return slice;},processJitCodeEvent:function(event){if(this.v8ProcessCodeMaps_[event.pid]===undefined)
-this.v8ProcessCodeMaps_[event.pid]=new tr.e.importer.TraceCodeMap();var map=this.v8ProcessCodeMaps_[event.pid];var data=event.args.data;if(event.name==='JitCodeMoved')
-map.moveEntry(data.code_start,data.new_code_start,data.code_len);else
-map.addEntry(data.code_start,data.code_len,data.name,data.script_id);},processMetadataEvent:function(event){if(event.name==='JitCodeAdded'||event.name==='JitCodeMoved'){this.v8SamplingData_.push(event);return;}
-if(event.argsStripped)
-return;if(event.name==='process_name'){var process=this.model_.getOrCreateProcess(event.pid);process.name=event.args.name;}else if(event.name==='process_labels'){var process=this.model_.getOrCreateProcess(event.pid);var labels=event.args.labels.split(',');for(var i=0;i<labels.length;i++)
-process.addLabelIfNeeded(labels[i]);}else if(event.name==='process_sort_index'){var process=this.model_.getOrCreateProcess(event.pid);process.sortIndex=event.args.sort_index;}else if(event.name==='thread_name'){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);thread.name=event.args.name;}else if(event.name==='thread_sort_index'){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);thread.sortIndex=event.args.sort_index;}else if(event.name==='num_cpus'){var n=event.args.number;if(this.softwareMeasuredCpuCount_!==undefined)
-n=Math.max(n,this.softwareMeasuredCpuCount_);this.softwareMeasuredCpuCount_=n;}else if(event.name==='stackFrames'){var stackFrames=event.args.stackFrames;if(stackFrames===undefined){this.model_.importWarning({type:'metadata_parse_error',message:'No stack frames found in a \''+event.name+'\' metadata event'});}else{this.importStackFrames_(stackFrames,'p'+event.pid+':');}}else if(event.name==='typeNames'){var objectTypeNameMap=event.args.typeNames;if(objectTypeNameMap===undefined){this.model_.importWarning({type:'metadata_parse_error',message:'No mapping from object type IDs to names found in a \''+
-event.name+'\' metadata event'});}else{this.importObjectTypeNameMap_(objectTypeNameMap,event.pid);}}else{this.model_.importWarning({type:'metadata_parse_error',message:'Unrecognized metadata name: '+event.name});}},processInstantEvent:function(event){if(event.name==='JitCodeAdded'||event.name==='JitCodeMoved'){this.v8SamplingData_.push(event);return;}
+slice.endStackFrame=this.getStackFrameForEvent_(event);this.mergeArgsInto_(slice.args,event.args,slice.title);}},mergeArgsInto_(dstArgs,srcArgs,eventName){for(const arg in srcArgs){if(dstArgs[arg]!==undefined){this.model_.importWarning({type:'arg_merge_error',message:'Different phases of '+eventName+' provided values for argument '+arg+'.'+' The last provided value will be used.'});}
+dstArgs[arg]=this.deepCopyIfNeeded_(srcArgs[arg]);}},processCompleteEvent(event){if(event.cat!==undefined&&event.cat.indexOf('trace_event_overhead')>-1){return undefined;}
+const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);if(event.flow_out){if(event.flow_in){event.flowPhase=STEP;}else{event.flowPhase=PRODUCER;}}else if(event.flow_in){event.flowPhase=CONSUMER;}
+const slice=thread.sliceGroup.pushCompleteSlice(event.cat,event.name,this.toModelTimeFromUs_(event.ts),this.maybeToModelTimeFromUs_(event.dur),this.maybeToModelTimeFromUs_(event.tts),this.maybeToModelTimeFromUs_(event.tdur),this.deepCopyIfNeeded_(event.args),event.argsStripped,getEventColor(event),event.bind_id);slice.startStackFrame=this.getStackFrameForEvent_(event);slice.endStackFrame=this.getStackFrameForEvent_(event,true);this.setContextsFromThread_(thread,slice);return slice;},processJitCodeEvent(event){if(this.v8ProcessCodeMaps_[event.pid]===undefined){this.v8ProcessCodeMaps_[event.pid]=new tr.e.importer.TraceCodeMap();}
+const map=this.v8ProcessCodeMaps_[event.pid];const data=event.args.data;if(event.name==='JitCodeMoved'){map.moveEntry(data.code_start,data.new_code_start,data.code_len);}else{map.addEntry(data.code_start,data.code_len,data.name,data.script_id);}},processMetadataEvent(event){if(event.name==='JitCodeAdded'||event.name==='JitCodeMoved'){this.v8SamplingData_.push(event);return;}
+if(event.argsStripped)return;if(event.name==='process_name'){const process=this.model_.getOrCreateProcess(event.pid);process.name=event.args.name;}else if(event.name==='process_labels'){const process=this.model_.getOrCreateProcess(event.pid);const labels=event.args.labels.split(',');for(let i=0;i<labels.length;i++){process.addLabelIfNeeded(labels[i]);}}else if(event.name==='process_uptime_seconds'){const process=this.model_.getOrCreateProcess(event.pid);process.uptime_seconds=event.args.uptime;}else if(event.name==='process_sort_index'){const process=this.model_.getOrCreateProcess(event.pid);process.sortIndex=event.args.sort_index;}else if(event.name==='thread_name'){const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);thread.name=event.args.name;}else if(event.name==='thread_sort_index'){const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);thread.sortIndex=event.args.sort_index;}else if(event.name==='num_cpus'){let n=event.args.number;if(this.softwareMeasuredCpuCount_!==undefined){n=Math.max(n,this.softwareMeasuredCpuCount_);}
+this.softwareMeasuredCpuCount_=n;}else if(event.name==='stackFrames'){const stackFrames=event.args.stackFrames;if(stackFrames===undefined){this.model_.importWarning({type:'metadata_parse_error',message:'No stack frames found in a \''+event.name+'\' metadata event'});}else{this.importStackFrames_(stackFrames,'p'+event.pid+':');}}else if(event.name==='typeNames'){const objectTypeNameMap=event.args.typeNames;if(objectTypeNameMap===undefined){this.model_.importWarning({type:'metadata_parse_error',message:'No mapping from object type IDs to names found in a \''+
+event.name+'\' metadata event'});}else{this.importObjectTypeNameMap_(objectTypeNameMap,event.pid);}}else if(event.name==='TraceConfig'){this.model_.metadata.push({name:'TraceConfig',value:event.args.value});}else{this.model_.importWarning({type:'metadata_parse_error',message:'Unrecognized metadata name: '+event.name});}},processInstantEvent(event){if(event.name==='JitCodeAdded'||event.name==='JitCodeMoved'){this.v8SamplingData_.push(event);return;}
 if(event.s==='t'||event.s===undefined){this.processDurationEvent(event);return;}
-var constructor;switch(event.s){case'g':constructor=tr.model.GlobalInstantEvent;break;case'p':constructor=tr.model.ProcessInstantEvent;break;default:this.model_.importWarning({type:'instant_parse_error',message:'I phase event with unknown "s" field value.'});return;}
-var instantEvent=new constructor(event.cat,event.name,getEventColor(event),timestampFromUs(event.ts),this.deepCopyIfNeeded_(event.args));switch(instantEvent.type){case tr.model.InstantEventType.GLOBAL:this.model_.instantEvents.push(instantEvent);break;case tr.model.InstantEventType.PROCESS:var process=this.model_.getOrCreateProcess(event.pid);process.instantEvents.push(instantEvent);break;default:throw new Error('Unknown instant event type: '+event.s);}},processV8Sample:function(event){var data=event.args.data;if(data.vm_state==='js'&&!data.stack.length)
-return;var rootStackFrame=this.v8ProcessRootStackFrame_[event.pid];if(!rootStackFrame){rootStackFrame=new tr.model.StackFrame(undefined,'v8-root-stack-frame','v8-root-stack-frame',0);this.v8ProcessRootStackFrame_[event.pid]=rootStackFrame;}
-function findChildWithEntryID(stackFrame,entryID){return tr.b.findFirstInArray(stackFrame.children,function(child){return child.entryID===entryID;});}
-var model=this.model_;function addStackFrame(lastStackFrame,entry){var childFrame=findChildWithEntryID(lastStackFrame,entry.id);if(childFrame)
-return childFrame;var frame=new tr.model.StackFrame(lastStackFrame,tr.b.GUID.allocate(),entry.name,ColorScheme.getColorIdForGeneralPurposeString(entry.name),entry.sourceInfo);frame.entryID=entry.id;model.addStackFrame(frame);return frame;}
-var lastStackFrame=rootStackFrame;if(data.stack.length>0&&this.v8ProcessCodeMaps_[event.pid]){var map=this.v8ProcessCodeMaps_[event.pid];data.stack.reverse();for(var i=0;i<data.stack.length;i++){var entry=map.lookupEntry(data.stack[i]);if(entry===undefined){entry={id:'unknown',name:'unknown',sourceInfo:undefined};}
-lastStackFrame=addStackFrame(lastStackFrame,entry);}}else{var entry={id:data.vm_state,name:data.vm_state,sourceInfo:undefined};lastStackFrame=addStackFrame(lastStackFrame,entry);}
-var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);var sample=new tr.model.Sample(undefined,thread,'V8 Sample',timestampFromUs(event.ts),lastStackFrame,1,this.deepCopyIfNeeded_(event.args));this.model_.samples.push(sample);},processTraceSampleEvent:function(event){if(event.name==='V8Sample'){this.v8SamplingData_.push(event);return;}
-var stackFrame=this.getStackFrameForEvent_(event);if(stackFrame===undefined){stackFrame=this.traceEventSampleStackFramesByName_[event.name];}
-if(stackFrame===undefined){var id='te-'+tr.b.GUID.allocate();stackFrame=new tr.model.StackFrame(undefined,id,event.name,ColorScheme.getColorIdForGeneralPurposeString(event.name));this.model_.addStackFrame(stackFrame);this.traceEventSampleStackFramesByName_[event.name]=stackFrame;}
-var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);var sample=new tr.model.Sample(undefined,thread,'Trace Event Sample',timestampFromUs(event.ts),stackFrame,1,this.deepCopyIfNeeded_(event.args));this.model_.samples.push(sample);},processMemoryDumpEvent:function(event){if(event.ph!=='v')
-throw new Error('Invalid memory dump event phase "'+event.ph+'".');var dumpId=event.id;if(dumpId===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory dump event (phase \''+event.ph+'\') without a dump ID.'});return;}
-var pid=event.pid;if(pid===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory dump event (phase\''+event.ph+'\', dump ID \''+
+let constructor;let parent;switch(event.s){case'g':constructor=tr.model.GlobalInstantEvent;parent=this.model_;break;case'p':constructor=tr.model.ProcessInstantEvent;parent=this.model_.getOrCreateProcess(event.pid);break;default:this.model_.importWarning({type:'instant_parse_error',message:'I phase event with unknown "s" field value.'});return;}
+const instantEvent=new constructor(event.cat,event.name,getEventColor(event),this.toModelTimeFromUs_(event.ts),this.deepCopyIfNeeded_(event.args),parent);parent.instantEvents.push(instantEvent);},getOrCreateProfileTree_(sampleType,id){if(!this.profileTrees_.has(sampleType)){this.profileTrees_.set(sampleType,new Map());}
+const profileTreeMap=this.profileTrees_.get(sampleType);if(profileTreeMap.has(id)){return profileTreeMap.get(id);}
+const profileTree=new tr.model.ProfileTree();profileTreeMap.set(id,profileTree);const info=this.profileInfo_.get(id);if(info!==undefined){profileTree.startTime=info.startTime;profileTree.pid=info.pid;profileTree.tid=info.tid;}
+return profileTree;},processSample(event){if(event.args===undefined||event.args.data===undefined){return;}
+if(event.id===undefined){throw new Error('No event ID in sample');}
+const data=event.args.data;if(data.startTime!==undefined){this.profileInfo_.set(event.id,{startTime:data.startTime,pid:event.pid,tid:event.tid});}
+const timeDeltas=data.timeDeltas;for(const sampleType in data){if(sampleType==='timeDeltas'||sampleType==='startTime'){continue;}
+if(data[sampleType].samples&&timeDeltas&&data[sampleType].samples.length!==timeDeltas.length){throw new Error('samples and timeDeltas array should have same length');}
+const profileTree=this.getOrCreateProfileTree_(sampleType,event.id);const nodes=data[sampleType].nodes;const samples=data[sampleType].samples;if(nodes!==undefined){for(const node of nodes){const ProfileNodeType=tr.model.ProfileNode.subTypes.getConstructor(undefined,sampleType);const profileNode=ProfileNodeType.constructFromObject(profileTree,node);if(profileNode===undefined){continue;}
+profileTree.add(profileNode);}}
+if(samples!==undefined){const thread=this.model_.getOrCreateProcess(profileTree.pid).getOrCreateThread(profileTree.tid);for(let i=0,len=samples.length;i<len;++i){const node=profileTree.getNode(samples[i]);profileTree.endTime+=timeDeltas[i];if(node===undefined)continue;const start=this.toModelTimeFromUs_(profileTree.endTime);this.model_.samples.push(new tr.model.Sample(start,node.sampleTitle,node,thread));}}}},processLegacyV8Sample(event){const data=event.args.data;const sampleType='legacySample';const ProfileNodeType=tr.model.ProfileNode.subTypes.getConstructor(undefined,sampleType);if(data.vm_state==='js'&&!data.stack.length)return;const profileTree=this.getOrCreateProfileTree_(sampleType,event.pid);if(profileTree.getNode(-1)===undefined){profileTree.add(new ProfileNodeType(-1,{url:'',scriptId:-1,functionName:'unknown'},undefined));}
+let node=undefined;if(data.stack.length>0&&this.v8ProcessCodeMaps_[event.pid]){const map=this.v8ProcessCodeMaps_[event.pid];data.stack.reverse();let parentNode=undefined;for(let i=0;i<data.stack.length;i++){const entry=map.lookupEntry(data.stack[i]);if(entry===undefined){node=profileTree.getNode(-1);}else{node=profileTree.getNode(entry.id);if(node===undefined){const sourceInfo=entry.sourceInfo;node=new ProfileNodeType(entry.id,{functionName:entry.name,url:entry.sourceInfo.file,lineNumber:sourceInfo.line!==-1?sourceInfo.line:undefined,columnNumber:sourceInfo.column!==-1?sourceInfo.column:undefined,scriptid:entry.sourceInfo.scriptId},parentNode);profileTree.add(node);}}
+parentNode=node;}}else{node=profileTree.getNode(data.vm_state);if(node===undefined){node=new ProfileNodeType(data.vm_state,{url:'',functionName:data.vm_state},undefined);profileTree.add(node);}}
+const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.model_.samples.push(new tr.model.Sample(this.toModelTimeFromUs_(event.ts),node.sampleTitle,node,thread));},processTraceSampleEvent(event){if(event.name==='V8Sample'||event.name.startsWith('Profile')){this.v8SamplingData_.push(event);return;}
+let node=this.stackFrameTree_.getNode(event.name);if(node===undefined&&event.sf!==undefined){node=this.stackFrameTree_.getNode('g'+event.sf);}
+if(node===undefined){let id=event.name;if(event.sf){id='g'+event.sf;}
+const ProfileNodeType=tr.model.ProfileNode.subTypes.getConstructor(undefined,'legacySample');node=this.stackFrameTree_.add(new ProfileNodeType(id,{functionName:event.name},undefined));}
+const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);const sample=new tr.model.Sample(this.toModelTimeFromUs_(event.ts),'Trace Event Sample',node,thread,undefined,1,this.deepCopyIfNeeded_(event.args));this.setContextsFromThread_(thread,sample);this.model_.samples.push(sample);},processMemoryDumpEvent(event){if(event.ph!=='v'){throw new Error('Invalid memory dump event phase "'+event.ph+'".');}
+const dumpId=event.id;if(dumpId===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory dump event (phase \''+event.ph+'\') without a dump ID.'});return;}
+const pid=event.pid;if(pid===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory dump event (phase\''+event.ph+'\', dump ID \''+
 dumpId+'\') without a PID.'});return;}
-var allEvents=this.allMemoryDumpEvents_;var dumpIdEvents=allEvents[dumpId];if(dumpIdEvents===undefined)
-allEvents[dumpId]=dumpIdEvents={};var processEvents=dumpIdEvents[pid];if(processEvents===undefined)
-dumpIdEvents[pid]=processEvents=[];processEvents.push(event);},processClockSyncEvent:function(event){if(event.ph!=='c')
-throw new Error('Invalid clock sync event phase "'+event.ph+'".');var syncId=event.args.sync_id;var issueStartTs=event.args.issue_ts;var issueEndTs=event.ts;if(syncId===undefined){this.model_.importWarning({type:'clock_sync_parse_error',message:'Clock sync at time '+issueEndTs+' without an ID.'});return;}
-if(issueStartTs===undefined){this.model_.importWarning({type:'clock_sync_parse_error',message:'Clock sync at time '+issueEndTs+' with ID '+syncId+' without a start timestamp.'});return;}
-this.model_.clockSyncManager.addClockSyncMarker(this.clockDomainId_,syncId,timestampFromUs(issueStartTs),timestampFromUs(issueEndTs-issueStartTs));this.model_.clockSyncRecords.push(new tr.model.PingPongClockSyncRecord(syncId,timestampFromUs(issueStartTs),timestampFromUs(issueEndTs-issueStartTs)));},processV8Events:function(){this.v8SamplingData_.sort(function(a,b){if(a.ts!==b.ts)
-return a.ts-b.ts;if(a.ph==='M'||a.ph==='I')
-return-1;else if(b.ph==='M'||b.ph==='I')
-return 1;return 0;});var length=this.v8SamplingData_.length;for(var i=0;i<length;++i){var event=this.v8SamplingData_[i];if(event.ph==='M'||event.ph==='I'){this.processJitCodeEvent(event);}else if(event.ph==='P'){this.processV8Sample(event);}}},importClockSyncMarkers:function(){this.model_.clockSyncRecords.push(new tr.model.InstantClockSyncRecord('ftrace_importer',0,{}));for(var i=0;i<this.events_.length;i++){var event=this.events_[i];if(event.ph!=='c')
-continue;var eventSizeInBytes=this.model_.importOptions.trackDetailedModelStats?JSON.stringify(event).length:undefined;this.model_.stats.willProcessBasicTraceEvent('clock_sync',event.cat,event.name,event.ts,eventSizeInBytes);this.processClockSyncEvent(event);}},importEvents:function(){if(this.stackFrameEvents_)
-this.importStackFrames_(this.stackFrameEvents_,'g');if(this.traceAnnotations_)
-this.importAnnotations_();var importOptions=this.model_.importOptions;var trackDetailedModelStats=importOptions.trackDetailedModelStats;var modelStats=this.model_.stats;var events=this.events_;for(var eI=0;eI<events.length;eI++){var event=events[eI];if(event.args==='__stripped__'){event.argsStripped=true;event.args=undefined;}
-var eventSizeInBytes;if(trackDetailedModelStats)
-eventSizeInBytes=JSON.stringify(event).length;else
-eventSizeInBytes=undefined;if(event.ph==='B'||event.ph==='E'){modelStats.willProcessBasicTraceEvent('begin_end (non-compact)',event.cat,event.name,event.ts,eventSizeInBytes);this.processDurationEvent(event);}else if(event.ph==='X'){modelStats.willProcessBasicTraceEvent('begin_end (compact)',event.cat,event.name,event.ts,eventSizeInBytes);var slice=this.processCompleteEvent(event);if(slice!==undefined&&event.bind_id!==undefined)
-this.processFlowEvent(event,slice);}else if(event.ph==='b'||event.ph==='e'||event.ph==='n'||event.ph==='S'||event.ph==='F'||event.ph==='T'||event.ph==='p'){modelStats.willProcessBasicTraceEvent('async',event.cat,event.name,event.ts,eventSizeInBytes);this.processAsyncEvent(event);}else if(event.ph==='I'||event.ph==='i'||event.ph==='R'){modelStats.willProcessBasicTraceEvent('instant',event.cat,event.name,event.ts,eventSizeInBytes);this.processInstantEvent(event);}else if(event.ph==='P'){modelStats.willProcessBasicTraceEvent('samples',event.cat,event.name,event.ts,eventSizeInBytes);this.processTraceSampleEvent(event);}else if(event.ph==='C'){modelStats.willProcessBasicTraceEvent('counters',event.cat,event.name,event.ts,eventSizeInBytes);this.processCounterEvent(event);}else if(event.ph==='M'){modelStats.willProcessBasicTraceEvent('metadata',event.cat,event.name,event.ts,eventSizeInBytes);this.processMetadataEvent(event);}else if(event.ph==='N'||event.ph==='D'||event.ph==='O'){modelStats.willProcessBasicTraceEvent('objects',event.cat,event.name,event.ts,eventSizeInBytes);this.processObjectEvent(event);}else if(event.ph==='s'||event.ph==='t'||event.ph==='f'){modelStats.willProcessBasicTraceEvent('flows',event.cat,event.name,event.ts,eventSizeInBytes);this.processFlowEvent(event);}else if(event.ph==='v'){modelStats.willProcessBasicTraceEvent('memory_dumps',event.cat,event.name,event.ts,eventSizeInBytes);this.processMemoryDumpEvent(event);}else if(event.ph==='c'){}else{modelStats.willProcessBasicTraceEvent('unknown',event.cat,event.name,event.ts,eventSizeInBytes);this.model_.importWarning({type:'parse_error',message:'Unrecognized event phase: '+
-event.ph+' ('+event.name+')'});}}
-this.processV8Events();tr.b.iterItems(this.v8ProcessRootStackFrame_,function(name,frame){frame.removeAllChildren();});},importStackFrames_:function(rawStackFrames,idPrefix){var model=this.model_;for(var id in rawStackFrames){var rawStackFrame=rawStackFrames[id];var fullId=idPrefix+id;var textForColor=rawStackFrame.category?rawStackFrame.category:rawStackFrame.name;var stackFrame=new tr.model.StackFrame(undefined,fullId,rawStackFrame.name,ColorScheme.getColorIdForGeneralPurposeString(textForColor));model.addStackFrame(stackFrame);}
-for(var id in rawStackFrames){var fullId=idPrefix+id;var stackFrame=model.stackFrames[fullId];if(stackFrame===undefined)
-throw new Error('Internal error');var rawStackFrame=rawStackFrames[id];var parentId=rawStackFrame.parent;var parentStackFrame;if(parentId===undefined){parentStackFrame=undefined;}else{var parentFullId=idPrefix+parentId;parentStackFrame=model.stackFrames[parentFullId];if(parentStackFrame===undefined){this.model_.importWarning({type:'metadata_parse_error',message:'Missing parent frame with ID '+parentFullId+' for stack frame \''+stackFrame.name+'\' (ID '+fullId+').'});}}
-stackFrame.parentFrame=parentStackFrame;}},importObjectTypeNameMap_:function(rawObjectTypeNameMap,pid){if(pid in this.objectTypeNameMap_){this.model_.importWarning({type:'metadata_parse_error',message:'Mapping from object type IDs to names provided for pid='+
+const allEvents=this.allMemoryDumpEvents_;let dumpIdEvents=allEvents[dumpId];if(dumpIdEvents===undefined){allEvents[dumpId]=dumpIdEvents={};}
+let processEvents=dumpIdEvents[pid];if(processEvents===undefined){dumpIdEvents[pid]=processEvents=[];}
+processEvents.push(event);},processClockSyncEvent(event){if(event.ph!=='c'){throw new Error('Invalid clock sync event phase "'+event.ph+'".');}
+const syncId=event.args.sync_id;if(syncId===undefined){this.model_.importWarning({type:'clock_sync_parse_error',message:'Clock sync at time '+event.ts+' without an ID.'});return;}
+if(event.args&&event.args.issue_ts!==undefined){this.model_.clockSyncManager.addClockSyncMarker(this.clockDomainId_,syncId,tr.b.Unit.timestampFromUs(event.args.issue_ts),tr.b.Unit.timestampFromUs(event.ts));}else{this.model_.clockSyncManager.addClockSyncMarker(this.clockDomainId_,syncId,tr.b.Unit.timestampFromUs(event.ts));}},processLegacyChromeClockSyncEvent(event){if(event.ph==='S'){this.legacyChromeClockSyncStartEvent_=event;}else if(event.ph==='F'){this.legacyChromeClockSyncFinishEvent_=event;}
+if(this.legacyChromeClockSyncStartEvent_===undefined||this.legacyChromeClockSyncFinishEvent_===undefined){return;}
+const startSyncId=this.legacyChromeClockSyncStartEvent_.name.substring(LEGACY_CHROME_CLOCK_SYNC_EVENT_NAME_PREFIX.length);const finishSyncId=this.legacyChromeClockSyncFinishEvent_.name.substring(LEGACY_CHROME_CLOCK_SYNC_EVENT_NAME_PREFIX.length);if(startSyncId!==finishSyncId){throw new Error('Inconsistent clock sync ID of legacy Chrome clock sync events');}
+this.model_.clockSyncManager.addClockSyncMarker(this.clockDomainId_,startSyncId,tr.b.Unit.timestampFromUs(this.legacyChromeClockSyncStartEvent_.ts),tr.b.Unit.timestampFromUs(this.legacyChromeClockSyncFinishEvent_.ts));},processV8Events(){this.v8SamplingData_.sort(function(a,b){if(a.ts!==b.ts)return a.ts-b.ts;if(a.ph==='M'||a.ph==='I'){return-1;}else if(b.ph==='M'||b.ph==='I'){return 1;}
+return 0;});const length=this.v8SamplingData_.length;for(let i=0;i<length;++i){const event=this.v8SamplingData_[i];if(event.ph==='M'||event.ph==='I'){this.processJitCodeEvent(event);}else if(event.ph==='P'){if(event.name.startsWith('Profile')){this.processSample(event);}else{this.processLegacyV8Sample(event);}}}},importClockSyncMarkers(){if(this.events_ instanceof tr.b.TraceStream){const parser=oboe().node('{cat ph}',this.importClockSyncMarker_.bind(this));this.events_.rewind();while(this.events_.hasData){parser.write(this.events_.readNumBytes());}
+parser.finish();}else{for(let i=0;i<this.events_.length;i++){this.importClockSyncMarker_(this.events_[i]);}}},importClockSyncMarker_(event){const isLegacyChromeClockSync=isLegacyChromeClockSyncEvent(event);if(event.ph!=='c'&&!isLegacyChromeClockSync)return;const eventSizeInBytes=this.model_.importOptions.trackDetailedModelStats?JSON.stringify(event).length:undefined;this.model_.stats.willProcessBasicTraceEvent('clock_sync',event.cat,event.name,event.ts,eventSizeInBytes);if(isLegacyChromeClockSync){this.processLegacyChromeClockSyncEvent(event);}else{this.processClockSyncEvent(event);}},importEvents(){this.hasEvents_=false;if(this.stackFrameEvents_){this.importStackFrames_(this.stackFrameEvents_,'g');}
+if(this.traceAnnotations_)this.importAnnotations_();if(this.events_ instanceof tr.b.TraceStream){const parser=oboe().node('{cat ph}',this.processEvent_.bind(this));this.events_.rewind();while(this.events_.hasData){parser.write(this.events_.readNumBytes());}
+parser.finish();}else{for(let eI=0;eI<this.events_.length;eI++){this.processEvent_(this.events_[eI]);}}
+this.createAsyncSlices_();this.processV8Events();for(const frame of Object.values(this.v8ProcessRootStackFrame_)){frame.removeAllChildren();}},storeSubtrace_(subtrace){this.subtraces_.push(subtrace);return oboe.drop;},storeSamples_(samples){this.sampleEvents_=samples;return oboe.drop;},storeStackFrames_(stackFrames){this.stackFrameEvents_=stackFrames;return oboe.drop;},storeDisplayTimeUnit_(unitName){if(!unitName)return;const unit=tr.b.TimeDisplayModes[unitName];if(unit===undefined){throw new Error('Unit '+unitName+' is not supported.');}
+this.model_.intrinsicTimeUnit=unit;return oboe.drop;},storeTraceAnnotations_(traceAnnotations){this.traceAnnotations_=traceAnnotations;return oboe.drop;},storeMetadata_(container){for(const fieldName of Object.keys(container)){if(NON_METADATA_FIELDS.has(fieldName))continue;this.model_.metadata.push({name:fieldName,value:container[fieldName]});if(fieldName!=='metadata')continue;const metadata=container[fieldName];if(metadata['highres-ticks']){this.model_.isTimeHighResolution=metadata['highres-ticks'];}
+if(metadata['clock-domain']){this.clockDomainId_=metadata['clock-domain'];}}
+return oboe.drop;},processEvent_(event){this.hasEvents_=true;const importOptions=this.model_.importOptions;const trackDetailedModelStats=importOptions.trackDetailedModelStats;const modelStats=this.model_.stats;if(event.args==='__stripped__'){event.argsStripped=true;event.args=undefined;}
+let eventSizeInBytes=undefined;if(trackDetailedModelStats){eventSizeInBytes=JSON.stringify(event).length;}
+switch(event.ph){case'B':case'E':modelStats.willProcessBasicTraceEvent('begin_end (non-compact)',event.cat,event.name,event.ts,eventSizeInBytes);this.processDurationEvent(event);break;case'X':{modelStats.willProcessBasicTraceEvent('begin_end (compact)',event.cat,event.name,event.ts,eventSizeInBytes);const slice=this.processCompleteEvent(event);if(slice!==undefined&&event.bind_id!==undefined){this.processFlowEvent(event,slice);}
+break;}
+case'b':case'e':case'n':case'S':case'F':case'T':case'p':modelStats.willProcessBasicTraceEvent('async',event.cat,event.name,event.ts,eventSizeInBytes);this.processAsyncEvent(event);break;case'I':case'i':case'R':modelStats.willProcessBasicTraceEvent('instant',event.cat,event.name,event.ts,eventSizeInBytes);this.processInstantEvent(event);break;case'P':modelStats.willProcessBasicTraceEvent('samples',event.cat,event.name,event.ts,eventSizeInBytes);this.processTraceSampleEvent(event);break;case'C':modelStats.willProcessBasicTraceEvent('counters',event.cat,event.name,event.ts,eventSizeInBytes);this.processCounterEvent(event);break;case'M':modelStats.willProcessBasicTraceEvent('metadata',event.cat,event.name,event.ts,eventSizeInBytes);this.processMetadataEvent(event);break;case'N':case'D':case'O':modelStats.willProcessBasicTraceEvent('objects',event.cat,event.name,event.ts,eventSizeInBytes);this.processObjectEvent(event);break;case's':case't':case'f':modelStats.willProcessBasicTraceEvent('flows',event.cat,event.name,event.ts,eventSizeInBytes);this.processFlowEvent(event);break;case'v':modelStats.willProcessBasicTraceEvent('memory_dumps',event.cat,event.name,event.ts,eventSizeInBytes);this.processMemoryDumpEvent(event);break;case'(':case')':this.processContextEvent(event);break;case'c':break;default:modelStats.willProcessBasicTraceEvent('unknown',event.cat,event.name,event.ts,eventSizeInBytes);this.model_.importWarning({type:'parse_error',message:'Unrecognized event phase: '+
+event.ph+' ('+event.name+')'});}
+return oboe.drop;},importStackFrames_(rawStackFrames,idPrefix){const model=this.model_;for(const id in rawStackFrames){const rawStackFrame=rawStackFrames[id];const fullId=idPrefix+id;const textForColor=rawStackFrame.category?rawStackFrame.category:rawStackFrame.name;const stackFrame=new tr.model.StackFrame(undefined,fullId,rawStackFrame.name,ColorScheme.getColorIdForGeneralPurposeString(textForColor));model.addStackFrame(stackFrame);}
+for(const id in rawStackFrames){const fullId=idPrefix+id;const stackFrame=model.stackFrames[fullId];if(stackFrame===undefined){throw new Error('Internal error');}
+const rawStackFrame=rawStackFrames[id];const parentId=rawStackFrame.parent;let parentStackFrame;if(parentId===undefined){parentStackFrame=undefined;}else{const parentFullId=idPrefix+parentId;parentStackFrame=model.stackFrames[parentFullId];if(parentStackFrame===undefined){this.model_.importWarning({type:'metadata_parse_error',message:'Missing parent frame with ID '+parentFullId+' for stack frame \''+stackFrame.name+'\' (ID '+fullId+').'});}}
+stackFrame.parentFrame=parentStackFrame;}
+const ProfileNodeType=tr.model.ProfileNode.subTypes.getConstructor(undefined,'legacySample');if(idPrefix==='g'){for(const id in rawStackFrames){const rawStackFrame=rawStackFrames[id];const textForColor=rawStackFrame.category?rawStackFrame.category:rawStackFrame.name;const node=this.stackFrameTree_.add(new ProfileNodeType('g'+id,{functionName:rawStackFrame.name},undefined));node.colorId=ColorScheme.getColorIdForGeneralPurposeString(textForColor);node.parentId=rawStackFrame.parent;}
+for(const id in rawStackFrames){const node=this.stackFrameTree_.getNode('g'+id);const parentId=node.parentId;let parentNode=undefined;if(parentId!==undefined){parentNode=this.stackFrameTree_.getNode('g'+parentId);if(parentNode===undefined){this.model_.importWarning({type:'metadata_parse_error',message:'Missing parent frame with ID '+parentId+' for stack frame \''+node.name+'\' (ID '+node.id+').'});}
+node.parentNode=parentNode;}}}},importObjectTypeNameMap_(rawObjectTypeNameMap,pid){if(pid in this.objectTypeNameMap_){this.model_.importWarning({type:'metadata_parse_error',message:'Mapping from object type IDs to names provided for pid='+
 pid+' multiple times.'});return;}
-var objectTypeNamePrefix=undefined;var objectTypeNameSuffix=undefined;var objectTypeNameMap={};for(var objectTypeId in rawObjectTypeNameMap){var rawObjectTypeName=rawObjectTypeNameMap[objectTypeId];if(objectTypeNamePrefix===undefined){for(var i=0;i<OBJECT_TYPE_NAME_PATTERNS.length;i++){var pattern=OBJECT_TYPE_NAME_PATTERNS[i];if(rawObjectTypeName.startsWith(pattern.prefix)&&rawObjectTypeName.endsWith(pattern.suffix)){objectTypeNamePrefix=pattern.prefix;objectTypeNameSuffix=pattern.suffix;break;}}}
+let objectTypeNamePrefix=undefined;let objectTypeNameSuffix=undefined;const objectTypeNameMap={};for(const objectTypeId in rawObjectTypeNameMap){const rawObjectTypeName=rawObjectTypeNameMap[objectTypeId];if(objectTypeNamePrefix===undefined){for(let i=0;i<OBJECT_TYPE_NAME_PATTERNS.length;i++){const pattern=OBJECT_TYPE_NAME_PATTERNS[i];if(rawObjectTypeName.startsWith(pattern.prefix)&&rawObjectTypeName.endsWith(pattern.suffix)){objectTypeNamePrefix=pattern.prefix;objectTypeNameSuffix=pattern.suffix;break;}}}
 if(objectTypeNamePrefix!==undefined&&rawObjectTypeName.startsWith(objectTypeNamePrefix)&&rawObjectTypeName.endsWith(objectTypeNameSuffix)){objectTypeNameMap[objectTypeId]=rawObjectTypeName.substring(objectTypeNamePrefix.length,rawObjectTypeName.length-objectTypeNameSuffix.length);}else{objectTypeNameMap[objectTypeId]=rawObjectTypeName;}}
-this.objectTypeNameMap_[pid]=objectTypeNameMap;},importAnnotations_:function(){for(var id in this.traceAnnotations_){var annotation=tr.model.Annotation.fromDictIfPossible(this.traceAnnotations_[id]);if(!annotation){this.model_.importWarning({type:'annotation_warning',message:'Unrecognized traceAnnotation typeName \"'+
+this.objectTypeNameMap_[pid]=objectTypeNameMap;},importAnnotations_(){for(const id in this.traceAnnotations_){const annotation=tr.model.Annotation.fromDictIfPossible(this.traceAnnotations_[id]);if(!annotation){this.model_.importWarning({type:'annotation_warning',message:'Unrecognized traceAnnotation typeName \"'+
 this.traceAnnotations_[id].typeName+'\"'});continue;}
-this.model_.addAnnotation(annotation);}},finalizeImport:function(){if(this.softwareMeasuredCpuCount_!==undefined){this.model_.kernel.softwareMeasuredCpuCount=this.softwareMeasuredCpuCount_;}
-this.createAsyncSlices_();this.createFlowSlices_();this.createExplicitObjects_();this.createImplicitObjects_();this.createMemoryDumps_();},getStackFrameForEvent_:function(event,opt_lookForEndEvent){var sf;var stack;if(opt_lookForEndEvent){sf=event.esf;stack=event.estack;}else{sf=event.sf;stack=event.stack;}
+this.model_.addAnnotation(annotation);}},finalizeImport(){if(this.softwareMeasuredCpuCount_!==undefined){this.model_.kernel.softwareMeasuredCpuCount=this.softwareMeasuredCpuCount_;}
+this.createFlowSlices_();this.createExplicitObjects_();this.createImplicitObjects_();this.createMemoryDumps_();},getStackFrameForEvent_(event,opt_lookForEndEvent){let sf;let stack;if(opt_lookForEndEvent){sf=event.esf;stack=event.estack;}else{sf=event.sf;stack=event.stack;}
 if(stack!==undefined&&sf!==undefined){this.model_.importWarning({type:'stack_frame_and_stack_error',message:'Event at '+event.ts+' cannot have both a stack and a stackframe.'});return undefined;}
-if(stack!==undefined)
-return this.model_.resolveStackToStackFrame_(event.pid,stack);if(sf===undefined)
-return undefined;var stackFrame=this.model_.stackFrames['g'+sf];if(stackFrame===undefined){this.model_.importWarning({type:'sample_import_error',message:'No frame for '+sf});return;}
-return stackFrame;},resolveStackToStackFrame_:function(pid,stack){return undefined;},importSampleData:function(){if(!this.sampleEvents_)
-return;var m=this.model_;var events=this.sampleEvents_;if(this.events_.length===0){for(var i=0;i<events.length;i++){var event=events[i];m.getOrCreateProcess(event.tid).getOrCreateThread(event.tid);}}
-var threadsByTid={};m.getAllThreads().forEach(function(t){threadsByTid[t.tid]=t;});for(var i=0;i<events.length;i++){var event=events[i];var thread=threadsByTid[event.tid];if(thread===undefined){m.importWarning({type:'sample_import_error',message:'Thread '+events.tid+'not found'});continue;}
-var cpu;if(event.cpu!==undefined)
-cpu=m.kernel.getOrCreateCpu(event.cpu);var stackFrame=this.getStackFrameForEvent_(event);var sample=new tr.model.Sample(cpu,thread,event.name,timestampFromUs(event.ts),stackFrame,event.weight);m.samples.push(sample);}},createAsyncSlices_:function(){if(this.allAsyncEvents_.length===0)
-return;this.allAsyncEvents_.sort(function(x,y){var d=x.event.ts-y.event.ts;if(d!==0)
-return d;return x.sequenceNumber-y.sequenceNumber;});var legacyEvents=[];var nestableAsyncEventsByKey={};var nestableMeasureAsyncEventsByKey={};for(var i=0;i<this.allAsyncEvents_.length;i++){var asyncEventState=this.allAsyncEvents_[i];var event=asyncEventState.event;if(event.ph==='S'||event.ph==='F'||event.ph==='T'||event.ph==='p'){legacyEvents.push(asyncEventState);continue;}
+if(stack!==undefined){return this.model_.resolveStackToStackFrame_(event.pid,stack);}
+if(sf===undefined)return undefined;const stackFrame=this.model_.stackFrames['g'+sf];if(stackFrame===undefined){this.model_.importWarning({type:'sample_import_error',message:'No frame for '+sf});return;}
+return stackFrame;},resolveStackToStackFrame_(pid,stack){return undefined;},importSampleData(){if(!this.sampleEvents_)return;const m=this.model_;const events=this.sampleEvents_;if(this.hasEvents_===undefined){throw new Error('importEvents is not run before importSampleData');}else if(!this.hasEvents_){for(let i=0;i<events.length;i++){const event=events[i];m.getOrCreateProcess(event.tid).getOrCreateThread(event.tid);}}
+const threadsByTid={};m.getAllThreads().forEach(function(t){threadsByTid[t.tid]=t;});for(let i=0;i<events.length;i++){const event=events[i];const thread=threadsByTid[event.tid];if(thread===undefined){m.importWarning({type:'sample_import_error',message:'Thread '+events.tid+'not found'});continue;}
+let cpu;if(event.cpu!==undefined){cpu=m.kernel.getOrCreateCpu(event.cpu);}
+const leafNode=this.stackFrameTree_.getNode('g'+event.sf);const sample=new tr.model.Sample(this.toModelTimeFromUs_(event.ts),event.name,leafNode,thread,cpu,event.weight);m.samples.push(sample);}},createAsyncSlices_(){if(this.allAsyncEvents_.length===0)return;this.allAsyncEvents_.sort(function(x,y){const d=x.event.ts-y.event.ts;if(d!==0)return d;return x.sequenceNumber-y.sequenceNumber;});const legacyEvents=[];const nestableAsyncEventsByKey={};const nestableMeasureAsyncEventsByKey={};for(let i=0;i<this.allAsyncEvents_.length;i++){const asyncEventState=this.allAsyncEvents_[i];const event=asyncEventState.event;if(event.ph==='S'||event.ph==='F'||event.ph==='T'||event.ph==='p'){legacyEvents.push(asyncEventState);continue;}
 if(event.cat===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async events (ph: b, e, or n) require a '+'cat parameter.'});continue;}
 if(event.name===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async events (ph: b, e, or n) require a '+'name parameter.'});continue;}
-if(event.id===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async events (ph: b, e, or n) require an '+'id parameter.'});continue;}
-if(event.cat==='blink.user_timing'){var matched=/([^\/:]+):([^\/:]+)\/?(.*)/.exec(event.name);if(matched!==null){var key=matched[1]+':'+event.cat;event.args=JSON.parse(Base64.atob(matched[3])||'{}');if(nestableMeasureAsyncEventsByKey[key]===undefined)
-nestableMeasureAsyncEventsByKey[key]=[];nestableMeasureAsyncEventsByKey[key].push(asyncEventState);continue;}}
-var key=event.cat+':'+event.id;if(nestableAsyncEventsByKey[key]===undefined)
-nestableAsyncEventsByKey[key]=[];nestableAsyncEventsByKey[key].push(asyncEventState);}
-this.createLegacyAsyncSlices_(legacyEvents);this.createNestableAsyncSlices_(nestableMeasureAsyncEventsByKey);this.createNestableAsyncSlices_(nestableAsyncEventsByKey);},createLegacyAsyncSlices_:function(legacyEvents){if(legacyEvents.length===0)
-return;legacyEvents.sort(function(x,y){var d=x.event.ts-y.event.ts;if(d!=0)
-return d;return x.sequenceNumber-y.sequenceNumber;});var asyncEventStatesByNameThenID={};for(var i=0;i<legacyEvents.length;i++){var asyncEventState=legacyEvents[i];var event=asyncEventState.event;var name=event.name;if(name===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Async events (ph: S, T, p, or F) require a name '+' parameter.'});continue;}
-var id=event.id;if(id===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Async events (ph: S, T, p, or F) require an id parameter.'});continue;}
-if(event.ph==='S'){if(asyncEventStatesByNameThenID[name]===undefined)
-asyncEventStatesByNameThenID[name]={};if(asyncEventStatesByNameThenID[name][id]){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.ts+', a slice of the same id '+id+' was alrady open.'});continue;}
-asyncEventStatesByNameThenID[name][id]=[];asyncEventStatesByNameThenID[name][id].push(asyncEventState);}else{if(asyncEventStatesByNameThenID[name]===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.ts+', no slice named '+name+' was open.'});continue;}
-if(asyncEventStatesByNameThenID[name][id]===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.ts+', no slice named '+name+' with id='+id+' was open.'});continue;}
-var events=asyncEventStatesByNameThenID[name][id];events.push(asyncEventState);if(event.ph==='F'){var asyncSliceConstructor=tr.model.AsyncSlice.getConstructor(events[0].event.cat,name);var slice=new asyncSliceConstructor(events[0].event.cat,name,getEventColor(events[0].event),timestampFromUs(events[0].event.ts),tr.b.concatenateObjects(events[0].event.args,events[events.length-1].event.args),timestampFromUs(event.ts-events[0].event.ts),true,undefined,undefined,events[0].event.argsStripped);slice.startThread=events[0].thread;slice.endThread=asyncEventState.thread;slice.id=id;var stepType=events[1].event.ph;var isValid=true;for(var j=1;j<events.length-1;++j){if(events[j].event.ph==='T'||events[j].event.ph==='p'){isValid=this.assertStepTypeMatches_(stepType,events[j]);if(!isValid)
-break;}
-if(events[j].event.ph==='S'){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.event.ts+', a slice named '+
-event.event.name+' with id='+event.event.id+' had a step before the start event.'});continue;}
-if(events[j].event.ph==='F'){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.event.ts+', a slice named '+
-event.event.name+' with id='+event.event.id+' had a step after the finish event.'});continue;}
-var startIndex=j+(stepType==='T'?0:-1);var endIndex=startIndex+1;var subName=events[j].event.name;if(!events[j].event.argsStripped&&(events[j].event.ph==='T'||events[j].event.ph==='p'))
-subName=subName+':'+events[j].event.args.step;var asyncSliceConstructor=tr.model.AsyncSlice.getConstructor(events[0].event.cat,subName);var subSlice=new asyncSliceConstructor(events[0].event.cat,subName,getEventColor(event,subName+j),timestampFromUs(events[startIndex].event.ts),this.deepCopyIfNeeded_(events[j].event.args),timestampFromUs(events[endIndex].event.ts-events[startIndex].event.ts),undefined,undefined,events[startIndex].event.argsStripped);subSlice.startThread=events[startIndex].thread;subSlice.endThread=events[endIndex].thread;subSlice.id=id;slice.subSlices.push(subSlice);}
-if(isValid){slice.startThread.asyncSliceGroup.push(slice);}
-delete asyncEventStatesByNameThenID[name][id];}}}},createNestableAsyncSlices_:function(nestableEventsByKey){for(var key in nestableEventsByKey){var eventStateEntries=nestableEventsByKey[key];var parentStack=[];for(var i=0;i<eventStateEntries.length;++i){var eventStateEntry=eventStateEntries[i];if(eventStateEntry.event.ph==='e'){var parentIndex=-1;for(var k=parentStack.length-1;k>=0;--k){if(parentStack[k].event.name===eventStateEntry.event.name){parentIndex=k;break;}}
+const id=TraceEventImporter.scopedIdForEvent_(event);if(id===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async events (ph: b, e, or n) require an '+'id parameter.'});continue;}
+if(event.cat==='blink.user_timing'){const matched=MEASURE_NAME_REGEX.exec(event.name);if(matched!==null){const key=matched[1]+':'+event.cat;try{event.args=JSON.parse(Base64.atob(matched[3])||'{}');}catch(e){}
+if(nestableMeasureAsyncEventsByKey[key]===undefined){nestableMeasureAsyncEventsByKey[key]=[];}
+nestableMeasureAsyncEventsByKey[key].push(asyncEventState);continue;}}
+const key=event.cat+':'+id.toStringWithDelimiter(':');if(nestableAsyncEventsByKey[key]===undefined){nestableAsyncEventsByKey[key]=[];}
+nestableAsyncEventsByKey[key].push(asyncEventState);}
+this.createLegacyAsyncSlices_(legacyEvents);this.createNestableAsyncSlices_(nestableMeasureAsyncEventsByKey);this.createNestableAsyncSlices_(nestableAsyncEventsByKey);},createLegacyAsyncSlice_(events){const asyncEventState=events[events.length-1];const event=asyncEventState.event;const name=event.name;const id=TraceEventImporter.scopedIdForEvent_(event);const key=id.toStringWithDelimiter(':');const asyncSliceConstructor=tr.model.AsyncSlice.subTypes.getConstructor(events[0].event.cat,name);let duration;if(event.ts!==undefined){duration=this.toModelTimeFromUs_(event.ts-events[0].event.ts);}
+const slice=new asyncSliceConstructor(events[0].event.cat,name,getEventColor(events[0].event),this.toModelTimeFromUs_(events[0].event.ts),Object.assign({},events[0].event.args,event.args),duration||0,true,undefined,undefined,events[0].event.argsStripped);if(duration===undefined){slice.didNotFinish=true;slice.error='Slice has no matching END. End time has been adjusted.';this.model_.importWarning({type:'async_slice_parse_error',message:'Legacy async BEGIN event at '+
+events[0].event.ts+' with name="'+
+name+'" and id='+key+' was unmatched.'});}
+slice.startThread=events[0].thread;slice.endThread=asyncEventState.thread;slice.id=key;const stepType=events[1].event.ph;let isValid=true;for(let j=1;j<events.length-1;++j){if(events[j].event.ph==='T'||events[j].event.ph==='p'){isValid=this.assertStepTypeMatches_(stepType,events[j]);if(!isValid)break;}
+if(events[j].event.ph==='S'){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+events[j].event.ts+', a slice named "'+
+name+'" with id='+id+' had a step before the start event.'});continue;}
+if(events[j].event.ph==='F'){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+events[j].event.ts+', a slice named '+
+name+' with id='+id+' had a step after the finish event.'});continue;}
+const startIndex=j+(stepType==='T'?0:-1);const endIndex=startIndex+1;let subName=name;if(!events[j].event.argsStripped&&(events[j].event.ph==='T'||events[j].event.ph==='p')){subName=events[j].event.args.step;}
+const asyncSliceConstructor=tr.model.AsyncSlice.subTypes.getConstructor(events[0].event.cat,subName);let duration;if(events[endIndex].event.ts!==undefined){duration=this.toModelTimeFromUs_(events[endIndex].event.ts-events[startIndex].event.ts);}
+const subSlice=new asyncSliceConstructor(events[0].event.cat,subName,getEventColor(events[0].event,subName+j),this.toModelTimeFromUs_(events[startIndex].event.ts),this.deepCopyIfNeeded_(events[j].event.args),duration||0,undefined,undefined,events[startIndex].event.argsStripped);if(duration===undefined){subSlice.didNotFinish=true;subSlice.error='Slice has no matching END. End time has been adjusted.';}
+subSlice.startThread=events[startIndex].thread;subSlice.endThread=events[endIndex].thread;subSlice.id=key;slice.subSlices.push(subSlice);}
+if(isValid){slice.startThread.asyncSliceGroup.push(slice);}},createLegacyAsyncSlices_(legacyEvents){if(legacyEvents.length===0)return;legacyEvents.sort(function(x,y){const d=x.event.ts-y.event.ts;if(d!==0)return d;return x.sequenceNumber-y.sequenceNumber;});const asyncEventStatesByNameThenID={};for(let i=0;i<legacyEvents.length;i++){const asyncEventState=legacyEvents[i];const event=asyncEventState.event;const name=event.name;if(name===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Async events (ph: S, T, p, or F) require a name '+' parameter.'});continue;}
+const id=TraceEventImporter.scopedIdForEvent_(event);if(id===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Async events (ph: S, T, p, or F) require an id parameter.'});continue;}
+const key=id.toStringWithDelimiter(':');if(event.ph==='S'){if(asyncEventStatesByNameThenID[name]===undefined){asyncEventStatesByNameThenID[name]={};}
+if(asyncEventStatesByNameThenID[name][key]){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.ts+', a slice of the same id '+id+' was alrady open.'});continue;}
+asyncEventStatesByNameThenID[name][key]=[];asyncEventStatesByNameThenID[name][key].push(asyncEventState);}else{if(asyncEventStatesByNameThenID[name]===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:`At ${event.ts}, no slice named "${name}" was open.`,});continue;}
+if(asyncEventStatesByNameThenID[name][key]===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:`At ${event.ts}, no slice named "${name}" with id=${id} was `+'open.',});continue;}
+const events=asyncEventStatesByNameThenID[name][key];events.push(asyncEventState);if(event.ph==='F'){this.createLegacyAsyncSlice_(events);delete asyncEventStatesByNameThenID[name][key];}}}
+for(const[name,statesByID]of
+Object.entries(asyncEventStatesByNameThenID)){for(const[id,states]of Object.entries(statesByID)){const startEvent=states[0].event;states.push({sequenceNumber:1+states[states.length-1].sequenceNumber,event:{ph:'F',name,id:startEvent.id,id2:startEvent.id2,scope:startEvent.scope,pid:startEvent.pid,tid:startEvent.tid,cat:startEvent.cat,args:{},},thread:this.model_.getOrCreateProcess(startEvent.pid).getOrCreateThread(startEvent.tid),});this.createLegacyAsyncSlice_(states);}}},createNestableAsyncSlices_(nestableEventsByKey){for(const key in nestableEventsByKey){const eventStateEntries=nestableEventsByKey[key];const parentStack=[];for(let i=0;i<eventStateEntries.length;++i){const eventStateEntry=eventStateEntries[i];if(eventStateEntry.event.ph==='e'){let parentIndex=-1;for(let k=parentStack.length-1;k>=0;--k){if(parentStack[k].event.name===eventStateEntry.event.name){parentIndex=k;break;}}
 if(parentIndex===-1){eventStateEntry.finished=false;}else{parentStack[parentIndex].end=eventStateEntry;while(parentIndex<parentStack.length){parentStack.pop();}}}
-if(parentStack.length>0)
-eventStateEntry.parentEntry=parentStack[parentStack.length-1];if(eventStateEntry.event.ph==='b'){parentStack.push(eventStateEntry);}}
-var topLevelSlices=[];for(var i=0;i<eventStateEntries.length;++i){var eventStateEntry=eventStateEntries[i];if(eventStateEntry.event.ph==='e'&&eventStateEntry.finished===undefined){continue;}
-var startState=undefined;var endState=undefined;var sliceArgs=eventStateEntry.event.args||{};var sliceError=undefined;if(eventStateEntry.event.ph==='n'){startState=eventStateEntry;endState=eventStateEntry;}else if(eventStateEntry.event.ph==='b'){if(eventStateEntry.end===undefined){eventStateEntry.end=eventStateEntries[eventStateEntries.length-1];sliceError='Slice has no matching END. End time has been adjusted.';this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async BEGIN event at '+
-eventStateEntry.event.ts+' with name='+
-eventStateEntry.event.name+' and id='+eventStateEntry.event.id+' was unmatched.'});}else{function concatenateArguments(args1,args2){if(args1.params===undefined||args2.params===undefined)
-return tr.b.concatenateObjects(args1,args2);var args3={};args3.params=tr.b.concatenateObjects(args1.params,args2.params);return tr.b.concatenateObjects(args1,args2,args3);}
-var endArgs=eventStateEntry.end.event.args||{};sliceArgs=concatenateArguments(sliceArgs,endArgs);}
+if(parentStack.length>0){eventStateEntry.parentEntry=parentStack[parentStack.length-1];}
+if(eventStateEntry.event.ph==='b'){parentStack.push(eventStateEntry);}}
+const topLevelSlices=[];for(let i=0;i<eventStateEntries.length;++i){const eventStateEntry=eventStateEntries[i];if(eventStateEntry.event.ph==='e'&&eventStateEntry.finished===undefined){continue;}
+let startState=undefined;let endState=undefined;let sliceArgs=eventStateEntry.event.args||{};let sliceError=undefined;const id=TraceEventImporter.scopedIdForEvent_(eventStateEntry.event);if(eventStateEntry.event.ph==='n'){startState=eventStateEntry;endState=eventStateEntry;}else if(eventStateEntry.event.ph==='b'){if(eventStateEntry.end===undefined){eventStateEntry.end=eventStateEntries[eventStateEntries.length-1];sliceError='Slice has no matching END. End time has been adjusted.';this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async BEGIN event at '+
+eventStateEntry.event.ts+' with name="'+
+eventStateEntry.event.name+'" and id='+id+' was unmatched.'});}else{function concatenateArguments(args1,args2){if(args1.params===undefined||args2.params===undefined){return Object.assign({},args1,args2);}
+const args3={};args3.params=Object.assign({},args1.params,args2.params);return Object.assign({},args1,args2,args3);}
+const endArgs=eventStateEntry.end.event.args||{};sliceArgs=concatenateArguments(sliceArgs,endArgs);}
 startState=eventStateEntry;endState=eventStateEntry.end;}else{sliceError='Slice has no matching BEGIN. Start time has been adjusted.';this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async END event at '+
 eventStateEntry.event.ts+' with name='+
-eventStateEntry.event.name+' and id='+eventStateEntry.event.id+' was unmatched.'});startState=eventStateEntries[0];endState=eventStateEntry;}
-var isTopLevel=(eventStateEntry.parentEntry===undefined);var asyncSliceConstructor=tr.model.AsyncSlice.getConstructor(eventStateEntry.event.cat,eventStateEntry.event.name);var thread_start=undefined;var thread_duration=undefined;if(startState.event.tts&&startState.event.use_async_tts){thread_start=timestampFromUs(startState.event.tts);if(endState.event.tts){var thread_end=timestampFromUs(endState.event.tts);thread_duration=thread_end-thread_start;}}
-var slice=new asyncSliceConstructor(eventStateEntry.event.cat,eventStateEntry.event.name,getEventColor(endState.event),timestampFromUs(startState.event.ts),sliceArgs,timestampFromUs(endState.event.ts-startState.event.ts),isTopLevel,thread_start,thread_duration,startState.event.argsStripped);slice.startThread=startState.thread;slice.endThread=endState.thread;slice.startStackFrame=this.getStackFrameForEvent_(startState.event);slice.endStackFrame=this.getStackFrameForEvent_(endState.event);slice.id=key;if(sliceError!==undefined)
-slice.error=sliceError;eventStateEntry.slice=slice;if(isTopLevel){topLevelSlices.push(slice);}else if(eventStateEntry.parentEntry.slice!==undefined){eventStateEntry.parentEntry.slice.subSlices.push(slice);}}
-for(var si=0;si<topLevelSlices.length;si++){topLevelSlices[si].startThread.asyncSliceGroup.push(topLevelSlices[si]);}}},assertStepTypeMatches_:function(stepType,event){if(stepType!=event.event.ph){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.event.ts+', a slice named '+
-event.event.name+' with id='+event.event.id+' had both begin and end steps, which is not allowed.'});return false;}
-return true;},createFlowSlices_:function(){if(this.allFlowEvents_.length===0)
-return;var that=this;function validateFlowEvent(){if(event.name===undefined){that.model_.importWarning({type:'flow_slice_parse_error',message:'Flow events (ph: s, t or f) require a name parameter.'});return false;}
-if(event.ph==='s'||event.ph==='f'||event.ph==='t'){if(event.id===undefined){that.model_.importWarning({type:'flow_slice_parse_error',message:'Flow events (ph: s, t or f) require an id parameter.'});return false;}
+eventStateEntry.event.name+' and id='+id+' was unmatched.'});startState=eventStateEntries[0];endState=eventStateEntry;}
+const isTopLevel=(eventStateEntry.parentEntry===undefined);const asyncSliceConstructor=tr.model.AsyncSlice.subTypes.getConstructor(eventStateEntry.event.cat,eventStateEntry.event.name);let threadStart=undefined;let threadDuration=undefined;if(startState.event.tts&&startState.event.use_async_tts){threadStart=this.toModelTimeFromUs_(startState.event.tts);if(endState.event.tts){const threadEnd=this.toModelTimeFromUs_(endState.event.tts);threadDuration=threadEnd-threadStart;}}
+const slice=new asyncSliceConstructor(eventStateEntry.event.cat,eventStateEntry.event.name,getEventColor(endState.event),this.toModelTimeFromUs_(startState.event.ts),sliceArgs,this.toModelTimeFromUs_(endState.event.ts-startState.event.ts),isTopLevel,threadStart,threadDuration,startState.event.argsStripped);slice.startThread=startState.thread;slice.endThread=endState.thread;slice.startStackFrame=this.getStackFrameForEvent_(startState.event);slice.endStackFrame=this.getStackFrameForEvent_(endState.event);slice.id=key;if(sliceError!==undefined){slice.error=sliceError;}
+eventStateEntry.slice=slice;if(isTopLevel){topLevelSlices.push(slice);}else if(eventStateEntry.parentEntry.slice!==undefined){eventStateEntry.parentEntry.slice.subSlices.push(slice);}}
+for(let si=0;si<topLevelSlices.length;si++){topLevelSlices[si].startThread.asyncSliceGroup.push(topLevelSlices[si]);}}},assertStepTypeMatches_(stepType,event){if(stepType!==event.event.ph){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.event.ts+', a slice named '+
+event.event.name+' with id='+
+TraceEventImporter.scopedIdForEvent_(event.event)+' had both begin and end steps, which is not allowed.'});return false;}
+return true;},validateFlowEvent_(event){if(event.name===undefined){this.model_.importWarning({type:'flow_slice_parse_error',message:'Flow events (ph: s, t or f) require a name parameter.'});return false;}
+if(event.ph==='s'||event.ph==='f'||event.ph==='t'){if(event.id===undefined){this.model_.importWarning({type:'flow_slice_parse_error',message:'Flow events (ph: s, t or f) require an id parameter.'});return false;}
 return true;}
-if(event.bind_id){if(event.flow_in===undefined&&event.flow_out===undefined){that.model_.importWarning({type:'flow_slice_parse_error',message:'Flow producer or consumer require flow_in or flow_out.'});return false;}
+if(event.bind_id){if(event.flow_in===undefined&&event.flow_out===undefined){this.model_.importWarning({type:'flow_slice_parse_error',message:'Flow producer or consumer require flow_in or flow_out.'});return false;}
 return true;}
-return false;}
-function createFlowEvent(thread,event,opt_slice){var startSlice,flowId,flowStartTs;if(event.bind_id){startSlice=opt_slice;flowId=event.bind_id;flowStartTs=timestampFromUs(event.ts+event.dur);}else{var ts=timestampFromUs(event.ts);startSlice=thread.sliceGroup.findSliceAtTs(ts);if(startSlice===undefined)
-return undefined;flowId=event.id;flowStartTs=ts;}
-var flowEvent=new tr.model.FlowEvent(event.cat,flowId,event.name,getEventColor(event),flowStartTs,that.deepCopyAlways_(event.args));flowEvent.startSlice=startSlice;flowEvent.startStackFrame=that.getStackFrameForEvent_(event);flowEvent.endStackFrame=undefined;startSlice.outFlowEvents.push(flowEvent);return flowEvent;}
-function finishFlowEventWith(flowEvent,thread,event,refGuid,bindToParent,opt_slice){var endSlice;if(event.bind_id){endSlice=opt_slice;}else{var ts=timestampFromUs(event.ts);if(bindToParent){endSlice=thread.sliceGroup.findSliceAtTs(ts);}else{endSlice=thread.sliceGroup.findNextSliceAfter(ts,refGuid);}
-if(endSlice===undefined)
-return false;}
-endSlice.inFlowEvents.push(flowEvent);flowEvent.endSlice=endSlice;flowEvent.duration=timestampFromUs(event.ts)-flowEvent.start;flowEvent.endStackFrame=that.getStackFrameForEvent_(event);that.mergeArgsInto_(flowEvent.args,event.args,flowEvent.title);return true;}
-function processFlowConsumer(flowIdToEvent,sliceGuidToEvent,event,slice){var flowEvent=flowIdToEvent[event.bind_id];if(flowEvent===undefined){that.model_.importWarning({type:'flow_slice_ordering_error',message:'Flow consumer '+event.bind_id+' does not have '+'a flow producer'});return false;}else if(flowEvent.endSlice){var flowProducer=flowEvent.startSlice;flowEvent=createFlowEvent(undefined,sliceGuidToEvent[flowProducer.guid],flowProducer);}
-var ok=finishFlowEventWith(flowEvent,undefined,event,refGuid,undefined,slice);if(ok){that.model_.flowEvents.push(flowEvent);}else{that.model_.importWarning({type:'flow_slice_end_error',message:'Flow consumer '+event.bind_id+' does not end '+'at an actual slice, so cannot be created.'});return false;}
-return true;}
-function processFlowProducer(flowIdToEvent,flowStatus,event,slice){if(flowIdToEvent[event.bind_id]&&flowStatus[event.bind_id]){that.model_.importWarning({type:'flow_slice_start_error',message:'Flow producer '+event.bind_id+' already seen'});return false;}
-var flowEvent=createFlowEvent(undefined,event,slice);if(!flowEvent){that.model_.importWarning({type:'flow_slice_start_error',message:'Flow producer '+event.bind_id+' does not start'+'a flow'});return false;}
-flowIdToEvent[event.bind_id]=flowEvent;return;}
-this.allFlowEvents_.sort(function(x,y){var d=x.event.ts-y.event.ts;if(d!=0)
-return d;return x.sequenceNumber-y.sequenceNumber;});var flowIdToEvent={};var sliceGuidToEvent={};var flowStatus={};for(var i=0;i<this.allFlowEvents_.length;++i){var data=this.allFlowEvents_[i];var refGuid=data.refGuid;var event=data.event;var thread=data.thread;if(!validateFlowEvent(event))
-continue;if(event.bind_id){var slice=data.slice;sliceGuidToEvent[slice.guid]=event;if(event.flowPhase===PRODUCER){if(!processFlowProducer(flowIdToEvent,flowStatus,event,slice))
-continue;flowStatus[event.bind_id]=true;}
-else{if(!processFlowConsumer(flowIdToEvent,sliceGuidToEvent,event,slice))
-continue;flowStatus[event.bind_id]=false;if(event.flowPhase===STEP){if(!processFlowProducer(flowIdToEvent,flowStatus,event,slice))
-continue;flowStatus[event.bind_id]=true;}}
+return false;},createFlowSlices_(){if(this.allFlowEvents_.length===0)return;const createFlowEvent=function(thread,event,opt_slice){let startSlice;let flowId;let flowStartTs;if(event.bind_id){startSlice=opt_slice;flowId=event.bind_id;flowStartTs=this.toModelTimeFromUs_(event.ts+event.dur);}else{const ts=this.toModelTimeFromUs_(event.ts);startSlice=thread.sliceGroup.findSliceAtTs(ts);if(startSlice===undefined)return undefined;flowId=event.id;flowStartTs=ts;}
+const flowEvent=new tr.model.FlowEvent(event.cat,flowId,event.name,getEventColor(event),flowStartTs,this.deepCopyAlways_(event.args));flowEvent.startSlice=startSlice;flowEvent.startStackFrame=this.getStackFrameForEvent_(event);flowEvent.endStackFrame=undefined;startSlice.outFlowEvents.push(flowEvent);return flowEvent;}.bind(this);const finishFlowEventWith=function(flowEvent,thread,event,refGuid,bindToParent,opt_slice){let endSlice;if(event.bind_id){endSlice=opt_slice;}else{const ts=this.toModelTimeFromUs_(event.ts);if(bindToParent){endSlice=thread.sliceGroup.findSliceAtTs(ts);}else{endSlice=thread.sliceGroup.findNextSliceAfter(ts,refGuid);}
+if(endSlice===undefined)return false;}
+endSlice.inFlowEvents.push(flowEvent);flowEvent.endSlice=endSlice;flowEvent.duration=this.toModelTimeFromUs_(event.ts)-flowEvent.start;flowEvent.endStackFrame=this.getStackFrameForEvent_(event);this.mergeArgsInto_(flowEvent.args,event.args,flowEvent.title);return true;}.bind(this);const processFlowConsumer=function(flowIdToEvent,sliceGuidToEvent,event,slice){let flowEvent=flowIdToEvent[event.bind_id];if(flowEvent===undefined){this.model_.importWarning({type:'flow_slice_ordering_error',message:'Flow consumer '+event.bind_id+' does not have '+'a flow producer'});return false;}else if(flowEvent.endSlice){const flowProducer=flowEvent.startSlice;flowEvent=createFlowEvent(undefined,sliceGuidToEvent[flowProducer.guid],flowProducer);}
+const refGuid=undefined;const ok=finishFlowEventWith(flowEvent,undefined,event,refGuid,undefined,slice);if(ok){this.model_.flowEvents.push(flowEvent);}else{this.model_.importWarning({type:'flow_slice_end_error',message:'Flow consumer '+event.bind_id+' does not end '+'at an actual slice, so cannot be created.'});return false;}
+return true;}.bind(this);const processFlowProducer=function(flowIdToEvent,flowStatus,event,slice){if(flowIdToEvent[event.bind_id]&&flowStatus[event.bind_id]){this.model_.importWarning({type:'flow_slice_start_error',message:'Flow producer '+event.bind_id+' already seen'});return false;}
+const flowEvent=createFlowEvent(undefined,event,slice);if(!flowEvent){this.model_.importWarning({type:'flow_slice_start_error',message:'Flow producer '+event.bind_id+' does not start'+'a flow'});return false;}
+flowIdToEvent[event.bind_id]=flowEvent;}.bind(this);this.allFlowEvents_.sort(function(x,y){const d=x.event.ts-y.event.ts;if(d!==0)return d;return x.sequenceNumber-y.sequenceNumber;});const flowIdToEvent={};const sliceGuidToEvent={};const flowStatus={};for(let i=0;i<this.allFlowEvents_.length;++i){const data=this.allFlowEvents_[i];const refGuid=data.refGuid;const event=data.event;const thread=data.thread;if(!this.validateFlowEvent_(event))continue;if(event.bind_id){const slice=data.slice;sliceGuidToEvent[slice.guid]=event;if(event.flowPhase===PRODUCER){if(!processFlowProducer(flowIdToEvent,flowStatus,event,slice)){continue;}
+flowStatus[event.bind_id]=true;}else{if(!processFlowConsumer(flowIdToEvent,sliceGuidToEvent,event,slice)){continue;}
+flowStatus[event.bind_id]=false;if(event.flowPhase===STEP){if(!processFlowProducer(flowIdToEvent,flowStatus,event,slice)){continue;}
+flowStatus[event.bind_id]=true;}}
 continue;}
-var flowEvent;if(event.ph==='s'){if(flowIdToEvent[event.id]){this.model_.importWarning({type:'flow_slice_start_error',message:'event id '+event.id+' already seen when '+'encountering start of flow event.'});continue;}
+const fullFlowId=JSON.stringify({id:event.id,cat:event.cat,name:event.name});let flowEvent;if(event.ph==='s'){if(flowIdToEvent[fullFlowId]){this.model_.importWarning({type:'flow_slice_start_error',message:'event id '+event.id+' already seen when '+'encountering start of flow event.'});continue;}
 flowEvent=createFlowEvent(thread,event);if(!flowEvent){this.model_.importWarning({type:'flow_slice_start_error',message:'event id '+event.id+' does not start '+'at an actual slice, so cannot be created.'});continue;}
-flowIdToEvent[event.id]=flowEvent;}else if(event.ph==='t'||event.ph==='f'){flowEvent=flowIdToEvent[event.id];if(flowEvent===undefined){this.model_.importWarning({type:'flow_slice_ordering_error',message:'Found flow phase '+event.ph+' for id: '+event.id+' but no flow start found.'});continue;}
-var bindToParent=event.ph==='t';if(event.ph==='f'){if(event.bp===undefined){if(event.cat.indexOf('input')>-1)
-bindToParent=true;else if(event.cat.indexOf('ipc.flow')>-1)
-bindToParent=true;}else{if(event.bp!=='e'){this.model_.importWarning({type:'flow_slice_bind_point_error',message:'Flow event with invalid binding point (event.bp).'});continue;}
+flowIdToEvent[fullFlowId]=flowEvent;}else if(event.ph==='t'||event.ph==='f'){flowEvent=flowIdToEvent[fullFlowId];if(flowEvent===undefined){this.model_.importWarning({type:'flow_slice_ordering_error',message:'Found flow phase '+event.ph+' for id: '+event.id+' but no flow start found.'});continue;}
+let bindToParent=event.ph==='t';if(event.ph==='f'){if(event.bp===undefined){if(event.cat.indexOf('input')>-1){bindToParent=true;}else if(event.cat.indexOf('ipc.flow')>-1){bindToParent=true;}}else{if(event.bp!=='e'){this.model_.importWarning({type:'flow_slice_bind_point_error',message:'Flow event with invalid binding point (event.bp).'});continue;}
 bindToParent=true;}}
-var ok=finishFlowEventWith(flowEvent,thread,event,refGuid,bindToParent);if(ok){that.model_.flowEvents.push(flowEvent);}else{this.model_.importWarning({type:'flow_slice_end_error',message:'event id '+event.id+' does not end '+'at an actual slice, so cannot be created.'});}
-flowIdToEvent[event.id]=undefined;if(ok&&event.ph==='t'){flowEvent=createFlowEvent(thread,event);flowIdToEvent[event.id]=flowEvent;}}}},createExplicitObjects_:function(){if(this.allObjectEvents_.length===0)
-return;function processEvent(objectEventState){var event=objectEventState.event;var scopedId=new tr.model.ScopedId(event.scope||tr.model.OBJECT_DEFAULT_SCOPE,event.id);var thread=objectEventState.thread;if(event.name===undefined){this.model_.importWarning({type:'object_parse_error',message:'While processing '+JSON.stringify(event)+': '+'Object events require an name parameter.'});}
-if(scopedId.id===undefined){this.model_.importWarning({type:'object_parse_error',message:'While processing '+JSON.stringify(event)+': '+'Object events require an id parameter.'});}
-var process=thread.parent;var ts=timestampFromUs(event.ts);var instance;if(event.ph==='N'){try{instance=process.objects.idWasCreated(scopedId,event.cat,event.name,ts);}catch(e){this.model_.importWarning({type:'object_parse_error',message:'While processing create of '+
+const ok=finishFlowEventWith(flowEvent,thread,event,refGuid,bindToParent);if(ok){this.model_.flowEvents.push(flowEvent);}else{this.model_.importWarning({type:'flow_slice_end_error',message:'event id '+event.id+' does not end '+'at an actual slice, so cannot be created.'});}
+flowIdToEvent[fullFlowId]=undefined;if(ok&&event.ph==='t'){flowEvent=createFlowEvent(thread,event);flowIdToEvent[fullFlowId]=flowEvent;}}}},createExplicitObjects_(){if(this.allObjectEvents_.length===0)return;const processEvent=function(objectEventState){const event=objectEventState.event;const scopedId=TraceEventImporter.scopedIdForEvent_(event);const thread=objectEventState.thread;if(event.name===undefined){this.model_.importWarning({type:'object_parse_error',message:'While processing '+JSON.stringify(event)+': '+'Object events require an name parameter.'});}
+if(scopedId===undefined||scopedId.id===undefined){this.model_.importWarning({type:'object_parse_error',message:'While processing '+JSON.stringify(event)+': '+'Object events require an id parameter.'});}
+const process=thread.parent;const ts=this.toModelTimeFromUs_(event.ts);let instance;if(event.ph==='N'){try{instance=process.objects.idWasCreated(scopedId,event.cat,event.name,ts);}catch(e){this.model_.importWarning({type:'object_parse_error',message:'While processing create of '+
 scopedId+' at ts='+ts+': '+e});return;}}else if(event.ph==='O'){if(event.args.snapshot===undefined){this.model_.importWarning({type:'object_parse_error',message:'While processing '+scopedId+' at ts='+ts+': '+'Snapshots must have args: {snapshot: ...}'});return;}
-var snapshot;try{var args=this.deepCopyIfNeeded_(event.args.snapshot);var cat;if(args.cat){cat=args.cat;delete args.cat;}else{cat=event.cat;}
-var baseTypename;if(args.base_type){baseTypename=args.base_type;delete args.base_type;}else{baseTypename=undefined;}
+let snapshot;try{const args=this.deepCopyIfNeeded_(event.args.snapshot);let cat;if(args.cat){cat=args.cat;delete args.cat;}else{cat=event.cat;}
+let baseTypename;if(args.base_type){baseTypename=args.base_type;delete args.base_type;}else{baseTypename=undefined;}
 snapshot=process.objects.addSnapshot(scopedId,cat,event.name,ts,args,baseTypename);snapshot.snapshottedOnThread=thread;}catch(e){this.model_.importWarning({type:'object_parse_error',message:'While processing snapshot of '+
 scopedId+' at ts='+ts+': '+e});return;}
-instance=snapshot.objectInstance;}else if(event.ph==='D'){try{process.objects.idWasDeleted(scopedId,event.cat,event.name,ts);var instanceMap=process.objects.getOrCreateInstanceMap_(scopedId);instance=instanceMap.lastInstance;}catch(e){this.model_.importWarning({type:'object_parse_error',message:'While processing delete of '+
+instance=snapshot.objectInstance;}else if(event.ph==='D'){try{process.objects.idWasDeleted(scopedId,event.cat,event.name,ts);const instanceMap=process.objects.getOrCreateInstanceMap_(scopedId);instance=instanceMap.lastInstance;}catch(e){this.model_.importWarning({type:'object_parse_error',message:'While processing delete of '+
 scopedId+' at ts='+ts+': '+e});return;}}
-if(instance)
-instance.colorId=getEventColor(event,instance.typeName);}
-this.allObjectEvents_.sort(function(x,y){var d=x.event.ts-y.event.ts;if(d!=0)
-return d;return x.sequenceNumber-y.sequenceNumber;});var allObjectEvents=this.allObjectEvents_;for(var i=0;i<allObjectEvents.length;i++){var objectEventState=allObjectEvents[i];try{processEvent.call(this,objectEventState);}catch(e){this.model_.importWarning({type:'object_parse_error',message:e.message});}}},createImplicitObjects_:function(){tr.b.iterItems(this.model_.processes,function(pid,process){this.createImplicitObjectsForProcess_(process);},this);},createImplicitObjectsForProcess_:function(process){function processField(referencingObject,referencingObjectFieldName,referencingObjectFieldValue,containingSnapshot){if(!referencingObjectFieldValue)
-return;if(referencingObjectFieldValue instanceof
-tr.model.ObjectSnapshot)
-return null;if(referencingObjectFieldValue.id===undefined)
-return;var implicitSnapshot=referencingObjectFieldValue;var rawId=implicitSnapshot.id;var m=/(.+)\/(.+)/.exec(rawId);if(!m)
-throw new Error('Implicit snapshots must have names.');delete implicitSnapshot.id;var name=m[1];var id=m[2];var res;var cat;if(implicitSnapshot.cat!==undefined)
-cat=implicitSnapshot.cat;else
-cat=containingSnapshot.objectInstance.category;var baseTypename;if(implicitSnapshot.base_type)
-baseTypename=implicitSnapshot.base_type;else
-baseTypename=undefined;var scope=containingSnapshot.objectInstance.scopedId.scope;try{res=process.objects.addSnapshot(new tr.model.ScopedId(scope,id),cat,name,containingSnapshot.ts,implicitSnapshot,baseTypename);}catch(e){this.model_.importWarning({type:'object_snapshot_parse_error',message:'While processing implicit snapshot of '+
+if(instance){instance.colorId=getEventColor(event,instance.typeName);}}.bind(this);this.allObjectEvents_.sort(function(x,y){const d=x.event.ts-y.event.ts;if(d!==0)return d;return x.sequenceNumber-y.sequenceNumber;});const allObjectEvents=this.allObjectEvents_;for(let i=0;i<allObjectEvents.length;i++){const objectEventState=allObjectEvents[i];try{processEvent.call(this,objectEventState);}catch(e){this.model_.importWarning({type:'object_parse_error',message:e.message});}}},createImplicitObjects_(){for(const proc of Object.values(this.model_.processes)){this.createImplicitObjectsForProcess_(proc);}},createImplicitObjectsForProcess_(process){function processField(referencingObject,referencingObjectFieldName,referencingObjectFieldValue,containingSnapshot){if(!referencingObjectFieldValue)return;if(referencingObjectFieldValue instanceof
+tr.model.ObjectSnapshot){return null;}
+if(referencingObjectFieldValue.id===undefined)return;const implicitSnapshot=referencingObjectFieldValue;const rawId=implicitSnapshot.id;const m=/(.+)\/(.+)/.exec(rawId);if(!m){throw new Error('Implicit snapshots must have names.');}
+delete implicitSnapshot.id;const name=m[1];const id=m[2];let res;let cat;if(implicitSnapshot.cat!==undefined){cat=implicitSnapshot.cat;}else{cat=containingSnapshot.objectInstance.category;}
+let baseTypename;if(implicitSnapshot.base_type){baseTypename=implicitSnapshot.base_type;}else{baseTypename=undefined;}
+const scope=containingSnapshot.objectInstance.scopedId.scope;try{res=process.objects.addSnapshot(new tr.model.ScopedId(scope,id),cat,name,containingSnapshot.ts,implicitSnapshot,baseTypename);}catch(e){this.model_.importWarning({type:'object_snapshot_parse_error',message:'While processing implicit snapshot of '+
 rawId+' at ts='+containingSnapshot.ts+': '+e});return;}
-res.objectInstance.hasImplicitSnapshots=true;res.containingSnapshot=containingSnapshot;res.snapshottedOnThread=containingSnapshot.snapshottedOnThread;referencingObject[referencingObjectFieldName]=res;if(!(res instanceof tr.model.ObjectSnapshot))
-throw new Error('Created object must be instanceof snapshot');return res.args;}
-function iterObject(object,func,containingSnapshot,thisArg){if(!(object instanceof Object))
-return;if(object instanceof Array){for(var i=0;i<object.length;i++){var res=func.call(thisArg,object,i,object[i],containingSnapshot);if(res===null)
-continue;if(res)
-iterObject(res,func,containingSnapshot,thisArg);else
-iterObject(object[i],func,containingSnapshot,thisArg);}
+res.objectInstance.hasImplicitSnapshots=true;res.containingSnapshot=containingSnapshot;res.snapshottedOnThread=containingSnapshot.snapshottedOnThread;referencingObject[referencingObjectFieldName]=res;if(!(res instanceof tr.model.ObjectSnapshot)){throw new Error('Created object must be instanceof snapshot');}
+return res.args;}
+function iterObject(object,func,containingSnapshot,thisArg){if(!(object instanceof Object))return;if(object instanceof Array){for(let i=0;i<object.length;i++){const res=func.call(thisArg,object,i,object[i],containingSnapshot);if(res===null)continue;if(res){iterObject(res,func,containingSnapshot,thisArg);}else{iterObject(object[i],func,containingSnapshot,thisArg);}}
 return;}
-for(var key in object){var res=func.call(thisArg,object,key,object[key],containingSnapshot);if(res===null)
-continue;if(res)
-iterObject(res,func,containingSnapshot,thisArg);else
-iterObject(object[key],func,containingSnapshot,thisArg);}}
-process.objects.iterObjectInstances(function(instance){instance.snapshots.forEach(function(snapshot){if(snapshot.args.id!==undefined)
-throw new Error('args cannot have an id field inside it');iterObject(snapshot.args,processField,snapshot,this);},this);},this);},createMemoryDumps_:function(){for(var dumpId in this.allMemoryDumpEvents_)
-this.createGlobalMemoryDump_(this.allMemoryDumpEvents_[dumpId],dumpId);},createGlobalMemoryDump_:function(dumpIdEvents,dumpId){var globalRange=new tr.b.Range();for(var pid in dumpIdEvents){var processEvents=dumpIdEvents[pid];for(var i=0;i<processEvents.length;i++)
-globalRange.addValue(timestampFromUs(processEvents[i].ts));}
-if(globalRange.isEmpty)
-throw new Error('Internal error: Global memory dump without events');var globalMemoryDump=new tr.model.GlobalMemoryDump(this.model_,globalRange.min);globalMemoryDump.duration=globalRange.range;this.model_.globalMemoryDumps.push(globalMemoryDump);var globalMemoryAllocatorDumpsByFullName={};var levelsOfDetail={};var allMemoryAllocatorDumpsByGuid={};for(var pid in dumpIdEvents){this.createProcessMemoryDump_(globalMemoryDump,globalMemoryAllocatorDumpsByFullName,levelsOfDetail,allMemoryAllocatorDumpsByGuid,dumpIdEvents[pid],pid,dumpId);}
-globalMemoryDump.levelOfDetail=levelsOfDetail.global;globalMemoryDump.memoryAllocatorDumps=this.inferMemoryAllocatorDumpTree_(globalMemoryAllocatorDumpsByFullName);this.parseMemoryDumpAllocatorEdges_(allMemoryAllocatorDumpsByGuid,dumpIdEvents,dumpId);},createProcessMemoryDump_:function(globalMemoryDump,globalMemoryAllocatorDumpsByFullName,levelsOfDetail,allMemoryAllocatorDumpsByGuid,processEvents,pid,dumpId){var processRange=new tr.b.Range();for(var i=0;i<processEvents.length;i++)
-processRange.addValue(timestampFromUs(processEvents[i].ts));if(processRange.isEmpty)
-throw new Error('Internal error: Process memory dump without events');var process=this.model_.getOrCreateProcess(pid);var processMemoryDump=new tr.model.ProcessMemoryDump(globalMemoryDump,process,processRange.min);processMemoryDump.duration=processRange.range;process.memoryDumps.push(processMemoryDump);globalMemoryDump.processMemoryDumps[pid]=processMemoryDump;var processMemoryAllocatorDumpsByFullName={};for(var i=0;i<processEvents.length;i++){var processEvent=processEvents[i];var dumps=processEvent.args.dumps;if(dumps===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'\'dumps\' field not found in a process memory dump'+' event for PID='+pid+' and dump ID='+dumpId+'.'});continue;}
+for(const key in object){const res=func.call(thisArg,object,key,object[key],containingSnapshot);if(res===null)continue;if(res){iterObject(res,func,containingSnapshot,thisArg);}else{iterObject(object[key],func,containingSnapshot,thisArg);}}}
+process.objects.iterObjectInstances(function(instance){instance.snapshots.forEach(function(snapshot){if(snapshot.args.id!==undefined){throw new Error('args cannot have an id field inside it');}
+iterObject(snapshot.args,processField,snapshot,this);},this);},this);},minimalTimestampInPidToEvents_(pidToEvents){let smallestTs=Infinity;for(const events of Object.values(pidToEvents)){for(const event of events){if(event.ts<smallestTs){smallestTs=event.ts;}}}
+return smallestTs;},createMemoryDumps_(){const pairs=Object.entries(this.allMemoryDumpEvents_);const key=x=>this.minimalTimestampInPidToEvents_(x);pairs.sort((x,y)=>key(x[1])-key(y[1]));for(const[dumpId,pidToEvents]of pairs){this.createGlobalMemoryDump_(pidToEvents,dumpId);}},createGlobalMemoryDump_(dumpIdEvents,dumpId){const globalRange=new tr.b.math.Range();for(const pid in dumpIdEvents){const processEvents=dumpIdEvents[pid];for(let i=0;i<processEvents.length;i++){globalRange.addValue(this.toModelTimeFromUs_(processEvents[i].ts));}}
+if(globalRange.isEmpty){throw new Error('Internal error: Global memory dump without events');}
+const globalMemoryDump=new tr.model.GlobalMemoryDump(this.model_,globalRange.min);globalMemoryDump.duration=globalRange.range;this.model_.globalMemoryDumps.push(globalMemoryDump);const globalMemoryAllocatorDumpsByFullName={};const levelsOfDetail={};const allMemoryAllocatorDumpsByGuid={};for(const pid in dumpIdEvents){this.createProcessMemoryDump_(globalMemoryDump,globalMemoryAllocatorDumpsByFullName,levelsOfDetail,allMemoryAllocatorDumpsByGuid,dumpIdEvents[pid],pid,dumpId);}
+globalMemoryDump.levelOfDetail=levelsOfDetail.global;globalMemoryDump.memoryAllocatorDumps=this.inferMemoryAllocatorDumpTree_(globalMemoryAllocatorDumpsByFullName);this.parseMemoryDumpAllocatorEdges_(allMemoryAllocatorDumpsByGuid,dumpIdEvents,dumpId);},createProcessMemoryDump_(globalMemoryDump,globalMemoryAllocatorDumpsByFullName,levelsOfDetail,allMemoryAllocatorDumpsByGuid,processEvents,pid,dumpId){const processRange=new tr.b.math.Range();for(let i=0;i<processEvents.length;i++){processRange.addValue(this.toModelTimeFromUs_(processEvents[i].ts));}
+if(processRange.isEmpty){throw new Error('Internal error: Process memory dump without events');}
+const process=this.model_.getOrCreateProcess(pid);const processMemoryDump=new tr.model.ProcessMemoryDump(globalMemoryDump,process,processRange.min);processMemoryDump.duration=processRange.range;process.memoryDumps.push(processMemoryDump);globalMemoryDump.processMemoryDumps[pid]=processMemoryDump;const processMemoryAllocatorDumpsByFullName={};for(let i=0;i<processEvents.length;i++){const processEvent=processEvents[i];const dumps=processEvent.args.dumps;if(dumps===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'\'dumps\' field not found in a process memory dump'+' event for PID='+pid+' and dump ID='+dumpId+'.'});continue;}
 this.parseMemoryDumpTotals_(processMemoryDump,dumps,pid,dumpId);this.parseMemoryDumpVmRegions_(processMemoryDump,dumps,pid,dumpId);this.parseMemoryDumpHeapDumps_(processMemoryDump,dumps,pid,dumpId);this.parseMemoryDumpLevelOfDetail_(levelsOfDetail,dumps,pid,dumpId);this.parseMemoryDumpAllocatorDumps_(processMemoryDump,globalMemoryDump,processMemoryAllocatorDumpsByFullName,globalMemoryAllocatorDumpsByFullName,allMemoryAllocatorDumpsByGuid,dumps,pid,dumpId);}
 if(levelsOfDetail.process===undefined){levelsOfDetail.process=processMemoryDump.vmRegions?DETAILED:LIGHT;}
 if(!this.updateMemoryDumpLevelOfDetail_(levelsOfDetail,'global',levelsOfDetail.process)){this.model_.importWarning({type:'memory_dump_parse_error',message:'diffent levels of detail provided for global memory'+' dump (dump ID='+dumpId+').'});}
-processMemoryDump.levelOfDetail=levelsOfDetail.process;delete levelsOfDetail.process;processMemoryDump.memoryAllocatorDumps=this.inferMemoryAllocatorDumpTree_(processMemoryAllocatorDumpsByFullName);},parseMemoryDumpTotals_:function(processMemoryDump,dumps,pid,dumpId){var rawTotals=dumps.process_totals;if(rawTotals===undefined)
-return;if(processMemoryDump.totals!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Process totals provided multiple times for'+' process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});return;}
-var totals={};var platformSpecificTotals=undefined;for(var rawTotalName in rawTotals){var rawTotalValue=rawTotals[rawTotalName];if(rawTotalValue===undefined)
-continue;if(rawTotalName==='resident_set_bytes'){totals.residentBytes=parseInt(rawTotalValue,16);continue;}
+processMemoryDump.levelOfDetail=levelsOfDetail.process;delete levelsOfDetail.process;processMemoryDump.memoryAllocatorDumps=this.inferMemoryAllocatorDumpTree_(processMemoryAllocatorDumpsByFullName);},parseMemoryDumpTotals_(processMemoryDump,dumps,pid,dumpId){const rawTotals=dumps.process_totals;if(rawTotals===undefined)return;if(processMemoryDump.totals!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Process totals provided multiple times for'+' process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});return;}
+const totals={};let platformSpecificTotals=undefined;for(const rawTotalName in rawTotals){const rawTotalValue=rawTotals[rawTotalName];if(rawTotalValue===undefined)continue;if(rawTotalName==='resident_set_bytes'){totals.residentBytes=parseInt(rawTotalValue,16);continue;}
 if(rawTotalName==='peak_resident_set_bytes'){totals.peakResidentBytes=parseInt(rawTotalValue,16);continue;}
 if(rawTotalName==='is_peak_rss_resetable'){totals.arePeakResidentBytesResettable=!!rawTotalValue;continue;}
+if(rawTotalName==='private_footprint_bytes'){totals.privateFootprintBytes=parseInt(rawTotalValue,16);continue;}
 if(platformSpecificTotals===undefined){platformSpecificTotals={};totals.platformSpecific=platformSpecificTotals;}
 platformSpecificTotals[rawTotalName]=parseInt(rawTotalValue,16);}
 if(totals.peakResidentBytes===undefined&&totals.arePeakResidentBytesResettable!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Optional field peak_resident_set_bytes found'+' but is_peak_rss_resetable not found in'+' process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});}
 if(totals.arePeakResidentBytesResettable!==undefined&&totals.peakResidentBytes===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Optional field is_peak_rss_resetable found'+' but peak_resident_set_bytes not found in'+' process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});}
-processMemoryDump.totals=totals;},parseMemoryDumpVmRegions_:function(processMemoryDump,dumps,pid,dumpId){var rawProcessMmaps=dumps.process_mmaps;if(rawProcessMmaps===undefined)
-return;var rawVmRegions=rawProcessMmaps.vm_regions;if(rawVmRegions===undefined)
-return;if(processMemoryDump.vmRegions!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'VM regions provided multiple times for'+' process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});return;}
-var vmRegions=new Array(rawVmRegions.length);for(var i=0;i<rawVmRegions.length;i++){var rawVmRegion=rawVmRegions[i];var byteStats={};var rawByteStats=rawVmRegion.bs;for(var rawByteStatName in rawByteStats){var rawByteStatValue=rawByteStats[rawByteStatName];if(rawByteStatValue===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Byte stat \''+rawByteStatName+'\' of VM region '+
+processMemoryDump.totals=totals;},parseMemoryDumpVmRegions_(processMemoryDump,dumps,pid,dumpId){const rawProcessMmaps=dumps.process_mmaps;if(rawProcessMmaps===undefined)return;const rawVmRegions=rawProcessMmaps.vm_regions;if(rawVmRegions===undefined)return;if(processMemoryDump.vmRegions!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'VM regions provided multiple times for'+' process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});return;}
+const vmRegions=new Array(rawVmRegions.length);for(let i=0;i<rawVmRegions.length;i++){const rawVmRegion=rawVmRegions[i];const byteStats={};const rawByteStats=rawVmRegion.bs;for(const rawByteStatName in rawByteStats){const rawByteStatValue=rawByteStats[rawByteStatName];if(rawByteStatValue===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Byte stat \''+rawByteStatName+'\' of VM region '+
 i+' ('+rawVmRegion.mf+') in process memory dump for '+'PID='+pid+' and dump ID='+dumpId+' does not have a value.'});continue;}
-var byteStatName=BYTE_STAT_NAME_MAP[rawByteStatName];if(byteStatName===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Unknown byte stat name \''+rawByteStatName+'\' ('+
+const byteStatName=BYTE_STAT_NAME_MAP[rawByteStatName];if(byteStatName===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Unknown byte stat name \''+rawByteStatName+'\' ('+
 rawByteStatValue+') of VM region '+i+' ('+
 rawVmRegion.mf+') in process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});continue;}
-byteStats[byteStatName]=parseInt(rawByteStatValue,16);}
+byteStats[byteStatName]=parseInt(rawByteStatValue,16);if(byteStatName==='proportionalResident'&&byteStats[byteStatName]===0){byteStats[byteStatName]=undefined;}}
 vmRegions[i]=new tr.model.VMRegion(parseInt(rawVmRegion.sa,16),parseInt(rawVmRegion.sz,16),rawVmRegion.pf,rawVmRegion.mf,byteStats);}
-processMemoryDump.vmRegions=tr.model.VMRegionClassificationNode.fromRegions(vmRegions);},parseMemoryDumpHeapDumps_:function(processMemoryDump,dumps,pid,dumpId){var rawHeapDumps=dumps.heaps;if(rawHeapDumps===undefined)
-return;if(processMemoryDump.heapDumps!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Heap dumps provided multiple times for'+' process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});return;}
-var model=this.model_;var idPrefix='p'+pid+':';var heapDumps={};var objectTypeNameMap=this.objectTypeNameMap_[pid];if(objectTypeNameMap===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing mapping from object type IDs to names.'});}
-for(var allocatorName in rawHeapDumps){var entries=rawHeapDumps[allocatorName].entries;if(entries===undefined||entries.length===0){this.model_.importWarning({type:'memory_dump_parse_error',message:'No heap entries in a '+allocatorName+' heap dump for PID='+pid+' and dump ID='+dumpId+'.'});continue;}
-var isOldFormat=entries[0].bt===undefined;if(!isOldFormat&&objectTypeNameMap===undefined){continue;}
-var heapDump=new tr.model.HeapDump(processMemoryDump,allocatorName);for(var i=0;i<entries.length;i++){var entry=entries[i];var leafStackFrameIndex=entry.bt;var leafStackFrame;if(isOldFormat){if(leafStackFrameIndex===undefined){leafStackFrame=undefined;}else{var leafStackFrameId=idPrefix+leafStackFrameIndex;if(leafStackFrameIndex===''){leafStackFrame=undefined;}else{leafStackFrame=model.stackFrames[leafStackFrameId];if(leafStackFrame===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing leaf stack frame (ID '+
-leafStackFrameId+') of heap entry '+i+' (size '+
-size+') in a '+allocatorName+' heap dump for PID='+pid+'.'});continue;}}
-leafStackFrameId+=':self';if(model.stackFrames[leafStackFrameId]!==undefined){leafStackFrame=model.stackFrames[leafStackFrameId];}else{leafStackFrame=new tr.model.StackFrame(leafStackFrame,leafStackFrameId,'<self>',undefined);model.addStackFrame(leafStackFrame);}}}else{if(leafStackFrameIndex===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing stack frame ID of heap entry '+i+' (size '+size+') in a '+allocatorName+' heap dump for PID='+pid+'.'});continue;}
-var leafStackFrameId=idPrefix+leafStackFrameIndex;if(leafStackFrameIndex===''){leafStackFrame=undefined;}else{leafStackFrame=model.stackFrames[leafStackFrameId];if(leafStackFrame===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing leaf stack frame (ID '+leafStackFrameId+') of heap entry '+i+' (size '+size+') in a '+
-allocatorName+' heap dump for PID='+pid+'.'});continue;}}}
-var objectTypeId=entry.type;var objectTypeName;if(objectTypeId===undefined){objectTypeName=undefined;}else if(objectTypeNameMap===undefined){continue;}else{objectTypeName=objectTypeNameMap[objectTypeId];if(objectTypeName===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing object type name (ID '+objectTypeId+') of heap entry '+i+' (size '+size+') in a '+
-allocatorName+' heap dump for pid='+pid+'.'});continue;}}
-var size=parseInt(entry.size,16);heapDump.addEntry(leafStackFrame,objectTypeName,size);}
-if(heapDump.entries.length>0)
-heapDumps[allocatorName]=heapDump;}
-if(Object.keys(heapDumps).length>0)
-processMemoryDump.heapDumps=heapDumps;},parseMemoryDumpLevelOfDetail_:function(levelsOfDetail,dumps,pid,dumpId){var rawLevelOfDetail=dumps.level_of_detail;var level;switch(rawLevelOfDetail){case'light':level=LIGHT;break;case'detailed':level=DETAILED;break;case undefined:level=undefined;break;default:this.model_.importWarning({type:'memory_dump_parse_error',message:'unknown raw level of detail \''+rawLevelOfDetail+'\' of process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});return;}
-if(!this.updateMemoryDumpLevelOfDetail_(levelsOfDetail,'process',level)){this.model_.importWarning({type:'memory_dump_parse_error',message:'diffent levels of detail provided for process memory'+' dump for PID='+pid+' (dump ID='+dumpId+').'});}},updateMemoryDumpLevelOfDetail_:function(levelsOfDetail,scope,level){if(!(scope in levelsOfDetail)||level===levelsOfDetail[scope]){levelsOfDetail[scope]=level;return true;}
+processMemoryDump.vmRegions=tr.model.VMRegionClassificationNode.fromRegions(vmRegions);},parseMemoryDumpHeapDumps_(processMemoryDump,dumps,pid,dumpId){const idPrefix='p'+pid+':';let importer;if(dumps.heaps){const processTypeMap=this.objectTypeNameMap_[pid];if(processTypeMap===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing mapping from object type IDs to names.'});}
+importer=new LegacyHeapDumpTraceEventImporter(this.model_,processMemoryDump,processTypeMap,idPrefix,dumpId,dumps.heaps);}else if(dumps.heaps_v2){const data=dumps.heaps_v2;this.heapProfileExpander=this.heapProfileExpander.expandData(data);this.addNewStackFramesFromExpander_(this.heapProfileExpander,idPrefix);importer=new HeapDumpTraceEventImporter(this.heapProfileExpander,this.model_.stackFrames,processMemoryDump,idPrefix,this.model_);}
+if(!importer)return;const heapDumps=importer.parse();if(!heapDumps)return;if(processMemoryDump.heapDumps!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Heap dumps provided multiple times for'+' process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});return;}
+if(Object.keys(heapDumps).length>0){processMemoryDump.heapDumps=heapDumps;}},addNewStackFramesFromExpander_(expander,idPrefix){const nodeMap=expander.getNewMap('nodes');const newStackFrames={};for(const[id,stackFrame]of nodeMap.entries()){if(!this.model_.stackFrames[idPrefix+id]){newStackFrames[id]={id,name:expander.getString(stackFrame.name_sid),};if(stackFrame.parent)newStackFrames[id].parent=stackFrame.parent;}}
+this.importStackFrames_(newStackFrames,idPrefix);},parseMemoryDumpLevelOfDetail_(levelsOfDetail,dumps,pid,dumpId){const rawLevelOfDetail=dumps.level_of_detail;let level;switch(rawLevelOfDetail){case'background':level=BACKGROUND;break;case'light':level=LIGHT;break;case'detailed':level=DETAILED;break;case undefined:level=undefined;break;default:this.model_.importWarning({type:'memory_dump_parse_error',message:'unknown raw level of detail \''+rawLevelOfDetail+'\' of process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});return;}
+if(!this.updateMemoryDumpLevelOfDetail_(levelsOfDetail,'process',level)){this.model_.importWarning({type:'memory_dump_parse_error',message:'diffent levels of detail provided for process memory'+' dump for PID='+pid+' (dump ID='+dumpId+').'});}},updateMemoryDumpLevelOfDetail_(levelsOfDetail,scope,level){if(!(scope in levelsOfDetail)||level===levelsOfDetail[scope]){levelsOfDetail[scope]=level;return true;}
 if(MEMORY_DUMP_LEVEL_OF_DETAIL_ORDER.indexOf(level)>MEMORY_DUMP_LEVEL_OF_DETAIL_ORDER.indexOf(levelsOfDetail[scope])){levelsOfDetail[scope]=level;}
-return false;},parseMemoryDumpAllocatorDumps_:function(processMemoryDump,globalMemoryDump,processMemoryAllocatorDumpsByFullName,globalMemoryAllocatorDumpsByFullName,allMemoryAllocatorDumpsByGuid,dumps,pid,dumpId){var rawAllocatorDumps=dumps.allocators;if(rawAllocatorDumps===undefined)
-return;for(var fullName in rawAllocatorDumps){var rawAllocatorDump=rawAllocatorDumps[fullName];var guid=rawAllocatorDump.guid;if(guid===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+fullName+' for PID='+pid+' and dump ID='+dumpId+' does not have a GUID.'});}
-var flags=rawAllocatorDump.flags||0;var isWeakDump=!!(flags&WEAK_MEMORY_ALLOCATOR_DUMP_FLAG);var containerMemoryDump;var dstIndex;if(fullName.startsWith(GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX)){fullName=fullName.substring(GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX.length);containerMemoryDump=globalMemoryDump;dstIndex=globalMemoryAllocatorDumpsByFullName;}else{containerMemoryDump=processMemoryDump;dstIndex=processMemoryAllocatorDumpsByFullName;}
-var allocatorDump=allMemoryAllocatorDumpsByGuid[guid];if(allocatorDump===undefined){if(fullName in dstIndex){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple GUIDs provided for'+' memory allocator dump '+fullName+': '+
+return false;},parseMemoryDumpAllocatorDumps_(processMemoryDump,globalMemoryDump,processMemoryAllocatorDumpsByFullName,globalMemoryAllocatorDumpsByFullName,allMemoryAllocatorDumpsByGuid,dumps,pid,dumpId){const rawAllocatorDumps=dumps.allocators;if(rawAllocatorDumps===undefined)return;for(let fullName in rawAllocatorDumps){const rawAllocatorDump=rawAllocatorDumps[fullName];const guid=rawAllocatorDump.guid;if(guid===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+fullName+' for PID='+pid+' and dump ID='+dumpId+' does not have a GUID.'});}
+const flags=rawAllocatorDump.flags||0;const isWeakDump=!!(flags&WEAK_MEMORY_ALLOCATOR_DUMP_FLAG);let containerMemoryDump;let dstIndex;if(fullName.startsWith(GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX)){fullName=fullName.substring(GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX.length);containerMemoryDump=globalMemoryDump;dstIndex=globalMemoryAllocatorDumpsByFullName;}else{containerMemoryDump=processMemoryDump;dstIndex=processMemoryAllocatorDumpsByFullName;}
+let allocatorDump=allMemoryAllocatorDumpsByGuid[guid];if(allocatorDump===undefined){if(fullName in dstIndex){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple GUIDs provided for'+' memory allocator dump '+fullName+': '+
 dstIndex[fullName].guid+', '+guid+' (ignored) for'+' PID='+pid+' and dump ID='+dumpId+'.'});continue;}
-allocatorDump=new tr.model.MemoryAllocatorDump(containerMemoryDump,fullName,guid);allocatorDump.weak=isWeakDump;dstIndex[fullName]=allocatorDump;if(guid!==undefined)
-allMemoryAllocatorDumpsByGuid[guid]=allocatorDump;}else{if(allocatorDump.containerMemoryDump!==containerMemoryDump){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+fullName+' (GUID='+guid+') for PID='+pid+' and dump ID='+
+allocatorDump=new tr.model.MemoryAllocatorDump(containerMemoryDump,fullName,guid);allocatorDump.weak=isWeakDump;dstIndex[fullName]=allocatorDump;if(guid!==undefined){allMemoryAllocatorDumpsByGuid[guid]=allocatorDump;}}else{if(allocatorDump.containerMemoryDump!==containerMemoryDump){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+fullName+' (GUID='+guid+') for PID='+pid+' and dump ID='+
 dumpId+' dumped in different contexts.'});continue;}
 if(allocatorDump.fullName!==fullName){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump with GUID='+guid+' for PID='+
 pid+' and dump ID='+dumpId+' has multiple names: '+
 allocatorDump.fullName+', '+fullName+' (ignored).'});continue;}
 if(!isWeakDump){allocatorDump.weak=false;}}
-var attributes=rawAllocatorDump.attrs;if(attributes===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+fullName+' (GUID='+guid+') for PID='+pid+' and dump ID='+dumpId+' does not have attributes.'});attributes={};}
-for(var attrName in attributes){var attrArgs=attributes[attrName];var attrType=attrArgs.type;var attrValue=attrArgs.value;switch(attrType){case'scalar':if(attrName in allocatorDump.numerics){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple values provided for scalar attribute '+
+let attributes=rawAllocatorDump.attrs;if(attributes===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+fullName+' (GUID='+guid+') for PID='+pid+' and dump ID='+dumpId+' does not have attributes.'});attributes={};}
+for(const attrName in attributes){const attrArgs=attributes[attrName];const attrType=attrArgs.type;const attrValue=attrArgs.value;switch(attrType){case'scalar':{if(attrName in allocatorDump.numerics){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple values provided for scalar attribute '+
 attrName+' of memory allocator dump '+fullName+' (GUID='+guid+') for PID='+pid+' and dump ID='+
 dumpId+'.'});break;}
-var unit=attrArgs.units==='bytes'?tr.v.Unit.byName.sizeInBytes_smallerIsBetter:tr.v.Unit.byName.unitlessNumber_smallerIsBetter;var value=parseInt(attrValue,16);allocatorDump.addNumeric(attrName,new tr.v.ScalarNumeric(unit,value));break;case'string':if(attrName in allocatorDump.diagnostics){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple values provided for string attribute '+
+const unit=attrArgs.units==='bytes'?tr.b.Unit.byName.sizeInBytes_smallerIsBetter:tr.b.Unit.byName.unitlessNumber_smallerIsBetter;const value=parseInt(attrValue,16);allocatorDump.addNumeric(attrName,new tr.b.Scalar(unit,value));break;}
+case'string':if(attrName in allocatorDump.diagnostics){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple values provided for string attribute '+
 attrName+' of memory allocator dump '+fullName+' (GUID='+guid+') for PID='+pid+' and dump ID='+
 dumpId+'.'});break;}
 allocatorDump.addDiagnostic(attrName,attrValue);break;default:this.model_.importWarning({type:'memory_dump_parse_error',message:'Unknown type provided for attribute '+attrName+' of memory allocator dump '+fullName+' (GUID='+guid+') for PID='+pid+' and dump ID='+dumpId+': '+
-attrType});break;}}}},inferMemoryAllocatorDumpTree_:function(memoryAllocatorDumpsByFullName){var rootAllocatorDumps=[];var fullNames=Object.keys(memoryAllocatorDumpsByFullName);fullNames.sort();for(var i=0;i<fullNames.length;i++){var fullName=fullNames[i];var allocatorDump=memoryAllocatorDumpsByFullName[fullName];while(true){var lastSlashIndex=fullName.lastIndexOf('/');if(lastSlashIndex===-1){rootAllocatorDumps.push(allocatorDump);break;}
-var parentFullName=fullName.substring(0,lastSlashIndex);var parentAllocatorDump=memoryAllocatorDumpsByFullName[parentFullName];var parentAlreadyExisted=true;if(parentAllocatorDump===undefined){parentAlreadyExisted=false;parentAllocatorDump=new tr.model.MemoryAllocatorDump(allocatorDump.containerMemoryDump,parentFullName);if(allocatorDump.weak!==false){parentAllocatorDump.weak=undefined;}
+attrType});break;}}}},inferMemoryAllocatorDumpTree_(memoryAllocatorDumpsByFullName){const rootAllocatorDumps=[];const fullNames=Object.keys(memoryAllocatorDumpsByFullName);fullNames.sort();for(let i=0;i<fullNames.length;i++){let fullName=fullNames[i];let allocatorDump=memoryAllocatorDumpsByFullName[fullName];while(true){const lastSlashIndex=fullName.lastIndexOf('/');if(lastSlashIndex===-1){rootAllocatorDumps.push(allocatorDump);break;}
+const parentFullName=fullName.substring(0,lastSlashIndex);let parentAllocatorDump=memoryAllocatorDumpsByFullName[parentFullName];let parentAlreadyExisted=true;if(parentAllocatorDump===undefined){parentAlreadyExisted=false;parentAllocatorDump=new tr.model.MemoryAllocatorDump(allocatorDump.containerMemoryDump,parentFullName);if(allocatorDump.weak!==false){parentAllocatorDump.weak=undefined;}
 memoryAllocatorDumpsByFullName[parentFullName]=parentAllocatorDump;}
 allocatorDump.parent=parentAllocatorDump;parentAllocatorDump.children.push(allocatorDump);if(parentAlreadyExisted){if(!allocatorDump.weak){while(parentAllocatorDump!==undefined&&parentAllocatorDump.weak===undefined){parentAllocatorDump.weak=false;parentAllocatorDump=parentAllocatorDump.parent;}}
 break;}
 fullName=parentFullName;allocatorDump=parentAllocatorDump;}}
-for(var fullName in memoryAllocatorDumpsByFullName){var allocatorDump=memoryAllocatorDumpsByFullName[fullName];if(allocatorDump.weak===undefined)
-allocatorDump.weak=true;}
-return rootAllocatorDumps;},parseMemoryDumpAllocatorEdges_:function(allMemoryAllocatorDumpsByGuid,dumpIdEvents,dumpId){for(var pid in dumpIdEvents){var processEvents=dumpIdEvents[pid];for(var i=0;i<processEvents.length;i++){var processEvent=processEvents[i];var dumps=processEvent.args.dumps;if(dumps===undefined)
-continue;var rawEdges=dumps.allocators_graph;if(rawEdges===undefined)
-continue;for(var j=0;j<rawEdges.length;j++){var rawEdge=rawEdges[j];var sourceGuid=rawEdge.source;var sourceDump=allMemoryAllocatorDumpsByGuid[sourceGuid];if(sourceDump===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Edge for PID='+pid+' and dump ID='+dumpId+' is missing source memory allocator dump (GUID='+
+for(const fullName in memoryAllocatorDumpsByFullName){const allocatorDump=memoryAllocatorDumpsByFullName[fullName];if(allocatorDump.weak===undefined){allocatorDump.weak=true;}}
+return rootAllocatorDumps;},parseMemoryDumpAllocatorEdges_(allMemoryAllocatorDumpsByGuid,dumpIdEvents,dumpId){for(const pid in dumpIdEvents){const processEvents=dumpIdEvents[pid];for(let i=0;i<processEvents.length;i++){const processEvent=processEvents[i];const dumps=processEvent.args.dumps;if(dumps===undefined)continue;const rawEdges=dumps.allocators_graph;if(rawEdges===undefined)continue;for(let j=0;j<rawEdges.length;j++){const rawEdge=rawEdges[j];const sourceGuid=rawEdge.source;const sourceDump=allMemoryAllocatorDumpsByGuid[sourceGuid];if(sourceDump===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Edge for PID='+pid+' and dump ID='+dumpId+' is missing source memory allocator dump (GUID='+
 sourceGuid+').'});continue;}
-var targetGuid=rawEdge.target;var targetDump=allMemoryAllocatorDumpsByGuid[targetGuid];if(targetDump===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Edge for PID='+pid+' and dump ID='+dumpId+' is missing target memory allocator dump (GUID='+
+const targetGuid=rawEdge.target;const targetDump=allMemoryAllocatorDumpsByGuid[targetGuid];if(targetDump===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Edge for PID='+pid+' and dump ID='+dumpId+' is missing target memory allocator dump (GUID='+
 targetGuid+').'});continue;}
-var importance=rawEdge.importance;var edge=new tr.model.MemoryAllocatorDumpLink(sourceDump,targetDump,importance);switch(rawEdge.type){case'ownership':if(sourceDump.owns!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+sourceDump.fullName+' (GUID='+sourceGuid+') already owns a memory'+' allocator dump ('+
+const importance=rawEdge.importance;const edge=new tr.model.MemoryAllocatorDumpLink(sourceDump,targetDump,importance);switch(rawEdge.type){case'ownership':if(sourceDump.owns!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+sourceDump.fullName+' (GUID='+sourceGuid+') already owns a memory'+' allocator dump ('+
 sourceDump.owns.target.fullName+').'});}else{sourceDump.owns=edge;targetDump.ownedBy.push(edge);}
-break;case'retention':sourceDump.retains.push(edge);targetDump.retainedBy.push(edge);break;default:this.model_.importWarning({type:'memory_dump_parse_error',message:'Invalid edge type: '+rawEdge.type+' (PID='+pid+', dump ID='+dumpId+', source='+sourceGuid+', target='+targetGuid+', importance='+importance+').'});}}}}}};tr.importer.Importer.register(TraceEventImporter);return{TraceEventImporter:TraceEventImporter};});'use strict';tr.exportTo('tr.e.measure',function(){var AsyncSlice=tr.model.AsyncSlice;function MeasureAsyncSlice(){this.groupTitle_='Ungrouped Measure';var matched=/([^\/:]+):([^\/:]+)\/?(.*)/.exec(arguments[1]);if(matched!==null){arguments[1]=matched[2];this.groupTitle_=matched[1];}
-AsyncSlice.apply(this,arguments);}
-MeasureAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get viewSubGroupTitle(){return this.groupTitle_;},get title(){return this.title_;},set title(title){this.title_=title;}};AsyncSlice.register(MeasureAsyncSlice,{categoryParts:['blink.user_timing']});return{MeasureAsyncSlice:MeasureAsyncSlice};});'use strict';tr.exportTo('tr.e.net',function(){var AsyncSlice=tr.model.AsyncSlice;function NetAsyncSlice(){AsyncSlice.apply(this,arguments);this.url_=undefined;this.byteCount_=undefined;this.isTitleComputed_=false;this.isUrlComputed_=false;}
-NetAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get viewSubGroupTitle(){return'NetLog';},get title(){if(this.isTitleComputed_||!this.isTopLevel)
-return this.title_;if(this.url!==undefined&&this.url.length>0){this.title_=this.url;}else if(this.args!==undefined&&this.args.source_type!==undefined){this.title_=this.args.source_type;}
-this.isTitleComputed_=true;return this.title_;},set title(title){this.title_=title;},get url(){if(this.isUrlComputed_)
-return this.url_;if(this.args!==undefined&&this.args.params!==undefined&&this.args.params.url!==undefined){this.url_=this.args.params.url;}else if(this.subSlices!==undefined&&this.subSlices.length>0){for(var i=0;i<this.subSlices.length&&!this.url_;i++){if(this.subSlices[i].url!==undefined)
-this.url_=this.subSlices[i].url;}}
-this.isUrlComputed_=true;return this.url_;},get byteCount(){if(this.byteCount_!==undefined)
-return this.byteCount_;this.byteCount_=0;if((this.originalTitle==='URL_REQUEST_JOB_FILTERED_BYTES_READ'||this.originalTitle==='URL_REQUEST_JOB_BYTES_READ')&&this.args!==undefined&&this.args.params!==undefined&&this.args.params.byte_count!==undefined){this.byteCount_=this.args.params.byte_count;}
-for(var i=0;i<this.subSlices.length;i++){this.byteCount_+=this.subSlices[i].byteCount;}
-return this.byteCount_;}};AsyncSlice.register(NetAsyncSlice,{categoryParts:['netlog','disabled-by-default-netlog']});return{NetAsyncSlice:NetAsyncSlice};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;function Activity(name,category,range,args){tr.model.TimedEvent.call(this,range.min);this.title=name;this.category=category;this.colorId=ColorScheme.getColorIdForGeneralPurposeString(name);this.duration=range.duration;this.args=args;this.name=name;};Activity.prototype={__proto__:tr.model.TimedEvent.prototype,shiftTimestampsForward:function(amount){this.start+=amount;},addBoundsToRange:function(range){range.addValue(this.start);range.addValue(this.end);}};return{Activity:Activity};});'use strict';tr.exportTo('tr.e.importer.android',function(){var Importer=tr.importer.Importer;var ACTIVITY_STATE={NONE:'none',CREATED:'created',STARTED:'started',RESUMED:'resumed',PAUSED:'paused',STOPPED:'stopped',DESTROYED:'destroyed'};var activityMap={};function EventLogImporter(model,events){this.model_=model;this.events_=events;this.importPriority=3;}
-var eventLogActivityRE=new RegExp('(\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}.\\d+)'+'\\s+(\\d+)\\s+(\\d+)\\s+([A-Z])\\s*'+'(am_\\w+)\\s*:(.*)');var amCreateRE=new RegExp('\s*\\[.*,.*,.*,(.*),.*,.*,.*,.*\\]');var amFocusedRE=new RegExp('\s*\\[\\d+,(.*)\\]');var amProcStartRE=new RegExp('\s*\\[\\d+,\\d+,\\d+,.*,activity,(.*)\\]');var amOnResumeRE=new RegExp('\s*\\[\\d+,(.*)\\]');var amOnPauseRE=new RegExp('\s*\\[\\d+,(.*)\\]');var amLaunchTimeRE=new RegExp('\s*\\[\\d+,\\d+,(.*),(\\d+),(\\d+)');var amDestroyRE=new RegExp('\s*\\[\\d+,\\d+,\\d+,(.*)\\]');EventLogImporter.canImport=function(events){if(!(typeof(events)==='string'||events instanceof String))
-return false;if(/^<!DOCTYPE html>/.test(events))
-return false;return eventLogActivityRE.test(events);};EventLogImporter.prototype={__proto__:Importer.prototype,get importerName(){return'EventLogImporter';},get model(){return this.model_;},getFullActivityName:function(component){var componentSplit=component.split('/');if(componentSplit[1].startsWith('.'))
-return componentSplit[0]+componentSplit[1];return componentSplit[1];},getProcName:function(component){var componentSplit=component.split('/');return componentSplit[0];},findOrCreateActivity:function(activityName){if(activityName in activityMap)
-return activityMap[activityName];var activity={state:ACTIVITY_STATE.NONE,name:activityName};activityMap[activityName]=activity;return activity;},deleteActivity:function(activityName){delete activityMap[activityName];},handleCreateActivity:function(ts,activityName){var activity=this.findOrCreateActivity(activityName);activity.state=ACTIVITY_STATE.CREATED;activity.createdTs=ts;},handleFocusActivity:function(ts,procName,activityName){var activity=this.findOrCreateActivity(activityName);activity.lastFocusedTs=ts;},handleProcStartForActivity:function(ts,activityName){var activity=this.findOrCreateActivity(activityName);activity.procStartTs=ts;},handleOnResumeCalled:function(ts,pid,activityName){var activity=this.findOrCreateActivity(activityName);activity.state=ACTIVITY_STATE.RESUMED;activity.lastResumeTs=ts;activity.pid=pid;},handleOnPauseCalled:function(ts,activityName){var activity=this.findOrCreateActivity(activityName);activity.state=ACTIVITY_STATE.PAUSED;activity.lastPauseTs=ts;if(ts>this.model_.bounds.min&&ts<this.model_.bounds.max)
-this.addActivityToProcess(activity);},handleLaunchTime:function(ts,activityName,launchTime){var activity=this.findOrCreateActivity(activityName);activity.launchTime=launchTime;},handleDestroyActivity:function(ts,activityName){this.deleteActivity(activityName);},addActivityToProcess:function(activity){if(activity.pid===undefined)
-return;var process=this.model_.getOrCreateProcess(activity.pid);var range=tr.b.Range.fromExplicitRange(Math.max(this.model_.bounds.min,activity.lastResumeTs),activity.lastPauseTs);var newActivity=new tr.model.Activity(activity.name,'Android Activity',range,{created:activity.createdTs,procstart:activity.procStartTs,lastfocus:activity.lastFocusedTs});process.activities.push(newActivity);},parseAmLine_:function(line){var match=eventLogActivityRE.exec(line);if(!match)
-return;var first_realtime_ts=this.model_.bounds.min-
-this.model_.realtime_to_monotonic_offset_ms;var year=new Date(first_realtime_ts).getFullYear();var ts=match[1].substring(0,5)+'-'+year+' '+
-match[1].substring(5,match[1].length);var monotonic_ts=Date.parse(ts)+
-this.model_.realtime_to_monotonic_offset_ms;var pid=match[2];var action=match[5];var data=match[6];if(action==='am_create_activity'){match=amCreateRE.exec(data);if(match&&match.length>=2){this.handleCreateActivity(monotonic_ts,this.getFullActivityName(match[1]));}}else if(action==='am_focused_activity'){match=amFocusedRE.exec(data);if(match&&match.length>=2){this.handleFocusActivity(monotonic_ts,this.getProcName(match[1]),this.getFullActivityName(match[1]));}}else if(action==='am_proc_start'){match=amProcStartRE.exec(data);if(match&&match.length>=2){this.handleProcStartForActivity(monotonic_ts,this.getFullActivityName(match[1]));}}else if(action==='am_on_resume_called'){match=amOnResumeRE.exec(data);if(match&&match.length>=2)
-this.handleOnResumeCalled(monotonic_ts,pid,match[1]);}else if(action==='am_on_paused_called'){match=amOnPauseRE.exec(data);if(match&&match.length>=2)
-this.handleOnPauseCalled(monotonic_ts,match[1]);}else if(action==='am_activity_launch_time'){match=amLaunchTimeRE.exec(data);this.handleLaunchTime(monotonic_ts,this.getFullActivityName(match[1]),match[2]);}else if(action==='am_destroy_activity'){match=amDestroyRE.exec(data);if(match&&match.length==2){this.handleDestroyActivity(monotonic_ts,this.getFullActivityName(match[1]));}}},importEvents:function(){if(isNaN(this.model_.realtime_to_monotonic_offset_ms)){this.model_.importWarning({type:'eveng_log_clock_sync',message:'Need a trace_event_clock_sync to map realtime to import.'});return;}
-this.model_.updateBounds();var lines=this.events_.split('\n');lines.forEach(this.parseAmLine_,this);for(var activityName in activityMap){var activity=activityMap[activityName];if(activity.state==ACTIVITY_STATE.RESUMED){activity.lastPauseTs=this.model_.bounds.max;this.addActivityToProcess(activity);}}}};Importer.register(EventLogImporter);return{EventLogImporter:EventLogImporter};});'use strict';tr.exportTo('tr.e.importer.battor',function(){function BattorImporter(model,events){this.importPriority=3;this.sampleRate_=undefined;this.model_=model;this.events_=events;this.explicitSyncMark_=undefined;}
-var TestExports={};var battorDataLineRE=new RegExp('^(\\d+\\.\\d+)\\s+(\\d+\\.\\d+)\\s+(\\d+\\.\\d+)'+'(?:\\s+<(\\S+)>)?$');var battorHeaderLineRE=/^# BattOr/;var sampleRateLineRE=/^# sample_rate (\d+) Hz/;BattorImporter.canImport=function(events){if(!(typeof(events)==='string'||events instanceof String))
-return false;return battorHeaderLineRE.test(events);};BattorImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'BattorImporter';},get model(){return this.model_;},importEvents:function(){if(this.model_.device.powerSeries){this.model_.importWarning({type:'import_error',message:'Power counter exists, can not import BattOr power trace.'});return;}
-var name='power';var series=new tr.model.PowerSeries(this.model_.device);this.importPowerSamples(series);var battorSyncMarks=this.model_.getClockSyncRecordsWithSyncId('battor');var shiftTs=undefined;shiftTs=this.correlationClockSync(battorSyncMarks,series);if(shiftTs===undefined)
-shiftTs=this.explicitClockSync();if(shiftTs===undefined){this.model_.importWarning({type:'clock_sync',message:'All of the BattOr power trace clock sync techinques failed.'});return;}
-series.shiftTimestampsForward(shiftTs);this.model_.device.powerSeries=series;},importPowerSamples:function(series){var lines=this.events_.split('\n');this.model_.updateBounds();var minTs=0;if(this.model_.bounds.min!==undefined)
-minTs=this.model_.bounds.min;lines.forEach(function(line){line=line.trim();if(line.length===0)
-return;if(/^#/.test(line)){groups=sampleRateLineRE.exec(line);if(!groups)
-return;this.sampleRate_=parseInt(groups[1]);}else{var groups=battorDataLineRE.exec(line);if(!groups){this.model_.importWarning({type:'parse_error',message:'Unrecognized line: '+line});return;}
-var time=parseFloat(groups[1])+minTs;var voltage_mV=parseFloat(groups[2]);var current_mA=parseFloat(groups[3]);series.addPowerSample(time,(voltage_mV*current_mA)/1000);if(groups[4]!==undefined&&this.explicitSyncMark_===undefined){var id=groups[4];this.explicitSyncMark_={'id':id,'ts':time};}}},this);},correlationClockSync:function(syncMarks,series){if(syncMarks.length!==2)
-return undefined;var syncCtr=this.model_.kernel.counters['null.vreg '+syncMarks[0].args['regulator']+' enabled'];if(syncCtr===undefined){this.model_.importWarning({type:'clock_sync',message:'Cannot correlate BattOr power trace without sync vreg.'});return undefined;}
-var syncEvents=[];var firstSyncEventTs=undefined;syncCtr.series[0].iterateAllEvents(function(event){if(event.timestamp>=syncMarks[0].start&&event.timestamp<=syncMarks[1].start){if(firstSyncEventTs===undefined)
-firstSyncEventTs=event.timestamp;var newEvent={'ts':(event.timestamp-firstSyncEventTs)/1000,'val':event.value};syncEvents.push(newEvent);}});var syncSamples=[];var syncNumSamples=Math.ceil(syncEvents[syncEvents.length-1].ts*this.sampleRate_);for(var i=1;i<syncEvents.length;i++){var sampleStartIdx=Math.ceil(syncEvents[i-1].ts*this.sampleRate_);var sampleEndIdx=Math.ceil(syncEvents[i].ts*this.sampleRate_);for(var j=sampleStartIdx;j<sampleEndIdx;j++){syncSamples[j]=syncEvents[i-1].val;}}
-var powerSamples=series.samples;if(powerSamples.length<syncSamples.length){this.model_.importWarning({type:'not_enough_samples',message:'Not enough power samples to correlate with sync signal.'});return undefined;}
-var maxShift=powerSamples.length-syncSamples.length;var minShift=0;var corrNumSamples=this.sampleRate_*5.0;if(powerSamples.length>corrNumSamples)
-minShift=powerSamples.length-corrNumSamples;var corr=[];for(var shift=minShift;shift<=maxShift;shift++){var corrSum=0;var powerAvg=0;for(var i=0;i<syncSamples.length;i++){corrSum+=(powerSamples[i+shift].power*syncSamples[i]);powerAvg+=powerSamples[i+shift].power;}
-powerAvg=powerAvg/syncSamples.length;corr.push(corrSum/powerAvg);}
-var corrPeakIdx=0;var corrPeak=0;for(var i=0;i<powerSamples.length;i++){if(corr[i]>corrPeak){corrPeak=corr[i];corrPeakIdx=i;}}
-var corrPeakTs=((minShift+corrPeakIdx)/this.sampleRate_);corrPeakTs*=1000;var syncStartTs=firstSyncEventTs-this.model_.bounds.min;var shiftTs=syncStartTs-corrPeakTs;return shiftTs;},explicitClockSync:function(){if(this.explicitSyncMark_===undefined)
-return undefined;var syncMarks=this.model.getClockSyncRecordsWithSyncId(this.explicitSyncMark_['id']);if(syncMarks.length!==1){this.model_.importWarning({type:'missing_sync_marker',message:'No single clock sync record found for explicit clock sync.'});return undefined;}
-var clockSync=syncMarks[0];var syncTs=clockSync.start;var traceTs=this.explicitSyncMark_['ts'];return syncTs-traceTs;},foundExplicitSyncMark:function(){return this.explicitSyncMark_!==undefined;}};tr.importer.Importer.register(BattorImporter);return{BattorImporter:BattorImporter,_BattorImporterTestExports:TestExports};});'use strict';tr.exportTo('tr.e.importer.ddms',function(){var kPid=0;var kCategory='java';var kMethodLutEndMarker='\n*end\n';var kThreadsStart='\n*threads\n';var kMethodsStart='\n*methods\n';var kTraceMethodEnter=0x00;var kTraceMethodExit=0x01;var kTraceUnroll=0x02;var kTraceMethodActionMask=0x03;var kTraceHeaderLength=32;var kTraceMagicValue=0x574f4c53;var kTraceVersionSingleClock=2;var kTraceVersionDualClock=3;var kTraceRecordSizeSingleClock=10;var kTraceRecordSizeDualClock=14;function Reader(string_payload){this.position_=0;this.data_=JSZip.utils.transformTo('uint8array',string_payload);}
-Reader.prototype={__proto__:Object.prototype,uint8:function(){var result=this.data_[this.position_];this.position_+=1;return result;},uint16:function(){var result=0;result+=this.uint8();result+=this.uint8()<<8;return result;},uint32:function(){var result=0;result+=this.uint8();result+=this.uint8()<<8;result+=this.uint8()<<16;result+=this.uint8()<<24;return result;},uint64:function(){var low=this.uint32();var high=this.uint32();var low_str=('0000000'+low.toString(16)).substr(-8);var high_str=('0000000'+high.toString(16)).substr(-8);var result=high_str+low_str;return result;},seekTo:function(position){this.position_=position;},hasMore:function(){return this.position_<this.data_.length;}};function DdmsImporter(model,data){this.importPriority=3;this.model_=model;this.data_=data;}
-DdmsImporter.canImport=function(data){if(typeof(data)==='string'||data instanceof String){var header=data.slice(0,1000);return header.startsWith('*version\n')&&header.indexOf('\nvm=')>=0&&header.indexOf(kThreadsStart)>=0;}
-return false;};DdmsImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'DdmsImporter';},get model(){return this.model_;},importEvents:function(){var divider=this.data_.indexOf(kMethodLutEndMarker)+
-kMethodLutEndMarker.length;this.metadata_=this.data_.slice(0,divider);this.methods_={};this.parseThreads();this.parseMethods();var traceReader=new Reader(this.data_.slice(divider));var magic=traceReader.uint32();if(magic!=kTraceMagicValue){throw Error('Failed to match magic value');}
-this.version_=traceReader.uint16();if(this.version_!=kTraceVersionDualClock){throw Error('Unknown version');}
-var dataOffest=traceReader.uint16();var startDateTime=traceReader.uint64();var recordSize=traceReader.uint16();traceReader.seekTo(dataOffest);while(traceReader.hasMore()){this.parseTraceEntry(traceReader);}},parseTraceEntry:function(reader){var tid=reader.uint16();var methodPacked=reader.uint32();var cpuSinceStart=reader.uint32();var wallClockSinceStart=reader.uint32();var method=methodPacked&~kTraceMethodActionMask;var action=methodPacked&kTraceMethodActionMask;var thread=this.getTid(tid);method=this.getMethodName(method);if(action==kTraceMethodEnter){thread.sliceGroup.beginSlice(kCategory,method,wallClockSinceStart,undefined,cpuSinceStart);}else if(thread.sliceGroup.openSliceCount){thread.sliceGroup.endSlice(wallClockSinceStart,cpuSinceStart);}},parseThreads:function(){var threads=this.metadata_.slice(this.metadata_.indexOf(kThreadsStart)+
-kThreadsStart.length);threads=threads.slice(0,threads.indexOf('\n*'));threads=threads.split('\n');threads.forEach(this.parseThread.bind(this));},parseThread:function(thread_line){var tid=thread_line.slice(0,thread_line.indexOf('\t'));var thread=this.getTid(parseInt(tid));thread.name=thread_line.slice(thread_line.indexOf('\t')+1);},getTid:function(tid){return this.model_.getOrCreateProcess(kPid).getOrCreateThread(tid);},parseMethods:function(){var methods=this.metadata_.slice(this.metadata_.indexOf(kMethodsStart)+
-kMethodsStart.length);methods=methods.slice(0,methods.indexOf('\n*'));methods=methods.split('\n');methods.forEach(this.parseMethod.bind(this));},parseMethod:function(method_line){var data=method_line.split('\t');var methodId=parseInt(data[0]);var methodName=data[1]+'.'+data[2]+data[3];this.addMethod(methodId,methodName);},addMethod:function(methodId,methodName){this.methods_[methodId]=methodName;},getMethodName:function(methodId){return this.methods_[methodId];}};tr.importer.Importer.register(DdmsImporter);return{DdmsImporter:DdmsImporter};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){function Parser(importer){this.importer=importer;this.model=importer.model;}
-Parser.prototype={__proto__:Object.prototype};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.mandatoryBaseClass=Parser;tr.b.decorateExtensionRegistry(Parser,options);return{Parser:Parser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function AndroidParser(importer){Parser.call(this,importer);importer.registerEventHandler('tracing_mark_write:android',AndroidParser.prototype.traceMarkWriteAndroidEvent.bind(this));importer.registerEventHandler('0:android',AndroidParser.prototype.traceMarkWriteAndroidEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
-function parseArgs(argsString){var args={};if(argsString){var argsArray=argsString.split(';');for(var i=0;i<argsArray.length;++i){var parts=argsArray[i].split('=');if(parts[0])
-args[parts.shift()]=parts.join('=');}}
+break;case'retention':sourceDump.retains.push(edge);targetDump.retainedBy.push(edge);break;default:this.model_.importWarning({type:'memory_dump_parse_error',message:'Invalid edge type: '+rawEdge.type+' (PID='+pid+', dump ID='+dumpId+', source='+sourceGuid+', target='+targetGuid+', importance='+importance+').'});}}}}},toModelTimeFromUs_(ts){if(!this.toModelTime_){this.toModelTime_=this.model_.clockSyncManager.getModelTimeTransformer(this.clockDomainId_);}
+return this.toModelTime_(tr.b.Unit.timestampFromUs(ts));},maybeToModelTimeFromUs_(ts){if(ts===undefined){return undefined;}
+return this.toModelTimeFromUs_(ts);}};tr.importer.Importer.register(TraceEventImporter);return{TraceEventImporter,};});'use strict';tr.exportTo('tr.e.net',function(){const AsyncSlice=tr.model.AsyncSlice;function NetAsyncSlice(){AsyncSlice.apply(this,arguments);this.url_=undefined;this.byteCount_=undefined;this.isTitleComputed_=false;this.isUrlComputed_=false;}
+NetAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get viewSubGroupTitle(){return'NetLog';},get title(){if(this.isTitleComputed_||!this.isTopLevel){return this.title_;}
+if(this.url!==undefined&&this.url.length>0){this.title_=this.url;}else if(this.args!==undefined&&this.args.source_type!==undefined){this.title_=this.args.source_type;}
+this.isTitleComputed_=true;return this.title_;},set title(title){this.title_=title;},get url(){if(this.isUrlComputed_){return this.url_;}
+if(this.args!==undefined&&this.args.params!==undefined&&this.args.params.url!==undefined){this.url_=this.args.params.url;}else if(this.subSlices!==undefined&&this.subSlices.length>0){for(let i=0;i<this.subSlices.length&&!this.url_;i++){if(this.subSlices[i].url!==undefined){this.url_=this.subSlices[i].url;}}}
+this.isUrlComputed_=true;return this.url_;},get byteCount(){if(this.byteCount_!==undefined){return this.byteCount_;}
+this.byteCount_=0;if((this.originalTitle==='URL_REQUEST_JOB_FILTERED_BYTES_READ'||this.originalTitle==='URL_REQUEST_JOB_BYTES_READ')&&this.args!==undefined&&this.args.params!==undefined&&this.args.params.byte_count!==undefined){this.byteCount_=this.args.params.byte_count;}
+for(let i=0;i<this.subSlices.length;i++){this.byteCount_+=this.subSlices[i].byteCount;}
+return this.byteCount_;}};AsyncSlice.subTypes.register(NetAsyncSlice,{categoryParts:['netlog','disabled-by-default-netlog']});return{NetAsyncSlice,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){function Parser(importer){this.importer=importer;this.model=importer.model;}
+Parser.prototype={__proto__:Object.prototype};const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.mandatoryBaseClass=Parser;tr.b.decorateExtensionRegistry(Parser,options);return{Parser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function AndroidParser(importer){Parser.call(this,importer);importer.registerEventHandler('tracing_mark_write:android',AndroidParser.prototype.traceMarkWriteAndroidEvent.bind(this));importer.registerEventHandler('0:android',AndroidParser.prototype.traceMarkWriteAndroidEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
+function parseArgs(argsString){const args={};if(argsString){const argsArray=argsString.split(';');for(let i=0;i<argsArray.length;++i){const parts=argsArray[i].split('=');if(parts[0]){args[parts.shift()]=parts.join('=');}}}
 return args;}
-AndroidParser.prototype={__proto__:Parser.prototype,openAsyncSlice:function(thread,category,name,cookie,ts,args){var asyncSliceConstructor=tr.model.AsyncSlice.getConstructor(category,name);var slice=new asyncSliceConstructor(category,name,ColorScheme.getColorIdForGeneralPurposeString(name),ts,args);var key=category+':'+name+':'+cookie;slice.id=cookie;slice.startThread=thread;if(!this.openAsyncSlices){this.openAsyncSlices={};}
-this.openAsyncSlices[key]=slice;},closeAsyncSlice:function(thread,category,name,cookie,ts,args){if(!this.openAsyncSlices){return;}
-var key=category+':'+name+':'+cookie;var slice=this.openAsyncSlices[key];if(!slice){return;}
-for(var arg in args){if(slice.args[arg]!==undefined){this.model_.importWarning({type:'parse_error',message:'Both the S and F events of '+slice.title+' provided values for argument '+arg+'.'+' The value of the F event will be used.'});}
+AndroidParser.prototype={__proto__:Parser.prototype,openAsyncSlice(thread,category,name,cookie,ts,args){const asyncSliceConstructor=tr.model.AsyncSlice.subTypes.getConstructor(category,name);const slice=new asyncSliceConstructor(category,name,ColorScheme.getColorIdForGeneralPurposeString(name),ts,args);const key=category+':'+name+':'+cookie;slice.id=cookie;slice.startThread=thread;if(!this.openAsyncSlices){this.openAsyncSlices={};}
+this.openAsyncSlices[key]=slice;},closeAsyncSlice(thread,category,name,cookie,ts,args){if(!this.openAsyncSlices){return;}
+const key=category+':'+name+':'+cookie;const slice=this.openAsyncSlices[key];if(!slice){return;}
+for(const arg in args){if(slice.args[arg]!==undefined){this.model_.importWarning({type:'parse_error',message:'Both the S and F events of '+slice.title+' provided values for argument '+arg+'.'+' The value of the F event will be used.'});}
 slice.args[arg]=args[arg];}
-slice.endThread=thread;slice.duration=ts-slice.start;slice.startThread.asyncSliceGroup.push(slice);slice.subSlices=[new tr.model.AsyncSlice(slice.category,slice.title,slice.colorId,slice.start,slice.args,slice.duration)];delete this.openAsyncSlices[key];},traceMarkWriteAndroidEvent:function(eventName,cpuNumber,pid,ts,eventBase){var eventData=eventBase.details.split('|');switch(eventData[0]){case'B':var ppid=parseInt(eventData[1]);var title=eventData[2];var args=parseArgs(eventData[3]);var category=eventData[4];if(category===undefined)
-category='android';var thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);thread.name=eventBase.threadName;if(!thread.sliceGroup.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
-this.ppids_[pid]=ppid;thread.sliceGroup.beginSlice(category,title,ts,args);break;case'E':var ppid=this.ppids_[pid];if(ppid===undefined){break;}
-var thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);if(!thread.sliceGroup.openSliceCount){break;}
-var slice=thread.sliceGroup.endSlice(ts);var args=parseArgs(eventData[3]);for(var arg in args){if(slice.args[arg]!==undefined){this.model_.importWarning({type:'parse_error',message:'Both the B and E events of '+slice.title+' provided values for argument '+arg+'.'+' The value of the E event will be used.'});}
+slice.endThread=thread;slice.duration=ts-slice.start;slice.startThread.asyncSliceGroup.push(slice);delete this.openAsyncSlices[key];},traceMarkWriteAndroidEvent(eventName,cpuNumber,pid,ts,eventBase){const eventData=eventBase.details.split('|');switch(eventData[0]){case'B':{const ppid=parseInt(eventData[1]);const title=eventData[2];const args=parseArgs(eventData[3]);let category=eventData[4];if(category===undefined)category='android';const thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);thread.name=eventBase.threadName;if(!thread.sliceGroup.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
+this.ppids_[pid]=ppid;thread.sliceGroup.beginSlice(category,title,ts,args);break;}
+case'E':{const ppid=this.ppids_[pid];if(ppid===undefined){break;}
+const thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);if(!thread.sliceGroup.openSliceCount){break;}
+const slice=thread.sliceGroup.endSlice(ts);const args=parseArgs(eventData[3]);for(const arg in args){if(slice.args[arg]!==undefined){this.model_.importWarning({type:'parse_error',message:'Both the B and E events of '+slice.title+' provided values for argument '+arg+'.'+' The value of the E event will be used.'});}
 slice.args[arg]=args[arg];}
-break;case'C':var ppid=parseInt(eventData[1]);var name=eventData[2];var value=parseInt(eventData[3]);var category=eventData[4];if(category===undefined)
-category='android';var ctr=this.model_.getOrCreateProcess(ppid).getOrCreateCounter(category,name);if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries(value,ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
-ctr.series.forEach(function(series){series.addCounterSample(ts,value);});break;case'S':var ppid=parseInt(eventData[1]);var name=eventData[2];var cookie=parseInt(eventData[3]);var args=parseArgs(eventData[4]);var category=eventData[5];if(category===undefined)
-category='android';var thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);thread.name=eventBase.threadName;this.ppids_[pid]=ppid;this.openAsyncSlice(thread,category,name,cookie,ts,args);break;case'F':var ppid=parseInt(eventData[1]);var name=eventData[2];var cookie=parseInt(eventData[3]);var args=parseArgs(eventData[4]);var category=eventData[5];if(category===undefined)
-category='android';var thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);thread.name=eventBase.threadName;this.ppids_[pid]=ppid;this.closeAsyncSlice(thread,category,name,cookie,ts,args);break;default:return false;}
-return true;}};Parser.register(AndroidParser);return{AndroidParser:AndroidParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;var binderTransRE=new RegExp('transaction=(\\d+) dest_node=(\\d+) '+'dest_proc=(\\d+) dest_thread=(\\d+) '+'reply=(\\d+) flags=(0x[0-9a-fA-F]+) '+'code=(0x[0-9a-fA-F]+)');var binderTransReceivedRE=/transaction=(\d+)/;function isBinderThread(name){return(name.indexOf('Binder')>-1);}
-var TF_ONE_WAY=0x01;var TF_ROOT_OBJECT=0x04;var TF_STATUS_CODE=0x08;var TF_ACCEPT_FDS=0x10;var NO_FLAGS=0;function binderFlagsToHuman(num){var flag=parseInt(num,16);var str='';if(flag&TF_ONE_WAY)
-str+='this is a one-way call: async, no return; ';if(flag&TF_ROOT_OBJECT)
-str+='contents are the components root object; ';if(flag&TF_STATUS_CODE)
-str+='contents are a 32-bit status code; ';if(flag&TF_ACCEPT_FDS)
-str+='allow replies with file descriptors; ';if(flag===NO_FLAGS)
-str+='No Flags Set';return str;}
+break;}
+case'C':{const ppid=parseInt(eventData[1]);const name=eventData[2];const value=parseInt(eventData[3]);let category=eventData[4];if(category===undefined)category='android';const ctr=this.model_.getOrCreateProcess(ppid).getOrCreateCounter(category,name);if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries(value,ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
+ctr.series.forEach(function(series){series.addCounterSample(ts,value);});break;}
+case'S':{const ppid=parseInt(eventData[1]);const name=eventData[2];const cookie=parseInt(eventData[3]);const args=parseArgs(eventData[4]);let category=eventData[5];if(category===undefined)category='android';const thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);thread.name=eventBase.threadName;this.ppids_[pid]=ppid;this.openAsyncSlice(thread,category,name,cookie,ts,args);break;}
+case'F':{const ppid=parseInt(eventData[1]);const name=eventData[2];const cookie=parseInt(eventData[3]);const args=parseArgs(eventData[4]);let category=eventData[5];if(category===undefined)category='android';const thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);thread.name=eventBase.threadName;this.ppids_[pid]=ppid;this.closeAsyncSlice(thread,category,name,cookie,ts,args);break;}
+default:return false;}
+return true;}};Parser.register(AndroidParser);return{AndroidParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;const binderTransRE=new RegExp('transaction=(\\d+) dest_node=(\\d+) '+'dest_proc=(\\d+) dest_thread=(\\d+) '+'reply=(\\d+) flags=(0x[0-9a-fA-F]+) '+'code=(0x[0-9a-fA-F]+)');const binderAllocRE=new RegExp('transaction=(\\d+) data_size=(\\d+) '+'offsets_size=(\\d+)');const binderTransReceivedRE=/transaction=(\d+)/;function isBinderThread(name){return(name.indexOf('Binder')>-1);}
+const TF_ONE_WAY=0x01;const TF_ROOT_OBJECT=0x04;const TF_STATUS_CODE=0x08;const TF_ACCEPT_FDS=0x10;const NO_FLAGS=0;function binderFlagsToHuman(num){const flag=parseInt(num,16);let str='';if(flag&TF_ONE_WAY){str+='this is a one-way call: async, no return; ';}
+if(flag&TF_ROOT_OBJECT){str+='contents are the components root object; ';}
+if(flag&TF_STATUS_CODE){str+='contents are a 32-bit status code; ';}
+if(flag&TF_ACCEPT_FDS){str+='allow replies with file descriptors; ';}
+if(flag===NO_FLAGS){str+='No Flags Set';}
+return str;}
 function isReplyToOrigin(calling,called){return(called.dest_proc===calling.calling_pid||called.dest_thread===calling.calling_pid);}
 function binderCodeToHuman(code){return'Java Layer Dependent';}
 function doInternalSlice(trans,slice,ts){if(slice.subSlices.length!==0){slice.subSlices[0].start=ts;return slice.subSlices[0];}
-var kthread=trans.calling_kthread.thread;var internal_slice=kthread.sliceGroup.pushCompleteSlice('binder',slice.title,ts,.001,0,0,slice.args);internal_slice.title=slice.title;internal_slice.id=slice.id;internal_slice.colorId=slice.colorId;slice.subSlices.push(internal_slice);return internal_slice;}
-function generateBinderArgsForSlice(trans,c_threadName){return{'Transaction Id':trans.transaction_key,'Destination Node':trans.dest_node,'Destination Process':trans.dest_proc,'Destination Thread':trans.dest_thread,'Destination Name':c_threadName,'Reply transaction?':trans.is_reply_transaction,'Flags':trans.flags+' '+
+const kthread=trans.calling_kthread.thread;const internalSlice=kthread.sliceGroup.pushCompleteSlice('binder',slice.title,ts,.001,0,0,slice.args);internalSlice.title=slice.title;internalSlice.id=slice.id;internalSlice.colorId=slice.colorId;slice.subSlices.push(internalSlice);return internalSlice;}
+function generateBinderArgsForSlice(trans,cThreadName){return{'Transaction Id':trans.transaction_key,'Destination Node':trans.dest_node,'Destination Process':trans.dest_proc,'Destination Thread':trans.dest_thread,'Destination Name':cThreadName,'Reply transaction?':trans.is_reply_transaction,'Flags':trans.flags+' '+
 binderFlagsToHuman(trans.flags),'Code':trans.code+' '+
 binderCodeToHuman(trans.code),'Calling PID':trans.calling_pid,'Calling tgid':trans.calling_kthread.thread.parent.pid};}
-function BinderTransaction(events,calling_pid,calling_ts,calling_kthread){this.transaction_key=parseInt(events[1]);this.dest_node=parseInt(events[2]);this.dest_proc=parseInt(events[3]);this.dest_thread=parseInt(events[4]);this.is_reply_transaction=parseInt(events[5])===1?true:false;this.expect_reply=((this.is_reply_transaction===false)&&(parseInt(events[6],16)&TF_ONE_WAY)===0);this.flags=events[6];this.code=events[7];this.calling_pid=calling_pid;this.calling_ts=calling_ts;this.calling_kthread=calling_kthread;}
-function BinderParser(importer){Parser.call(this,importer);importer.registerEventHandler('binder_locked',BinderParser.prototype.binderLocked.bind(this));importer.registerEventHandler('binder_unlock',BinderParser.prototype.binderUnlock.bind(this));importer.registerEventHandler('binder_lock',BinderParser.prototype.binderLock.bind(this));importer.registerEventHandler('binder_transaction',BinderParser.prototype.binderTransaction.bind(this));importer.registerEventHandler('binder_transaction_received',BinderParser.prototype.binderTransactionReceived.bind(this));this.model_=importer.model;this.kthreadlookup={};this.importer_=importer;this.transWaitingRecv={};this.syncTransWaitingCompletion={};this.recursiveSyncTransWaitingCompletion_ByPID={};this.receivedTransWaitingConversion={};}
-BinderParser.prototype={__proto__:Parser.prototype,binderLock:function(eventName,cpuNumber,pid,ts,eventBase){var tgid=parseInt(eventBase.tgid);this.doNameMappings(pid,tgid,eventName.threadName);var kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);kthread.binderAttemptLockTS=ts;kthread.binderOpenTsA=ts;return true;},binderLocked:function(eventName,cpuNumber,pid,ts,eventBase){var binder_thread=isBinderThread(eventBase.threadName);var tgid,name;var as_slice;var need_push=false;var kthread,rthread;tgid=parseInt(eventBase.tgid);name=eventBase.threadName;kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);this.doNameMappings(pid,tgid,name);rthread=kthread.thread;kthread.binderLockAquiredTS=ts;if(kthread.binderAttemptLockTS===undefined)
-return false;var args=this.generateArgsForSlice(tgid,pid,name,kthread);rthread.sliceGroup.pushCompleteSlice('binder','binder lock waiting',kthread.binderAttemptLockTS,ts-kthread.binderAttemptLockTS,0,0,args);kthread.binderAttemptLockTS=undefined;return true;},binderUnlock:function(eventName,cpuNumber,pid,ts,eventBase){var tgid=parseInt(eventBase.tgid);var kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);if(kthread.binderLockAquiredTS===undefined)
-return false;var args=this.generateArgsForSlice(tgid,pid,eventBase.threadName,kthread);kthread.thread.sliceGroup.pushCompleteSlice('binder','binder lock held',kthread.binderLockAquiredTS,ts-kthread.binderLockAquiredTS,0,0,args);kthread.binderLockAquiredTS=undefined;return true;},binderTransaction:function(eventName,cpuNumber,pid,ts,eventBase){var event=binderTransRE.exec(eventBase.details);if(event===undefined)
-return false;var tgid=parseInt(eventBase.tgid);this.doNameMappings(pid,tgid,eventBase.threadName);var kthread;kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);var trans=new BinderTransaction(event,pid,ts,kthread);var args=generateBinderArgsForSlice(trans,eventBase.threadName);var prior_receive=this.getPriorReceiveOnPID(pid);if(prior_receive!==false){return this.modelPriorReceive(prior_receive,ts,pid,tgid,kthread,trans,args,event);}
-var recursive_trans=this.getRecursiveTransactionNeedingCompletion(pid);if(recursive_trans!==false)
-return this.modelRecursiveTransactions(recursive_trans,ts,pid,kthread,trans,args);var slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','',ts,.03,0,0,args);slice.colorId=ColorScheme.getColorIdForGeneralPurposeString(ts.toString());trans.slice=slice;if(trans.expect_reply)
-slice.title='binder transaction';else
-slice.title='binder transaction async';this.addTransactionWaitingForRecv(trans.transaction_key,trans);return true;},binderTransactionReceived:function(eventName,cpuNumber,pid,ts,eventBase){var event=binderTransReceivedRE.exec(eventBase.details);if(event===undefined)
-return false;var transactionkey=parseInt(event[1]);var tgid=parseInt(eventBase.tgid);var kthread;kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);var syncComplete=this.getSyncTransNeedsCompletion(transactionkey);if(syncComplete!==false){var sync_trans=syncComplete[0];var sync_slice=sync_trans.slice;var response_trans=syncComplete[1];var response_slice=response_trans.slice;sync_slice.duration=ts-sync_slice.start;var sync_internal=doInternalSlice(sync_trans,sync_slice,ts);var response_ts=response_slice.start+response_slice.duration;var response_internal=doInternalSlice(response_trans,response_slice,response_ts);if(response_slice.outFlowEvents.length===0||sync_slice.inFlowEvents.length===0){var flow=this.generateFlow(response_internal,sync_internal,response_trans,sync_trans);sync_slice.inFlowEvents.push(flow);response_slice.outFlowEvents.push(flow);this.model_.flowEvents.push(flow);}
-for(var i=1;i<sync_slice.inFlowEvents.length;i++){sync_slice.inFlowEvents[i].duration=ts-sync_slice.inFlowEvents[i].start;}
+function BinderTransaction(events,callingPid,callingTs,callingKthread){this.transaction_key=parseInt(events[1]);this.dest_node=parseInt(events[2]);this.dest_proc=parseInt(events[3]);this.dest_thread=parseInt(events[4]);this.is_reply_transaction=parseInt(events[5])===1?true:false;this.expect_reply=((this.is_reply_transaction===false)&&(parseInt(events[6],16)&TF_ONE_WAY)===0);this.flags=events[6];this.code=events[7];this.calling_pid=callingPid;this.calling_ts=callingTs;this.calling_kthread=callingKthread;}
+function BinderParser(importer){Parser.call(this,importer);importer.registerEventHandler('binder_locked',BinderParser.prototype.binderLocked.bind(this));importer.registerEventHandler('binder_unlock',BinderParser.prototype.binderUnlock.bind(this));importer.registerEventHandler('binder_lock',BinderParser.prototype.binderLock.bind(this));importer.registerEventHandler('binder_transaction',BinderParser.prototype.binderTransaction.bind(this));importer.registerEventHandler('binder_transaction_received',BinderParser.prototype.binderTransactionReceived.bind(this));importer.registerEventHandler('binder_transaction_alloc_buf',BinderParser.prototype.binderTransactionAllocBuf.bind(this));this.model_=importer.model;this.kthreadlookup={};this.importer_=importer;this.transWaitingRecv={};this.syncTransWaitingCompletion={};this.recursiveSyncTransWaitingCompletion_ByPID={};this.receivedTransWaitingConversion={};}
+BinderParser.prototype={__proto__:Parser.prototype,binderLock(eventName,cpuNumber,pid,ts,eventBase){const tgid=parseInt(eventBase.tgid);if(isNaN(tgid))return false;this.doNameMappings(pid,tgid,eventName.threadName);const kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);kthread.binderAttemptLockTS=ts;kthread.binderOpenTsA=ts;return true;},binderLocked(eventName,cpuNumber,pid,ts,eventBase){const tgid=parseInt(eventBase.tgid);if(isNaN(tgid))return false;const binderThread=isBinderThread(eventBase.threadName);const name=eventBase.threadName;const kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);this.doNameMappings(pid,tgid,name);const rthread=kthread.thread;kthread.binderLockAquiredTS=ts;if(kthread.binderAttemptLockTS===undefined)return false;const args=this.generateArgsForSlice(tgid,pid,name,kthread);rthread.sliceGroup.pushCompleteSlice('binder','binder lock waiting',kthread.binderAttemptLockTS,ts-kthread.binderAttemptLockTS,0,0,args);kthread.binderAttemptLockTS=undefined;return true;},binderUnlock(eventName,cpuNumber,pid,ts,eventBase){const tgid=parseInt(eventBase.tgid);if(isNaN(tgid))return false;const kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);if(kthread.binderLockAquiredTS===undefined)return false;const args=this.generateArgsForSlice(tgid,pid,eventBase.threadName,kthread);kthread.thread.sliceGroup.pushCompleteSlice('binder','binder lock held',kthread.binderLockAquiredTS,ts-kthread.binderLockAquiredTS,0,0,args);kthread.binderLockAquiredTS=undefined;return true;},binderTransaction(eventName,cpuNumber,pid,ts,eventBase){const event=binderTransRE.exec(eventBase.details);if(event===undefined)return false;const tgid=parseInt(eventBase.tgid);if(isNaN(tgid))return false;this.doNameMappings(pid,tgid,eventBase.threadName);const kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);const trans=new BinderTransaction(event,pid,ts,kthread);const args=generateBinderArgsForSlice(trans,eventBase.threadName);const priorReceive=this.getPriorReceiveOnPID(pid);if(priorReceive!==false){return this.modelPriorReceive(priorReceive,ts,pid,tgid,kthread,trans,args,event);}
+const recursiveTrans=this.getRecursiveTransactionNeedingCompletion(pid);if(recursiveTrans!==false){return this.modelRecursiveTransactions(recursiveTrans,ts,pid,kthread,trans,args);}
+const slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','',ts,.03,0,0,args);slice.colorId=ColorScheme.getColorIdForGeneralPurposeString(ts.toString());trans.slice=slice;if(trans.expect_reply){slice.title='binder transaction';}else{slice.title='binder transaction async';}
+this.addTransactionWaitingForRecv(trans.transaction_key,trans);return true;},binderTransactionReceived(eventName,cpuNumber,pid,ts,eventBase){const event=binderTransReceivedRE.exec(eventBase.details);if(event===undefined)return false;const tgid=parseInt(eventBase.tgid);if(isNaN(tgid))return false;const transactionkey=parseInt(event[1]);const kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);const syncComplete=this.getSyncTransNeedsCompletion(transactionkey);if(syncComplete!==false){const syncTrans=syncComplete[0];const syncSlice=syncTrans.slice;const responseTrans=syncComplete[1];const responseSlice=responseTrans.slice;syncSlice.duration=ts-syncSlice.start;const syncInternal=doInternalSlice(syncTrans,syncSlice,ts);const responseTs=responseSlice.start+responseSlice.duration;const responseInternal=doInternalSlice(responseTrans,responseSlice,responseTs);if(responseSlice.outFlowEvents.length===0||syncSlice.inFlowEvents.length===0){const flow=this.generateFlow(responseInternal,syncInternal,responseTrans,syncTrans);syncSlice.inFlowEvents.push(flow);responseSlice.outFlowEvents.push(flow);this.model_.flowEvents.push(flow);}
+for(let i=1;i<syncSlice.inFlowEvents.length;i++){syncSlice.inFlowEvents[i].duration=ts-syncSlice.inFlowEvents[i].start;}
 return true;}
-var tr_for_recv=this.getTransactionWaitingForRecv(transactionkey);if(tr_for_recv!==false){if(!tr_for_recv.expect_reply){var args=generateBinderArgsForSlice(tr_for_recv,eventBase.threadName);var slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','binder Async recv',ts,.03,0,0,args);var fake_event=[0,0,0,0,0,0,0];var fake_trans=new BinderTransaction(fake_event,pid,ts,kthread);var flow=this.generateFlow(tr_for_recv.slice,slice,tr_for_recv,fake_trans);this.model_.flowEvents.push(flow);tr_for_recv.slice.title='binder transaction async';tr_for_recv.slice.duration=.03;return true;}
-tr_for_recv.slice.title='binder transaction';this.setCurrentReceiveOnPID(pid,[ts,tr_for_recv]);return true;}
-return false;},modelRecursiveTransactions:function(recursive_trans,ts,pid,kthread,trans,args){var recursive_slice=recursive_trans[1].slice;var orig_slice=recursive_trans[0].slice;recursive_slice.duration=ts-recursive_slice.start;trans.slice=recursive_slice;if(trans.is_reply_transaction){orig_slice.duration=ts-orig_slice.start;this.addSyncTransNeedingCompletion(trans.transaction_key,recursive_trans);if(isReplyToOrigin(recursive_trans[0],trans))
-this.removeRecursiveTransaction(pid);}else{var slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','',ts,.03,0,0,args);trans.slice=slice;this.addTransactionWaitingForRecv(trans.transaction_key,trans);}
-return true;},modelPriorReceive:function(prior_receive,ts,pid,tgid,kthread,trans,args,event){var callee_slice=prior_receive[1].slice;var callee_trans=prior_receive[1];var recv_ts=prior_receive[0];var slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','',recv_ts,ts-recv_ts,0,0,args);var flow=this.generateFlow(callee_slice,slice,callee_trans,trans);this.model_.flowEvents.push(flow);trans.slice=slice;if(trans.is_reply_transaction){slice.title='binder reply';this.addSyncTransNeedingCompletion(trans.transaction_key,[callee_trans,trans]);}else{slice.title='binder reply';var trans1=new BinderTransaction(event,pid,ts,kthread);slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','binder transaction',recv_ts,(ts-recv_ts),0,0,args);if(!trans.expect_reply){slice.title='binder transaction async';slice.duration=.03;}else{}
-trans1.slice=slice;this.addRecursiveSyncTransNeedingCompletion(pid,[callee_trans,trans]);this.addTransactionWaitingForRecv(trans.transaction_key,trans1);}
-return true;},getRecursiveTransactionNeedingCompletion:function(pid){if(this.recursiveSyncTransWaitingCompletion_ByPID[pid]===undefined)
-return false;var len=this.recursiveSyncTransWaitingCompletion_ByPID[pid].length;if(len===0)
-return false;return this.recursiveSyncTransWaitingCompletion_ByPID[pid][len-1];},addRecursiveSyncTransNeedingCompletion:function(pid,tuple){if(this.recursiveSyncTransWaitingCompletion_ByPID[pid]===undefined)
-this.recursiveSyncTransWaitingCompletion_ByPID[pid]=[];this.recursiveSyncTransWaitingCompletion_ByPID[pid].push(tuple);},removeRecursiveTransaction:function(pid){var len=this.recursiveSyncTransWaitingCompletion_ByPID[pid].length;if(len===0){delete this.recursiveSyncTransWaitingCompletion_ByPID[pid];return;}
-this.recursiveSyncTransWaitingCompletion_ByPID[pid].splice(len-1,1);},setCurrentReceiveOnPID:function(pid,tuple){if(this.receivedTransWaitingConversion[pid]===undefined){this.receivedTransWaitingConversion[pid]=[];}
-this.receivedTransWaitingConversion[pid].push(tuple);},getPriorReceiveOnPID:function(pid){if(this.receivedTransWaitingConversion[pid]===undefined)
-return false;var len=this.receivedTransWaitingConversion[pid].length;if(len===0)
-return false;return this.receivedTransWaitingConversion[pid].splice(len-1,1)[0];},addSyncTransNeedingCompletion:function(transactionkey,tuple){var dict=this.syncTransWaitingCompletion;dict[transactionkey]=tuple;},getSyncTransNeedsCompletion:function(transactionkey){var ret=this.syncTransWaitingCompletion[transactionkey];if(ret===undefined)
-return false;delete this.syncTransWaitingCompletion[transactionkey];return ret;},getTransactionWaitingForRecv:function(transactionkey){var ret=this.transWaitingRecv[transactionkey];if(ret===undefined)
-return false;delete this.transWaitingRecv[transactionkey];return ret;},addTransactionWaitingForRecv:function(transactionkey,transaction){this.transWaitingRecv[transactionkey]=transaction;},generateFlow:function(from,to,from_trans,to_trans){var title='Transaction from : '+
-this.pid2name(from_trans.calling_pid)+' From PID: '+from_trans.calling_pid+' to pid: '+
-to_trans.calling_pid+' Thread Name: '+this.pid2name(to_trans.calling_pid);var ts=from.start;var flow=new tr.model.FlowEvent('binder','binder',title,1,ts,[]);flow.startSlice=from;flow.endSlice=to;flow.start=from.start;flow.duration=to.start-ts;from.outFlowEvents.push(flow);to.inFlowEvents.push(flow);return flow;},generateArgsForSlice:function(tgid,pid,name,kthread){return{'Thread Name':name,'pid':pid,'gid':tgid};},pid2name:function(pid){return this.kthreadlookup[pid];},doNameMappings:function(pid,tgid,name){this.registerPidName(pid,name);this.registerPidName(tgid,name);},registerPidName:function(pid,name){if(this.pid2name(pid)===undefined)
-this.kthreadlookup[pid]=name;}};Parser.register(BinderParser);return{BinderParser:BinderParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function BusParser(importer){Parser.call(this,importer);importer.registerEventHandler('memory_bus_usage',BusParser.prototype.traceMarkWriteBusEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
-BusParser.prototype={__proto__:Parser.prototype,traceMarkWriteBusEvent:function(eventName,cpuNumber,pid,ts,eventBase,threadName){var re=new RegExp('bus=(\\S+) rw_bytes=(\\d+) r_bytes=(\\d+) '+'w_bytes=(\\d+) cycles=(\\d+) ns=(\\d+)');var event=re.exec(eventBase.details);var name=event[1];var rw_bytes=parseInt(event[2]);var r_bytes=parseInt(event[3]);var w_bytes=parseInt(event[4]);var cycles=parseInt(event[5]);var ns=parseInt(event[6]);var r_bw=r_bytes*1000000000/ns;r_bw/=1024*1024;var w_bw=w_bytes*1000000000/ns;w_bw/=1024*1024;var ctr=this.model_.kernel.getOrCreateCounter(null,'bus '+name+' read');if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries('value',ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
-ctr.series.forEach(function(series){series.addCounterSample(ts,r_bw);});ctr=this.model_.kernel.getOrCreateCounter(null,'bus '+name+' write');if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries('value',ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
-ctr.series.forEach(function(series){series.addCounterSample(ts,r_bw);});return true;}};Parser.register(BusParser);return{BusParser:BusParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function ClockParser(importer){Parser.call(this,importer);importer.registerEventHandler('clock_set_rate',ClockParser.prototype.traceMarkWriteClockEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
-ClockParser.prototype={__proto__:Parser.prototype,traceMarkWriteClockEvent:function(eventName,cpuNumber,pid,ts,eventBase,threadName){var event=/(\S+) state=(\d+) cpu_id=(\d+)/.exec(eventBase.details);var name=event[1];var rate=parseInt(event[2]);var ctr=this.model_.kernel.getOrCreateCounter(null,name);if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries('value',ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
-ctr.series.forEach(function(series){series.addCounterSample(ts,rate);});return true;}};Parser.register(ClockParser);return{ClockParser:ClockParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function CpufreqParser(importer){Parser.call(this,importer);importer.registerEventHandler('cpufreq_interactive_up',CpufreqParser.prototype.cpufreqUpDownEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_down',CpufreqParser.prototype.cpufreqUpDownEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_already',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_notyet',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_setspeed',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_target',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_boost',CpufreqParser.prototype.cpufreqBoostUnboostEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_unboost',CpufreqParser.prototype.cpufreqBoostUnboostEvent.bind(this));}
-function splitData(input){var data={};var args=input.split(/\s+/);var len=args.length;for(var i=0;i<len;i++){var item=args[i].split('=');data[item[0]]=parseInt(item[1]);}
+const trForRecv=this.getTransactionWaitingForRecv(transactionkey);if(trForRecv!==false){if(!trForRecv.expect_reply){const args=generateBinderArgsForSlice(trForRecv,eventBase.threadName);const slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','binder Async recv',ts,.03,0,0,args);const fakeEvent=[0,0,0,0,0,0,0];const fakeTrans=new BinderTransaction(fakeEvent,pid,ts,kthread);const flow=this.generateFlow(trForRecv.slice,slice,trForRecv,fakeTrans);this.model_.flowEvents.push(flow);trForRecv.slice.title='binder transaction async';trForRecv.slice.duration=.03;return true;}
+trForRecv.slice.title='binder transaction';this.setCurrentReceiveOnPID(pid,[ts,trForRecv]);return true;}
+return false;},binderTransactionAllocBuf(eventName,cpuNumber,pid,ts,eventBase){const event=binderAllocRE.exec(eventBase.details);if(event===null)return false;const tgid=parseInt(eventBase.tgid);if(isNaN(tgid))return false;const transactionkey=parseInt(event[1]);const kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);const trans=this.peekTransactionWaitingForRecv(transactionkey);if(trans&&trans.slice){trans.slice.args['Data Size']=parseInt(event[2]);trans.slice.args['Offsets Size']=parseInt(event[3]);return true;}
+return false;},modelRecursiveTransactions(recursiveTrans,ts,pid,kthread,trans,args){const recursiveSlice=recursiveTrans[1].slice;const origSlice=recursiveTrans[0].slice;recursiveSlice.duration=ts-recursiveSlice.start;recursiveSlice.args=args;trans.slice=recursiveSlice;if(trans.is_reply_transaction){origSlice.duration=ts-origSlice.start;this.addSyncTransNeedingCompletion(trans.transaction_key,recursiveTrans);if(isReplyToOrigin(recursiveTrans[0],trans)){this.removeRecursiveTransaction(pid);}}else{const slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','',ts,.03,0,0,args);trans.slice=slice;this.addTransactionWaitingForRecv(trans.transaction_key,trans);}
+return true;},modelPriorReceive(priorReceive,ts,pid,tgid,kthread,trans,args,event){const calleeSlice=priorReceive[1].slice;const calleeTrans=priorReceive[1];const recvTs=priorReceive[0];let slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','',recvTs,ts-recvTs,0,0);const flow=this.generateFlow(calleeSlice,slice,calleeTrans,trans);this.model_.flowEvents.push(flow);trans.slice=slice;if(trans.is_reply_transaction){slice.title='binder reply';slice.args=args;this.addSyncTransNeedingCompletion(trans.transaction_key,[calleeTrans,trans]);}else{slice.title='binder reply';const trans1=new BinderTransaction(event,pid,ts,kthread);slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','binder transaction',recvTs,(ts-recvTs),0,0,args);if(!trans.expect_reply){slice.title='binder transaction async';slice.duration=.03;}else{}
+trans1.slice=slice;this.addRecursiveSyncTransNeedingCompletion(pid,[calleeTrans,trans]);this.addTransactionWaitingForRecv(trans.transaction_key,trans1);}
+return true;},getRecursiveTransactionNeedingCompletion(pid){if(this.recursiveSyncTransWaitingCompletion_ByPID[pid]===undefined){return false;}
+const len=this.recursiveSyncTransWaitingCompletion_ByPID[pid].length;if(len===0)return false;return this.recursiveSyncTransWaitingCompletion_ByPID[pid][len-1];},addRecursiveSyncTransNeedingCompletion(pid,tuple){if(this.recursiveSyncTransWaitingCompletion_ByPID[pid]===undefined){this.recursiveSyncTransWaitingCompletion_ByPID[pid]=[];}
+this.recursiveSyncTransWaitingCompletion_ByPID[pid].push(tuple);},removeRecursiveTransaction(pid){const len=this.recursiveSyncTransWaitingCompletion_ByPID[pid].length;if(len===0){delete this.recursiveSyncTransWaitingCompletion_ByPID[pid];return;}
+this.recursiveSyncTransWaitingCompletion_ByPID[pid].splice(len-1,1);},setCurrentReceiveOnPID(pid,tuple){if(this.receivedTransWaitingConversion[pid]===undefined){this.receivedTransWaitingConversion[pid]=[];}
+this.receivedTransWaitingConversion[pid].push(tuple);},getPriorReceiveOnPID(pid){if(this.receivedTransWaitingConversion[pid]===undefined){return false;}
+const len=this.receivedTransWaitingConversion[pid].length;if(len===0)return false;return this.receivedTransWaitingConversion[pid].splice(len-1,1)[0];},addSyncTransNeedingCompletion(transactionkey,tuple){const dict=this.syncTransWaitingCompletion;dict[transactionkey]=tuple;},getSyncTransNeedsCompletion(transactionkey){const ret=this.syncTransWaitingCompletion[transactionkey];if(ret===undefined)return false;delete this.syncTransWaitingCompletion[transactionkey];return ret;},getTransactionWaitingForRecv(transactionkey){const ret=this.transWaitingRecv[transactionkey];if(ret===undefined)return false;delete this.transWaitingRecv[transactionkey];return ret;},peekTransactionWaitingForRecv(transactionkey){const ret=this.transWaitingRecv[transactionkey];if(ret===undefined)return false;return ret;},addTransactionWaitingForRecv(transactionkey,transaction){this.transWaitingRecv[transactionkey]=transaction;},generateFlow(from,to,fromTrans,toTrans){const title='Transaction from : '+
+this.pid2name(fromTrans.calling_pid)+' From PID: '+fromTrans.calling_pid+' to pid: '+
+toTrans.calling_pid+' Thread Name: '+this.pid2name(toTrans.calling_pid);const ts=from.start;const flow=new tr.model.FlowEvent('binder','binder',title,1,ts,[]);flow.startSlice=from;flow.endSlice=to;flow.start=from.start;flow.duration=to.start-ts;from.outFlowEvents.push(flow);to.inFlowEvents.push(flow);return flow;},generateArgsForSlice(tgid,pid,name,kthread){return{'Thread Name':name,pid,'gid':tgid};},pid2name(pid){return this.kthreadlookup[pid];},doNameMappings(pid,tgid,name){this.registerPidName(pid,name);this.registerPidName(tgid,name);},registerPidName(pid,name){if(this.pid2name(pid)===undefined){this.kthreadlookup[pid]=name;}}};Parser.register(BinderParser);return{BinderParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function BusParser(importer){Parser.call(this,importer);importer.registerEventHandler('memory_bus_usage',BusParser.prototype.traceMarkWriteBusEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
+BusParser.prototype={__proto__:Parser.prototype,traceMarkWriteBusEvent(eventName,cpuNumber,pid,ts,eventBase,threadName){const re=new RegExp('bus=(\\S+) rw_bytes=(\\d+) r_bytes=(\\d+) '+'w_bytes=(\\d+) cycles=(\\d+) ns=(\\d+)');const event=re.exec(eventBase.details);const name=event[1];const rwBytes=parseInt(event[2]);const rBytes=parseInt(event[3]);const wBytes=parseInt(event[4]);const cycles=parseInt(event[5]);const ns=parseInt(event[6]);const sec=tr.b.convertUnit(ns,tr.b.UnitPrefixScale.METRIC.NANO,tr.b.UnitPrefixScale.METRIC.NONE);const readBandwidthInBps=rBytes/sec;const readBandwidthInMiBps=tr.b.convertUnit(readBandwidthInBps,tr.b.UnitPrefixScale.BINARY.NONE,tr.b.UnitPrefixScale.BINARY.MEBI);const writeBandwidthInBps=wBytes/sec;const writeBandwidthInMiBps=tr.b.convertUnit(writeBandwidthInBps,tr.b.UnitPrefixScale.BINARY.NONE,tr.b.UnitPrefixScale.BINARY.MEBI);let ctr=this.model_.kernel.getOrCreateCounter(null,'bus '+name+' read');if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries('value',ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
+ctr.series.forEach(function(series){series.addCounterSample(ts,readBandwidthInMiBps);});ctr=this.model_.kernel.getOrCreateCounter(null,'bus '+name+' write');if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries('value',ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
+ctr.series.forEach(function(series){series.addCounterSample(ts,writeBandwidthInMiBps);});return true;}};Parser.register(BusParser);return{BusParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function ClockParser(importer){Parser.call(this,importer);importer.registerEventHandler('clock_set_rate',ClockParser.prototype.traceMarkWriteClockEvent.bind(this));importer.registerEventHandler('clk_set_rate',ClockParser.prototype.traceMarkWriteClkEvent.bind(this));importer.registerEventHandler('clock_enable',ClockParser.prototype.traceMarkWriteClockOnOffEvent.bind(this));importer.registerEventHandler('clock_disable',ClockParser.prototype.traceMarkWriteClockOnOffEvent.bind(this));importer.registerEventHandler('clk_enable',ClockParser.prototype.traceMarkWriteClkOnEvent.bind(this));importer.registerEventHandler('clk_disable',ClockParser.prototype.traceMarkWriteClkOffEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
+ClockParser.prototype={__proto__:Parser.prototype,clockMark(name,subName,value,ts){const ctr=this.model_.kernel.getOrCreateCounter(null,name+' '+subName);if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries('value',ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
+ctr.series.forEach(function(series){series.addCounterSample(ts,value);});},traceMarkWriteClockEvent(eventName,cpuNumber,pid,ts,eventBase,threadName){const event=/(\S+) state=(\d+)/.exec(eventBase.details);const name=event[1];const rate=parseInt(event[2]);this.clockMark(name,'Frequency',rate,ts);return true;},traceMarkWriteClkEvent(eventName,cpuNumber,pid,ts,eventBase,threadName){const event=/(\S+) (\d+)/.exec(eventBase.details);const name=event[1];const rate=parseInt(event[2]);this.clockMark(name,'Frequency',rate,ts);return true;},traceMarkWriteClockOnOffEvent(eventName,cpuNumber,pid,ts,eventBase,threadName){const event=/(\S+) state=(\d+)/.exec(eventBase.details);const name=event[1];const state=parseInt(event[2]);this.clockMark(name,'State',state,ts);return true;},traceMarkWriteClkOnEvent(eventName,cpuNumber,pid,ts,eventBase,threadName){const event=/\S+/.exec(eventBase.details);const name=event[0];this.clockMark(name,'State',1,ts);return true;},traceMarkWriteClkOffEvent(eventName,cpuNumber,pid,ts,eventBase,threadName){const event=/\S+/.exec(eventBase.details);const name=event[0];this.clockMark(name,'State',0,ts);return true;}};Parser.register(ClockParser);return{ClockParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function CpufreqParser(importer){Parser.call(this,importer);importer.registerEventHandler('cpufreq_interactive_up',CpufreqParser.prototype.cpufreqUpDownEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_down',CpufreqParser.prototype.cpufreqUpDownEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_already',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_notyet',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_setspeed',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_target',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_boost',CpufreqParser.prototype.cpufreqBoostUnboostEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_unboost',CpufreqParser.prototype.cpufreqBoostUnboostEvent.bind(this));}
+function splitData(input){const data={};const args=input.split(/\s+/);const len=args.length;for(let i=0;i<len;i++){const item=args[i].split('=');data[item[0]]=parseInt(item[1]);}
 return data;}
-CpufreqParser.prototype={__proto__:Parser.prototype,cpufreqSlice:function(ts,eventName,cpu,args){var kthread=this.importer.getOrCreatePseudoThread('cpufreq');kthread.openSlice=eventName;var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},cpufreqBoostSlice:function(ts,eventName,args){var kthread=this.importer.getOrCreatePseudoThread('cpufreq_boost');kthread.openSlice=eventName;var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},cpufreqUpDownEvent:function(eventName,cpuNumber,pid,ts,eventBase){var data=splitData(eventBase.details);this.cpufreqSlice(ts,eventName,data.cpu,data);return true;},cpufreqTargetEvent:function(eventName,cpuNumber,pid,ts,eventBase){var data=splitData(eventBase.details);this.cpufreqSlice(ts,eventName,data.cpu,data);return true;},cpufreqBoostUnboostEvent:function(eventName,cpuNumber,pid,ts,eventBase){this.cpufreqBoostSlice(ts,eventName,{type:eventBase.details});return true;}};Parser.register(CpufreqParser);return{CpufreqParser:CpufreqParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function DiskParser(importer){Parser.call(this,importer);importer.registerEventHandler('f2fs_write_begin',DiskParser.prototype.f2fsWriteBeginEvent.bind(this));importer.registerEventHandler('f2fs_write_end',DiskParser.prototype.f2fsWriteEndEvent.bind(this));importer.registerEventHandler('f2fs_sync_file_enter',DiskParser.prototype.f2fsSyncFileEnterEvent.bind(this));importer.registerEventHandler('f2fs_sync_file_exit',DiskParser.prototype.f2fsSyncFileExitEvent.bind(this));importer.registerEventHandler('ext4_sync_file_enter',DiskParser.prototype.ext4SyncFileEnterEvent.bind(this));importer.registerEventHandler('ext4_sync_file_exit',DiskParser.prototype.ext4SyncFileExitEvent.bind(this));importer.registerEventHandler('ext4_da_write_begin',DiskParser.prototype.ext4WriteBeginEvent.bind(this));importer.registerEventHandler('ext4_da_write_end',DiskParser.prototype.ext4WriteEndEvent.bind(this));importer.registerEventHandler('block_rq_issue',DiskParser.prototype.blockRqIssueEvent.bind(this));importer.registerEventHandler('block_rq_complete',DiskParser.prototype.blockRqCompleteEvent.bind(this));}
-DiskParser.prototype={__proto__:Parser.prototype,openAsyncSlice:function(ts,category,threadName,pid,key,name){var kthread=this.importer.getOrCreateKernelThread(category+':'+threadName,pid);var asyncSliceConstructor=tr.model.AsyncSlice.getConstructor(category,name);var slice=new asyncSliceConstructor(category,name,ColorScheme.getColorIdForGeneralPurposeString(name),ts);slice.startThread=kthread.thread;if(!kthread.openAsyncSlices){kthread.openAsyncSlices={};}
-kthread.openAsyncSlices[key]=slice;},closeAsyncSlice:function(ts,category,threadName,pid,key,args){var kthread=this.importer.getOrCreateKernelThread(category+':'+threadName,pid);if(kthread.openAsyncSlices){var slice=kthread.openAsyncSlices[key];if(slice){slice.duration=ts-slice.start;slice.args=args;slice.endThread=kthread.thread;slice.subSlices=[new tr.model.AsyncSlice(category,slice.title,slice.colorId,slice.start,slice.args,slice.duration)];kthread.thread.asyncSliceGroup.push(slice);delete kthread.openAsyncSlices[key];}}},f2fsWriteBeginEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev = \((\d+,\d+)\), ino = (\d+), pos = (\d+), len = (\d+), flags = (\d+)/.exec(eventBase.details);if(!event)
-return false;var device=event[1];var inode=parseInt(event[2]);var pos=parseInt(event[3]);var len=parseInt(event[4]);var key=device+'-'+inode+'-'+pos+'-'+len;this.openAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,'f2fs_write');return true;},f2fsWriteEndEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev = \((\d+,\d+)\), ino = (\d+), pos = (\d+), len = (\d+), copied = (\d+)/.exec(eventBase.details);if(!event)
-return false;var device=event[1];var inode=parseInt(event[2]);var pos=parseInt(event[3]);var len=parseInt(event[4]);var error=parseInt(event[5])!==len;var key=device+'-'+inode+'-'+pos+'-'+len;this.closeAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,{device:device,inode:inode,error:error});return true;},ext4WriteBeginEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev (\d+,\d+) ino (\d+) pos (\d+) len (\d+) flags (\d+)/.exec(eventBase.details);if(!event)
-return false;var device=event[1];var inode=parseInt(event[2]);var pos=parseInt(event[3]);var len=parseInt(event[4]);var key=device+'-'+inode+'-'+pos+'-'+len;this.openAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,'ext4_write');return true;},ext4WriteEndEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev (\d+,\d+) ino (\d+) pos (\d+) len (\d+) copied (\d+)/.exec(eventBase.details);if(!event)
-return false;var device=event[1];var inode=parseInt(event[2]);var pos=parseInt(event[3]);var len=parseInt(event[4]);var error=parseInt(event[5])!==len;var key=device+'-'+inode+'-'+pos+'-'+len;this.closeAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,{device:device,inode:inode,error:error});return true;},f2fsSyncFileEnterEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=new RegExp('dev = \\((\\d+,\\d+)\\), ino = (\\d+), pino = (\\d+), i_mode = (\\S+), '+'i_size = (\\d+), i_nlink = (\\d+), i_blocks = (\\d+), i_advise = (\\d+)').exec(eventBase.details);if(!event)
-return false;var device=event[1];var inode=parseInt(event[2]);var key=device+'-'+inode;this.openAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,'fsync');return true;},f2fsSyncFileExitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=new RegExp('dev = \\((\\d+,\\d+)\\), ino = (\\d+), checkpoint is (\\S+), '+'datasync = (\\d+), ret = (\\d+)').exec(eventBase.details.replace('not needed','not_needed'));if(!event)
-return false;var device=event[1];var inode=parseInt(event[2]);var error=parseInt(event[5]);var key=device+'-'+inode;this.closeAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,{device:device,inode:inode,error:error});return true;},ext4SyncFileEnterEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev (\d+,\d+) ino (\d+) parent (\d+) datasync (\d+)/.exec(eventBase.details);if(!event)
-return false;var device=event[1];var inode=parseInt(event[2]);var datasync=event[4]==1;var key=device+'-'+inode;var action=datasync?'fdatasync':'fsync';this.openAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,action);return true;},ext4SyncFileExitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev (\d+,\d+) ino (\d+) ret (\d+)/.exec(eventBase.details);if(!event)
-return false;var device=event[1];var inode=parseInt(event[2]);var error=parseInt(event[3]);var key=device+'-'+inode;this.closeAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,{device:device,inode:inode,error:error});return true;},blockRqIssueEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=new RegExp('(\\d+,\\d+) (F)?([DWRN])(F)?(A)?(S)?(M)? '+'\\d+ \\(.*\\) (\\d+) \\+ (\\d+) \\[.*\\]').exec(eventBase.details);if(!event)
-return false;var action;switch(event[3]){case'D':action='discard';break;case'W':action='write';break;case'R':action='read';break;case'N':action='none';break;default:action='unknown';break;}
+CpufreqParser.prototype={__proto__:Parser.prototype,cpufreqSlice(ts,eventName,cpu,args){const kthread=this.importer.getOrCreatePseudoThread('cpufreq');kthread.openSlice=eventName;const slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},cpufreqBoostSlice(ts,eventName,args){const kthread=this.importer.getOrCreatePseudoThread('cpufreq_boost');kthread.openSlice=eventName;const slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},cpufreqUpDownEvent(eventName,cpuNumber,pid,ts,eventBase){const data=splitData(eventBase.details);this.cpufreqSlice(ts,eventName,data.cpu,data);return true;},cpufreqTargetEvent(eventName,cpuNumber,pid,ts,eventBase){const data=splitData(eventBase.details);this.cpufreqSlice(ts,eventName,data.cpu,data);return true;},cpufreqBoostUnboostEvent(eventName,cpuNumber,pid,ts,eventBase){this.cpufreqBoostSlice(ts,eventName,{type:eventBase.details});return true;}};Parser.register(CpufreqParser);return{CpufreqParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function DiskParser(importer){Parser.call(this,importer);importer.registerEventHandler('f2fs_write_begin',DiskParser.prototype.f2fsWriteBeginEvent.bind(this));importer.registerEventHandler('f2fs_write_end',DiskParser.prototype.f2fsWriteEndEvent.bind(this));importer.registerEventHandler('f2fs_sync_file_enter',DiskParser.prototype.f2fsSyncFileEnterEvent.bind(this));importer.registerEventHandler('f2fs_sync_file_exit',DiskParser.prototype.f2fsSyncFileExitEvent.bind(this));importer.registerEventHandler('ext4_sync_file_enter',DiskParser.prototype.ext4SyncFileEnterEvent.bind(this));importer.registerEventHandler('ext4_sync_file_exit',DiskParser.prototype.ext4SyncFileExitEvent.bind(this));importer.registerEventHandler('ext4_da_write_begin',DiskParser.prototype.ext4WriteBeginEvent.bind(this));importer.registerEventHandler('ext4_da_write_end',DiskParser.prototype.ext4WriteEndEvent.bind(this));importer.registerEventHandler('block_rq_issue',DiskParser.prototype.blockRqIssueEvent.bind(this));importer.registerEventHandler('block_rq_complete',DiskParser.prototype.blockRqCompleteEvent.bind(this));}
+DiskParser.prototype={__proto__:Parser.prototype,openAsyncSlice(ts,category,threadName,pid,key,name){const kthread=this.importer.getOrCreateKernelThread(category+':'+threadName,pid);const asyncSliceConstructor=tr.model.AsyncSlice.subTypes.getConstructor(category,name);const slice=new asyncSliceConstructor(category,name,ColorScheme.getColorIdForGeneralPurposeString(name),ts);slice.startThread=kthread.thread;if(!kthread.openAsyncSlices){kthread.openAsyncSlices={};}
+kthread.openAsyncSlices[key]=slice;},closeAsyncSlice(ts,category,threadName,pid,key,args){const kthread=this.importer.getOrCreateKernelThread(category+':'+threadName,pid);if(kthread.openAsyncSlices){const slice=kthread.openAsyncSlices[key];if(slice){slice.duration=ts-slice.start;slice.args=args;slice.endThread=kthread.thread;slice.subSlices=[new tr.model.AsyncSlice(category,slice.title,slice.colorId,slice.start,slice.args,slice.duration)];kthread.thread.asyncSliceGroup.push(slice);delete kthread.openAsyncSlices[key];}}},f2fsWriteBeginEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/dev = \((\d+,\d+)\), ino = (\d+), pos = (\d+), len = (\d+), flags = (\d+)/.exec(eventBase.details);if(!event)return false;const device=event[1];const inode=parseInt(event[2]);const pos=parseInt(event[3]);const len=parseInt(event[4]);const key=device+'-'+inode+'-'+pos+'-'+len;this.openAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,'f2fs_write');return true;},f2fsWriteEndEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/dev = \((\d+,\d+)\), ino = (\d+), pos = (\d+), len = (\d+), copied = (\d+)/.exec(eventBase.details);if(!event)return false;const device=event[1];const inode=parseInt(event[2]);const pos=parseInt(event[3]);const len=parseInt(event[4]);const error=parseInt(event[5])!==len;const key=device+'-'+inode+'-'+pos+'-'+len;this.closeAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,{device,inode,error});return true;},ext4WriteBeginEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/dev (\d+,\d+) ino (\d+) pos (\d+) len (\d+) flags (\d+)/.exec(eventBase.details);if(!event)return false;const device=event[1];const inode=parseInt(event[2]);const pos=parseInt(event[3]);const len=parseInt(event[4]);const key=device+'-'+inode+'-'+pos+'-'+len;this.openAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,'ext4_write');return true;},ext4WriteEndEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/dev (\d+,\d+) ino (\d+) pos (\d+) len (\d+) copied (\d+)/.exec(eventBase.details);if(!event)return false;const device=event[1];const inode=parseInt(event[2]);const pos=parseInt(event[3]);const len=parseInt(event[4]);const error=parseInt(event[5])!==len;const key=device+'-'+inode+'-'+pos+'-'+len;this.closeAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,{device,inode,error});return true;},f2fsSyncFileEnterEvent(eventName,cpuNumber,pid,ts,eventBase){const event=new RegExp('dev = \\((\\d+,\\d+)\\), ino = (\\d+), pino = (\\d+), i_mode = (\\S+), '+'i_size = (\\d+), i_nlink = (\\d+), i_blocks = (\\d+), i_advise = (\\d+)').exec(eventBase.details);if(!event)return false;const device=event[1];const inode=parseInt(event[2]);const key=device+'-'+inode;this.openAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,'fsync');return true;},f2fsSyncFileExitEvent(eventName,cpuNumber,pid,ts,eventBase){const event=new RegExp('dev = \\((\\d+,\\d+)\\), ino = (\\d+), checkpoint is (\\S+), '+'datasync = (\\d+), ret = (\\d+)').exec(eventBase.details.replace('not needed','not_needed'));if(!event)return false;const device=event[1];const inode=parseInt(event[2]);const error=parseInt(event[5]);const key=device+'-'+inode;this.closeAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,{device,inode,error});return true;},ext4SyncFileEnterEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/dev (\d+,\d+) ino (\d+) parent (\d+) datasync (\d+)/.exec(eventBase.details);if(!event)return false;const device=event[1];const inode=parseInt(event[2]);const datasync=(event[4]==='1')||(event[4]===1);const key=device+'-'+inode;const action=datasync?'fdatasync':'fsync';this.openAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,action);return true;},ext4SyncFileExitEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/dev (\d+,\d+) ino (\d+) ret (\d+)/.exec(eventBase.details);if(!event)return false;const device=event[1];const inode=parseInt(event[2]);const error=parseInt(event[3]);const key=device+'-'+inode;this.closeAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,{device,inode,error});return true;},blockRqIssueEvent(eventName,cpuNumber,pid,ts,eventBase){const event=new RegExp('(\\d+,\\d+) (F)?([DWRN])(F)?(A)?(S)?(M)? '+'\\d+ \\(.*\\) (\\d+) \\+ (\\d+) \\[.*\\]').exec(eventBase.details);if(!event)return false;let action;switch(event[3]){case'D':action='discard';break;case'W':action='write';break;case'R':action='read';break;case'N':action='none';break;default:action='unknown';break;}
 if(event[2]){action+=' flush';}
-if(event[4]=='F'){action+=' fua';}
-if(event[5]=='A'){action+=' ahead';}
-if(event[6]=='S'){action+=' sync';}
-if(event[7]=='M'){action+=' meta';}
-var device=event[1];var sector=parseInt(event[8]);var numSectors=parseInt(event[9]);var key=device+'-'+sector+'-'+numSectors;this.openAsyncSlice(ts,'block',eventBase.threadName,eventBase.pid,key,action);return true;},blockRqCompleteEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=new RegExp('(\\d+,\\d+) (F)?([DWRN])(F)?(A)?(S)?(M)? '+'\\(.*\\) (\\d+) \\+ (\\d+) \\[(.*)\\]').exec(eventBase.details);if(!event)
-return false;var device=event[1];var sector=parseInt(event[8]);var numSectors=parseInt(event[9]);var error=parseInt(event[10]);var key=device+'-'+sector+'-'+numSectors;this.closeAsyncSlice(ts,'block',eventBase.threadName,eventBase.pid,key,{device:device,sector:sector,numSectors:numSectors,error:error});return true;}};Parser.register(DiskParser);return{DiskParser:DiskParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function DrmParser(importer){Parser.call(this,importer);importer.registerEventHandler('drm_vblank_event',DrmParser.prototype.vblankEvent.bind(this));}
-DrmParser.prototype={__proto__:Parser.prototype,drmVblankSlice:function(ts,eventName,args){var kthread=this.importer.getOrCreatePseudoThread('drm_vblank');kthread.openSlice=eventName;var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},vblankEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/crtc=(\d+), seq=(\d+)/.exec(eventBase.details);if(!event)
-return false;var crtc=parseInt(event[1]);var seq=parseInt(event[2]);this.drmVblankSlice(ts,'vblank:'+crtc,{crtc:crtc,seq:seq});return true;}};Parser.register(DrmParser);return{DrmParser:DrmParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function ExynosParser(importer){Parser.call(this,importer);importer.registerEventHandler('exynos_busfreq_target_int',ExynosParser.prototype.busfreqTargetIntEvent.bind(this));importer.registerEventHandler('exynos_busfreq_target_mif',ExynosParser.prototype.busfreqTargetMifEvent.bind(this));importer.registerEventHandler('exynos_page_flip_state',ExynosParser.prototype.pageFlipStateEvent.bind(this));}
-ExynosParser.prototype={__proto__:Parser.prototype,exynosBusfreqSample:function(name,ts,frequency){var targetCpu=this.importer.getOrCreateCpu(0);var counter=targetCpu.getOrCreateCounter('',name);if(counter.numSeries===0){counter.addSeries(new tr.model.CounterSeries('frequency',ColorScheme.getColorIdForGeneralPurposeString(counter.name+'.'+'frequency')));}
-counter.series.forEach(function(series){series.addCounterSample(ts,frequency);});},busfreqTargetIntEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/frequency=(\d+)/.exec(eventBase.details);if(!event)
-return false;this.exynosBusfreqSample('INT Frequency',ts,parseInt(event[1]));return true;},busfreqTargetMifEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/frequency=(\d+)/.exec(eventBase.details);if(!event)
-return false;this.exynosBusfreqSample('MIF Frequency',ts,parseInt(event[1]));return true;},exynosPageFlipStateOpenSlice:function(ts,pipe,fb,state){var kthread=this.importer.getOrCreatePseudoThread('exynos_flip_state (pipe:'+pipe+', fb:'+fb+')');kthread.openSliceTS=ts;kthread.openSlice=state;},exynosPageFlipStateCloseSlice:function(ts,pipe,fb,args){var kthread=this.importer.getOrCreatePseudoThread('exynos_flip_state (pipe:'+pipe+', fb:'+fb+')');if(kthread.openSlice){var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),kthread.openSliceTS,args,ts-kthread.openSliceTS);kthread.thread.sliceGroup.pushSlice(slice);}
-kthread.openSlice=undefined;},pageFlipStateEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/pipe=(\d+), fb=(\d+), state=(.*)/.exec(eventBase.details);if(!event)
-return false;var pipe=parseInt(event[1]);var fb=parseInt(event[2]);var state=event[3];this.exynosPageFlipStateCloseSlice(ts,pipe,fb,{pipe:pipe,fb:fb});if(state!=='flipped')
-this.exynosPageFlipStateOpenSlice(ts,pipe,fb,state);return true;}};Parser.register(ExynosParser);return{ExynosParser:ExynosParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var Parser=tr.e.importer.linux_perf.Parser;function GestureParser(importer){Parser.call(this,importer);importer.registerEventHandler('tracing_mark_write:log',GestureParser.prototype.logEvent.bind(this));importer.registerEventHandler('tracing_mark_write:SyncInterpret',GestureParser.prototype.syncEvent.bind(this));importer.registerEventHandler('tracing_mark_write:HandleTimer',GestureParser.prototype.timerEvent.bind(this));}
-GestureParser.prototype={__proto__:Parser.prototype,gestureOpenSlice:function(title,ts,opt_args){var thread=this.importer.getOrCreatePseudoThread('gesture').thread;thread.sliceGroup.beginSlice('touchpad_gesture',title,ts,opt_args);},gestureCloseSlice:function(title,ts){var thread=this.importer.getOrCreatePseudoThread('gesture').thread;if(thread.sliceGroup.openSliceCount){var slice=thread.sliceGroup.mostRecentlyOpenedPartialSlice;if(slice.title!=title){this.importer.model.importWarning({type:'title_match_error',message:'Titles do not match. Title is '+
+if(event[4]==='F'){action+=' fua';}
+if(event[5]==='A'){action+=' ahead';}
+if(event[6]==='S'){action+=' sync';}
+if(event[7]==='M'){action+=' meta';}
+const device=event[1];const sector=parseInt(event[8]);const numSectors=parseInt(event[9]);const key=device+'-'+sector+'-'+numSectors;this.openAsyncSlice(ts,'block',eventBase.threadName,eventBase.pid,key,action);return true;},blockRqCompleteEvent(eventName,cpuNumber,pid,ts,eventBase){const event=new RegExp('(\\d+,\\d+) (F)?([DWRN])(F)?(A)?(S)?(M)? '+'\\(.*\\) (\\d+) \\+ (\\d+) \\[(.*)\\]').exec(eventBase.details);if(!event)return false;const device=event[1];const sector=parseInt(event[8]);const numSectors=parseInt(event[9]);const error=parseInt(event[10]);const key=device+'-'+sector+'-'+numSectors;this.closeAsyncSlice(ts,'block',eventBase.threadName,eventBase.pid,key,{device,sector,numSectors,error});return true;}};Parser.register(DiskParser);return{DiskParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function DmaFenceParser(importer){Parser.call(this,importer);this.model_=importer.model_;importer.registerEventHandler('dma_fence_init',DmaFenceParser.prototype.initEvent.bind(this));importer.registerEventHandler('dma_fence_emit',DmaFenceParser.prototype.initEvent.bind(this));importer.registerEventHandler('dma_fence_destroy',DmaFenceParser.prototype.fenceDestroyEvent.bind(this));importer.registerEventHandler('dma_fence_enable_signal',DmaFenceParser.prototype.fenceEnableSignalEvent.bind(this));importer.registerEventHandler('dma_fence_signaled',DmaFenceParser.prototype.fenceSignaledEvent.bind(this));importer.registerEventHandler('dma_fence_wait_start',DmaFenceParser.prototype.fenceWaitEvent.bind(this));importer.registerEventHandler('dma_fence_wait_end',DmaFenceParser.prototype.fenceWaitEvent.bind(this));importer.registerEventHandler('fence_init',DmaFenceParser.prototype.initEvent.bind(this));importer.registerEventHandler('fence_emit',DmaFenceParser.prototype.initEvent.bind(this));importer.registerEventHandler('fence_destroy',DmaFenceParser.prototype.fenceDestroyEvent.bind(this));importer.registerEventHandler('fence_enable_signal',DmaFenceParser.prototype.fenceEnableSignalEvent.bind(this));importer.registerEventHandler('fence_signaled',DmaFenceParser.prototype.fenceSignaledEvent.bind(this));importer.registerEventHandler('fence_wait_start',DmaFenceParser.prototype.fenceWaitEvent.bind(this));importer.registerEventHandler('fence_wait_end',DmaFenceParser.prototype.fenceWaitEvent.bind(this));this.model_=importer.model_;}
+const fenceRE=/driver=(\S+) timeline=(\S+) context=(\d+) seqno=(\d+)/;DmaFenceParser.prototype={__proto__:Parser.prototype,initEvent(eventName,cpuNumber,pid,ts,eventBase){const event=fenceRE.exec(eventBase.details);if(!event)return false;if(eventBase.tgid===undefined){return false;}
+const thread=this.importer.getOrCreatePseudoThread(event[2]);thread.lastActiveTs=ts;return true;},fenceDestroyEvent(eventName,cpuNumber,pid,ts,eventBase){const event=fenceRE.exec(eventBase.details);if(!event)return false;if(eventBase.tgid===undefined){return false;}
+const thread=this.importer.getOrCreatePseudoThread(event[2]);const name='fence_destroy('+event[4]+')';const colorName='fence('+event[4]+')';if(thread.lastActiveTs!==undefined){const duration=ts-thread.lastActiveTs;const slice=new tr.model.ThreadSlice('',name,ColorScheme.getColorIdForGeneralPurposeString(colorName),thread.lastActiveTs,{driver:event[1],context:event[3]},duration);thread.thread.sliceGroup.pushSlice(slice);}
+if(thread.thread.sliceGroup.openSliceCount>0){thread.thread.sliceGroup.endSlice(ts);}
+thread.lastActiveTs=ts;},fenceEnableSignalEvent(eventName,cpuNumber,pid,ts,eventBase){const event=fenceRE.exec(eventBase.details);if(!event)return false;if(eventBase.tgid===undefined){return false;}
+const thread=this.importer.getOrCreatePseudoThread(event[2]);const name='fence_enable('+event[4]+')';const colorName='fence('+event[4]+')';if(thread.lastActiveTs!==undefined){const duration=ts-thread.lastActiveTs;const slice=new tr.model.ThreadSlice('',name,ColorScheme.getColorIdForGeneralPurposeString(colorName),thread.lastActiveTs,{driver:event[1],context:event[3]},duration);thread.thread.sliceGroup.pushSlice(slice);}
+if(thread.thread.sliceGroup.openSliceCount>0){thread.thread.sliceGroup.endSlice(ts);}
+thread.lastActiveTs=ts;},fenceSignaledEvent(eventName,cpuNumber,pid,ts,eventBase){const event=fenceRE.exec(eventBase.details);if(!event)return false;if(eventBase.tgid===undefined){return false;}
+const thread=this.importer.getOrCreatePseudoThread(event[2]);const name='fence_signal('+event[4]+')';const colorName='fence('+event[4]+')';if(thread.lastActiveTs!==undefined){const duration=ts-thread.lastActiveTs;const slice=new tr.model.ThreadSlice('',name,ColorScheme.getColorIdForGeneralPurposeString(colorName),thread.lastActiveTs,{driver:event[1],context:event[3]},duration);thread.thread.sliceGroup.pushSlice(slice);}
+if(thread.thread.sliceGroup.openSliceCount>0){thread.thread.sliceGroup.endSlice(ts);}
+thread.lastActiveTs=ts;return true;},fenceWaitEvent(eventName,cpuNumber,pid,ts,eventBase){if(eventBase.tgid===undefined)return false;const event=fenceRE.exec(eventBase.details);if(!event)return false;const tgid=parseInt(eventBase.tgid);const thread=this.model_.getOrCreateProcess(tgid).getOrCreateThread(pid);thread.name=eventBase.threadName;const slices=thread.kernelSliceGroup;if(!slices.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
+const name='dma_fence_wait("'+event[2]+'")';if(eventName.endsWith('start')){const slice=slices.beginSlice(null,name,ts,{driver:event[1],context:event[3],seqno:event[4],});}else{if(slices.openSliceCount>0){slices.endSlice(ts);}}
+return true;},};Parser.register(DmaFenceParser);return{DmaFenceParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function DrmParser(importer){Parser.call(this,importer);importer.registerEventHandler('drm_vblank_event',DrmParser.prototype.vblankEvent.bind(this));}
+DrmParser.prototype={__proto__:Parser.prototype,drmVblankSlice(ts,eventName,args){const kthread=this.importer.getOrCreatePseudoThread('drm_vblank');kthread.openSlice=eventName;const slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},vblankEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/crtc=(\d+), seq=(\d+)/.exec(eventBase.details);if(!event)return false;const crtc=parseInt(event[1]);const seq=parseInt(event[2]);this.drmVblankSlice(ts,'vblank:'+crtc,{crtc,seq});return true;}};Parser.register(DrmParser);return{DrmParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function ExynosParser(importer){Parser.call(this,importer);importer.registerEventHandler('exynos_busfreq_target_int',ExynosParser.prototype.busfreqTargetIntEvent.bind(this));importer.registerEventHandler('exynos_busfreq_target_mif',ExynosParser.prototype.busfreqTargetMifEvent.bind(this));importer.registerEventHandler('exynos_page_flip_state',ExynosParser.prototype.pageFlipStateEvent.bind(this));}
+ExynosParser.prototype={__proto__:Parser.prototype,exynosBusfreqSample(name,ts,frequency){const targetCpu=this.importer.getOrCreateCpu(0);const counter=targetCpu.getOrCreateCounter('',name);if(counter.numSeries===0){counter.addSeries(new tr.model.CounterSeries('frequency',ColorScheme.getColorIdForGeneralPurposeString(counter.name+'.'+'frequency')));}
+counter.series.forEach(function(series){series.addCounterSample(ts,frequency);});},busfreqTargetIntEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/frequency=(\d+)/.exec(eventBase.details);if(!event)return false;this.exynosBusfreqSample('INT Frequency',ts,parseInt(event[1]));return true;},busfreqTargetMifEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/frequency=(\d+)/.exec(eventBase.details);if(!event)return false;this.exynosBusfreqSample('MIF Frequency',ts,parseInt(event[1]));return true;},exynosPageFlipStateOpenSlice(ts,pipe,fb,state){const kthread=this.importer.getOrCreatePseudoThread('exynos_flip_state (pipe:'+pipe+', fb:'+fb+')');kthread.openSliceTS=ts;kthread.openSlice=state;},exynosPageFlipStateCloseSlice(ts,pipe,fb,args){const kthread=this.importer.getOrCreatePseudoThread('exynos_flip_state (pipe:'+pipe+', fb:'+fb+')');if(kthread.openSlice){const slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),kthread.openSliceTS,args,ts-kthread.openSliceTS);kthread.thread.sliceGroup.pushSlice(slice);}
+kthread.openSlice=undefined;},pageFlipStateEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/pipe=(\d+), fb=(\d+), state=(.*)/.exec(eventBase.details);if(!event)return false;const pipe=parseInt(event[1]);const fb=parseInt(event[2]);const state=event[3];this.exynosPageFlipStateCloseSlice(ts,pipe,fb,{pipe,fb});if(state!=='flipped'){this.exynosPageFlipStateOpenSlice(ts,pipe,fb,state);}
+return true;}};Parser.register(ExynosParser);return{ExynosParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const Parser=tr.e.importer.linux_perf.Parser;function GestureParser(importer){Parser.call(this,importer);importer.registerEventHandler('tracing_mark_write:log',GestureParser.prototype.logEvent.bind(this));importer.registerEventHandler('tracing_mark_write:SyncInterpret',GestureParser.prototype.syncEvent.bind(this));importer.registerEventHandler('tracing_mark_write:HandleTimer',GestureParser.prototype.timerEvent.bind(this));}
+GestureParser.prototype={__proto__:Parser.prototype,gestureOpenSlice(title,ts,opt_args){const thread=this.importer.getOrCreatePseudoThread('gesture').thread;thread.sliceGroup.beginSlice('touchpad_gesture',title,ts,opt_args);},gestureCloseSlice(title,ts){const thread=this.importer.getOrCreatePseudoThread('gesture').thread;if(thread.sliceGroup.openSliceCount){const slice=thread.sliceGroup.mostRecentlyOpenedPartialSlice;if(slice.title!==title){this.importer.model.importWarning({type:'title_match_error',message:'Titles do not match. Title is '+
 slice.title+' in openSlice, and is '+
-title+' in endSlice'});}else{thread.sliceGroup.endSlice(ts);}}},logEvent:function(eventName,cpuNumber,pid,ts,eventBase){var innerEvent=/^\s*(\w+):\s*(\w+)$/.exec(eventBase.details);switch(innerEvent[1]){case'start':this.gestureOpenSlice('GestureLog',ts,{name:innerEvent[2]});break;case'end':this.gestureCloseSlice('GestureLog',ts);}
-return true;},syncEvent:function(eventName,cpuNumber,pid,ts,eventBase){var innerEvent=/^\s*(\w+):\s*(\w+)$/.exec(eventBase.details);switch(innerEvent[1]){case'start':this.gestureOpenSlice('SyncInterpret',ts,{interpreter:innerEvent[2]});break;case'end':this.gestureCloseSlice('SyncInterpret',ts);}
-return true;},timerEvent:function(eventName,cpuNumber,pid,ts,eventBase){var innerEvent=/^\s*(\w+):\s*(\w+)$/.exec(eventBase.details);switch(innerEvent[1]){case'start':this.gestureOpenSlice('HandleTimer',ts,{interpreter:innerEvent[2]});break;case'end':this.gestureCloseSlice('HandleTimer',ts);}
-return true;}};Parser.register(GestureParser);return{GestureParser:GestureParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function I915Parser(importer){Parser.call(this,importer);importer.registerEventHandler('i915_gem_object_create',I915Parser.prototype.gemObjectCreateEvent.bind(this));importer.registerEventHandler('i915_gem_object_bind',I915Parser.prototype.gemObjectBindEvent.bind(this));importer.registerEventHandler('i915_gem_object_unbind',I915Parser.prototype.gemObjectBindEvent.bind(this));importer.registerEventHandler('i915_gem_object_change_domain',I915Parser.prototype.gemObjectChangeDomainEvent.bind(this));importer.registerEventHandler('i915_gem_object_pread',I915Parser.prototype.gemObjectPreadWriteEvent.bind(this));importer.registerEventHandler('i915_gem_object_pwrite',I915Parser.prototype.gemObjectPreadWriteEvent.bind(this));importer.registerEventHandler('i915_gem_object_fault',I915Parser.prototype.gemObjectFaultEvent.bind(this));importer.registerEventHandler('i915_gem_object_clflush',I915Parser.prototype.gemObjectDestroyEvent.bind(this));importer.registerEventHandler('i915_gem_object_destroy',I915Parser.prototype.gemObjectDestroyEvent.bind(this));importer.registerEventHandler('i915_gem_ring_dispatch',I915Parser.prototype.gemRingDispatchEvent.bind(this));importer.registerEventHandler('i915_gem_ring_flush',I915Parser.prototype.gemRingFlushEvent.bind(this));importer.registerEventHandler('i915_gem_request',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_add',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_complete',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_retire',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_wait_begin',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_wait_end',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_ring_wait_begin',I915Parser.prototype.gemRingWaitEvent.bind(this));importer.registerEventHandler('i915_gem_ring_wait_end',I915Parser.prototype.gemRingWaitEvent.bind(this));importer.registerEventHandler('i915_reg_rw',I915Parser.prototype.regRWEvent.bind(this));importer.registerEventHandler('i915_flip_request',I915Parser.prototype.flipEvent.bind(this));importer.registerEventHandler('i915_flip_complete',I915Parser.prototype.flipEvent.bind(this));importer.registerEventHandler('intel_gpu_freq_change',I915Parser.prototype.gpuFrequency.bind(this));}
-I915Parser.prototype={__proto__:Parser.prototype,i915FlipOpenSlice:function(ts,obj,plane){var kthread=this.importer.getOrCreatePseudoThread('i915_flip');kthread.openSliceTS=ts;kthread.openSlice='flip:'+obj+'/'+plane;},i915FlipCloseSlice:function(ts,args){var kthread=this.importer.getOrCreatePseudoThread('i915_flip');if(kthread.openSlice){var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),kthread.openSliceTS,args,ts-kthread.openSliceTS);kthread.thread.sliceGroup.pushSlice(slice);}
-kthread.openSlice=undefined;},i915GemObjectSlice:function(ts,eventName,obj,args){var kthread=this.importer.getOrCreatePseudoThread('i915_gem');kthread.openSlice=eventName+':'+obj;var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},i915GemRingSlice:function(ts,eventName,dev,ring,args){var kthread=this.importer.getOrCreatePseudoThread('i915_gem_ring');kthread.openSlice=eventName+':'+dev+'.'+ring;var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},i915RegSlice:function(ts,eventName,reg,args){var kthread=this.importer.getOrCreatePseudoThread('i915_reg');kthread.openSlice=eventName+':'+reg;var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},i915FreqChangeSlice:function(ts,eventName,args){var kthread=this.importer.getOrCreatePseudoThread('i915_gpu_freq');kthread.openSlice=eventName;var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},gemObjectCreateEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/obj=(\w+), size=(\d+)/.exec(eventBase.details);if(!event)
-return false;var obj=event[1];var size=parseInt(event[2]);this.i915GemObjectSlice(ts,eventName,obj,{obj:obj,size:size});return true;},gemObjectBindEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/obj=(\w+), offset=(\w+), size=(\d+)/.exec(eventBase.details);if(!event)
-return false;var obj=event[1];var offset=event[2];var size=parseInt(event[3]);this.i915ObjectGemSlice(ts,eventName+':'+obj,{obj:obj,offset:offset,size:size});return true;},gemObjectChangeDomainEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/obj=(\w+), read=(\w+=>\w+), write=(\w+=>\w+)/.exec(eventBase.details);if(!event)
-return false;var obj=event[1];var read=event[2];var write=event[3];this.i915GemObjectSlice(ts,eventName,obj,{obj:obj,read:read,write:write});return true;},gemObjectPreadWriteEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/obj=(\w+), offset=(\d+), len=(\d+)/.exec(eventBase.details);if(!event)
-return false;var obj=event[1];var offset=parseInt(event[2]);var len=parseInt(event[3]);this.i915GemObjectSlice(ts,eventName,obj,{obj:obj,offset:offset,len:len});return true;},gemObjectFaultEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/obj=(\w+), (\w+) index=(\d+)/.exec(eventBase.details);if(!event)
-return false;var obj=event[1];var type=event[2];var index=parseInt(event[3]);this.i915GemObjectSlice(ts,eventName,obj,{obj:obj,type:type,index:index});return true;},gemObjectDestroyEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/obj=(\w+)/.exec(eventBase.details);if(!event)
-return false;var obj=event[1];this.i915GemObjectSlice(ts,eventName,obj,{obj:obj});return true;},gemRingDispatchEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev=(\d+), ring=(\d+), seqno=(\d+)/.exec(eventBase.details);if(!event)
-return false;var dev=parseInt(event[1]);var ring=parseInt(event[2]);var seqno=parseInt(event[3]);this.i915GemRingSlice(ts,eventName,dev,ring,{dev:dev,ring:ring,seqno:seqno});return true;},gemRingFlushEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev=(\d+), ring=(\w+), invalidate=(\w+), flush=(\w+)/.exec(eventBase.details);if(!event)
-return false;var dev=parseInt(event[1]);var ring=parseInt(event[2]);var invalidate=event[3];var flush=event[4];this.i915GemRingSlice(ts,eventName,dev,ring,{dev:dev,ring:ring,invalidate:invalidate,flush:flush});return true;},gemRequestEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev=(\d+), ring=(\d+), seqno=(\d+)/.exec(eventBase.details);if(!event)
-return false;var dev=parseInt(event[1]);var ring=parseInt(event[2]);var seqno=parseInt(event[3]);this.i915GemRingSlice(ts,eventName,dev,ring,{dev:dev,ring:ring,seqno:seqno});return true;},gemRingWaitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev=(\d+), ring=(\d+)/.exec(eventBase.details);if(!event)
-return false;var dev=parseInt(event[1]);var ring=parseInt(event[2]);this.i915GemRingSlice(ts,eventName,dev,ring,{dev:dev,ring:ring});return true;},regRWEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/(\w+) reg=(\w+), len=(\d+), val=(\(\w+, \w+\))/.exec(eventBase.details);if(!event)
-return false;var rw=event[1];var reg=event[2];var len=event[3];var data=event[3];this.i915RegSlice(ts,rw,reg,{rw:rw,reg:reg,len:len,data:data});return true;},flipEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/plane=(\d+), obj=(\w+)/.exec(eventBase.details);if(!event)
-return false;var plane=parseInt(event[1]);var obj=event[2];if(eventName=='i915_flip_request')
-this.i915FlipOpenSlice(ts,obj,plane);else
-this.i915FlipCloseSlice(ts,{obj:obj,plane:plane});return true;},gpuFrequency:function(eventName,cpuNumver,pid,ts,eventBase){var event=/new_freq=(\d+)/.exec(eventBase.details);if(!event)
-return false;var freq=parseInt(event[1]);this.i915FreqChangeSlice(ts,eventName,{freq:freq});return true;}};Parser.register(I915Parser);return{I915Parser:I915Parser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function IrqParser(importer){Parser.call(this,importer);importer.registerEventHandler('irq_handler_entry',IrqParser.prototype.irqHandlerEntryEvent.bind(this));importer.registerEventHandler('irq_handler_exit',IrqParser.prototype.irqHandlerExitEvent.bind(this));importer.registerEventHandler('softirq_raise',IrqParser.prototype.softirqRaiseEvent.bind(this));importer.registerEventHandler('softirq_entry',IrqParser.prototype.softirqEntryEvent.bind(this));importer.registerEventHandler('softirq_exit',IrqParser.prototype.softirqExitEvent.bind(this));importer.registerEventHandler('ipi_entry',IrqParser.prototype.ipiEntryEvent.bind(this));importer.registerEventHandler('ipi_exit',IrqParser.prototype.ipiExitEvent.bind(this));}
-var irqHandlerEntryRE=/irq=(\d+) name=(.+)/;var irqHandlerExitRE=/irq=(\d+) ret=(.+)/;var softirqRE=/vec=(\d+) \[action=(.+)\]/;var ipiHandlerExitRE=/\((.+)\)/;IrqParser.prototype={__proto__:Parser.prototype,irqHandlerEntryEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=irqHandlerEntryRE.exec(eventBase.details);if(!event)
-return false;var irq=parseInt(event[1]);var name=event[2];var thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);thread.lastEntryTs=ts;thread.irqName=name;return true;},irqHandlerExitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=irqHandlerExitRE.exec(eventBase.details);if(!event)
-return false;var irq=parseInt(event[1]);var ret=event[2];var thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);if(thread.lastEntryTs!==undefined){var duration=ts-thread.lastEntryTs;var slice=new tr.model.Slice('','IRQ ('+thread.irqName+')',ColorScheme.getColorIdForGeneralPurposeString(event[1]),thread.lastEntryTs,{ret:ret},duration);thread.thread.sliceGroup.pushSlice(slice);}
-thread.lastEntryTs=undefined;thread.irqName=undefined;return true;},softirqRaiseEvent:function(eventName,cpuNumber,pid,ts,eventBase){return true;},softirqEntryEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=softirqRE.exec(eventBase.details);if(!event)
-return false;var action=event[2];var thread=this.importer.getOrCreatePseudoThread('softirq cpu '+cpuNumber);thread.lastEntryTs=ts;return true;},softirqExitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=softirqRE.exec(eventBase.details);if(!event)
-return false;var vec=parseInt(event[1]);var action=event[2];var thread=this.importer.getOrCreatePseudoThread('softirq cpu '+cpuNumber);if(thread.lastEntryTs!==undefined){var duration=ts-thread.lastEntryTs;var slice=new tr.model.Slice('',action,ColorScheme.getColorIdForGeneralPurposeString(event[1]),thread.lastEntryTs,{vec:vec},duration);thread.thread.sliceGroup.pushSlice(slice);}
-thread.lastEntryTs=undefined;return true;},ipiEntryEvent:function(eventName,cpuNumber,pid,ts,eventBase){var thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);thread.lastEntryTs=ts;return true;},ipiExitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=ipiHandlerExitRE.exec(eventBase.details);if(!event)
-return false;var ipiName=event[1];var thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);if(thread.lastEntryTs!==undefined){var duration=ts-thread.lastEntryTs;var slice=new tr.model.Slice('','IPI ('+ipiName+')',ColorScheme.getColorIdForGeneralPurposeString(ipiName),thread.lastEntryTs,{},duration);thread.thread.sliceGroup.pushSlice(slice);}
-thread.lastEntryTs=undefined;return true;}};Parser.register(IrqParser);return{IrqParser:IrqParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var LinuxPerfParser=tr.e.importer.linux_perf.Parser;function KernelFuncParser(importer){LinuxPerfParser.call(this,importer);importer.registerEventHandler('graph_ent',KernelFuncParser.prototype.traceKernelFuncEnterEvent.bind(this));importer.registerEventHandler('graph_ret',KernelFuncParser.prototype.traceKernelFuncReturnEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
-var TestExports={};var funcEnterRE=new RegExp('func=(.+)');TestExports.funcEnterRE=funcEnterRE;KernelFuncParser.prototype={__proto__:LinuxPerfParser.prototype,traceKernelFuncEnterEvent:function(eventName,cpuNumber,pid,ts,eventBase){var eventData=funcEnterRE.exec(eventBase.details);if(!eventData)
-return false;if(eventBase.tgid===undefined){return false;}
-var tgid=parseInt(eventBase.tgid);var name=eventData[1];var thread=this.model_.getOrCreateProcess(tgid).getOrCreateThread(pid);thread.name=eventBase.threadName;var slices=thread.kernelSliceGroup;if(!slices.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
-var slice=slices.beginSlice(null,name,ts,{});return true;},traceKernelFuncReturnEvent:function(eventName,cpuNumber,pid,ts,eventBase){if(eventBase.tgid===undefined){return false;}
-var tgid=parseInt(eventBase.tgid);var thread=this.model_.getOrCreateProcess(tgid).getOrCreateThread(pid);thread.name=eventBase.threadName;var slices=thread.kernelSliceGroup;if(!slices.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
+title+' in endSlice'});}else{thread.sliceGroup.endSlice(ts);}}},logEvent(eventName,cpuNumber,pid,ts,eventBase){const innerEvent=/^\s*(\w+):\s*(\w+)$/.exec(eventBase.details);switch(innerEvent[1]){case'start':this.gestureOpenSlice('GestureLog',ts,{name:innerEvent[2]});break;case'end':this.gestureCloseSlice('GestureLog',ts);}
+return true;},syncEvent(eventName,cpuNumber,pid,ts,eventBase){const innerEvent=/^\s*(\w+):\s*(\w+)$/.exec(eventBase.details);switch(innerEvent[1]){case'start':this.gestureOpenSlice('SyncInterpret',ts,{interpreter:innerEvent[2]});break;case'end':this.gestureCloseSlice('SyncInterpret',ts);}
+return true;},timerEvent(eventName,cpuNumber,pid,ts,eventBase){const innerEvent=/^\s*(\w+):\s*(\w+)$/.exec(eventBase.details);switch(innerEvent[1]){case'start':this.gestureOpenSlice('HandleTimer',ts,{interpreter:innerEvent[2]});break;case'end':this.gestureCloseSlice('HandleTimer',ts);}
+return true;}};Parser.register(GestureParser);return{GestureParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function I2cParser(importer){Parser.call(this,importer);importer.registerEventHandler('i2c_write',I2cParser.prototype.i2cWriteEvent.bind(this));importer.registerEventHandler('i2c_read',I2cParser.prototype.i2cReadEvent.bind(this));importer.registerEventHandler('i2c_reply',I2cParser.prototype.i2cReplyEvent.bind(this));importer.registerEventHandler('i2c_result',I2cParser.prototype.i2cResultEvent.bind(this));}
+const i2cWriteReplyRE=new RegExp('i2c-(\\d+) #(\\d+) a=([\\da-fA-F]+) f=([\\da-fA-F]+) l=(\\d+) '+'(\\[[\\da-fA-F\\-]+\\])');const i2cReadRE=/i2c-(\d+) #(\d+) a=([\da-fA-F]+) f=([\da-fA-F]+) l=(\d+)/;const i2cResultRE=/i2c-(\d+) n=(\d+) ret=(\d+)/;I2cParser.prototype={__proto__:Parser.prototype,i2cWriteEvent(eventName,cpuNumber,pid,ts,eventBase){const event=i2cWriteReplyRE.exec(eventBase.details);if(!event)return false;const adapterNumber=parseInt(event[1]);const messageNumber=event[2];const address=event[3];const flags=event[4];const dataLength=event[5];const data=event[6];const thread=this.importer.getOrCreatePseudoThread('i2c adapter '+adapterNumber);pushLastSliceIfNeeded(thread,event[1],ts);thread.lastEntryTitle='i2c write';thread.lastEntryTs=ts;thread.lastEntryArgs={'Message number':messageNumber,'Address':address,'Flags':flags,'Data Length':dataLength,'Data':data};return true;},i2cReadEvent(eventName,cpuNumber,pid,ts,eventBase){const event=i2cReadRE.exec(eventBase.details);if(!event)return false;const adapterNumber=parseInt(event[1]);const messageNumber=event[2];const address=event[3];const flags=event[4];const dataLength=event[5];const thread=this.importer.getOrCreatePseudoThread('i2c adapter '+adapterNumber);pushLastSliceIfNeeded(thread,event[1],ts);thread.lastEntryTitle='i2c read';thread.lastEntryTs=ts;thread.lastEntryArgs={'Message number':messageNumber,'Address':address,'Flags':flags,'Data Length':dataLength};return true;},i2cReplyEvent(eventName,cpuNumber,pid,ts,eventBase){const event=i2cWriteReplyRE.exec(eventBase.details);if(!event)return false;const adapterNumber=parseInt(event[1]);const messageNumber=event[2];const address=event[3];const flags=event[4];const dataLength=event[5];const data=event[6];const thread=this.importer.getOrCreatePseudoThread('i2c adapter '+adapterNumber);pushLastSliceIfNeeded(thread,event[1],ts);thread.lastEntryTitle='i2c reply';thread.lastEntryTs=ts;thread.lastEntryArgs={'Message number':messageNumber,'Address':address,'Flags':flags,'Data Length':dataLength,'Data':data};return true;},i2cResultEvent(eventName,cpuNumber,pid,ts,eventBase){const event=i2cResultRE.exec(eventBase.details);if(!event)return false;const adapterNumber=parseInt(event[1]);const numMessages=event[2];const ret=event[3];const thread=this.importer.getOrCreatePseudoThread('i2c adapter '+adapterNumber);const args=thread.lastEntryArgs;if(args!==undefined){args['Number of messages']=numMessages;args.Return=ret;}
+pushLastSliceIfNeeded(thread,event[1],ts);thread.lastEntryTitle=undefined;thread.lastEntryTs=undefined;thread.lastEntryArgs=undefined;return true;},};function pushLastSliceIfNeeded(thread,id,currentTs){if(thread.lastEntryTs!==undefined){const duration=currentTs-thread.lastEntryTs;const slice=new tr.model.ThreadSlice('',thread.lastEntryTitle,ColorScheme.getColorIdForGeneralPurposeString(id),thread.lastEntryTs,thread.lastEntryArgs,duration);thread.thread.sliceGroup.pushSlice(slice);}}
+Parser.register(I2cParser);return{I2cParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function I915Parser(importer){Parser.call(this,importer);importer.registerEventHandler('i915_gem_object_create',I915Parser.prototype.gemObjectCreateEvent.bind(this));importer.registerEventHandler('i915_gem_object_bind',I915Parser.prototype.gemObjectBindEvent.bind(this));importer.registerEventHandler('i915_gem_object_unbind',I915Parser.prototype.gemObjectBindEvent.bind(this));importer.registerEventHandler('i915_gem_object_change_domain',I915Parser.prototype.gemObjectChangeDomainEvent.bind(this));importer.registerEventHandler('i915_gem_object_pread',I915Parser.prototype.gemObjectPreadWriteEvent.bind(this));importer.registerEventHandler('i915_gem_object_pwrite',I915Parser.prototype.gemObjectPreadWriteEvent.bind(this));importer.registerEventHandler('i915_gem_object_fault',I915Parser.prototype.gemObjectFaultEvent.bind(this));importer.registerEventHandler('i915_gem_object_clflush',I915Parser.prototype.gemObjectDestroyEvent.bind(this));importer.registerEventHandler('i915_gem_object_destroy',I915Parser.prototype.gemObjectDestroyEvent.bind(this));importer.registerEventHandler('i915_gem_ring_dispatch',I915Parser.prototype.gemRingDispatchEvent.bind(this));importer.registerEventHandler('i915_gem_ring_flush',I915Parser.prototype.gemRingFlushEvent.bind(this));importer.registerEventHandler('i915_gem_request',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_add',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_complete',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_retire',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_wait_begin',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_wait_end',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_ring_wait_begin',I915Parser.prototype.gemRingWaitEvent.bind(this));importer.registerEventHandler('i915_gem_ring_wait_end',I915Parser.prototype.gemRingWaitEvent.bind(this));importer.registerEventHandler('i915_reg_rw',I915Parser.prototype.regRWEvent.bind(this));importer.registerEventHandler('i915_flip_request',I915Parser.prototype.flipEvent.bind(this));importer.registerEventHandler('i915_flip_complete',I915Parser.prototype.flipEvent.bind(this));importer.registerEventHandler('intel_gpu_freq_change',I915Parser.prototype.gpuFrequency.bind(this));}
+I915Parser.prototype={__proto__:Parser.prototype,i915FlipOpenSlice(ts,obj,plane){const kthread=this.importer.getOrCreatePseudoThread('i915_flip');kthread.openSliceTS=ts;kthread.openSlice='flip:'+obj+'/'+plane;},i915FlipCloseSlice(ts,args){const kthread=this.importer.getOrCreatePseudoThread('i915_flip');if(kthread.openSlice){const slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),kthread.openSliceTS,args,ts-kthread.openSliceTS);kthread.thread.sliceGroup.pushSlice(slice);}
+kthread.openSlice=undefined;},i915GemObjectSlice(ts,eventName,obj,args){const kthread=this.importer.getOrCreatePseudoThread('i915_gem');kthread.openSlice=eventName+':'+obj;const slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},i915GemRingSlice(ts,eventName,dev,ring,args){const kthread=this.importer.getOrCreatePseudoThread('i915_gem_ring');kthread.openSlice=eventName+':'+dev+'.'+ring;const slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},i915RegSlice(ts,eventName,reg,args){const kthread=this.importer.getOrCreatePseudoThread('i915_reg');kthread.openSlice=eventName+':'+reg;const slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},i915FreqChangeSlice(ts,eventName,args){const kthread=this.importer.getOrCreatePseudoThread('i915_gpu_freq');kthread.openSlice=eventName;const slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},gemObjectCreateEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/obj=(\w+), size=(\d+)/.exec(eventBase.details);if(!event)return false;const obj=event[1];const size=parseInt(event[2]);this.i915GemObjectSlice(ts,eventName,obj,{obj,size});return true;},gemObjectBindEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/obj=(\w+), offset=(\w+), size=(\d+)/.exec(eventBase.details);if(!event)return false;const obj=event[1];const offset=event[2];const size=parseInt(event[3]);this.i915ObjectGemSlice(ts,eventName+':'+obj,{obj,offset,size});return true;},gemObjectChangeDomainEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/obj=(\w+), read=(\w+=>\w+), write=(\w+=>\w+)/.exec(eventBase.details);if(!event)return false;const obj=event[1];const read=event[2];const write=event[3];this.i915GemObjectSlice(ts,eventName,obj,{obj,read,write});return true;},gemObjectPreadWriteEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/obj=(\w+), offset=(\d+), len=(\d+)/.exec(eventBase.details);if(!event)return false;const obj=event[1];const offset=parseInt(event[2]);const len=parseInt(event[3]);this.i915GemObjectSlice(ts,eventName,obj,{obj,offset,len});return true;},gemObjectFaultEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/obj=(\w+), (\w+) index=(\d+)/.exec(eventBase.details);if(!event)return false;const obj=event[1];const type=event[2];const index=parseInt(event[3]);this.i915GemObjectSlice(ts,eventName,obj,{obj,type,index});return true;},gemObjectDestroyEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/obj=(\w+)/.exec(eventBase.details);if(!event)return false;const obj=event[1];this.i915GemObjectSlice(ts,eventName,obj,{obj});return true;},gemRingDispatchEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/dev=(\d+), ring=(\d+), seqno=(\d+)/.exec(eventBase.details);if(!event)return false;const dev=parseInt(event[1]);const ring=parseInt(event[2]);const seqno=parseInt(event[3]);this.i915GemRingSlice(ts,eventName,dev,ring,{dev,ring,seqno});return true;},gemRingFlushEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/dev=(\d+), ring=(\w+), invalidate=(\w+), flush=(\w+)/.exec(eventBase.details);if(!event)return false;const dev=parseInt(event[1]);const ring=parseInt(event[2]);const invalidate=event[3];const flush=event[4];this.i915GemRingSlice(ts,eventName,dev,ring,{dev,ring,invalidate,flush});return true;},gemRequestEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/dev=(\d+), ring=(\d+), seqno=(\d+)/.exec(eventBase.details);if(!event)return false;const dev=parseInt(event[1]);const ring=parseInt(event[2]);const seqno=parseInt(event[3]);this.i915GemRingSlice(ts,eventName,dev,ring,{dev,ring,seqno});return true;},gemRingWaitEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/dev=(\d+), ring=(\d+)/.exec(eventBase.details);if(!event)return false;const dev=parseInt(event[1]);const ring=parseInt(event[2]);this.i915GemRingSlice(ts,eventName,dev,ring,{dev,ring});return true;},regRWEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/(\w+) reg=(\w+), len=(\d+), val=(\(\w+, \w+\))/.exec(eventBase.details);if(!event)return false;const rw=event[1];const reg=event[2];const len=event[3];const data=event[3];this.i915RegSlice(ts,rw,reg,{rw,reg,len,data});return true;},flipEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/plane=(\d+), obj=(\w+)/.exec(eventBase.details);if(!event)return false;const plane=parseInt(event[1]);const obj=event[2];if(eventName==='i915_flip_request'){this.i915FlipOpenSlice(ts,obj,plane);}else{this.i915FlipCloseSlice(ts,{obj,plane});}
+return true;},gpuFrequency(eventName,cpuNumver,pid,ts,eventBase){const event=/new_freq=(\d+)/.exec(eventBase.details);if(!event)return false;const freq=parseInt(event[1]);this.i915FreqChangeSlice(ts,eventName,{freq});return true;}};Parser.register(I915Parser);return{I915Parser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function IonHeapParser(importer){Parser.call(this,importer);importer.registerEventHandler('ion_heap_shrink',IonHeapParser.prototype.traceIonHeapShrink.bind(this));importer.registerEventHandler('ion_heap_grow',IonHeapParser.prototype.traceIonHeapGrow.bind(this));this.model_=importer.model_;}
+const TestExports={};const ionHeapRE=new RegExp('heap_name=(\\S+), len=(\\d+), total_allocated=(\\d+)');TestExports.ionHeapRE=ionHeapRE;IonHeapParser.prototype={__proto__:Parser.prototype,traceIonHeapShrink(eventName,cpuNumber,pid,ts,eventBase,threadName){const event=ionHeapRE.exec(eventBase.details);if(!event)return false;const name=event[1];const len=parseInt(event[2]);const totalAllocated=parseInt(event[3]);const ionHeap=totalAllocated+len;const ctr=this.model_.kernel.getOrCreateCounter(null,name+' ion heap');if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries('value',ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
+ctr.series.forEach(function(series){series.addCounterSample(ts,ionHeap);});return true;},traceIonHeapGrow(eventName,cpuNumber,pid,ts,eventBase,threadName){const event=ionHeapRE.exec(eventBase.details);if(!event)return false;const name=event[1];const len=parseInt(event[2]);const totalAllocated=parseInt(event[3]);const ionHeap=totalAllocated+len;const ctr=this.model_.kernel.getOrCreateCounter(null,name+' ion heap');if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries('value',ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
+ctr.series.forEach(function(series){series.addCounterSample(ts,ionHeap);});return true;}};Parser.register(IonHeapParser);return{IonHeapParser,_IonHeapParserTestExports:TestExports};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function IrqParser(importer){Parser.call(this,importer);importer.registerEventHandler('irq_handler_entry',IrqParser.prototype.irqHandlerEntryEvent.bind(this));importer.registerEventHandler('irq_handler_exit',IrqParser.prototype.irqHandlerExitEvent.bind(this));importer.registerEventHandler('softirq_raise',IrqParser.prototype.softirqRaiseEvent.bind(this));importer.registerEventHandler('softirq_entry',IrqParser.prototype.softirqEntryEvent.bind(this));importer.registerEventHandler('softirq_exit',IrqParser.prototype.softirqExitEvent.bind(this));importer.registerEventHandler('ipi_entry',IrqParser.prototype.ipiEntryEvent.bind(this));importer.registerEventHandler('ipi_exit',IrqParser.prototype.ipiExitEvent.bind(this));importer.registerEventHandler('preempt_disable',IrqParser.prototype.preemptStartEvent.bind(this));importer.registerEventHandler('preempt_enable',IrqParser.prototype.preemptEndEvent.bind(this));importer.registerEventHandler('irq_disable',IrqParser.prototype.irqoffStartEvent.bind(this));importer.registerEventHandler('irq_enable',IrqParser.prototype.irqoffEndEvent.bind(this));}
+const irqHandlerEntryRE=/irq=(\d+) name=(.+)/;const irqHandlerExitRE=/irq=(\d+) ret=(.+)/;const softirqRE=/vec=(\d+) \[action=(.+)\]/;const ipiHandlerExitRE=/\((.+)\)/;const preemptirqRE=/caller=(.+) parent=(.+)/;IrqParser.prototype={__proto__:Parser.prototype,irqHandlerEntryEvent(eventName,cpuNumber,pid,ts,eventBase){const event=irqHandlerEntryRE.exec(eventBase.details);if(!event)return false;const irq=parseInt(event[1]);const name=event[2];const thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);thread.lastEntryTs=ts;thread.irqName=name;return true;},irqHandlerExitEvent(eventName,cpuNumber,pid,ts,eventBase){const event=irqHandlerExitRE.exec(eventBase.details);if(!event)return false;const irq=parseInt(event[1]);const ret=event[2];const thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);if(thread.lastEntryTs!==undefined){const duration=ts-thread.lastEntryTs;const slice=new tr.model.ThreadSlice('','IRQ ('+thread.irqName+')',ColorScheme.getColorIdForGeneralPurposeString(event[1]),thread.lastEntryTs,{ret},duration);thread.thread.sliceGroup.pushSlice(slice);}
+thread.lastEntryTs=undefined;thread.irqName=undefined;return true;},softirqRaiseEvent(eventName,cpuNumber,pid,ts,eventBase){return true;},softirqEntryEvent(eventName,cpuNumber,pid,ts,eventBase){const event=softirqRE.exec(eventBase.details);if(!event)return false;const action=event[2];const thread=this.importer.getOrCreatePseudoThread('softirq cpu '+cpuNumber);thread.lastEntryTs=ts;return true;},softirqExitEvent(eventName,cpuNumber,pid,ts,eventBase){const event=softirqRE.exec(eventBase.details);if(!event)return false;const vec=parseInt(event[1]);const action=event[2];const thread=this.importer.getOrCreatePseudoThread('softirq cpu '+cpuNumber);if(thread.lastEntryTs!==undefined){const duration=ts-thread.lastEntryTs;const slice=new tr.model.ThreadSlice('',action,ColorScheme.getColorIdForGeneralPurposeString(event[1]),thread.lastEntryTs,{vec},duration);thread.thread.sliceGroup.pushSlice(slice);}
+thread.lastEntryTs=undefined;return true;},ipiEntryEvent(eventName,cpuNumber,pid,ts,eventBase){const thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);thread.lastEntryTs=ts;return true;},ipiExitEvent(eventName,cpuNumber,pid,ts,eventBase){const event=ipiHandlerExitRE.exec(eventBase.details);if(!event)return false;const ipiName=event[1];const thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);if(thread.lastEntryTs!==undefined){const duration=ts-thread.lastEntryTs;const slice=new tr.model.ThreadSlice('','IPI ('+ipiName+')',ColorScheme.getColorIdForGeneralPurposeString(ipiName),thread.lastEntryTs,{},duration);thread.thread.sliceGroup.pushSlice(slice);}
+thread.lastEntryTs=undefined;return true;},preemptStartEvent(eventName,cpuNumber,pid,ts,eventBase){const event=preemptirqRE.exec(eventBase.details);if(!event)return false;const thread=this.importer.getOrCreatePseudoThread('preempt cpu '+cpuNumber);thread.lastEntryTs=ts;thread.preemptStartCaller=event[1];thread.preemptStartParent=event[2];return true;},preemptEndEvent(eventName,cpuNumber,pid,ts,eventBase){const event=preemptirqRE.exec(eventBase.details);if(!event)return false;const thread=this.importer.getOrCreatePseudoThread('preempt cpu '+cpuNumber);thread.preemptEndCaller=event[1];thread.preemptEndParent=event[2];if(thread.lastEntryTs!==undefined){const duration=ts-thread.lastEntryTs;const slice=new tr.model.ThreadSlice('',thread.preemptStartParent+': '+thread.preemptStartCaller,ColorScheme.getColorIdForGeneralPurposeString(thread.preemptEndCaller),thread.lastEntryTs,{},duration);thread.thread.sliceGroup.pushSlice(slice);}
+thread.lastEntryTs=undefined;return true;},irqoffStartEvent(eventName,cpuNumber,pid,ts,eventBase){const event=preemptirqRE.exec(eventBase.details);if(!event)return false;const thread=this.importer.getOrCreatePseudoThread('irqoff cpu '+cpuNumber);thread.lastEntryTs=ts;thread.irqoffStartCaller=event[1];thread.irqoffStartParent=event[2];return true;},irqoffEndEvent(eventName,cpuNumber,pid,ts,eventBase){const event=preemptirqRE.exec(eventBase.details);if(!event)return false;const thread=this.importer.getOrCreatePseudoThread('irqoff cpu '+cpuNumber);thread.irqoffEndCaller=event[1];thread.irqoffEndParent=event[2];if(thread.lastEntryTs!==undefined){const duration=ts-thread.lastEntryTs;const slice=new tr.model.ThreadSlice('',thread.irqoffStartParent+': '+thread.irqoffStartCaller,ColorScheme.getColorIdForGeneralPurposeString(thread.irqoffEndCaller),thread.lastEntryTs,{},duration);thread.thread.sliceGroup.pushSlice(slice);}
+thread.lastEntryTs=undefined;return true;}};Parser.register(IrqParser);return{IrqParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const LinuxPerfParser=tr.e.importer.linux_perf.Parser;function KernelFuncParser(importer){LinuxPerfParser.call(this,importer);importer.registerEventHandler('graph_ent',KernelFuncParser.prototype.traceKernelFuncEnterEvent.bind(this));importer.registerEventHandler('graph_ret',KernelFuncParser.prototype.traceKernelFuncReturnEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
+const TestExports={};const funcEnterRE=new RegExp('func=(.+)');TestExports.funcEnterRE=funcEnterRE;KernelFuncParser.prototype={__proto__:LinuxPerfParser.prototype,traceKernelFuncEnterEvent(eventName,cpuNumber,pid,ts,eventBase){const eventData=funcEnterRE.exec(eventBase.details);if(!eventData)return false;if(eventBase.tgid===undefined){return false;}
+const tgid=parseInt(eventBase.tgid);const name=eventData[1];const thread=this.model_.getOrCreateProcess(tgid).getOrCreateThread(pid);thread.name=eventBase.threadName;const slices=thread.kernelSliceGroup;if(!slices.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
+const slice=slices.beginSlice(null,name,ts,{});return true;},traceKernelFuncReturnEvent(eventName,cpuNumber,pid,ts,eventBase){if(eventBase.tgid===undefined){return false;}
+const tgid=parseInt(eventBase.tgid);const thread=this.model_.getOrCreateProcess(tgid).getOrCreateThread(pid);thread.name=eventBase.threadName;const slices=thread.kernelSliceGroup;if(!slices.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
 if(slices.openSliceCount>0){slices.endSlice(ts);}
-return true;}};LinuxPerfParser.register(KernelFuncParser);return{KernelFuncParser:KernelFuncParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function MaliParser(importer){Parser.call(this,importer);importer.registerEventHandler('mali_dvfs_event',MaliParser.prototype.dvfsEventEvent.bind(this));importer.registerEventHandler('mali_dvfs_set_clock',MaliParser.prototype.dvfsSetClockEvent.bind(this));importer.registerEventHandler('mali_dvfs_set_voltage',MaliParser.prototype.dvfsSetVoltageEvent.bind(this));this.addJMCounter('mali_hwc_MESSAGES_SENT','Messages Sent');this.addJMCounter('mali_hwc_MESSAGES_RECEIVED','Messages Received');this.addJMCycles('mali_hwc_GPU_ACTIVE','GPU Active');this.addJMCycles('mali_hwc_IRQ_ACTIVE','IRQ Active');for(var i=0;i<7;i++){var jobStr='JS'+i;var jobHWCStr='mali_hwc_'+jobStr;this.addJMCounter(jobHWCStr+'_JOBS',jobStr+' Jobs');this.addJMCounter(jobHWCStr+'_TASKS',jobStr+' Tasks');this.addJMCycles(jobHWCStr+'_ACTIVE',jobStr+' Active');this.addJMCycles(jobHWCStr+'_WAIT_READ',jobStr+' Wait Read');this.addJMCycles(jobHWCStr+'_WAIT_ISSUE',jobStr+' Wait Issue');this.addJMCycles(jobHWCStr+'_WAIT_DEPEND',jobStr+' Wait Depend');this.addJMCycles(jobHWCStr+'_WAIT_FINISH',jobStr+' Wait Finish');}
-this.addTilerCounter('mali_hwc_TRIANGLES','Triangles');this.addTilerCounter('mali_hwc_QUADS','Quads');this.addTilerCounter('mali_hwc_POLYGONS','Polygons');this.addTilerCounter('mali_hwc_POINTS','Points');this.addTilerCounter('mali_hwc_LINES','Lines');this.addTilerCounter('mali_hwc_VCACHE_HIT','VCache Hit');this.addTilerCounter('mali_hwc_VCACHE_MISS','VCache Miss');this.addTilerCounter('mali_hwc_FRONT_FACING','Front Facing');this.addTilerCounter('mali_hwc_BACK_FACING','Back Facing');this.addTilerCounter('mali_hwc_PRIM_VISIBLE','Prim Visible');this.addTilerCounter('mali_hwc_PRIM_CULLED','Prim Culled');this.addTilerCounter('mali_hwc_PRIM_CLIPPED','Prim Clipped');this.addTilerCounter('mali_hwc_WRBUF_HIT','Wrbuf Hit');this.addTilerCounter('mali_hwc_WRBUF_MISS','Wrbuf Miss');this.addTilerCounter('mali_hwc_WRBUF_LINE','Wrbuf Line');this.addTilerCounter('mali_hwc_WRBUF_PARTIAL','Wrbuf Partial');this.addTilerCounter('mali_hwc_WRBUF_STALL','Wrbuf Stall');this.addTilerCycles('mali_hwc_ACTIVE','Tiler Active');this.addTilerCycles('mali_hwc_INDEX_WAIT','Index Wait');this.addTilerCycles('mali_hwc_INDEX_RANGE_WAIT','Index Range Wait');this.addTilerCycles('mali_hwc_VERTEX_WAIT','Vertex Wait');this.addTilerCycles('mali_hwc_PCACHE_WAIT','Pcache Wait');this.addTilerCycles('mali_hwc_WRBUF_WAIT','Wrbuf Wait');this.addTilerCycles('mali_hwc_BUS_READ','Bus Read');this.addTilerCycles('mali_hwc_BUS_WRITE','Bus Write');this.addTilerCycles('mali_hwc_TILER_UTLB_STALL','Tiler UTLB Stall');this.addTilerCycles('mali_hwc_TILER_UTLB_HIT','Tiler UTLB Hit');this.addFragCycles('mali_hwc_FRAG_ACTIVE','Active');this.addFragCounter('mali_hwc_FRAG_PRIMATIVES','Primitives');this.addFragCounter('mali_hwc_FRAG_PRIMATIVES_DROPPED','Primitives Dropped');this.addFragCycles('mali_hwc_FRAG_CYCLE_DESC','Descriptor Processing');this.addFragCycles('mali_hwc_FRAG_CYCLES_PLR','PLR Processing??');this.addFragCycles('mali_hwc_FRAG_CYCLES_VERT','Vertex Processing');this.addFragCycles('mali_hwc_FRAG_CYCLES_TRISETUP','Triangle Setup');this.addFragCycles('mali_hwc_FRAG_CYCLES_RAST','Rasterization???');this.addFragCounter('mali_hwc_FRAG_THREADS','Threads');this.addFragCounter('mali_hwc_FRAG_DUMMY_THREADS','Dummy Threads');this.addFragCounter('mali_hwc_FRAG_QUADS_RAST','Quads Rast');this.addFragCounter('mali_hwc_FRAG_QUADS_EZS_TEST','Quads EZS Test');this.addFragCounter('mali_hwc_FRAG_QUADS_EZS_KILLED','Quads EZS Killed');this.addFragCounter('mali_hwc_FRAG_QUADS_LZS_TEST','Quads LZS Test');this.addFragCounter('mali_hwc_FRAG_QUADS_LZS_KILLED','Quads LZS Killed');this.addFragCycles('mali_hwc_FRAG_CYCLE_NO_TILE','No Tiles');this.addFragCounter('mali_hwc_FRAG_NUM_TILES','Tiles');this.addFragCounter('mali_hwc_FRAG_TRANS_ELIM','Transactions Eliminated');this.addComputeCycles('mali_hwc_COMPUTE_ACTIVE','Active');this.addComputeCounter('mali_hwc_COMPUTE_TASKS','Tasks');this.addComputeCounter('mali_hwc_COMPUTE_THREADS','Threads Started');this.addComputeCycles('mali_hwc_COMPUTE_CYCLES_DESC','Waiting for Descriptors');this.addTripipeCycles('mali_hwc_TRIPIPE_ACTIVE','Active');this.addArithCounter('mali_hwc_ARITH_WORDS','Instructions (/Pipes)');this.addArithCycles('mali_hwc_ARITH_CYCLES_REG','Reg scheduling stalls (/Pipes)');this.addArithCycles('mali_hwc_ARITH_CYCLES_L0','L0 cache miss stalls (/Pipes)');this.addArithCounter('mali_hwc_ARITH_FRAG_DEPEND','Frag dep check failures (/Pipes)');this.addLSCounter('mali_hwc_LS_WORDS','Instruction Words Completed');this.addLSCounter('mali_hwc_LS_ISSUES','Full Pipeline Issues');this.addLSCounter('mali_hwc_LS_RESTARTS','Restarts (unpairable insts)');this.addLSCounter('mali_hwc_LS_REISSUES_MISS','Pipeline reissue (cache miss/uTLB)');this.addLSCounter('mali_hwc_LS_REISSUES_VD','Pipeline reissue (varying data)');this.addLSCounter('mali_hwc_LS_REISSUE_ATTRIB_MISS','Pipeline reissue (attribute cache miss)');this.addLSCounter('mali_hwc_LS_REISSUE_NO_WB','Writeback not used');this.addTexCounter('mali_hwc_TEX_WORDS','Words');this.addTexCounter('mali_hwc_TEX_BUBBLES','Bubbles');this.addTexCounter('mali_hwc_TEX_WORDS_L0','Words L0');this.addTexCounter('mali_hwc_TEX_WORDS_DESC','Words Desc');this.addTexCounter('mali_hwc_TEX_THREADS','Threads');this.addTexCounter('mali_hwc_TEX_RECIRC_FMISS','Recirc due to Full Miss');this.addTexCounter('mali_hwc_TEX_RECIRC_DESC','Recirc due to Desc Miss');this.addTexCounter('mali_hwc_TEX_RECIRC_MULTI','Recirc due to Multipass');this.addTexCounter('mali_hwc_TEX_RECIRC_PMISS','Recirc due to Partial Cache Miss');this.addTexCounter('mali_hwc_TEX_RECIRC_CONF','Recirc due to Cache Conflict');this.addLSCCounter('mali_hwc_LSC_READ_HITS','Read Hits');this.addLSCCounter('mali_hwc_LSC_READ_MISSES','Read Misses');this.addLSCCounter('mali_hwc_LSC_WRITE_HITS','Write Hits');this.addLSCCounter('mali_hwc_LSC_WRITE_MISSES','Write Misses');this.addLSCCounter('mali_hwc_LSC_ATOMIC_HITS','Atomic Hits');this.addLSCCounter('mali_hwc_LSC_ATOMIC_MISSES','Atomic Misses');this.addLSCCounter('mali_hwc_LSC_LINE_FETCHES','Line Fetches');this.addLSCCounter('mali_hwc_LSC_DIRTY_LINE','Dirty Lines');this.addLSCCounter('mali_hwc_LSC_SNOOPS','Snoops');this.addAXICounter('mali_hwc_AXI_TLB_STALL','Address channel stall');this.addAXICounter('mali_hwc_AXI_TLB_MISS','Cache Miss');this.addAXICounter('mali_hwc_AXI_TLB_TRANSACTION','Transactions');this.addAXICounter('mali_hwc_LS_TLB_MISS','LS Cache Miss');this.addAXICounter('mali_hwc_LS_TLB_HIT','LS Cache Hit');this.addAXICounter('mali_hwc_AXI_BEATS_READ','Read Beats');this.addAXICounter('mali_hwc_AXI_BEATS_WRITE','Write Beats');this.addMMUCounter('mali_hwc_MMU_TABLE_WALK','Page Table Walks');this.addMMUCounter('mali_hwc_MMU_REPLAY_MISS','Cache Miss from Replay Buffer');this.addMMUCounter('mali_hwc_MMU_REPLAY_FULL','Replay Buffer Full');this.addMMUCounter('mali_hwc_MMU_NEW_MISS','Cache Miss on New Request');this.addMMUCounter('mali_hwc_MMU_HIT','Cache Hit');this.addMMUCycles('mali_hwc_UTLB_STALL','UTLB Stalled');this.addMMUCycles('mali_hwc_UTLB_REPLAY_MISS','UTLB Replay Miss');this.addMMUCycles('mali_hwc_UTLB_REPLAY_FULL','UTLB Replay Full');this.addMMUCycles('mali_hwc_UTLB_NEW_MISS','UTLB New Miss');this.addMMUCycles('mali_hwc_UTLB_HIT','UTLB Hit');this.addL2Counter('mali_hwc_L2_READ_BEATS','Read Beats');this.addL2Counter('mali_hwc_L2_WRITE_BEATS','Write Beats');this.addL2Counter('mali_hwc_L2_ANY_LOOKUP','Any Lookup');this.addL2Counter('mali_hwc_L2_READ_LOOKUP','Read Lookup');this.addL2Counter('mali_hwc_L2_SREAD_LOOKUP','Shareable Read Lookup');this.addL2Counter('mali_hwc_L2_READ_REPLAY','Read Replayed');this.addL2Counter('mali_hwc_L2_READ_SNOOP','Read Snoop');this.addL2Counter('mali_hwc_L2_READ_HIT','Read Cache Hit');this.addL2Counter('mali_hwc_L2_CLEAN_MISS','CleanUnique Miss');this.addL2Counter('mali_hwc_L2_WRITE_LOOKUP','Write Lookup');this.addL2Counter('mali_hwc_L2_SWRITE_LOOKUP','Shareable Write Lookup');this.addL2Counter('mali_hwc_L2_WRITE_REPLAY','Write Replayed');this.addL2Counter('mali_hwc_L2_WRITE_SNOOP','Write Snoop');this.addL2Counter('mali_hwc_L2_WRITE_HIT','Write Cache Hit');this.addL2Counter('mali_hwc_L2_EXT_READ_FULL','ExtRD with BIU Full');this.addL2Counter('mali_hwc_L2_EXT_READ_HALF','ExtRD with BIU >1/2 Full');this.addL2Counter('mali_hwc_L2_EXT_WRITE_FULL','ExtWR with BIU Full');this.addL2Counter('mali_hwc_L2_EXT_WRITE_HALF','ExtWR with BIU >1/2 Full');this.addL2Counter('mali_hwc_L2_EXT_READ','External Read (ExtRD)');this.addL2Counter('mali_hwc_L2_EXT_READ_LINE','ExtRD (linefill)');this.addL2Counter('mali_hwc_L2_EXT_WRITE','External Write (ExtWR)');this.addL2Counter('mali_hwc_L2_EXT_WRITE_LINE','ExtWR (linefill)');this.addL2Counter('mali_hwc_L2_EXT_WRITE_SMALL','ExtWR (burst size <64B)');this.addL2Counter('mali_hwc_L2_EXT_BARRIER','External Barrier');this.addL2Counter('mali_hwc_L2_EXT_AR_STALL','Address Read stalls');this.addL2Counter('mali_hwc_L2_EXT_R_BUF_FULL','Response Buffer full stalls');this.addL2Counter('mali_hwc_L2_EXT_RD_BUF_FULL','Read Data Buffer full stalls');this.addL2Counter('mali_hwc_L2_EXT_R_RAW','RAW hazard stalls');this.addL2Counter('mali_hwc_L2_EXT_W_STALL','Write Data stalls');this.addL2Counter('mali_hwc_L2_EXT_W_BUF_FULL','Write Data Buffer full');this.addL2Counter('mali_hwc_L2_EXT_R_W_HAZARD','WAW or WAR hazard stalls');this.addL2Counter('mali_hwc_L2_TAG_HAZARD','Tag hazard replays');this.addL2Cycles('mali_hwc_L2_SNOOP_FULL','Snoop buffer full');this.addL2Cycles('mali_hwc_L2_REPLAY_FULL','Replay buffer full');importer.registerEventHandler('tracing_mark_write:mali_driver',MaliParser.prototype.maliDDKEvent.bind(this));this.model_=importer.model_;}
-MaliParser.prototype={__proto__:Parser.prototype,maliDDKOpenSlice:function(pid,tid,ts,func,blockinfo){var thread=this.importer.model_.getOrCreateProcess(pid).getOrCreateThread(tid);var funcArgs=/^([\w\d_]*)(?:\(\))?:?\s*(.*)$/.exec(func);thread.sliceGroup.beginSlice('gpu-driver',funcArgs[1],ts,{'args':funcArgs[2],'blockinfo':blockinfo});},maliDDKCloseSlice:function(pid,tid,ts,args,blockinfo){var thread=this.importer.model_.getOrCreateProcess(pid).getOrCreateThread(tid);if(!thread.sliceGroup.openSliceCount){return;}
-thread.sliceGroup.endSlice(ts);},autoDetectLineRE:function(line){var lineREWithThread=/^\s*\(([\w\-]*)\)\s*(\w+):\s*([\w\\\/\.\-]*@\d*):?\s*(.*)$/;if(lineREWithThread.test(line))
-return lineREWithThread;var lineRENoThread=/^s*()(\w+):\s*([\w\\\/.\-]*):?\s*(.*)$/;if(lineRENoThread.test(line))
-return lineRENoThread;return null;},lineRE:null,maliDDKEvent:function(eventName,cpuNumber,pid,ts,eventBase){if(this.lineRE==null){this.lineRE=this.autoDetectLineRE(eventBase.details);if(this.lineRE==null)
-return false;}
-var maliEvent=this.lineRE.exec(eventBase.details);var tid=(maliEvent[1]===''?'mali':maliEvent[1]);switch(maliEvent[2]){case'cros_trace_print_enter':this.maliDDKOpenSlice(pid,tid,ts,maliEvent[4],maliEvent[3]);break;case'cros_trace_print_exit':this.maliDDKCloseSlice(pid,tid,ts,[],maliEvent[3]);}
-return true;},dvfsSample:function(counterName,seriesName,ts,s){var value=parseInt(s);var counter=this.model_.kernel.getOrCreateCounter('DVFS',counterName);if(counter.numSeries===0){counter.addSeries(new tr.model.CounterSeries(seriesName,ColorScheme.getColorIdForGeneralPurposeString(counter.name)));}
-counter.series.forEach(function(series){series.addCounterSample(ts,value);});},dvfsEventEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/utilization=(\d+)/.exec(eventBase.details);if(!event)
-return false;this.dvfsSample('DVFS Utilization','utilization',ts,event[1]);return true;},dvfsSetClockEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/frequency=(\d+)/.exec(eventBase.details);if(!event)
-return false;this.dvfsSample('DVFS Frequency','frequency',ts,event[1]);return true;},dvfsSetVoltageEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/voltage=(\d+)/.exec(eventBase.details);if(!event)
-return false;this.dvfsSample('DVFS Voltage','voltage',ts,event[1]);return true;},hwcSample:function(cat,counterName,seriesName,ts,eventBase){var event=/val=(\d+)/.exec(eventBase.details);if(!event)
-return false;var value=parseInt(event[1]);var counter=this.model_.kernel.getOrCreateCounter(cat,counterName);if(counter.numSeries===0){counter.addSeries(new tr.model.CounterSeries(seriesName,ColorScheme.getColorIdForGeneralPurposeString(counter.name)));}
-counter.series.forEach(function(series){series.addCounterSample(ts,value);});return true;},jmSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:jm','JM: '+ctrName,seriesName,ts,eventBase);},addJMCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.jmSample(hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addJMCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.jmSample(hwcTitle,'cycles',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},tilerSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:tiler','Tiler: '+ctrName,seriesName,ts,eventBase);},addTilerCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.tilerSample(hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addTilerCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.tilerSample(hwcTitle,'cycles',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},fragSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:fragment','Fragment: '+ctrName,seriesName,ts,eventBase);},addFragCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.fragSample(hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addFragCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.fragSample(hwcTitle,'cycles',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},computeSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:compute','Compute: '+ctrName,seriesName,ts,eventBase);},addComputeCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.computeSample(hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addComputeCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.computeSample(hwcTitle,'cycles',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addTripipeCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:shader','Tripipe: '+hwcTitle,'cycles',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},arithSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:arith','Arith: '+ctrName,seriesName,ts,eventBase);},addArithCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.arithSample(hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addArithCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.arithSample(hwcTitle,'cycles',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addLSCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:ls','LS: '+hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},textureSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:texture','Texture: '+ctrName,seriesName,ts,eventBase);},addTexCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.textureSample(hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addLSCCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:lsc','LSC: '+hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addAXICounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:axi','AXI: '+hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},mmuSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:mmu','MMU: '+ctrName,seriesName,ts,eventBase);},addMMUCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.mmuSample(hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addMMUCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.mmuSample(hwcTitle,'cycles',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},l2Sample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:l2','L2: '+ctrName,seriesName,ts,eventBase);},addL2Counter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.l2Sample(hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addL2Cycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.l2Sample(hwcTitle,'cycles',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));}};Parser.register(MaliParser);return{MaliParser:MaliParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var Parser=tr.e.importer.linux_perf.Parser;function MemReclaimParser(importer){Parser.call(this,importer);importer.registerEventHandler('mm_vmscan_kswapd_wake',MemReclaimParser.prototype.kswapdWake.bind(this));importer.registerEventHandler('mm_vmscan_kswapd_sleep',MemReclaimParser.prototype.kswapdSleep.bind(this));importer.registerEventHandler('mm_vmscan_direct_reclaim_begin',MemReclaimParser.prototype.reclaimBegin.bind(this));importer.registerEventHandler('mm_vmscan_direct_reclaim_end',MemReclaimParser.prototype.reclaimEnd.bind(this));}
-var kswapdWakeRE=/nid=(\d+) order=(\d+)/;var kswapdSleepRE=/nid=(\d+)/;var reclaimBeginRE=/order=(\d+) may_writepage=\d+ gfp_flags=(.+)/;var reclaimEndRE=/nr_reclaimed=(\d+)/;MemReclaimParser.prototype={__proto__:Parser.prototype,kswapdWake:function(eventName,cpuNumber,pid,ts,eventBase){var event=kswapdWakeRE.exec(eventBase.details);if(!event)
-return false;var tgid=parseInt(eventBase.tgid);var nid=parseInt(event[1]);var order=parseInt(event[2]);var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);if(kthread.openSliceTS){if(order>kthread.order){kthread.order=order;}}else{kthread.openSliceTS=ts;kthread.order=order;}
-return true;},kswapdSleep:function(eventName,cpuNumber,pid,ts,eventBase){var tgid=parseInt(eventBase.tgid);var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);if(kthread.openSliceTS){kthread.thread.sliceGroup.pushCompleteSlice('memreclaim',eventBase.threadName,kthread.openSliceTS,ts-kthread.openSliceTS,0,0,{order:kthread.order});}
-kthread.openSliceTS=undefined;kthread.order=undefined;return true;},reclaimBegin:function(eventName,cpuNumber,pid,ts,eventBase){var event=reclaimBeginRE.exec(eventBase.details);if(!event)
-return false;var order=parseInt(event[1]);var gfp=event[2];var tgid=parseInt(eventBase.tgid);var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);kthread.openSliceTS=ts;kthread.order=order;kthread.gfp=gfp;return true;},reclaimEnd:function(eventName,cpuNumber,pid,ts,eventBase){var event=reclaimEndRE.exec(eventBase.details);if(!event)
-return false;var nr_reclaimed=parseInt(event[1]);var tgid=parseInt(eventBase.tgid);var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);if(kthread.openSliceTS!==undefined){kthread.thread.sliceGroup.pushCompleteSlice('memreclaim','direct reclaim',kthread.openSliceTS,ts-kthread.openSliceTS,0,0,{order:kthread.order,gfp:kthread.gfp,nr_reclaimed:nr_reclaimed});}
-kthread.openSliceTS=undefined;kthread.order=undefined;kthread.gfp=undefined;return true;}};Parser.register(MemReclaimParser);return{MemReclaimParser:MemReclaimParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function PowerParser(importer){Parser.call(this,importer);importer.registerEventHandler('power_start',PowerParser.prototype.powerStartEvent.bind(this));importer.registerEventHandler('power_frequency',PowerParser.prototype.powerFrequencyEvent.bind(this));importer.registerEventHandler('cpu_frequency',PowerParser.prototype.cpuFrequencyEvent.bind(this));importer.registerEventHandler('cpu_frequency_limits',PowerParser.prototype.cpuFrequencyLimitsEvent.bind(this));importer.registerEventHandler('cpu_idle',PowerParser.prototype.cpuIdleEvent.bind(this));}
-PowerParser.prototype={__proto__:Parser.prototype,cpuStateSlice:function(ts,targetCpuNumber,eventType,cpuState){var targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);var powerCounter;if(eventType!='1'){this.importer.model.importWarning({type:'parse_error',message:'Don\'t understand power_start events of '+'type '+eventType});return;}
-powerCounter=targetCpu.getOrCreateCounter('','C-State');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('state',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'state')));}
-powerCounter.series.forEach(function(series){series.addCounterSample(ts,cpuState);});},cpuIdleSlice:function(ts,targetCpuNumber,cpuState){var targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);var powerCounter=targetCpu.getOrCreateCounter('','C-State');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('state',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name)));}
-var val=(cpuState!=4294967295?cpuState+1:0);powerCounter.series.forEach(function(series){series.addCounterSample(ts,val);});},cpuFrequencySlice:function(ts,targetCpuNumber,powerState){var targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);var powerCounter=targetCpu.getOrCreateCounter('','Clock Frequency');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('state',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'state')));}
-powerCounter.series.forEach(function(series){series.addCounterSample(ts,powerState);});},cpuFrequencyLimitsSlice:function(ts,targetCpuNumber,minFreq,maxFreq){var targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);var powerCounter=targetCpu.getOrCreateCounter('','Clock Frequency Limits');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('Min Frequency',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'Min Frequency')));powerCounter.addSeries(new tr.model.CounterSeries('Max Frequency',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'Max Frequency')));}
-powerCounter.series.forEach(function(series){if(series.name=='Min Frequency')
-series.addCounterSample(ts,minFreq);if(series.name=='Max Frequency')
-series.addCounterSample(ts,maxFreq);});},powerStartEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/type=(\d+) state=(\d) cpu_id=(\d+)/.exec(eventBase.details);if(!event)
-return false;var targetCpuNumber=parseInt(event[3]);var cpuState=parseInt(event[2]);this.cpuStateSlice(ts,targetCpuNumber,event[1],cpuState);return true;},powerFrequencyEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/type=(\d+) state=(\d+) cpu_id=(\d+)/.exec(eventBase.details);if(!event)
-return false;var targetCpuNumber=parseInt(event[3]);var powerState=parseInt(event[2]);this.cpuFrequencySlice(ts,targetCpuNumber,powerState);return true;},cpuFrequencyEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/state=(\d+) cpu_id=(\d+)/.exec(eventBase.details);if(!event)
-return false;var targetCpuNumber=parseInt(event[2]);var powerState=parseInt(event[1]);this.cpuFrequencySlice(ts,targetCpuNumber,powerState);return true;},cpuFrequencyLimitsEvent:function(eventName,cpu,pid,ts,eventBase){var event=/min=(\d+) max=(\d+) cpu_id=(\d+)/.exec(eventBase.details);if(!event)
-return false;var targetCpuNumber=parseInt(event[3]);var minFreq=parseInt(event[1]);var maxFreq=parseInt(event[2]);this.cpuFrequencyLimitsSlice(ts,targetCpuNumber,minFreq,maxFreq);return true;},cpuIdleEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/state=(\d+) cpu_id=(\d+)/.exec(eventBase.details);if(!event)
-return false;var targetCpuNumber=parseInt(event[2]);var cpuState=parseInt(event[1]);this.cpuIdleSlice(ts,targetCpuNumber,cpuState);return true;}};Parser.register(PowerParser);return{PowerParser:PowerParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function RegulatorParser(importer){Parser.call(this,importer);importer.registerEventHandler('regulator_enable',RegulatorParser.prototype.regulatorEnableEvent.bind(this));importer.registerEventHandler('regulator_enable_delay',RegulatorParser.prototype.regulatorEnableDelayEvent.bind(this));importer.registerEventHandler('regulator_enable_complete',RegulatorParser.prototype.regulatorEnableCompleteEvent.bind(this));importer.registerEventHandler('regulator_disable',RegulatorParser.prototype.regulatorDisableEvent.bind(this));importer.registerEventHandler('regulator_disable_complete',RegulatorParser.prototype.regulatorDisableCompleteEvent.bind(this));importer.registerEventHandler('regulator_set_voltage',RegulatorParser.prototype.regulatorSetVoltageEvent.bind(this));importer.registerEventHandler('regulator_set_voltage_complete',RegulatorParser.prototype.regulatorSetVoltageCompleteEvent.bind(this));this.model_=importer.model_;}
-var regulatorEnableRE=/name=(.+)/;var regulatorDisableRE=/name=(.+)/;var regulatorSetVoltageCompleteRE=/name=(\S+), val=(\d+)/;RegulatorParser.prototype={__proto__:Parser.prototype,getCtr_:function(ctrName,valueName){var ctr=this.model_.kernel.getOrCreateCounter(null,'vreg '+ctrName+' '+valueName);if(ctr.series[0]===undefined){ctr.addSeries(new tr.model.CounterSeries(valueName,ColorScheme.getColorIdForGeneralPurposeString(ctrName+'.'+valueName)));}
-return ctr;},regulatorEnableEvent:function(eventName,cpuNum,pid,ts,eventBase){var event=regulatorEnableRE.exec(eventBase.details);if(!event)
-return false;var name=event[1];var ctr=this.getCtr_(name,'enabled');ctr.series[0].addCounterSample(ts,1);return true;},regulatorEnableDelayEvent:function(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorEnableCompleteEvent:function(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorDisableEvent:function(eventName,cpuNum,pid,ts,eventBase){var event=regulatorDisableRE.exec(eventBase.details);if(!event)
-return false;var name=event[1];var ctr=this.getCtr_(name,'enabled');ctr.series[0].addCounterSample(ts,0);return true;},regulatorDisableCompleteEvent:function(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorSetVoltageEvent:function(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorSetVoltageCompleteEvent:function(eventName,cpuNum,pid,ts,eventBase){var event=regulatorSetVoltageCompleteRE.exec(eventBase.details);if(!event)
-return false;var name=event[1];var voltage=parseInt(event[2]);var ctr=this.getCtr_(name,'voltage');ctr.series[0].addCounterSample(ts,voltage);return true;}};Parser.register(RegulatorParser);return{RegulatorParser:RegulatorParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var Parser=tr.e.importer.linux_perf.Parser;function SchedParser(importer){Parser.call(this,importer);importer.registerEventHandler('sched_switch',SchedParser.prototype.schedSwitchEvent.bind(this));importer.registerEventHandler('sched_wakeup',SchedParser.prototype.schedWakeupEvent.bind(this));importer.registerEventHandler('sched_blocked_reason',SchedParser.prototype.schedBlockedEvent.bind(this));importer.registerEventHandler('sched_cpu_hotplug',SchedParser.prototype.schedCpuHotplugEvent.bind(this));}
-var TestExports={};var schedSwitchRE=new RegExp('prev_comm=(.+) prev_pid=(\\d+) prev_prio=(\\d+) '+'prev_state=(\\S\\+?|\\S\\|\\S) ==> '+'next_comm=(.+) next_pid=(\\d+) next_prio=(\\d+)');var schedBlockedRE=new RegExp('pid=(\\d+) iowait=(\\d) caller=(.+)');TestExports.schedSwitchRE=schedSwitchRE;var schedWakeupRE=/comm=(.+) pid=(\d+) prio=(\d+) success=(\d+) target_cpu=(\d+)/;TestExports.schedWakeupRE=schedWakeupRE;SchedParser.prototype={__proto__:Parser.prototype,schedSwitchEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=schedSwitchRE.exec(eventBase.details);if(!event)
-return false;var prevState=event[4];var nextComm=event[5];var nextPid=parseInt(event[6]);var nextPrio=parseInt(event[7]);var nextThread=this.importer.threadsByLinuxPid[nextPid];var nextName;if(nextThread)
-nextName=nextThread.userFriendlyName;else
-nextName=nextComm;var cpu=this.importer.getOrCreateCpu(cpuNumber);cpu.switchActiveThread(ts,{stateWhenDescheduled:prevState},nextPid,nextName,{comm:nextComm,tid:nextPid,prio:nextPrio});return true;},schedWakeupEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=schedWakeupRE.exec(eventBase.details);if(!event)
-return false;var fromPid=pid;var comm=event[1];var pid=parseInt(event[2]);var prio=parseInt(event[3]);this.importer.markPidRunnable(ts,pid,comm,prio,fromPid);return true;},schedCpuHotplugEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/cpu (\d+) (.+) error=(\d+)/.exec(eventBase.details);if(!event)
-return false;var cpuNumber=event[1];var state=event[2];var targetCpu=this.importer.getOrCreateCpu(cpuNumber);var powerCounter=targetCpu.getOrCreateCounter('','Cpu Hotplug');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('State',tr.b.ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'State')));}
-powerCounter.series.forEach(function(series){if(series.name=='State')
-series.addCounterSample(ts,state.localeCompare('offline')?0:1);});return true;},schedBlockedEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=schedBlockedRE.exec(eventBase.details);if(!event)
-return false;var pid=parseInt(event[1]);var iowait=parseInt(event[2]);var caller=event[3];this.importer.addPidBlockedReason(ts,pid,iowait,caller);return true;}};Parser.register(SchedParser);return{SchedParser:SchedParser,_SchedParserTestExports:TestExports};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function SyncParser(importer){Parser.call(this,importer);importer.registerEventHandler('sync_timeline',SyncParser.prototype.timelineEvent.bind(this));importer.registerEventHandler('sync_wait',SyncParser.prototype.syncWaitEvent.bind(this));importer.registerEventHandler('sync_pt',SyncParser.prototype.syncPtEvent.bind(this));this.model_=importer.model_;}
-var syncTimelineRE=/name=(\S+) value=(\S*)/;var syncWaitRE=/(\S+) name=(\S+) state=(\d+)/;var syncPtRE=/name=(\S+) value=(\S*)/;SyncParser.prototype={__proto__:Parser.prototype,timelineEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=syncTimelineRE.exec(eventBase.details);if(!event)
-return false;var thread=this.importer.getOrCreatePseudoThread(event[1]);if(thread.lastActiveTs!==undefined){var duration=ts-thread.lastActiveTs;var value=thread.lastActiveValue;if(value==undefined)
-value=' ';var slice=new tr.model.Slice('',value,ColorScheme.getColorIdForGeneralPurposeString(value),thread.lastActiveTs,{},duration);thread.thread.sliceGroup.pushSlice(slice);}
-thread.lastActiveTs=ts;thread.lastActiveValue=event[2];return true;},syncWaitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=syncWaitRE.exec(eventBase.details);if(!event)
-return false;if(eventBase.tgid===undefined){return false;}
-var tgid=parseInt(eventBase.tgid);var thread=this.model_.getOrCreateProcess(tgid).getOrCreateThread(pid);thread.name=eventBase.threadName;var slices=thread.kernelSliceGroup;if(!slices.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
-var name='fence_wait("'+event[2]+'")';if(event[1]=='begin'){var slice=slices.beginSlice(null,name,ts,{'Start state':event[3]});}else if(event[1]=='end'){if(slices.openSliceCount>0){slices.endSlice(ts);}}else{return false;}
-return true;},syncPtEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=syncPtRE.exec(eventBase.details);if(!event)
-return false;return true;var thread=this.importer.getOrCreateKernelThread(eventBase[1]).thread;thread.syncWaitSyncPts[event[1]]=event[2];return true;}};Parser.register(SyncParser);return{SyncParser:SyncParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function WorkqueueParser(importer){Parser.call(this,importer);importer.registerEventHandler('workqueue_execute_start',WorkqueueParser.prototype.executeStartEvent.bind(this));importer.registerEventHandler('workqueue_execute_end',WorkqueueParser.prototype.executeEndEvent.bind(this));importer.registerEventHandler('workqueue_queue_work',WorkqueueParser.prototype.executeQueueWork.bind(this));importer.registerEventHandler('workqueue_activate_work',WorkqueueParser.prototype.executeActivateWork.bind(this));}
-var workqueueExecuteStartRE=/work struct (.+): function (\S+)/;var workqueueExecuteEndRE=/work struct (.+)/;WorkqueueParser.prototype={__proto__:Parser.prototype,executeStartEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=workqueueExecuteStartRE.exec(eventBase.details);if(!event)
-return false;var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,pid,pid);kthread.openSliceTS=ts;kthread.openSlice=event[2];return true;},executeEndEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=workqueueExecuteEndRE.exec(eventBase.details);if(!event)
-return false;var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,pid,pid);if(kthread.openSlice){var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),kthread.openSliceTS,{},ts-kthread.openSliceTS);kthread.thread.sliceGroup.pushSlice(slice);}
-kthread.openSlice=undefined;return true;},executeQueueWork:function(eventName,cpuNumber,pid,ts,eventBase){return true;},executeActivateWork:function(eventName,cpuNumber,pid,ts,eventBase){return true;}};Parser.register(WorkqueueParser);return{WorkqueueParser:WorkqueueParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var InstantClockSyncRecord=tr.model.InstantClockSyncRecord;function FTraceImporter(model,events){this.importPriority=2;this.model_=model;this.events_=events;this.newlyAddedClockSyncRecords_=[];this.wakeups_=[];this.blocked_reasons_=[];this.kernelThreadStates_={};this.buildMapFromLinuxPidsToThreads_();this.lines_=[];this.pseudoThreadCounter=1;this.parsers_=[];this.eventHandlers_={};}
-var TestExports={};var lineREWithTGID=new RegExp('^\\s*(.+)-(\\d+)\\s+\\(\\s*(\\d+|-+)\\)\\s\\[(\\d+)\\]'+'\\s+[dX.][Nnp.][Hhs.][0-9a-f.]'+'\\s+(\\d+\\.\\d+):\\s+(\\S+):\\s(.*)$');var lineParserWithTGID=function(line){var groups=lineREWithTGID.exec(line);if(!groups){return groups;}
-var tgid=groups[3];if(tgid[0]==='-')
-tgid=undefined;return{threadName:groups[1],pid:groups[2],tgid:tgid,cpuNumber:groups[4],timestamp:groups[5],eventName:groups[6],details:groups[7]};};TestExports.lineParserWithTGID=lineParserWithTGID;var lineREWithIRQInfo=new RegExp('^\\s*(.+)-(\\d+)\\s+\\[(\\d+)\\]'+'\\s+[dX.][Nnp.][Hhs.][0-9a-f.]'+'\\s+(\\d+\\.\\d+):\\s+(\\S+):\\s(.*)$');var lineParserWithIRQInfo=function(line){var groups=lineREWithIRQInfo.exec(line);if(!groups){return groups;}
-return{threadName:groups[1],pid:groups[2],cpuNumber:groups[3],timestamp:groups[4],eventName:groups[5],details:groups[6]};};TestExports.lineParserWithIRQInfo=lineParserWithIRQInfo;var lineREWithLegacyFmt=/^\s*(.+)-(\d+)\s+\[(\d+)\]\s*(\d+\.\d+):\s+(\S+):\s(.*)$/;var lineParserWithLegacyFmt=function(line){var groups=lineREWithLegacyFmt.exec(line);if(!groups){return groups;}
-return{threadName:groups[1],pid:groups[2],cpuNumber:groups[3],timestamp:groups[4],eventName:groups[5],details:groups[6]};};TestExports.lineParserWithLegacyFmt=lineParserWithLegacyFmt;var traceEventClockSyncRE=/trace_event_clock_sync: parent_ts=(\d+\.?\d*)/;TestExports.traceEventClockSyncRE=traceEventClockSyncRE;var realTimeClockSyncRE=/trace_event_clock_sync: realtime_ts=(\d+)/;var genericClockSyncRE=/trace_event_clock_sync: name=(\w+)/;var pseudoKernelPID=0;function autoDetectLineParser(line){if(line[0]=='{')
-return false;if(lineREWithTGID.test(line))
-return lineParserWithTGID;if(lineREWithIRQInfo.test(line))
-return lineParserWithIRQInfo;if(lineREWithLegacyFmt.test(line))
-return lineParserWithLegacyFmt;return undefined;};TestExports.autoDetectLineParser=autoDetectLineParser;FTraceImporter.canImport=function(events){if(!(typeof(events)==='string'||events instanceof String))
-return false;if(FTraceImporter._extractEventsFromSystraceHTML(events,false).ok)
-return true;if(FTraceImporter._extractEventsFromSystraceMultiHTML(events,false).ok)
-return true;if(/^# tracer:/.test(events))
-return true;var lineBreakIndex=events.indexOf('\n');if(lineBreakIndex>-1)
-events=events.substring(0,lineBreakIndex);if(autoDetectLineParser(events))
-return true;return false;};FTraceImporter._extractEventsFromSystraceHTML=function(incoming_events,produce_result){var failure={ok:false};if(produce_result===undefined)
-produce_result=true;if(/^<!DOCTYPE html>/.test(incoming_events)==false)
-return failure;var r=new tr.importer.SimpleLineReader(incoming_events);if(!r.advanceToLineMatching(/^  <script>$/))
-return failure;if(!r.advanceToLineMatching(/^  var linuxPerfData = "\\$/))
-return failure;var events_begin_at_line=r.curLineNumber+1;r.beginSavingLines();if(!r.advanceToLineMatching(/^  <\/script>$/))
-return failure;var raw_events=r.endSavingLinesAndGetResult();raw_events=raw_events.slice(1,raw_events.length-1);if(!r.advanceToLineMatching(/^<\/body>$/))
-return failure;if(!r.advanceToLineMatching(/^<\/html>$/))
-return failure;function endsWith(str,suffix){return str.indexOf(suffix,str.length-suffix.length)!==-1;}
-function stripSuffix(str,suffix){if(!endsWith(str,suffix))
-return str;return str.substring(str,str.length-suffix.length);}
-var events=[];if(produce_result){for(var i=0;i<raw_events.length;i++){var event=raw_events[i];event=stripSuffix(event,'\\n\\');events.push(event);}}else{events=[raw_events[raw_events.length-1]];}
-var oldLastEvent=events[events.length-1];var newLastEvent=stripSuffix(oldLastEvent,'\\n";');if(newLastEvent==oldLastEvent)
-return failure;events[events.length-1]=newLastEvent;return{ok:true,lines:produce_result?events:undefined,events_begin_at_line:events_begin_at_line};};FTraceImporter._extractEventsFromSystraceMultiHTML=function(incoming_events,produce_result){var failure={ok:false};if(produce_result===undefined)
-produce_result=true;if(new RegExp('^<!DOCTYPE HTML>','i').test(incoming_events)==false)
-return failure;var r=new tr.importer.SimpleLineReader(incoming_events);var events=[];while(!/^# tracer:/.test(events)){if(!r.advanceToLineMatching(/^  <script class="trace-data" type="application\/text">$/))
-return failure;var events_begin_at_line=r.curLineNumber+1;r.beginSavingLines();if(!r.advanceToLineMatching(/^  <\/script>$/))
-return failure;events=r.endSavingLinesAndGetResult();events=events.slice(1,events.length-1);}
-if(!r.advanceToLineMatching(/^<\/body>$/))
-return failure;if(!r.advanceToLineMatching(/^<\/html>$/))
-return failure;return{ok:true,lines:produce_result?events:undefined,events_begin_at_line:events_begin_at_line};};FTraceImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'FTraceImporter';},get model(){return this.model_;},importEvents:function(){this.parsers_=this.createParsers_();this.registerDefaultHandlers_();this.parseLines_();this.importClockSyncRecords_();var modelTimeTransformer=this.getModelTimeTransformer_();if(modelTimeTransformer===undefined){this.model_.importWarning({type:'clock_sync',message:'Cannot import kernel trace without a clock sync.'});return;}
-this.shiftNewlyAddedClockSyncRecords_(modelTimeTransformer);this.importCpuData_(modelTimeTransformer);this.buildMapFromLinuxPidsToThreads_();this.buildPerThreadCpuSlicesFromCpuState_();},registerEventHandler:function(eventName,handler){this.eventHandlers_[eventName]=handler;},getOrCreateCpu:function(cpuNumber){return this.model_.kernel.getOrCreateCpu(cpuNumber);},getOrCreateKernelThread:function(kernelThreadName,pid,tid){if(!this.kernelThreadStates_[kernelThreadName]){var thread=this.model_.getOrCreateProcess(pid).getOrCreateThread(tid);thread.name=kernelThreadName;this.kernelThreadStates_[kernelThreadName]={pid:pid,thread:thread,openSlice:undefined,openSliceTS:undefined};this.threadsByLinuxPid[pid]=thread;}
-return this.kernelThreadStates_[kernelThreadName];},getOrCreateBinderKernelThread:function(kernelThreadName,pid,tid){var key=kernelThreadName+pid+tid;if(!this.kernelThreadStates_[key]){var thread=this.model_.getOrCreateProcess(pid).getOrCreateThread(tid);thread.name=kernelThreadName;this.kernelThreadStates_[key]={pid:pid,thread:thread,openSlice:undefined,openSliceTS:undefined};this.threadsByLinuxPid[pid]=thread;}
-return this.kernelThreadStates_[key];},getOrCreatePseudoThread:function(threadName){var thread=this.kernelThreadStates_[threadName];if(!thread){thread=this.getOrCreateKernelThread(threadName,pseudoKernelPID,this.pseudoThreadCounter);this.pseudoThreadCounter++;}
-return thread;},markPidRunnable:function(ts,pid,comm,prio,fromPid){this.wakeups_.push({ts:ts,tid:pid,fromTid:fromPid});},addPidBlockedReason:function(ts,pid,iowait,caller){this.blocked_reasons_.push({ts:ts,tid:pid,iowait:iowait,caller:caller});},buildMapFromLinuxPidsToThreads_:function(){this.threadsByLinuxPid={};this.model_.getAllThreads().forEach(function(thread){this.threadsByLinuxPid[thread.tid]=thread;}.bind(this));},buildPerThreadCpuSlicesFromCpuState_:function(){var SCHEDULING_STATE=tr.model.SCHEDULING_STATE;for(var cpuNumber in this.model_.kernel.cpus){var cpu=this.model_.kernel.cpus[cpuNumber];for(var i=0;i<cpu.slices.length;i++){var cpuSlice=cpu.slices[i];var thread=this.threadsByLinuxPid[cpuSlice.args.tid];if(!thread)
-continue;cpuSlice.threadThatWasRunning=thread;if(!thread.tempCpuSlices)
-thread.tempCpuSlices=[];thread.tempCpuSlices.push(cpuSlice);}}
-for(var i in this.wakeups_){var wakeup=this.wakeups_[i];var thread=this.threadsByLinuxPid[wakeup.tid];if(!thread)
-continue;thread.tempWakeups=thread.tempWakeups||[];thread.tempWakeups.push(wakeup);}
-for(var i in this.blocked_reasons_){var reason=this.blocked_reasons_[i];var thread=this.threadsByLinuxPid[reason.tid];if(!thread)
-continue;thread.tempBlockedReasons=thread.tempBlockedReasons||[];thread.tempBlockedReasons.push(reason);}
-this.model_.getAllThreads().forEach(function(thread){if(thread.tempCpuSlices===undefined)
-return;var origSlices=thread.tempCpuSlices;delete thread.tempCpuSlices;origSlices.sort(function(x,y){return x.start-y.start;});var wakeups=thread.tempWakeups||[];delete thread.tempWakeups;wakeups.sort(function(x,y){return x.ts-y.ts;});var reasons=thread.tempBlockedReasons||[];delete thread.tempBlockedReasons;reasons.sort(function(x,y){return x.ts-y.ts;});var slices=[];if(origSlices.length){var slice=origSlices[0];if(wakeups.length&&wakeups[0].ts<slice.start){var wakeup=wakeups.shift();var wakeupDuration=slice.start-wakeup.ts;var args={'wakeup from tid':wakeup.fromTid};slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNABLE,'',wakeup.ts,args,wakeupDuration));}
-var runningSlice=new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNING,'',slice.start,{},slice.duration);runningSlice.cpuOnWhichThreadWasRunning=slice.cpu;slices.push(runningSlice);}
-var wakeup=undefined;for(var i=1;i<origSlices.length;i++){var prevSlice=origSlices[i-1];var nextSlice=origSlices[i];var midDuration=nextSlice.start-prevSlice.end;while(wakeups.length&&wakeups[0].ts<nextSlice.start){var w=wakeups.shift();if(wakeup===undefined&&w.ts>prevSlice.end){wakeup=w;}}
-var blocked_reason=undefined;while(reasons.length&&reasons[0].ts<prevSlice.end){var r=reasons.shift();}
-if(wakeup!==undefined&&reasons.length&&reasons[0].ts<wakeup.ts){blocked_reason=reasons.shift();}
-var pushSleep=function(state){if(wakeup!==undefined){midDuration=wakeup.ts-prevSlice.end;}
-if(blocked_reason!==undefined){var args={'kernel callsite when blocked:':blocked_reason.caller};if(blocked_reason.iowait){switch(state){case SCHEDULING_STATE.UNINTR_SLEEP:state=SCHEDULING_STATE.UNINTR_SLEEP_IO;break;case SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL:state=SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL_IO;break;case SCHEDULING_STATE.UNINTR_SLEEP_WAKING:state=SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL_IO;break;default:}}
+return true;}};LinuxPerfParser.register(KernelFuncParser);return{KernelFuncParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function MaliParser(importer){Parser.call(this,importer);importer.registerEventHandler('mali_dvfs_event',MaliParser.prototype.dvfsEventEvent.bind(this));importer.registerEventHandler('mali_dvfs_set_clock',MaliParser.prototype.dvfsSetClockEvent.bind(this));importer.registerEventHandler('mali_dvfs_set_voltage',MaliParser.prototype.dvfsSetVoltageEvent.bind(this));this.addJMCounter('mali_hwc_MESSAGES_SENT','Messages Sent');this.addJMCounter('mali_hwc_MESSAGES_RECEIVED','Messages Received');this.addJMCycles('mali_hwc_GPU_ACTIVE','GPU Active');this.addJMCycles('mali_hwc_IRQ_ACTIVE','IRQ Active');for(let i=0;i<7;i++){const jobStr='JS'+i;const jobHWCStr='mali_hwc_'+jobStr;this.addJMCounter(jobHWCStr+'_JOBS',jobStr+' Jobs');this.addJMCounter(jobHWCStr+'_TASKS',jobStr+' Tasks');this.addJMCycles(jobHWCStr+'_ACTIVE',jobStr+' Active');this.addJMCycles(jobHWCStr+'_WAIT_READ',jobStr+' Wait Read');this.addJMCycles(jobHWCStr+'_WAIT_ISSUE',jobStr+' Wait Issue');this.addJMCycles(jobHWCStr+'_WAIT_DEPEND',jobStr+' Wait Depend');this.addJMCycles(jobHWCStr+'_WAIT_FINISH',jobStr+' Wait Finish');}
+this.addTilerCounter('mali_hwc_TRIANGLES','Triangles');this.addTilerCounter('mali_hwc_QUADS','Quads');this.addTilerCounter('mali_hwc_POLYGONS','Polygons');this.addTilerCounter('mali_hwc_POINTS','Points');this.addTilerCounter('mali_hwc_LINES','Lines');this.addTilerCounter('mali_hwc_VCACHE_HIT','VCache Hit');this.addTilerCounter('mali_hwc_VCACHE_MISS','VCache Miss');this.addTilerCounter('mali_hwc_FRONT_FACING','Front Facing');this.addTilerCounter('mali_hwc_BACK_FACING','Back Facing');this.addTilerCounter('mali_hwc_PRIM_VISIBLE','Prim Visible');this.addTilerCounter('mali_hwc_PRIM_CULLED','Prim Culled');this.addTilerCounter('mali_hwc_PRIM_CLIPPED','Prim Clipped');this.addTilerCounter('mali_hwc_WRBUF_HIT','Wrbuf Hit');this.addTilerCounter('mali_hwc_WRBUF_MISS','Wrbuf Miss');this.addTilerCounter('mali_hwc_WRBUF_LINE','Wrbuf Line');this.addTilerCounter('mali_hwc_WRBUF_PARTIAL','Wrbuf Partial');this.addTilerCounter('mali_hwc_WRBUF_STALL','Wrbuf Stall');this.addTilerCycles('mali_hwc_ACTIVE','Tiler Active');this.addTilerCycles('mali_hwc_INDEX_WAIT','Index Wait');this.addTilerCycles('mali_hwc_INDEX_RANGE_WAIT','Index Range Wait');this.addTilerCycles('mali_hwc_VERTEX_WAIT','Vertex Wait');this.addTilerCycles('mali_hwc_PCACHE_WAIT','Pcache Wait');this.addTilerCycles('mali_hwc_WRBUF_WAIT','Wrbuf Wait');this.addTilerCycles('mali_hwc_BUS_READ','Bus Read');this.addTilerCycles('mali_hwc_BUS_WRITE','Bus Write');this.addTilerCycles('mali_hwc_TILER_UTLB_STALL','Tiler UTLB Stall');this.addTilerCycles('mali_hwc_TILER_UTLB_HIT','Tiler UTLB Hit');this.addFragCycles('mali_hwc_FRAG_ACTIVE','Active');this.addFragCounter('mali_hwc_FRAG_PRIMATIVES','Primitives');this.addFragCounter('mali_hwc_FRAG_PRIMATIVES_DROPPED','Primitives Dropped');this.addFragCycles('mali_hwc_FRAG_CYCLE_DESC','Descriptor Processing');this.addFragCycles('mali_hwc_FRAG_CYCLES_PLR','PLR Processing??');this.addFragCycles('mali_hwc_FRAG_CYCLES_VERT','Vertex Processing');this.addFragCycles('mali_hwc_FRAG_CYCLES_TRISETUP','Triangle Setup');this.addFragCycles('mali_hwc_FRAG_CYCLES_RAST','Rasterization???');this.addFragCounter('mali_hwc_FRAG_THREADS','Threads');this.addFragCounter('mali_hwc_FRAG_DUMMY_THREADS','Dummy Threads');this.addFragCounter('mali_hwc_FRAG_QUADS_RAST','Quads Rast');this.addFragCounter('mali_hwc_FRAG_QUADS_EZS_TEST','Quads EZS Test');this.addFragCounter('mali_hwc_FRAG_QUADS_EZS_KILLED','Quads EZS Killed');this.addFragCounter('mali_hwc_FRAG_QUADS_LZS_TEST','Quads LZS Test');this.addFragCounter('mali_hwc_FRAG_QUADS_LZS_KILLED','Quads LZS Killed');this.addFragCycles('mali_hwc_FRAG_CYCLE_NO_TILE','No Tiles');this.addFragCounter('mali_hwc_FRAG_NUM_TILES','Tiles');this.addFragCounter('mali_hwc_FRAG_TRANS_ELIM','Transactions Eliminated');this.addComputeCycles('mali_hwc_COMPUTE_ACTIVE','Active');this.addComputeCounter('mali_hwc_COMPUTE_TASKS','Tasks');this.addComputeCounter('mali_hwc_COMPUTE_THREADS','Threads Started');this.addComputeCycles('mali_hwc_COMPUTE_CYCLES_DESC','Waiting for Descriptors');this.addTripipeCycles('mali_hwc_TRIPIPE_ACTIVE','Active');this.addArithCounter('mali_hwc_ARITH_WORDS','Instructions (/Pipes)');this.addArithCycles('mali_hwc_ARITH_CYCLES_REG','Reg scheduling stalls (/Pipes)');this.addArithCycles('mali_hwc_ARITH_CYCLES_L0','L0 cache miss stalls (/Pipes)');this.addArithCounter('mali_hwc_ARITH_FRAG_DEPEND','Frag dep check failures (/Pipes)');this.addLSCounter('mali_hwc_LS_WORDS','Instruction Words Completed');this.addLSCounter('mali_hwc_LS_ISSUES','Full Pipeline Issues');this.addLSCounter('mali_hwc_LS_RESTARTS','Restarts (unpairable insts)');this.addLSCounter('mali_hwc_LS_REISSUES_MISS','Pipeline reissue (cache miss/uTLB)');this.addLSCounter('mali_hwc_LS_REISSUES_VD','Pipeline reissue (varying data)');this.addLSCounter('mali_hwc_LS_REISSUE_ATTRIB_MISS','Pipeline reissue (attribute cache miss)');this.addLSCounter('mali_hwc_LS_REISSUE_NO_WB','Writeback not used');this.addTexCounter('mali_hwc_TEX_WORDS','Words');this.addTexCounter('mali_hwc_TEX_BUBBLES','Bubbles');this.addTexCounter('mali_hwc_TEX_WORDS_L0','Words L0');this.addTexCounter('mali_hwc_TEX_WORDS_DESC','Words Desc');this.addTexCounter('mali_hwc_TEX_THREADS','Threads');this.addTexCounter('mali_hwc_TEX_RECIRC_FMISS','Recirc due to Full Miss');this.addTexCounter('mali_hwc_TEX_RECIRC_DESC','Recirc due to Desc Miss');this.addTexCounter('mali_hwc_TEX_RECIRC_MULTI','Recirc due to Multipass');this.addTexCounter('mali_hwc_TEX_RECIRC_PMISS','Recirc due to Partial Cache Miss');this.addTexCounter('mali_hwc_TEX_RECIRC_CONF','Recirc due to Cache Conflict');this.addLSCCounter('mali_hwc_LSC_READ_HITS','Read Hits');this.addLSCCounter('mali_hwc_LSC_READ_MISSES','Read Misses');this.addLSCCounter('mali_hwc_LSC_WRITE_HITS','Write Hits');this.addLSCCounter('mali_hwc_LSC_WRITE_MISSES','Write Misses');this.addLSCCounter('mali_hwc_LSC_ATOMIC_HITS','Atomic Hits');this.addLSCCounter('mali_hwc_LSC_ATOMIC_MISSES','Atomic Misses');this.addLSCCounter('mali_hwc_LSC_LINE_FETCHES','Line Fetches');this.addLSCCounter('mali_hwc_LSC_DIRTY_LINE','Dirty Lines');this.addLSCCounter('mali_hwc_LSC_SNOOPS','Snoops');this.addAXICounter('mali_hwc_AXI_TLB_STALL','Address channel stall');this.addAXICounter('mali_hwc_AXI_TLB_MISS','Cache Miss');this.addAXICounter('mali_hwc_AXI_TLB_TRANSACTION','Transactions');this.addAXICounter('mali_hwc_LS_TLB_MISS','LS Cache Miss');this.addAXICounter('mali_hwc_LS_TLB_HIT','LS Cache Hit');this.addAXICounter('mali_hwc_AXI_BEATS_READ','Read Beats');this.addAXICounter('mali_hwc_AXI_BEATS_WRITE','Write Beats');this.addMMUCounter('mali_hwc_MMU_TABLE_WALK','Page Table Walks');this.addMMUCounter('mali_hwc_MMU_REPLAY_MISS','Cache Miss from Replay Buffer');this.addMMUCounter('mali_hwc_MMU_REPLAY_FULL','Replay Buffer Full');this.addMMUCounter('mali_hwc_MMU_NEW_MISS','Cache Miss on New Request');this.addMMUCounter('mali_hwc_MMU_HIT','Cache Hit');this.addMMUCycles('mali_hwc_UTLB_STALL','UTLB Stalled');this.addMMUCycles('mali_hwc_UTLB_REPLAY_MISS','UTLB Replay Miss');this.addMMUCycles('mali_hwc_UTLB_REPLAY_FULL','UTLB Replay Full');this.addMMUCycles('mali_hwc_UTLB_NEW_MISS','UTLB New Miss');this.addMMUCycles('mali_hwc_UTLB_HIT','UTLB Hit');this.addL2Counter('mali_hwc_L2_READ_BEATS','Read Beats');this.addL2Counter('mali_hwc_L2_WRITE_BEATS','Write Beats');this.addL2Counter('mali_hwc_L2_ANY_LOOKUP','Any Lookup');this.addL2Counter('mali_hwc_L2_READ_LOOKUP','Read Lookup');this.addL2Counter('mali_hwc_L2_SREAD_LOOKUP','Shareable Read Lookup');this.addL2Counter('mali_hwc_L2_READ_REPLAY','Read Replayed');this.addL2Counter('mali_hwc_L2_READ_SNOOP','Read Snoop');this.addL2Counter('mali_hwc_L2_READ_HIT','Read Cache Hit');this.addL2Counter('mali_hwc_L2_CLEAN_MISS','CleanUnique Miss');this.addL2Counter('mali_hwc_L2_WRITE_LOOKUP','Write Lookup');this.addL2Counter('mali_hwc_L2_SWRITE_LOOKUP','Shareable Write Lookup');this.addL2Counter('mali_hwc_L2_WRITE_REPLAY','Write Replayed');this.addL2Counter('mali_hwc_L2_WRITE_SNOOP','Write Snoop');this.addL2Counter('mali_hwc_L2_WRITE_HIT','Write Cache Hit');this.addL2Counter('mali_hwc_L2_EXT_READ_FULL','ExtRD with BIU Full');this.addL2Counter('mali_hwc_L2_EXT_READ_HALF','ExtRD with BIU >1/2 Full');this.addL2Counter('mali_hwc_L2_EXT_WRITE_FULL','ExtWR with BIU Full');this.addL2Counter('mali_hwc_L2_EXT_WRITE_HALF','ExtWR with BIU >1/2 Full');this.addL2Counter('mali_hwc_L2_EXT_READ','External Read (ExtRD)');this.addL2Counter('mali_hwc_L2_EXT_READ_LINE','ExtRD (linefill)');this.addL2Counter('mali_hwc_L2_EXT_WRITE','External Write (ExtWR)');this.addL2Counter('mali_hwc_L2_EXT_WRITE_LINE','ExtWR (linefill)');this.addL2Counter('mali_hwc_L2_EXT_WRITE_SMALL','ExtWR (burst size <64B)');this.addL2Counter('mali_hwc_L2_EXT_BARRIER','External Barrier');this.addL2Counter('mali_hwc_L2_EXT_AR_STALL','Address Read stalls');this.addL2Counter('mali_hwc_L2_EXT_R_BUF_FULL','Response Buffer full stalls');this.addL2Counter('mali_hwc_L2_EXT_RD_BUF_FULL','Read Data Buffer full stalls');this.addL2Counter('mali_hwc_L2_EXT_R_RAW','RAW hazard stalls');this.addL2Counter('mali_hwc_L2_EXT_W_STALL','Write Data stalls');this.addL2Counter('mali_hwc_L2_EXT_W_BUF_FULL','Write Data Buffer full');this.addL2Counter('mali_hwc_L2_EXT_R_W_HAZARD','WAW or WAR hazard stalls');this.addL2Counter('mali_hwc_L2_TAG_HAZARD','Tag hazard replays');this.addL2Cycles('mali_hwc_L2_SNOOP_FULL','Snoop buffer full');this.addL2Cycles('mali_hwc_L2_REPLAY_FULL','Replay buffer full');importer.registerEventHandler('tracing_mark_write:mali_driver',MaliParser.prototype.maliDDKEvent.bind(this));importer.registerEventHandler('mali_job_systrace_event_start',MaliParser.prototype.maliJobEvent.bind(this));importer.registerEventHandler('mali_job_systrace_event_stop',MaliParser.prototype.maliJobEvent.bind(this));this.model_=importer.model_;this.deferredJobs_={};}
+MaliParser.prototype={__proto__:Parser.prototype,maliDDKOpenSlice(pid,tid,ts,func,blockinfo){const thread=this.importer.model_.getOrCreateProcess(pid).getOrCreateThread(tid);const funcArgs=/^([\w\d_]*)(?:\(\))?:?\s*(.*)$/.exec(func);thread.sliceGroup.beginSlice('gpu-driver',funcArgs[1],ts,{'args':funcArgs[2],blockinfo});},maliDDKCloseSlice(pid,tid,ts,args,blockinfo){const thread=this.importer.model_.getOrCreateProcess(pid).getOrCreateThread(tid);if(!thread.sliceGroup.openSliceCount){return;}
+thread.sliceGroup.endSlice(ts);},autoDetectLineRE(line){const lineREWithThread=/^\s*\(([\w\-]*)\)\s*(\w+):\s*([\w\\\/\.\-]*@\d*):?\s*(.*)$/;if(lineREWithThread.test(line)){return lineREWithThread;}
+const lineRENoThread=/^s*()(\w+):\s*([\w\\\/.\-]*):?\s*(.*)$/;if(lineRENoThread.test(line)){return lineRENoThread;}
+return null;},lineRE:null,maliDDKEvent(eventName,cpuNumber,pid,ts,eventBase){if(this.lineRE===null){this.lineRE=this.autoDetectLineRE(eventBase.details);if(this.lineRE===null)return false;}
+const maliEvent=this.lineRE.exec(eventBase.details);const tid=(maliEvent[1]===''?'mali':maliEvent[1]);switch(maliEvent[2]){case'cros_trace_print_enter':this.maliDDKOpenSlice(pid,tid,ts,maliEvent[4],maliEvent[3]);break;case'cros_trace_print_exit':this.maliDDKCloseSlice(pid,tid,ts,[],maliEvent[3]);}
+return true;},maliJobEvent(eventName,cpuNumber,pid,ts,eventBase){const jobEventRE=/^.*tracing_mark_write: (S|F)\|(\d+)\|(\w+)-job\|(\d+)\|(\d+)\|(\d+)\|(\d+)\|(\d+)\|([a-z0-9]+)\|(\d+)$/;const jobEvent=jobEventRE.exec(eventBase.details);if(!jobEvent){this.model_.importWarning({type:'parse_error',args:'unexpected mali_job_systrace_event_* event syntax'});return;}
+const jobType=jobEvent[3];const jobId=jobEvent[4];const thread=this.importer.model_.getOrCreateProcess(0).getOrCreateThread('mali:'+jobType);switch(jobEvent[1]){case'S':{const args={ctx:jobEvent[9],pid:parseInt(jobEvent[2],10),dep0:parseInt(jobEvent[5],10),dep1:parseInt(jobEvent[7],10)};if(thread.sliceGroup.openSliceCount){if(!(jobType in this.deferredJobs_)){this.deferredJobs_[jobType]=[];}
+this.deferredJobs_[jobType].push({id:jobId,args});}else{thread.sliceGroup.beginSlice(null,jobId,ts,args);}}break;case'F':{if(!thread.sliceGroup.openSliceCount){return;}
+if(thread.sliceGroup.mostRecentlyOpenedPartialSlice.title!==jobId){this.model_.importWarning({type:'invalid event nesting',message:'non-sequential jobs in same mali job slot'});}
+thread.sliceGroup.endSlice(ts);const deferredJobs=this.deferredJobs_[jobType];if(deferredJobs&&deferredJobs.length){const job=deferredJobs.shift();thread.sliceGroup.beginSlice(null,job.id,ts,job.args);}}break;}
+return true;},dvfsSample(counterName,seriesName,ts,s){const value=parseInt(s);const counter=this.model_.kernel.getOrCreateCounter('DVFS',counterName);if(counter.numSeries===0){counter.addSeries(new tr.model.CounterSeries(seriesName,ColorScheme.getColorIdForGeneralPurposeString(counter.name)));}
+counter.series.forEach(function(series){series.addCounterSample(ts,value);});},dvfsEventEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/utilization=(\d+)/.exec(eventBase.details);if(!event)return false;this.dvfsSample('DVFS Utilization','utilization',ts,event[1]);return true;},dvfsSetClockEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/frequency=(\d+)/.exec(eventBase.details);if(!event)return false;this.dvfsSample('DVFS Frequency','frequency',ts,event[1]);return true;},dvfsSetVoltageEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/voltage=(\d+)/.exec(eventBase.details);if(!event)return false;this.dvfsSample('DVFS Voltage','voltage',ts,event[1]);return true;},hwcSample(cat,counterName,seriesName,ts,eventBase){const event=/val=(\d+)/.exec(eventBase.details);if(!event)return false;const value=parseInt(event[1]);const counter=this.model_.kernel.getOrCreateCounter(cat,counterName);if(counter.numSeries===0){counter.addSeries(new tr.model.CounterSeries(seriesName,ColorScheme.getColorIdForGeneralPurposeString(counter.name)));}
+counter.series.forEach(function(series){series.addCounterSample(ts,value);});return true;},jmSample(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:jm','JM: '+ctrName,seriesName,ts,eventBase);},addJMCounter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.jmSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addJMCycles(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.jmSample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},tilerSample(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:tiler','Tiler: '+ctrName,seriesName,ts,eventBase);},addTilerCounter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.tilerSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addTilerCycles(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.tilerSample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},fragSample(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:fragment','Fragment: '+ctrName,seriesName,ts,eventBase);},addFragCounter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.fragSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addFragCycles(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.fragSample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},computeSample(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:compute','Compute: '+ctrName,seriesName,ts,eventBase);},addComputeCounter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.computeSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addComputeCycles(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.computeSample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addTripipeCycles(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:shader','Tripipe: '+hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},arithSample(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:arith','Arith: '+ctrName,seriesName,ts,eventBase);},addArithCounter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.arithSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addArithCycles(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.arithSample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addLSCounter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:ls','LS: '+hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},textureSample(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:texture','Texture: '+ctrName,seriesName,ts,eventBase);},addTexCounter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.textureSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addLSCCounter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:lsc','LSC: '+hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addAXICounter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:axi','AXI: '+hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},mmuSample(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:mmu','MMU: '+ctrName,seriesName,ts,eventBase);},addMMUCounter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.mmuSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addMMUCycles(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.mmuSample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},l2Sample(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:l2','L2: '+ctrName,seriesName,ts,eventBase);},addL2Counter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.l2Sample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addL2Cycles(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.l2Sample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));}};Parser.register(MaliParser);return{MaliParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const Parser=tr.e.importer.linux_perf.Parser;function MemReclaimParser(importer){Parser.call(this,importer);importer.registerEventHandler('mm_vmscan_kswapd_wake',MemReclaimParser.prototype.kswapdWake.bind(this));importer.registerEventHandler('mm_vmscan_kswapd_sleep',MemReclaimParser.prototype.kswapdSleep.bind(this));importer.registerEventHandler('mm_vmscan_direct_reclaim_begin',MemReclaimParser.prototype.reclaimBegin.bind(this));importer.registerEventHandler('mm_vmscan_direct_reclaim_end',MemReclaimParser.prototype.reclaimEnd.bind(this));importer.registerEventHandler('lowmemory_kill',MemReclaimParser.prototype.lowmemoryKill.bind(this));}
+const kswapdWakeRE=/nid=(\d+) order=(\d+)/;const kswapdSleepRE=/nid=(\d+)/;const reclaimBeginRE=/order=(\d+) may_writepage=\d+ gfp_flags=(.+)/;const reclaimEndRE=/nr_reclaimed=(\d+)/;const lowmemoryRE=/([^ ]+) \((\d+)\), page cache (\d+)kB \(limit (\d+)kB\), free (-?\d+)Kb/;MemReclaimParser.prototype={__proto__:Parser.prototype,kswapdWake(eventName,cpuNumber,pid,ts,eventBase){const event=kswapdWakeRE.exec(eventBase.details);if(!event)return false;const tgid=parseInt(eventBase.tgid);const nid=parseInt(event[1]);const order=parseInt(event[2]);const kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);if(kthread.openSliceTS){if(order>kthread.order){kthread.order=order;}}else{kthread.openSliceTS=ts;kthread.order=order;}
+return true;},kswapdSleep(eventName,cpuNumber,pid,ts,eventBase){const tgid=parseInt(eventBase.tgid);const kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);if(kthread.openSliceTS){kthread.thread.sliceGroup.pushCompleteSlice('memreclaim',eventBase.threadName,kthread.openSliceTS,ts-kthread.openSliceTS,0,0,{order:kthread.order});}
+kthread.openSliceTS=undefined;kthread.order=undefined;return true;},reclaimBegin(eventName,cpuNumber,pid,ts,eventBase){const event=reclaimBeginRE.exec(eventBase.details);if(!event)return false;const order=parseInt(event[1]);const gfp=event[2];const tgid=parseInt(eventBase.tgid);const kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);kthread.openSliceTS=ts;kthread.order=order;kthread.gfp=gfp;return true;},reclaimEnd(eventName,cpuNumber,pid,ts,eventBase){const event=reclaimEndRE.exec(eventBase.details);if(!event)return false;const nrReclaimed=parseInt(event[1]);const tgid=parseInt(eventBase.tgid);const kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);if(kthread.openSliceTS!==undefined){kthread.thread.sliceGroup.pushCompleteSlice('memreclaim','direct reclaim',kthread.openSliceTS,ts-kthread.openSliceTS,0,0,{order:kthread.order,gfp:kthread.gfp,nr_reclaimed:nrReclaimed});}
+kthread.openSliceTS=undefined;kthread.order=undefined;kthread.gfp=undefined;return true;},lowmemoryKill(eventName,cpuNumber,pid,ts,eventBase){const event=lowmemoryRE.exec(eventBase.details);if(!event)return false;const tgid=parseInt(eventBase.tgid);const killedName=event[1];const killedPid=parseInt(event[2]);const cache=parseInt(event[3]);const free=parseInt(event[5]);const kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);kthread.thread.sliceGroup.pushCompleteSlice('lowmemory','low memory kill',ts,0,0,0,{killed_name:killedName,killed_pid:killedPid,cache,free});return true;}};Parser.register(MemReclaimParser);return{MemReclaimParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function PowerParser(importer){Parser.call(this,importer);importer.registerEventHandler('power_start',PowerParser.prototype.powerStartEvent.bind(this));importer.registerEventHandler('power_frequency',PowerParser.prototype.powerFrequencyEvent.bind(this));importer.registerEventHandler('cpu_frequency',PowerParser.prototype.cpuFrequencyEvent.bind(this));importer.registerEventHandler('cpu_frequency_limits',PowerParser.prototype.cpuFrequencyLimitsEvent.bind(this));importer.registerEventHandler('cpu_idle',PowerParser.prototype.cpuIdleEvent.bind(this));}
+PowerParser.prototype={__proto__:Parser.prototype,cpuStateSlice(ts,targetCpuNumber,eventType,cpuState){const targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);if(eventType!=='1'){this.importer.model.importWarning({type:'parse_error',message:'Don\'t understand power_start events of '+'type '+eventType});return;}
+const powerCounter=targetCpu.getOrCreateCounter('','C-State');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('state',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'state')));}
+powerCounter.series.forEach(function(series){series.addCounterSample(ts,cpuState);});},cpuIdleSlice(ts,targetCpuNumber,cpuState){const targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);const powerCounter=targetCpu.getOrCreateCounter('','C-State');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('state',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name)));}
+const val=(cpuState!==4294967295?cpuState+1:0);powerCounter.series.forEach(function(series){series.addCounterSample(ts,val);});},cpuFrequencySlice(ts,targetCpuNumber,powerState){const targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);const powerCounter=targetCpu.getOrCreateCounter('','Clock Frequency');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('state',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'state')));}
+powerCounter.series.forEach(function(series){series.addCounterSample(ts,powerState);});},cpuFrequencyLimitsSlice(ts,targetCpuNumber,minFreq,maxFreq){const targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);const powerCounter=targetCpu.getOrCreateCounter('','Clock Frequency Limits');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('Min Frequency',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'Min Frequency')));powerCounter.addSeries(new tr.model.CounterSeries('Max Frequency',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'Max Frequency')));}
+powerCounter.series.forEach(function(series){if(series.name==='Min Frequency'){series.addCounterSample(ts,minFreq);}
+if(series.name==='Max Frequency'){series.addCounterSample(ts,maxFreq);}});},powerStartEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/type=(\d+) state=(\d) cpu_id=(\d+)/.exec(eventBase.details);if(!event)return false;const targetCpuNumber=parseInt(event[3]);const cpuState=parseInt(event[2]);this.cpuStateSlice(ts,targetCpuNumber,event[1],cpuState);return true;},powerFrequencyEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/type=(\d+) state=(\d+) cpu_id=(\d+)/.exec(eventBase.details);if(!event)return false;const targetCpuNumber=parseInt(event[3]);const powerState=parseInt(event[2]);this.cpuFrequencySlice(ts,targetCpuNumber,powerState);return true;},cpuFrequencyEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/state=(\d+) cpu_id=(\d+)/.exec(eventBase.details);if(!event)return false;const targetCpuNumber=parseInt(event[2]);const powerState=parseInt(event[1]);this.cpuFrequencySlice(ts,targetCpuNumber,powerState);return true;},cpuFrequencyLimitsEvent(eventName,cpu,pid,ts,eventBase){const event=/min=(\d+) max=(\d+) cpu_id=(\d+)/.exec(eventBase.details);if(!event)return false;const targetCpuNumber=parseInt(event[3]);const minFreq=parseInt(event[1]);const maxFreq=parseInt(event[2]);this.cpuFrequencyLimitsSlice(ts,targetCpuNumber,minFreq,maxFreq);return true;},cpuIdleEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/state=(\d+) cpu_id=(\d+)/.exec(eventBase.details);if(!event)return false;const targetCpuNumber=parseInt(event[2]);const cpuState=parseInt(event[1]);this.cpuIdleSlice(ts,targetCpuNumber,cpuState);return true;}};Parser.register(PowerParser);return{PowerParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function RegulatorParser(importer){Parser.call(this,importer);importer.registerEventHandler('regulator_enable',RegulatorParser.prototype.regulatorEnableEvent.bind(this));importer.registerEventHandler('regulator_enable_delay',RegulatorParser.prototype.regulatorEnableDelayEvent.bind(this));importer.registerEventHandler('regulator_enable_complete',RegulatorParser.prototype.regulatorEnableCompleteEvent.bind(this));importer.registerEventHandler('regulator_disable',RegulatorParser.prototype.regulatorDisableEvent.bind(this));importer.registerEventHandler('regulator_disable_complete',RegulatorParser.prototype.regulatorDisableCompleteEvent.bind(this));importer.registerEventHandler('regulator_set_voltage',RegulatorParser.prototype.regulatorSetVoltageEvent.bind(this));importer.registerEventHandler('regulator_set_voltage_complete',RegulatorParser.prototype.regulatorSetVoltageCompleteEvent.bind(this));this.model_=importer.model_;}
+const regulatorEnableRE=/name=(.+)/;const regulatorDisableRE=/name=(.+)/;const regulatorSetVoltageCompleteRE=/name=(\S+), val=(\d+)/;RegulatorParser.prototype={__proto__:Parser.prototype,getCtr_(ctrName,valueName){const ctr=this.model_.kernel.getOrCreateCounter(null,'vreg '+ctrName+' '+valueName);if(ctr.series[0]===undefined){ctr.addSeries(new tr.model.CounterSeries(valueName,ColorScheme.getColorIdForGeneralPurposeString(ctrName+'.'+valueName)));}
+return ctr;},regulatorEnableEvent(eventName,cpuNum,pid,ts,eventBase){const event=regulatorEnableRE.exec(eventBase.details);if(!event)return false;const name=event[1];const ctr=this.getCtr_(name,'enabled');ctr.series[0].addCounterSample(ts,1);return true;},regulatorEnableDelayEvent(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorEnableCompleteEvent(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorDisableEvent(eventName,cpuNum,pid,ts,eventBase){const event=regulatorDisableRE.exec(eventBase.details);if(!event)return false;const name=event[1];const ctr=this.getCtr_(name,'enabled');ctr.series[0].addCounterSample(ts,0);return true;},regulatorDisableCompleteEvent(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorSetVoltageEvent(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorSetVoltageCompleteEvent(eventName,cpuNum,pid,ts,eventBase){const event=regulatorSetVoltageCompleteRE.exec(eventBase.details);if(!event)return false;const name=event[1];const voltage=parseInt(event[2]);const ctr=this.getCtr_(name,'voltage');ctr.series[0].addCounterSample(ts,voltage);return true;}};Parser.register(RegulatorParser);return{RegulatorParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const Parser=tr.e.importer.linux_perf.Parser;function RssParser(importer){Parser.call(this,importer);importer.registerEventHandler('rss_stat',RssParser.prototype.rssStat.bind(this));}
+const TestExports={};const rssStatRE=new RegExp('member=(\\d+) size=(\\d+)');TestExports.rssStatRE=rssStatRE;const unknownThreadName='<...>';RssParser.prototype={__proto__:Parser.prototype,rssStat(eventName,cpuNumber,pid,ts,eventBase){const event=rssStatRE.exec(eventBase.details);if(!event)return false;const member=parseInt(event[1]);const size=parseInt(event[2]);if(eventBase.tgid===undefined){return false;}
+const tgid=parseInt(eventBase.tgid);const process=this.importer.model_.getOrCreateProcess(tgid);let subTitle='';if(member===0){subTitle=' (file pages)';}else if(member===1){subTitle=' (anon)';}
+const rssCounter=process.getOrCreateCounter('RSS','RSS '+member+subTitle);if(rssCounter.numSeries===0){rssCounter.addSeries(new tr.model.CounterSeries('RSS',tr.b.ColorScheme.getColorIdForGeneralPurposeString(rssCounter.name)));}
+rssCounter.series.forEach(function(series){series.addCounterSample(ts,size);});return true;},};Parser.register(RssParser);return{RssParser,_RssParserTestExports:TestExports};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const Parser=tr.e.importer.linux_perf.Parser;function SchedParser(importer){Parser.call(this,importer);importer.registerEventHandler('sched_switch',SchedParser.prototype.schedSwitchEvent.bind(this));importer.registerEventHandler('sched_wakeup',SchedParser.prototype.schedWakeupEvent.bind(this));importer.registerEventHandler('sched_blocked_reason',SchedParser.prototype.schedBlockedEvent.bind(this));importer.registerEventHandler('sched_cpu_hotplug',SchedParser.prototype.schedCpuHotplugEvent.bind(this));}
+const TestExports={};const schedSwitchRE=new RegExp('prev_comm=(.+) prev_pid=(\\d+) prev_prio=(\\d+) '+'prev_state=(\\S\\+?|\\S\\|\\S) ==> '+'next_comm=(.+) next_pid=(\\d+) next_prio=(\\d+)');const schedBlockedRE=new RegExp('pid=(\\d+) iowait=(\\d) caller=(.+)');TestExports.schedSwitchRE=schedSwitchRE;const schedWakeupRE=/comm=(.+) pid=(\d+) prio=(\d+)(?: success=\d+)? target_cpu=(\d+)/;TestExports.schedWakeupRE=schedWakeupRE;const unknownThreadName='<...>';SchedParser.prototype={__proto__:Parser.prototype,schedSwitchEvent(eventName,cpuNumber,pid,ts,eventBase){const event=schedSwitchRE.exec(eventBase.details);if(!event)return false;const prevState=event[4];const nextComm=event[5];const nextPid=parseInt(event[6]);const nextPrio=parseInt(event[7]);if(eventBase.tgid!==undefined){const tgid=parseInt(eventBase.tgid);const process=this.importer.model_.getOrCreateProcess(tgid);const storedThread=process.getThread(pid);if(!storedThread){const thread=process.getOrCreateThread(pid);thread.name=eventBase.threadName;}else if(storedThread.name===unknownThreadName){storedThread.name=eventBase.threadName;}}
+const nextThread=this.importer.threadsByLinuxPid[nextPid];let nextName;if(nextThread){nextName=nextThread.userFriendlyName;}else{nextName=nextComm;}
+const cpu=this.importer.getOrCreateCpu(cpuNumber);cpu.switchActiveThread(ts,{stateWhenDescheduled:prevState},nextPid,nextName,{comm:nextComm,tid:nextPid,prio:nextPrio});return true;},schedWakeupEvent(eventName,cpuNumber,pid,ts,eventBase){const event=schedWakeupRE.exec(eventBase.details);if(!event)return false;const fromPid=pid;const comm=event[1];pid=parseInt(event[2]);const prio=parseInt(event[3]);this.importer.markPidRunnable(ts,pid,comm,prio,fromPid);return true;},schedCpuHotplugEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/cpu (\d+) (.+) error=(\d+)/.exec(eventBase.details);if(!event)return false;cpuNumber=event[1];const state=event[2];const targetCpu=this.importer.getOrCreateCpu(cpuNumber);const powerCounter=targetCpu.getOrCreateCounter('','Cpu Hotplug');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('State',tr.b.ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'State')));}
+powerCounter.series.forEach(function(series){if(series.name==='State'){series.addCounterSample(ts,state.localeCompare('offline')?0:1);}});return true;},schedBlockedEvent(eventName,cpuNumber,pid,ts,eventBase){const event=schedBlockedRE.exec(eventBase.details);if(!event)return false;pid=parseInt(event[1]);const iowait=parseInt(event[2]);const caller=event[3];this.importer.addPidBlockedReason(ts,pid,iowait,caller);return true;}};Parser.register(SchedParser);return{SchedParser,_SchedParserTestExports:TestExports};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function SyncParser(importer){Parser.call(this,importer);importer.registerEventHandler('sync_timeline',SyncParser.prototype.timelineEvent.bind(this));importer.registerEventHandler('sync_wait',SyncParser.prototype.syncWaitEvent.bind(this));importer.registerEventHandler('sync_pt',SyncParser.prototype.syncPtEvent.bind(this));this.model_=importer.model_;}
+const syncTimelineRE=/name=(\S+) value=(\S*)/;const syncWaitRE=/(\S+) name=(\S+) state=(\d+)/;const syncPtRE=/name=(\S+) value=(\S*)/;SyncParser.prototype={__proto__:Parser.prototype,timelineEvent(eventName,cpuNumber,pid,ts,eventBase){const event=syncTimelineRE.exec(eventBase.details);if(!event)return false;const thread=this.importer.getOrCreatePseudoThread(event[1]);if(thread.lastActiveTs!==undefined){const duration=ts-thread.lastActiveTs;let value=thread.lastActiveValue;if(value===undefined)value=' ';const slice=new tr.model.ThreadSlice('',value,ColorScheme.getColorIdForGeneralPurposeString(value),thread.lastActiveTs,{},duration);thread.thread.sliceGroup.pushSlice(slice);}
+thread.lastActiveTs=ts;thread.lastActiveValue=event[2];return true;},syncWaitEvent(eventName,cpuNumber,pid,ts,eventBase){const event=syncWaitRE.exec(eventBase.details);if(!event)return false;if(eventBase.tgid===undefined){return false;}
+const tgid=parseInt(eventBase.tgid);const thread=this.model_.getOrCreateProcess(tgid).getOrCreateThread(pid);thread.name=eventBase.threadName;const slices=thread.kernelSliceGroup;if(!slices.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
+const name='fence_wait("'+event[2]+'")';if(event[1]==='begin'){const slice=slices.beginSlice(null,name,ts,{'Start state':event[3]});}else if(event[1]==='end'){if(slices.openSliceCount>0){slices.endSlice(ts);}}else{return false;}
+return true;},syncPtEvent(eventName,cpuNumber,pid,ts,eventBase){return!!syncPtRE.exec(eventBase.details);}};Parser.register(SyncParser);return{SyncParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function WorkqueueParser(importer){Parser.call(this,importer);importer.registerEventHandler('workqueue_execute_start',WorkqueueParser.prototype.executeStartEvent.bind(this));importer.registerEventHandler('workqueue_execute_end',WorkqueueParser.prototype.executeEndEvent.bind(this));importer.registerEventHandler('workqueue_queue_work',WorkqueueParser.prototype.executeQueueWork.bind(this));importer.registerEventHandler('workqueue_activate_work',WorkqueueParser.prototype.executeActivateWork.bind(this));}
+const workqueueExecuteStartRE=/work struct (.+): function (\S+)/;const workqueueExecuteEndRE=/work struct (.+)/;WorkqueueParser.prototype={__proto__:Parser.prototype,executeStartEvent(eventName,cpuNumber,pid,ts,eventBase){const event=workqueueExecuteStartRE.exec(eventBase.details);if(!event)return false;const kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,pid,pid);kthread.openSliceTS=ts;kthread.openSlice=event[2];return true;},executeEndEvent(eventName,cpuNumber,pid,ts,eventBase){const event=workqueueExecuteEndRE.exec(eventBase.details);if(!event)return false;const kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,pid,pid);if(kthread.openSlice){const slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),kthread.openSliceTS,{},ts-kthread.openSliceTS);kthread.thread.sliceGroup.pushSlice(slice);}
+kthread.openSlice=undefined;return true;},executeQueueWork(eventName,cpuNumber,pid,ts,eventBase){return true;},executeActivateWork(eventName,cpuNumber,pid,ts,eventBase){return true;}};Parser.register(WorkqueueParser);return{WorkqueueParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const MONOTONIC_TO_FTRACE_GLOBAL_SYNC_ID='linux_clock_monotonic_to_ftrace_global';const IMPORT_PRIORITY=2;function FTraceImporter(model,events){this.importPriority=IMPORT_PRIORITY;this.model_=model;this.events_=events;this.wakeups_=[];this.blockedReasons_=[];this.kernelThreadStates_={};this.buildMapFromLinuxPidsToThreads_();this.lines_=[];this.pseudoThreadCounter=1;this.parsers_=[];this.eventHandlers_={};this.haveClockSyncedMonotonicToGlobal_=false;this.clockDomainId_=tr.model.ClockDomainId.LINUX_FTRACE_GLOBAL;}
+const TestExports={};const lineREWithTGID=new RegExp('^\\s*(.+)-(\\d+)\\s+\\(\\s*(\\d+|-+)\\)\\s\\[(\\d+)\\]'+'\\s+[dX.][Nnp.][Hhs.][0-9a-f.]'+'\\s+(\\d+\\.\\d+):\\s+(\\S+):\\s(.*)$');const lineParserWithTGID=function(line){const groups=lineREWithTGID.exec(line);if(!groups)return groups;let tgid=groups[3];if(tgid[0]==='-')tgid=undefined;return{threadName:groups[1],pid:groups[2],tgid,cpuNumber:groups[4],timestamp:groups[5],eventName:groups[6],details:groups[7]};};TestExports.lineParserWithTGID=lineParserWithTGID;const lineREWithIRQInfo=new RegExp('^\\s*(.+)-(\\d+)\\s+\\[(\\d+)\\]'+'\\s+[dX.][Nnp.][Hhs.][0-9a-f.]'+'\\s+(\\d+\\.\\d+):\\s+(\\S+):\\s(.*)$');const lineParserWithIRQInfo=function(line){const groups=lineREWithIRQInfo.exec(line);if(!groups)return groups;return{threadName:groups[1],pid:groups[2],cpuNumber:groups[3],timestamp:groups[4],eventName:groups[5],details:groups[6]};};TestExports.lineParserWithIRQInfo=lineParserWithIRQInfo;const lineREWithLegacyFmt=/^\s*(.+)-(\d+)\s+\[(\d+)\]\s*(\d+\.\d+):\s+(\S+):\s(.*)$/;const lineParserWithLegacyFmt=function(line){const groups=lineREWithLegacyFmt.exec(line);if(!groups){return groups;}
+return{threadName:groups[1],pid:groups[2],cpuNumber:groups[3],timestamp:groups[4],eventName:groups[5],details:groups[6]};};TestExports.lineParserWithLegacyFmt=lineParserWithLegacyFmt;const traceEventClockSyncRE=/trace_event_clock_sync: parent_ts=(\d+\.?\d*)/;TestExports.traceEventClockSyncRE=traceEventClockSyncRE;const realTimeClockSyncRE=/trace_event_clock_sync: realtime_ts=(\d+)/;const genericClockSyncRE=/trace_event_clock_sync: name=([\w\-]+)/;const pseudoKernelPID=0;function autoDetectLineParser(line){if(line[0]==='{')return false;if(lineREWithTGID.test(line))return lineParserWithTGID;if(lineREWithIRQInfo.test(line))return lineParserWithIRQInfo;if(lineREWithLegacyFmt.test(line))return lineParserWithLegacyFmt;return undefined;}
+TestExports.autoDetectLineParser=autoDetectLineParser;FTraceImporter.canImport=function(events){if(events instanceof tr.b.TraceStream)events=events.header;if(!(typeof(events)==='string'||events instanceof String)){return false;}
+if(FTraceImporter._extractEventsFromSystraceHTML(events,false).ok){return true;}
+if(FTraceImporter._extractEventsFromSystraceMultiHTML(events,false).ok){return true;}
+if(/^# tracer:/.test(events))return true;const lineBreakIndex=events.indexOf('\n');if(lineBreakIndex>-1)events=events.substring(0,lineBreakIndex);if(autoDetectLineParser(events))return true;return false;};FTraceImporter._extractEventsFromSystraceHTML=function(incomingEvents,produceResult){const failure={ok:false};if(produceResult===undefined)produceResult=true;const header=incomingEvents instanceof tr.b.TraceStream?incomingEvents.header:incomingEvents;if(!/^<!DOCTYPE html>/.test(header))return failure;const r=new tr.importer.SimpleLineReader(incomingEvents);if(!r.advanceToLineMatching(/^  <script>$/))return failure;if(!r.advanceToLineMatching(/^  var linuxPerfData = "\\$/))return failure;const eventsBeginAtLine=r.curLineNumber+1;r.beginSavingLines();if(!r.advanceToLineMatching(/^  <\/script>$/))return failure;let rawEvents=r.endSavingLinesAndGetResult();rawEvents=rawEvents.slice(1,rawEvents.length-1);if(!r.advanceToLineMatching(/^<\/body>$/))return failure;if(!r.advanceToLineMatching(/^<\/html>$/))return failure;function endsWith(str,suffix){return str.indexOf(suffix,str.length-suffix.length)!==-1;}
+function stripSuffix(str,suffix){if(!endsWith(str,suffix))return str;return str.substring(str,str.length-suffix.length);}
+let events=[];if(produceResult){for(let i=0;i<rawEvents.length;i++){let event=rawEvents[i];event=stripSuffix(event,'\\n\\');events.push(event);}}else{events=[rawEvents[rawEvents.length-1]];}
+const oldLastEvent=events[events.length-1];const newLastEvent=stripSuffix(oldLastEvent,'\\n";');if(newLastEvent===oldLastEvent)return failure;events[events.length-1]=newLastEvent;return{ok:true,lines:produceResult?events:undefined,eventsBeginAtLine};};FTraceImporter._extractEventsFromSystraceMultiHTML=function(incomingEvents,produceResult){const failure={ok:false};if(produceResult===undefined)produceResult=true;const header=incomingEvents instanceof tr.b.TraceStream?incomingEvents.header:incomingEvents;if(!(new RegExp('^<!DOCTYPE HTML>','i').test(header)))return failure;const r=new tr.importer.SimpleLineReader(incomingEvents);let events=[];let eventsBeginAtLine;while(!/^# tracer:/.test(events)){if(!r.advanceToLineMatching(/^  <script class="trace-data" type="application\/text">$/)){return failure;}
+eventsBeginAtLine=r.curLineNumber+1;r.beginSavingLines();if(!r.advanceToLineMatching(/^  <\/script>$/))return failure;events=r.endSavingLinesAndGetResult();events=events.slice(1,events.length-1);}
+if(!r.advanceToLineMatching(/^<\/body>$/))return failure;if(!r.advanceToLineMatching(/^<\/html>$/))return failure;return{ok:true,lines:produceResult?events:undefined,eventsBeginAtLine,};};FTraceImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'FTraceImporter';},get model(){return this.model_;},importClockSyncMarkers(){this.lazyInit_();this.forEachLine_(function(text,eventBase,cpuNumber,pid,ts){const eventName=eventBase.eventName;if(eventName!=='tracing_mark_write'&&eventName!=='0')return;if(traceEventClockSyncRE.exec(eventBase.details)||genericClockSyncRE.exec(eventBase.details)){this.traceClockSyncEvent_(eventName,cpuNumber,pid,ts,eventBase);}else if(realTimeClockSyncRE.exec(eventBase.details)){const match=realTimeClockSyncRE.exec(eventBase.details);this.model_.realtime_to_monotonic_offset_ms=ts-match[1];}}.bind(this));},importEvents(){if(this.lines_.length===0)return;const modelTimeTransformer=this.model_.clockSyncManager.getModelTimeTransformer(this.clockDomainId_);this.importCpuData_(modelTimeTransformer);this.buildMapFromLinuxPidsToThreads_();this.buildPerThreadCpuSlicesFromCpuState_();},registerEventHandler(eventName,handler){this.eventHandlers_[eventName]=handler;},getOrCreateCpu(cpuNumber){return this.model_.kernel.getOrCreateCpu(cpuNumber);},getOrCreateKernelThread(kernelThreadName,pid,tid){if(!this.kernelThreadStates_[kernelThreadName]){const thread=this.model_.getOrCreateProcess(pid).getOrCreateThread(tid);thread.name=kernelThreadName;this.kernelThreadStates_[kernelThreadName]={pid,thread,openSlice:undefined,openSliceTS:undefined};this.threadsByLinuxPid[tid]=thread;}
+return this.kernelThreadStates_[kernelThreadName];},getOrCreateBinderKernelThread(kernelThreadName,pid,tid){const key=kernelThreadName+pid+tid;if(!this.kernelThreadStates_[key]){const thread=this.model_.getOrCreateProcess(pid).getOrCreateThread(tid);thread.name=kernelThreadName;this.kernelThreadStates_[key]={pid,thread,openSlice:undefined,openSliceTS:undefined};this.threadsByLinuxPid[tid]=thread;}
+return this.kernelThreadStates_[key];},getOrCreatePseudoThread(threadName){let thread=this.kernelThreadStates_[threadName];if(!thread){thread=this.getOrCreateKernelThread(threadName,pseudoKernelPID,this.pseudoThreadCounter);this.pseudoThreadCounter++;}
+return thread;},markPidRunnable(ts,pid,comm,prio,fromPid){this.wakeups_.push({ts,tid:pid,fromTid:fromPid});},addPidBlockedReason(ts,pid,iowait,caller){this.blockedReasons_.push({ts,tid:pid,iowait,caller});},buildMapFromLinuxPidsToThreads_(){this.threadsByLinuxPid={};this.model_.getAllThreads().forEach(function(thread){this.threadsByLinuxPid[thread.tid]=thread;}.bind(this));},buildPerThreadCpuSlicesFromCpuState_(){const SCHEDULING_STATE=tr.model.SCHEDULING_STATE;for(const cpuNumber in this.model_.kernel.cpus){const cpu=this.model_.kernel.cpus[cpuNumber];for(let i=0;i<cpu.slices.length;i++){const cpuSlice=cpu.slices[i];const thread=this.threadsByLinuxPid[cpuSlice.args.tid];if(!thread)continue;cpuSlice.threadThatWasRunning=thread;if(!thread.tempCpuSlices){thread.tempCpuSlices=[];}
+thread.tempCpuSlices.push(cpuSlice);}}
+for(const i in this.wakeups_){const wakeup=this.wakeups_[i];const thread=this.threadsByLinuxPid[wakeup.tid];if(!thread)continue;thread.tempWakeups=thread.tempWakeups||[];thread.tempWakeups.push(wakeup);}
+for(const i in this.blockedReasons_){const reason=this.blockedReasons_[i];const thread=this.threadsByLinuxPid[reason.tid];if(!thread)continue;thread.tempBlockedReasons=thread.tempBlockedReasons||[];thread.tempBlockedReasons.push(reason);}
+this.model_.getAllThreads().forEach(function(thread){if(thread.tempCpuSlices===undefined)return;const origSlices=thread.tempCpuSlices;delete thread.tempCpuSlices;origSlices.sort(function(x,y){return x.start-y.start;});const wakeups=thread.tempWakeups||[];delete thread.tempWakeups;wakeups.sort(function(x,y){return x.ts-y.ts;});const reasons=thread.tempBlockedReasons||[];delete thread.tempBlockedReasons;reasons.sort(function(x,y){return x.ts-y.ts;});const slices=[];if(origSlices.length){const slice=origSlices[0];if(wakeups.length&&wakeups[0].ts<slice.start){const wakeup=wakeups.shift();const wakeupDuration=slice.start-wakeup.ts;const args={'wakeup from tid':wakeup.fromTid};slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNABLE,'',wakeup.ts,args,wakeupDuration));}
+const runningSlice=new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNING,'',slice.start,{},slice.duration);runningSlice.cpuOnWhichThreadWasRunning=slice.cpu;slices.push(runningSlice);}
+for(let i=1;i<origSlices.length;i++){let wakeup=undefined;const prevSlice=origSlices[i-1];const nextSlice=origSlices[i];let midDuration=nextSlice.start-prevSlice.end;while(wakeups.length&&wakeups[0].ts<nextSlice.start){const w=wakeups.shift();if(wakeup===undefined&&w.ts>prevSlice.end){wakeup=w;}}
+let blockedReason=undefined;while(reasons.length&&reasons[0].ts<prevSlice.end){const r=reasons.shift();}
+if(wakeup!==undefined&&reasons.length&&reasons[0].ts<wakeup.ts){blockedReason=reasons.shift();}
+const pushSleep=function(state){if(wakeup!==undefined){midDuration=wakeup.ts-prevSlice.end;}
+if(blockedReason!==undefined){const args={'kernel callsite when blocked:':blockedReason.caller};if(blockedReason.iowait){switch(state){case SCHEDULING_STATE.UNINTR_SLEEP:state=SCHEDULING_STATE.UNINTR_SLEEP_IO;break;case SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL:state=SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL_IO;break;case SCHEDULING_STATE.UNINTR_SLEEP_WAKING:state=SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL_IO;break;default:}}
 slices.push(new tr.model.ThreadTimeSlice(thread,state,'',prevSlice.end,args,midDuration));}else{slices.push(new tr.model.ThreadTimeSlice(thread,state,'',prevSlice.end,{},midDuration));}
-if(wakeup!==undefined){var wakeupDuration=nextSlice.start-wakeup.ts;var args={'wakeup from tid':wakeup.fromTid};slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNABLE,'',wakeup.ts,args,wakeupDuration));wakeup=undefined;}};if(prevSlice.args.stateWhenDescheduled=='S'){pushSleep(SCHEDULING_STATE.SLEEPING);}else if(prevSlice.args.stateWhenDescheduled=='R'||prevSlice.args.stateWhenDescheduled=='R+'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNABLE,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='D'){pushSleep(SCHEDULING_STATE.UNINTR_SLEEP);}else if(prevSlice.args.stateWhenDescheduled=='T'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.STOPPED,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='t'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.DEBUG,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='Z'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.ZOMBIE,'',ioWaitId,prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='X'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.EXIT_DEAD,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='x'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.TASK_DEAD,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='K'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.WAKE_KILL,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='W'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.WAKING,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='D|K'){pushSleep(SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL);}else if(prevSlice.args.stateWhenDescheduled=='D|W'){pushSleep(SCHEDULING_STATE.UNINTR_SLEEP_WAKING);}else{slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.UNKNOWN,'',prevSlice.end,{},midDuration));this.model_.importWarning({type:'parse_error',message:'Unrecognized sleep state: '+
+if(wakeup!==undefined){const wakeupDuration=nextSlice.start-wakeup.ts;const args={'wakeup from tid':wakeup.fromTid};slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNABLE,'',wakeup.ts,args,wakeupDuration));wakeup=undefined;}};if(prevSlice.args.stateWhenDescheduled==='S'){pushSleep(SCHEDULING_STATE.SLEEPING);}else if(prevSlice.args.stateWhenDescheduled==='R'||prevSlice.args.stateWhenDescheduled==='R+'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNABLE,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='D'){pushSleep(SCHEDULING_STATE.UNINTR_SLEEP);}else if(prevSlice.args.stateWhenDescheduled==='T'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.STOPPED,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='t'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.DEBUG,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='Z'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.ZOMBIE,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='X'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.EXIT_DEAD,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='x'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.TASK_DEAD,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='K'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.WAKE_KILL,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='W'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.WAKING,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='D|K'){pushSleep(SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL);}else if(prevSlice.args.stateWhenDescheduled==='D|W'){pushSleep(SCHEDULING_STATE.UNINTR_SLEEP_WAKING);}else{slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.UNKNOWN,'',prevSlice.end,{},midDuration));this.model_.importWarning({type:'parse_error',message:'Unrecognized sleep state: '+
 prevSlice.args.stateWhenDescheduled});}
-var runningSlice=new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNING,'',nextSlice.start,{},nextSlice.duration);runningSlice.cpuOnWhichThreadWasRunning=prevSlice.cpu;slices.push(runningSlice);}
-thread.timeSlices=slices;},this);},getModelTimeTransformer_:function(){var isAttachedToChromeTrace=this.model.getClockSyncRecordsWithSyncId('ftrace_importer').length!==0;var monotonicSyncs=this.model_.getClockSyncRecordsWithSyncId('monotonic');if(monotonicSyncs.length==0)
-return isAttachedToChromeTrace?undefined:tr.b.identity;var sync=monotonicSyncs[0].args;if(sync.parentTS===0)
-return tr.b.identity;return function(ts){return ts+sync.parentTS-sync.perfTS;};},createParsers_:function(){var allTypeInfos=tr.e.importer.linux_perf.Parser.getAllRegisteredTypeInfos();var parsers=allTypeInfos.map(function(typeInfo){return new typeInfo.constructor(this);},this);return parsers;},registerDefaultHandlers_:function(){this.registerEventHandler('tracing_mark_write',FTraceImporter.prototype.traceMarkingWriteEvent_.bind(this));this.registerEventHandler('0',FTraceImporter.prototype.traceMarkingWriteEvent_.bind(this));this.registerEventHandler('tracing_mark_write:trace_event_clock_sync',function(){return true;});this.registerEventHandler('0:trace_event_clock_sync',function(){return true;});},traceClockSyncEvent_:function(eventName,cpuNumber,pid,ts,eventBase){var event=/name=(\w+?)\s(.+)/.exec(eventBase.details);if(event){var name=event[1];var pieces=event[2].split(' ');var args={perfTS:ts};for(var i=0;i<pieces.length;i++){var parts=pieces[i].split('=');if(parts.length!=2)
-throw new Error('omgbbq');args[parts[0]]=parts[1];}
-this.addClockSyncRecord_(new InstantClockSyncRecord(name,ts,args));return true;}
-event=/parent_ts=(\d+\.?\d*)/.exec(eventBase.details);if(!event)
-return false;this.addClockSyncRecord_(new InstantClockSyncRecord('monotonic',ts,{perfTS:ts,parentTS:event[1]*1000}));return true;},traceMarkingWriteEvent_:function(eventName,cpuNumber,pid,ts,eventBase,threadName){eventBase.details=eventBase.details.replace(/\\n.*$/,'');var event=/^\s*(\w+):\s*(.*)$/.exec(eventBase.details);if(!event){var tag=eventBase.details.substring(0,2);if(tag=='B|'||tag=='E'||tag=='E|'||tag=='X|'||tag=='C|'||tag=='S|'||tag=='F|'){eventBase.subEventName='android';}else{return false;}}else{eventBase.subEventName=event[1];eventBase.details=event[2];}
-var writeEventName=eventName+':'+eventBase.subEventName;var handler=this.eventHandlers_[writeEventName];if(!handler){this.model_.importWarning({type:'parse_error',message:'Unknown trace_marking_write event '+writeEventName});return true;}
-return handler(writeEventName,cpuNumber,pid,ts,eventBase,threadName);},importClockSyncRecords_:function(){this.forEachLine_(function(text,eventBase,cpuNumber,pid,ts){var eventName=eventBase.eventName;if(eventName!=='tracing_mark_write'&&eventName!=='0')
-return;if(traceEventClockSyncRE.exec(eventBase.details))
-this.traceClockSyncEvent_(eventName,cpuNumber,pid,ts,eventBase);if(realTimeClockSyncRE.exec(eventBase.details)){var match=realTimeClockSyncRE.exec(eventBase.details);this.model_.realtime_to_monotonic_offset_ms=ts-match[1];}
-if(genericClockSyncRE.exec(eventBase.details))
-this.traceClockSyncEvent_(eventName,cpuNumber,pid,ts,eventBase);}.bind(this));},addClockSyncRecord_:function(csr){this.newlyAddedClockSyncRecords_.push(csr);this.model_.clockSyncRecords.push(csr);},shiftNewlyAddedClockSyncRecords_:function(modelTimeTransformer){this.newlyAddedClockSyncRecords_.forEach(function(csr){csr.start=modelTimeTransformer(csr.start);});},importCpuData_:function(modelTimeTransformer){this.forEachLine_(function(text,eventBase,cpuNumber,pid,ts){var eventName=eventBase.eventName;var handler=this.eventHandlers_[eventName];if(!handler){this.model_.importWarning({type:'parse_error',message:'Unknown event '+eventName+' ('+text+')'});return;}
-ts=modelTimeTransformer(ts);if(!handler(eventName,cpuNumber,pid,ts,eventBase)){this.model_.importWarning({type:'parse_error',message:'Malformed '+eventName+' event ('+text+')'});}}.bind(this));},parseLines_:function(){var lines=[];var extractResult=FTraceImporter._extractEventsFromSystraceHTML(this.events_,true);if(!extractResult.ok)
-extractResult=FTraceImporter._extractEventsFromSystraceMultiHTML(this.events_,true);var lines=extractResult.ok?extractResult.lines:this.events_.split('\n');var lineParser=undefined;for(var lineNumber=0;lineNumber<lines.length;++lineNumber){var line=lines[lineNumber].trim();if(line.length==0||/^#/.test(line))
-continue;if(!lineParser){lineParser=autoDetectLineParser(line);if(!lineParser){this.model_.importWarning({type:'parse_error',message:'Cannot parse line: '+line});continue;}}
-var eventBase=lineParser(line);if(!eventBase){this.model_.importWarning({type:'parse_error',message:'Unrecognized line: '+line});continue;}
-this.lines_.push([line,eventBase,parseInt(eventBase.cpuNumber),parseInt(eventBase.pid),parseFloat(eventBase.timestamp)*1000]);}},forEachLine_:function(handler){for(var i=0;i<this.lines_.length;++i){var line=this.lines_[i];handler.apply(this,line);}}};tr.importer.Importer.register(FTraceImporter);return{FTraceImporter:FTraceImporter,_FTraceImporterTestExports:TestExports};});'use strict';tr.exportTo('tr.e.audits',function(){var VSYNC_COUNTER_PRECISIONS={'android.VSYNC-app':15,'android.VSYNC':15};var VSYNC_SLICE_PRECISIONS={'RenderWidgetHostViewAndroid::OnVSync':5,'VSYNC':10,'vblank':10,'DisplayLinkMac::GetVSyncParameters':5};var BEGIN_FRAME_SLICE_PRECISION={'Scheduler::BeginFrame':10};function VSyncAuditor(model){tr.c.Auditor.call(this,model);};VSyncAuditor.prototype={__proto__:tr.c.Auditor.prototype,runAnnotate:function(){this.model.device.vSyncTimestamps=this.findVSyncTimestamps(this.model);},findVSyncTimestamps:function(model){var times=[];var maxPrecision=Number.NEGATIVE_INFINITY;var maxTitle=undefined;function useInstead(title,precisions){var precision=precisions[title];if(precision===undefined)
-return false;if(title===maxTitle)
-return true;if(precision<=maxPrecision){if(precision===maxPrecision){console.warn('Encountered two different VSync events ('+
-maxTitle+', '+title+') with the same precision, '+'ignoring the newer one ('+title+')');}
+const runningSlice=new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNING,'',nextSlice.start,{},nextSlice.duration);runningSlice.cpuOnWhichThreadWasRunning=prevSlice.cpu;slices.push(runningSlice);}
+thread.timeSlices=slices;},this);},createParsers_(){const allTypeInfos=tr.e.importer.linux_perf.Parser.getAllRegisteredTypeInfos();const parsers=allTypeInfos.map(function(typeInfo){return new typeInfo.constructor(this);},this);return parsers;},registerDefaultHandlers_(){this.registerEventHandler('tracing_mark_write',FTraceImporter.prototype.traceMarkingWriteEvent_.bind(this));this.registerEventHandler('0',FTraceImporter.prototype.traceMarkingWriteEvent_.bind(this));this.registerEventHandler('tracing_mark_write:trace_event_clock_sync',function(){return true;});this.registerEventHandler('0:trace_event_clock_sync',function(){return true;});},traceClockSyncEvent_(eventName,cpuNumber,pid,ts,eventBase){let event=/name=(\w+?)\s(.+)/.exec(eventBase.details);if(event){const name=event[1];const pieces=event[2].split(' ');const args={perfTs:ts};for(let i=0;i<pieces.length;i++){const parts=pieces[i].split('=');if(parts.length!==2){throw new Error('omgbbq');}
+args[parts[0]]=parts[1];}
+this.model_.clockSyncManager.addClockSyncMarker(this.clockDomainId_,name,ts);return true;}
+event=/name=([\w\-]+)/.exec(eventBase.details);if(event){this.model_.clockSyncManager.addClockSyncMarker(this.clockDomainId_,event[1],ts);return true;}
+event=/parent_ts=(\d+\.?\d*)/.exec(eventBase.details);if(!event)return false;let monotonicTs=event[1]*1000;if(monotonicTs===0)monotonicTs=ts;if(this.haveClockSyncedMonotonicToGlobal_){return true;}
+this.model_.clockSyncManager.addClockSyncMarker(this.clockDomainId_,MONOTONIC_TO_FTRACE_GLOBAL_SYNC_ID,ts);this.model_.clockSyncManager.addClockSyncMarker(tr.model.ClockDomainId.LINUX_CLOCK_MONOTONIC,MONOTONIC_TO_FTRACE_GLOBAL_SYNC_ID,monotonicTs);this.haveClockSyncedMonotonicToGlobal_=true;return true;},traceMarkingWriteEvent_(eventName,cpuNumber,pid,ts,eventBase,threadName){eventBase.details=eventBase.details.replace(/\\n.*$/,'');const event=/^\s*(\w+):\s*(.*)$/.exec(eventBase.details);if(!event){const tag=eventBase.details.substring(0,2);if(tag==='B|'||tag==='E'||tag==='E|'||tag==='X|'||tag==='C|'||tag==='S|'||tag==='F|'){eventBase.subEventName='android';}else{return false;}}else{eventBase.subEventName=event[1];eventBase.details=event[2];}
+const writeEventName=eventName+':'+eventBase.subEventName;const handler=this.eventHandlers_[writeEventName];if(!handler){this.model_.importWarning({type:'parse_error',message:'Unknown trace_marking_write event '+writeEventName});return true;}
+return handler(writeEventName,cpuNumber,pid,ts,eventBase,threadName);},importCpuData_(modelTimeTransformer){this.forEachLine_(function(text,eventBase,cpuNumber,pid,ts){const eventName=eventBase.eventName;const handler=this.eventHandlers_[eventName];if(!handler){this.model_.importWarning({type:'parse_error',message:'Unknown event '+eventName+' ('+text+')'});return;}
+ts=modelTimeTransformer(ts);if(!handler(eventName,cpuNumber,pid,ts,eventBase)){this.model_.importWarning({type:'parse_error',message:'Malformed '+eventName+' event ('+text+')'});}}.bind(this));},parseLines_(){let extractResult=FTraceImporter._extractEventsFromSystraceHTML(this.events_,true);if(!extractResult.ok){extractResult=FTraceImporter._extractEventsFromSystraceMultiHTML(this.events_,true);}
+let lineParser=undefined;if(extractResult.ok){for(const line of extractResult.lines){lineParser=this.parseLine_(line,lineParser);}}else{const r=new tr.importer.SimpleLineReader(this.events_);for(const line of r){lineParser=this.parseLine_(line,lineParser);}}},parseLine_(line,lineParser){line=line.trim();if(line.length===0)return lineParser;if(/^#/.test(line)){const clockType=/^# clock_type=([A-Z_]+)$/.exec(line);if(clockType){this.clockDomainId_=clockType[1];}
+return lineParser;}
+if(!lineParser){lineParser=autoDetectLineParser(line);if(!lineParser){this.model_.importWarning({type:'parse_error',message:'Cannot parse line: '+line});return lineParser;}}
+const eventBase=lineParser(line);if(!eventBase){this.model_.importWarning({type:'parse_error',message:'Unrecognized line: '+line});return lineParser;}
+this.lines_.push([line,eventBase,parseInt(eventBase.cpuNumber),parseInt(eventBase.pid),parseFloat(eventBase.timestamp)*1000]);return lineParser;},forEachLine_(handler){for(let i=0;i<this.lines_.length;++i){const line=this.lines_[i];handler.apply(this,line);}},lazyInit_(){this.parsers_=this.createParsers_();this.registerDefaultHandlers_();this.parseLines_();}};tr.importer.Importer.register(FTraceImporter);return{FTraceImporter,_FTraceImporterTestExports:TestExports,IMPORT_PRIORITY,};});'use strict';tr.exportTo('tr.e.importer.android.atrace_process_dump',function(){const IMPORT_PRIORITY=tr.e.importer.linux_perf.IMPORT_PRIORITY+1;const HEADER='ATRACE_PROCESS_DUMP';const PROTECTION_FLAG_LETTERS={'-':0,'r':tr.model.VMRegion.PROTECTION_FLAG_READ,'w':tr.model.VMRegion.PROTECTION_FLAG_WRITE,'x':tr.model.VMRegion.PROTECTION_FLAG_EXECUTE,'s':tr.model.VMRegion.PROTECTION_FLAG_MAYSHARE,};class AtraceProcessDumpImporter extends tr.importer.Importer{constructor(model,data){super(model,data);this.importPriority=IMPORT_PRIORITY;this.model_=model;this.raw_data_=data;this.clock_sync_markers_={};this.snapshots_=[];this.processes_={};}
+static canImport(events){if(!(typeof(events)==='string'||events instanceof String)){return false;}
+return events.startsWith(HEADER);}
+get importerName(){return'AtraceProcessDumpImporter';}
+get model(){return this.model_;}
+lazyParseData(){if(this.raw_data_===undefined){return;}
+const dump=JSON.parse(this.raw_data_.slice(HEADER.length+1));this.clock_sync_markers_=dump.clock_sync_markers;this.snapshots_=dump.dump.snapshots;this.processes_=dump.dump.processes;this.raw_data_=undefined;}
+importClockSyncMarkers(){this.lazyParseData();for(const syncId in this.clock_sync_markers_){const ts=parseInt(this.clock_sync_markers_[syncId]);this.model_.clockSyncManager.addClockSyncMarker(tr.model.ClockDomainId.LINUX_CLOCK_MONOTONIC,syncId,ts);}}
+setProcessMemoryDumpTotals_(pmd,processInfo){pmd.totals={'residentBytes':processInfo.rss*1024,'platformSpecific':{'vm':processInfo.vm*1024}};const totals=pmd.totals.platformSpecific;function importGpuMetric(name){if(processInfo[name]!==undefined&&processInfo[name]>0){totals[name]=processInfo[name]*1024;totals[name+'_pss']=processInfo[name+'_pss']*1024;}}
+importGpuMetric('gpu_egl');importGpuMetric('gpu_gl');importGpuMetric('gpu_etc');if(processInfo.pss!==undefined){totals.pss=processInfo.pss*1024;totals.swp=processInfo.swp*1024;totals.pc=processInfo.pc*1024;totals.pd=processInfo.pd*1024;totals.sc=processInfo.sc*1024;totals.sd=processInfo.sd*1024;}}
+setProcessMemoryDumpVmRegions_(pmd,processInfo){if(processInfo.mmaps===undefined){return;}
+const vmRegions=[];for(const memoryMap of processInfo.mmaps){const addr=memoryMap.vm.split('-').map(x=>parseInt(x,16));let flags=0;for(const letter of memoryMap.flags){flags|=PROTECTION_FLAG_LETTERS[letter];}
+const totals={'proportionalResident':memoryMap.pss*1024,'privateCleanResident':memoryMap.pc*1024,'privateDirtyResident':memoryMap.pd*1024,'sharedCleanResident':memoryMap.sc*1024,'sharedDirtyResident':memoryMap.sd*1024,'swapped':memoryMap.swp*1024,};vmRegions.push(new tr.model.VMRegion(addr[0],addr[1]-addr[0],flags,memoryMap.file,totals));}
+pmd.vmRegions=tr.model.VMRegionClassificationNode.fromRegions(vmRegions);}
+importEvents(){this.lazyParseData();for(const[pid,process]of Object.entries(this.processes_)){const modelProcess=this.model_.getProcess(pid);if(modelProcess===undefined){continue;}
+modelProcess.name=process.name;const threads=process.threads;if(threads===undefined){continue;}
+for(const[tid,thread]of Object.entries(threads)){const modelThread=modelProcess.threads[tid];if(modelThread===undefined){continue;}
+modelThread.name=thread.name;}}
+const memCounter=this.model_.kernel.getOrCreateCounter('global','SystemMemory');const memUsedSeries=new tr.model.CounterSeries('Used (KB)',0);const memSwappedSeries=new tr.model.CounterSeries('Swapped (KB)',0);memCounter.addSeries(memUsedSeries);memCounter.addSeries(memSwappedSeries);for(const snapshot of this.snapshots_){const ts=parseInt(snapshot.ts);const memoryDump=snapshot.memdump;if(memoryDump===undefined){const memInfo=snapshot.meminfo;if(memInfo===undefined){continue;}
+const memCaches=memInfo.Buffers+memInfo.Cached-memInfo.Mapped;const memUsed=memInfo.MemTotal-memInfo.MemFree-memCaches;const memSwapped=memInfo.SwapTotal-memInfo.SwapFree;memUsedSeries.addCounterSample(ts,memUsed);memSwappedSeries.addCounterSample(ts,memSwapped);continue;}
+const gmd=new tr.model.GlobalMemoryDump(this.model_,ts);this.model_.globalMemoryDumps.push(gmd);for(const[pid,processInfo]of Object.entries(memoryDump)){if(processInfo.rss===undefined){continue;}
+const modelProcess=this.model_.getProcess(pid);if(modelProcess===undefined){continue;}
+const pmd=new tr.model.ProcessMemoryDump(gmd,modelProcess,ts);gmd.processMemoryDumps[pid]=pmd;modelProcess.memoryDumps.push(pmd);this.setProcessMemoryDumpTotals_(pmd,processInfo);this.setProcessMemoryDumpVmRegions_(pmd,processInfo);}}}}
+tr.importer.Importer.register(AtraceProcessDumpImporter);return{AtraceProcessDumpImporter,};});'use strict';tr.exportTo('tr.model',function(){const ColorScheme=tr.b.ColorScheme;function Activity(name,category,range,args){tr.model.TimedEvent.call(this,range.min);this.title=name;this.category=category;this.colorId=ColorScheme.getColorIdForGeneralPurposeString(name);this.duration=range.duration;this.args=args;this.name=name;}
+Activity.prototype={__proto__:tr.model.TimedEvent.prototype,shiftTimestampsForward(amount){this.start+=amount;},addBoundsToRange(range){range.addValue(this.start);range.addValue(this.end);}};return{Activity,};});'use strict';tr.exportTo('tr.e.importer.android',function(){const Importer=tr.importer.Importer;const ACTIVITY_STATE={NONE:'none',CREATED:'created',STARTED:'started',RESUMED:'resumed',PAUSED:'paused',STOPPED:'stopped',DESTROYED:'destroyed'};const activityMap={};function EventLogImporter(model,events){this.model_=model;this.events_=events;this.importPriority=3;}
+const eventLogActivityRE=new RegExp('(\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}.\\d+)'+'\\s+(\\d+)\\s+(\\d+)\\s+([A-Z])\\s*'+'(am_\\w+)\\s*:(.*)');const amCreateRE=new RegExp('\s*\\[.*,.*,.*,(.*),.*,.*,.*,.*\\]');const amFocusedRE=new RegExp('\s*\\[\\d+,(.*)\\]');const amProcStartRE=new RegExp('\s*\\[\\d+,\\d+,\\d+,.*,activity,(.*)\\]');const amOnResumeRE=new RegExp('\s*\\[\\d+,(.*)\\]');const amOnPauseRE=new RegExp('\s*\\[\\d+,(.*)\\]');const amLaunchTimeRE=new RegExp('\s*\\[\\d+,\\d+,(.*),(\\d+),(\\d+)');const amDestroyRE=new RegExp('\s*\\[\\d+,\\d+,\\d+,(.*)\\]');EventLogImporter.canImport=function(events){if(!(typeof(events)==='string'||events instanceof String)){return false;}
+if(/^<!DOCTYPE html>/.test(events))return false;return eventLogActivityRE.test(events);};EventLogImporter.prototype={__proto__:Importer.prototype,get importerName(){return'EventLogImporter';},get model(){return this.model_;},getFullActivityName(component){const componentSplit=component.split('/');if(componentSplit[1].startsWith('.')){return componentSplit[0]+componentSplit[1];}
+return componentSplit[1];},getProcName(component){const componentSplit=component.split('/');return componentSplit[0];},findOrCreateActivity(activityName){if(activityName in activityMap){return activityMap[activityName];}
+const activity={state:ACTIVITY_STATE.NONE,name:activityName};activityMap[activityName]=activity;return activity;},deleteActivity(activityName){delete activityMap[activityName];},handleCreateActivity(ts,activityName){const activity=this.findOrCreateActivity(activityName);activity.state=ACTIVITY_STATE.CREATED;activity.createdTs=ts;},handleFocusActivity(ts,procName,activityName){const activity=this.findOrCreateActivity(activityName);activity.lastFocusedTs=ts;},handleProcStartForActivity(ts,activityName){const activity=this.findOrCreateActivity(activityName);activity.procStartTs=ts;},handleOnResumeCalled(ts,pid,activityName){const activity=this.findOrCreateActivity(activityName);activity.state=ACTIVITY_STATE.RESUMED;activity.lastResumeTs=ts;activity.pid=pid;},handleOnPauseCalled(ts,activityName){const activity=this.findOrCreateActivity(activityName);activity.state=ACTIVITY_STATE.PAUSED;activity.lastPauseTs=ts;if(ts>this.model_.bounds.min&&ts<this.model_.bounds.max){this.addActivityToProcess(activity);}},handleLaunchTime(ts,activityName,launchTime){const activity=this.findOrCreateActivity(activityName);activity.launchTime=launchTime;},handleDestroyActivity(ts,activityName){this.deleteActivity(activityName);},addActivityToProcess(activity){if(activity.pid===undefined)return;const process=this.model_.getOrCreateProcess(activity.pid);const range=tr.b.math.Range.fromExplicitRange(Math.max(this.model_.bounds.min,activity.lastResumeTs),activity.lastPauseTs);const newActivity=new tr.model.Activity(activity.name,'Android Activity',range,{created:activity.createdTs,procstart:activity.procStartTs,lastfocus:activity.lastFocusedTs});process.activities.push(newActivity);},parseAmLine_(line){let match=eventLogActivityRE.exec(line);if(!match)return;const firstRealtimeTs=this.model_.bounds.min-
+this.model_.realtime_to_monotonic_offset_ms;const year=new Date(firstRealtimeTs).getFullYear();const ts=match[1].substring(0,5)+'-'+year+' '+
+match[1].substring(5,match[1].length);const monotonicTs=Date.parse(ts)+
+this.model_.realtime_to_monotonic_offset_ms;const pid=match[2];const action=match[5];const data=match[6];if(action==='am_create_activity'){match=amCreateRE.exec(data);if(match&&match.length>=2){this.handleCreateActivity(monotonicTs,this.getFullActivityName(match[1]));}}else if(action==='am_focused_activity'){match=amFocusedRE.exec(data);if(match&&match.length>=2){this.handleFocusActivity(monotonicTs,this.getProcName(match[1]),this.getFullActivityName(match[1]));}}else if(action==='am_proc_start'){match=amProcStartRE.exec(data);if(match&&match.length>=2){this.handleProcStartForActivity(monotonicTs,this.getFullActivityName(match[1]));}}else if(action==='am_on_resume_called'){match=amOnResumeRE.exec(data);if(match&&match.length>=2){this.handleOnResumeCalled(monotonicTs,pid,match[1]);}}else if(action==='am_on_paused_called'){match=amOnPauseRE.exec(data);if(match&&match.length>=2){this.handleOnPauseCalled(monotonicTs,match[1]);}}else if(action==='am_activity_launch_time'){match=amLaunchTimeRE.exec(data);this.handleLaunchTime(monotonicTs,this.getFullActivityName(match[1]),match[2]);}else if(action==='am_destroy_activity'){match=amDestroyRE.exec(data);if(match&&match.length===2){this.handleDestroyActivity(monotonicTs,this.getFullActivityName(match[1]));}}},importEvents(){if(isNaN(this.model_.realtime_to_monotonic_offset_ms)){this.model_.importWarning({type:'eveng_log_clock_sync',message:'Need a trace_event_clock_sync to map realtime to import.'});return;}
+this.model_.updateBounds();const lines=this.events_.split('\n');lines.forEach(this.parseAmLine_,this);for(const activityName in activityMap){const activity=activityMap[activityName];if(activity.state===ACTIVITY_STATE.RESUMED){activity.lastPauseTs=this.model_.bounds.max;this.addActivityToProcess(activity);}}}};Importer.register(EventLogImporter);return{EventLogImporter,};});'use strict';tr.exportTo('tr.e.importer.android.process_data',function(){const Importer=tr.importer.Importer;const PROCESS_DUMP_HEADER='PROCESS DUMP';function ProcessDataImporter(model,processData){this.model_=model;this.processDataLines=processData.split('\n');this.importPriority=3;}
+ProcessDataImporter.canImport=function(events){if(!(typeof(events)==='string'||events instanceof String)){return false;}
+if(events.split('\n')[0]===PROCESS_DUMP_HEADER){return true;}
+return false;};ProcessDataImporter.prototype={__proto__:Importer.prototype,get importerName(){return'ProcessDataImporter';},get model(){return this.model_;},parseEventData(data){const allDumpedProcesses={};let parseProcesses=false;let parseThreads=false;let legacy=false;for(let i=1;i<data.length;i++){const cols=data[i].split(/\s+/);if(cols[0].startsWith('USER')){if(parseProcesses){parseProcesses=false;parseThreads=true;}else{parseThreads=false;parseProcesses=true;}
+const colCount=cols.length;if(parseProcesses&&colCount===9){legacy=false;}else if(parseProcesses&&colCount===8){legacy=true;}
+continue;}
+if(parseProcesses){const pid=Number(cols[1]);if(allDumpedProcesses[pid]===undefined){allDumpedProcesses[pid]={};}
+allDumpedProcesses[pid]={'name':cols[8],pid,'comm':cols[9]};continue;}
+if(parseThreads){let pid;let tid;let name;if(legacy){pid=Number(cols[1]);if(allDumpedProcesses[pid]!==undefined){tid=pid;}else{tid=pid;pid=Number(cols[2]);}
+name=cols.slice(8).join(' ');}else{pid=Number(cols[1]);tid=Number(cols[2]);name=cols.slice(3).join(' ');}
+if(allDumpedProcesses[pid]===undefined)continue;if(allDumpedProcesses[pid].threads===undefined){allDumpedProcesses[pid].threads={};}
+allDumpedProcesses[pid].threads[tid]={tid,name};continue;}}
+return allDumpedProcesses;},importEvents(){const allDumpedProcesses=this.parseEventData(this.processDataLines);const modelProcesses=this.model_.getAllProcesses();for(let i=0;i<modelProcesses.length;i++){const modelProcess=modelProcesses[i];const pid=modelProcess.pid;const dumpedProcess=allDumpedProcesses[pid];if(dumpedProcess===undefined){continue;}
+modelProcess.name=dumpedProcess.name;const processDumpThreads=dumpedProcess.threads;if(processDumpThreads!==undefined){for(const tid in modelProcess.threads){const modelThread=modelProcess.threads[tid];if(Number(pid)===Number(tid)){modelThread.name='UI thread';}else if(modelThread.name==='<...>'){if(processDumpThreads[tid]!==undefined){modelThread.name=processDumpThreads[tid].name;}}}}}}};Importer.register(ProcessDataImporter);return{ProcessDataImporter,};});'use strict';tr.exportTo('tr.e.importer.battor',function(){function BattorImporter(model,events){this.importPriority=3;this.model_=model;this.samples_=[];this.syncTimestampsById_=new Map();this.parseTrace_(events);}
+const battorDataLineRE=new RegExp('^(-?\\d+\\.\\d+)\\s+(-?\\d+\\.\\d+)\\s+(-?\\d+\\.\\d+)'+'(?:\\s+<(\\S+)>)?$');const battorHeaderLineRE=/^# BattOr/;BattorImporter.canImport=function(events){if(!(typeof(events)==='string'||events instanceof String)){return false;}
+return battorHeaderLineRE.test(events);};BattorImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'BattorImporter';},get model(){return this.model_;},importClockSyncMarkers(){for(const[syncId,ts]of this.syncTimestampsById_){this.model_.clockSyncManager.addClockSyncMarker(tr.model.ClockDomainId.BATTOR,syncId,ts);}},importEvents(){if(this.model_.device.powerSeries){this.model_.importWarning({type:'import_error',message:'Power counter exists, can not import BattOr power trace.'});return;}
+const modelTimeTransformer=this.model_.clockSyncManager.getModelTimeTransformer(tr.model.ClockDomainId.BATTOR);const powerSeries=this.model_.device.powerSeries=new tr.model.PowerSeries(this.model_.device);for(let i=0;i<this.samples_.length;i++){const sample=this.samples_[i];powerSeries.addPowerSample(modelTimeTransformer(sample.ts),sample.powerInW);}},parseTrace_(trace){const lines=trace.split('\n');for(let line of lines){line=line.trim();if(line.length===0)continue;if(line.startsWith('#'))continue;const groups=battorDataLineRE.exec(line);if(!groups){this.model_.importWarning({type:'parse_error',message:'Unrecognized line in BattOr trace: '+line});continue;}
+const ts=parseFloat(groups[1]);const voltageInV=tr.b.convertUnit(parseFloat(groups[2]),tr.b.UnitPrefixScale.METRIC.MILLI,tr.b.UnitPrefixScale.METRIC.NONE);const currentInA=tr.b.convertUnit(parseFloat(groups[3]),tr.b.UnitPrefixScale.METRIC.MILLI,tr.b.UnitPrefixScale.METRIC.NONE);const syncId=groups[4];if(syncId){this.syncTimestampsById_.set(syncId,ts);}
+if(voltageInV<0||currentInA<0){this.model_.importWarning({type:'parse_error',message:'The following line in the BattOr trace has a negative '+'voltage or current, neither of which are allowed: '+line+'. A common cause of this is that the device is charging '+'while the trace is being recorded.'});continue;}
+this.samples_.push(new Sample(ts,voltageInV,currentInA));}}};function Sample(ts,voltageInV,currentInA){this.ts=ts;this.voltageInV=voltageInV;this.currentInA=currentInA;}
+Sample.prototype={get powerInW(){return this.voltageInV*this.currentInA;}};tr.importer.Importer.register(BattorImporter);return{BattorImporter,};});'use strict';tr.exportTo('tr.e.importer.ddms',function(){const kPid=0;const kCategory='java';const kMethodLutEndMarker='\n*end\n';const kThreadsStart='\n*threads\n';const kMethodsStart='\n*methods\n';const kTraceMethodEnter=0x00;const kTraceMethodExit=0x01;const kTraceUnroll=0x02;const kTraceMethodActionMask=0x03;const kTraceHeaderLength=32;const kTraceMagicValue=0x574f4c53;const kTraceVersionSingleClock=2;const kTraceVersionDualClock=3;const kTraceRecordSizeSingleClock=10;const kTraceRecordSizeDualClock=14;function Reader(stringPayload){this.position_=0;this.data_=new Uint8Array(stringPayload.length);for(let i=0;i<stringPayload.length;++i){this.data_[i]=stringPayload.charCodeAt(i);}}
+Reader.prototype={__proto__:Object.prototype,uint8(){const result=this.data_[this.position_];this.position_+=1;return result;},uint16(){let result=0;result+=this.uint8();result+=this.uint8()<<8;return result;},uint32(){let result=0;result+=this.uint8();result+=this.uint8()<<8;result+=this.uint8()<<16;result+=this.uint8()<<24;return result;},uint64(){const low=this.uint32();const high=this.uint32();const lowStr=('0000000'+low.toString(16)).substr(-8);const highStr=('0000000'+high.toString(16)).substr(-8);const result=highStr+lowStr;return result;},seekTo(position){this.position_=position;},hasMore(){return this.position_<this.data_.length;}};function DdmsImporter(model,data){this.importPriority=3;this.model_=model;this.data_=data;}
+DdmsImporter.canImport=function(data){if(typeof(data)==='string'||data instanceof String){const header=data.slice(0,1000);return header.startsWith('*version\n')&&header.indexOf('\nvm=')>=0&&header.indexOf(kThreadsStart)>=0;}
+return false;};DdmsImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'DdmsImporter';},get model(){return this.model_;},importEvents(){const divider=this.data_.indexOf(kMethodLutEndMarker)+
+kMethodLutEndMarker.length;this.metadata_=this.data_.slice(0,divider);this.methods_={};this.parseThreads();this.parseMethods();const traceReader=new Reader(this.data_.slice(divider));const magic=traceReader.uint32();if(magic!==kTraceMagicValue){throw Error('Failed to match magic value');}
+this.version_=traceReader.uint16();if(this.version_!==kTraceVersionDualClock){throw Error('Unknown version');}
+const dataOffest=traceReader.uint16();const startDateTime=traceReader.uint64();const recordSize=traceReader.uint16();traceReader.seekTo(dataOffest);while(traceReader.hasMore()){this.parseTraceEntry(traceReader);}},parseTraceEntry(reader){const tid=reader.uint16();const methodPacked=reader.uint32();const cpuSinceStart=reader.uint32();const wallClockSinceStart=reader.uint32();let method=methodPacked&~kTraceMethodActionMask;const action=methodPacked&kTraceMethodActionMask;const thread=this.getTid(tid);method=this.getMethodName(method);if(action===kTraceMethodEnter){thread.sliceGroup.beginSlice(kCategory,method,wallClockSinceStart,undefined,cpuSinceStart);}else if(thread.sliceGroup.openSliceCount){thread.sliceGroup.endSlice(wallClockSinceStart,cpuSinceStart);}},parseThreads(){let threads=this.metadata_.slice(this.metadata_.indexOf(kThreadsStart)+
+kThreadsStart.length);threads=threads.slice(0,threads.indexOf('\n*'));threads=threads.split('\n');threads.forEach(this.parseThread.bind(this));},parseThread(threadLine){const tid=threadLine.slice(0,threadLine.indexOf('\t'));const thread=this.getTid(parseInt(tid));thread.name=threadLine.slice(threadLine.indexOf('\t')+1);},getTid(tid){return this.model_.getOrCreateProcess(kPid).getOrCreateThread(tid);},parseMethods(){let methods=this.metadata_.slice(this.metadata_.indexOf(kMethodsStart)+
+kMethodsStart.length);methods=methods.slice(0,methods.indexOf('\n*'));methods=methods.split('\n');methods.forEach(this.parseMethod.bind(this));},parseMethod(methodLine){const data=methodLine.split('\t');const methodId=parseInt(data[0]);const methodName=data[1]+'.'+data[2]+data[3];this.addMethod(methodId,methodName);},addMethod(methodId,methodName){this.methods_[methodId]=methodName;},getMethodName(methodId){return this.methods_[methodId];}};tr.importer.Importer.register(DdmsImporter);return{DdmsImporter,};});'use strict';tr.exportTo('tr.e.audits',function(){class LowMemoryAuditor extends tr.c.Auditor{constructor(model){super();this.model_=model;}
+runAnnotate(){this.model_.device.lowMemoryEvents=this.getLowMemoryEvents_();}
+getLowMemoryEvents_(){const model=this.model_;const result=[];for(const process of model.getAllProcesses()){for(const e of process.getDescendantEvents()){if(!(e instanceof tr.model.ThreadSlice)||e.duration!==0){continue;}
+if(e.category!=='lowmemory'){continue;}
+result.push(e);}}
+return result;}}
+tr.c.Auditor.register(LowMemoryAuditor);return{LowMemoryAuditor};});'use strict';function filterDuplicateTimestamps(timestamps){const dedupedTimestamps=[];let lastTs=0;for(const ts of timestamps){if(ts-lastTs>=1){dedupedTimestamps.push(ts);lastTs=ts;}}
+return dedupedTimestamps;}
+tr.exportTo('tr.e.audits',function(){const VSYNC_COUNTER_PRECISIONS={'android.VSYNC-app':15,'android.VSYNC':15};const VSYNC_SLICE_PRECISIONS={'RenderWidgetHostViewAndroid::OnVSync':5,'VSYNC':10,'vblank':10,'DisplayLinkMac::GetVSyncParameters':5};const BEGIN_FRAME_SLICE_PRECISION={'DisplayScheduler::BeginFrame':10};function VSyncAuditor(model){tr.c.Auditor.call(this,model);}
+VSyncAuditor.prototype={__proto__:tr.c.Auditor.prototype,runAnnotate(){this.model.device.vSyncTimestamps=this.findVSyncTimestamps(this.model);},findVSyncTimestamps(model){let times=[];let maxPrecision=Number.NEGATIVE_INFINITY;let maxTitle=undefined;function useInstead(title,precisions){const precision=precisions[title];if(precision===undefined)return false;if(title===maxTitle)return true;if(precision<=maxPrecision){if(precision===maxPrecision){model.importWarning({type:'VSyncAuditor',message:'Encountered two different VSync events ('+
+maxTitle+', '+title+') with the same precision, '+'ignoring the newer one ('+title+')',showToUser:false,});}
 return false;}
 maxPrecision=precision;maxTitle=title;times=[];return true;}
-for(var pid in model.processes){var process=model.processes[pid];for(var cid in process.counters){if(useInstead(cid,VSYNC_COUNTER_PRECISIONS)){var counter=process.counters[cid];for(var i=0;i<counter.series.length;i++){var series=counter.series[i];Array.prototype.push.apply(times,series.timestamps);}}}
-for(var tid in process.threads){var thread=process.threads[tid];for(var i=0;i<thread.sliceGroup.slices.length;i++){var slice=thread.sliceGroup.slices[i];if(useInstead(slice.title,VSYNC_SLICE_PRECISIONS))
-times.push(slice.start);else if(useInstead(slice.title,BEGIN_FRAME_SLICE_PRECISION)&&slice.args.args&&slice.args.args.frame_time_us)
-times.push(slice.args.args.frame_time_us/1000.0);}}}
-times.sort(function(x,y){return x-y;});return times;}};tr.c.Auditor.register(VSyncAuditor);return{VSyncAuditor:VSyncAuditor};});'use strict';tr.exportTo('tr.importer',function(){function EmptyImporter(events){this.importPriority=0;};EmptyImporter.canImport=function(eventData){if(eventData instanceof Array&&eventData.length==0)
-return true;if(typeof(eventData)==='string'||eventData instanceof String){return eventData.length==0;}
-return false;};EmptyImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'EmptyImporter';}};tr.importer.Importer.register(EmptyImporter);return{EmptyImporter:EmptyImporter};});'use strict';tr.exportTo('tr.model.um',function(){function AnimationExpectation(parentModel,initiatorTitle,start,duration){tr.model.um.UserExpectation.call(this,parentModel,initiatorTitle,start,duration);this.frameEvents_=undefined;}
-AnimationExpectation.prototype={__proto__:tr.model.um.UserExpectation.prototype,constructor:AnimationExpectation,get frameEvents(){if(this.frameEvents_)
-return this.frameEvents_;this.frameEvents_=new tr.model.EventSet();this.associatedEvents.forEach(function(event){if(event.title===tr.model.helpers.IMPL_RENDERING_STATS)
-this.frameEvents_.push(event);},this);return this.frameEvents_;}};tr.model.um.UserExpectation.register(AnimationExpectation,{stageTitle:'Animation',colorId:tr.b.ColorScheme.getColorIdForReservedName('rail_animation')});return{AnimationExpectation:AnimationExpectation};});'use strict';tr.exportTo('tr.importer',function(){function ProtoExpectation(irType,name){this.irType=irType;this.names=new Set(name?[name]:undefined);this.start=Infinity;this.end=-Infinity;this.associatedEvents=new tr.model.EventSet();this.isAnimationBegin=false;}
-ProtoExpectation.RESPONSE_TYPE='r';ProtoExpectation.ANIMATION_TYPE='a';ProtoExpectation.IGNORED_TYPE='ignored';ProtoExpectation.prototype={get isValid(){return this.end>this.start;},containsTypeNames:function(typeNames){for(var i=0;i<this.associatedEvents.length;++i){if(typeNames.indexOf(this.associatedEvents[i].typeName)>=0)
-return true;}
-return false;},containsSliceTitle:function(title){for(var i=0;i<this.associatedEvents.length;++i){if(title===this.associatedEvents[i].title)
-return true;}
-return false;},createInteractionRecord:function(model){if(!this.isValid){console.error('Invalid ProtoExpectation: '+this.debug()+' File a bug with this trace!');return undefined;}
-var initiatorTitles=[];this.names.forEach(function(name){initiatorTitles.push(name);});initiatorTitles=initiatorTitles.sort().join(',');var duration=this.end-this.start;var ir=undefined;switch(this.irType){case ProtoExpectation.RESPONSE_TYPE:ir=new tr.model.um.ResponseExpectation(model,initiatorTitles,this.start,duration,this.isAnimationBegin);break;case ProtoExpectation.ANIMATION_TYPE:ir=new tr.model.um.AnimationExpectation(model,initiatorTitles,this.start,duration);break;}
-if(!ir)
-return undefined;ir.sourceEvents.addEventSet(this.associatedEvents);function pushAssociatedEvents(event){ir.associatedEvents.push(event);if(event.associatedEvents)
-ir.associatedEvents.addEventSet(event.associatedEvents);}
-this.associatedEvents.forEach(function(event){pushAssociatedEvents(event);if(event.subSlices)
-event.subSlices.forEach(pushAssociatedEvents);});return ir;},merge:function(other){other.names.forEach(function(name){this.names.add(name);}.bind(this));this.associatedEvents.addEventSet(other.associatedEvents);this.start=Math.min(this.start,other.start);this.end=Math.max(this.end,other.end);if(other.isAnimationBegin)
-this.isAnimationBegin=true;},pushEvent:function(event){this.start=Math.min(this.start,event.start);this.end=Math.max(this.end,event.end);this.associatedEvents.push(event);},containsTimestampInclusive:function(timestamp){return(this.start<=timestamp)&&(timestamp<=this.end);},intersects:function(other){return(other.start<this.end)&&(other.end>this.start);},isNear:function(event,threshold){return(this.end+threshold)>event.start;},debug:function(){var debugString=this.irType+'(';debugString+=parseInt(this.start)+' ';debugString+=parseInt(this.end);this.associatedEvents.forEach(function(event){debugString+=' '+event.typeName;});return debugString+')';}};return{ProtoExpectation:ProtoExpectation};});'use strict';tr.exportTo('tr.importer',function(){var ProtoExpectation=tr.importer.ProtoExpectation;var INPUT_TYPE=tr.e.cc.INPUT_EVENT_TYPE_NAMES;var KEYBOARD_TYPE_NAMES=[INPUT_TYPE.CHAR,INPUT_TYPE.KEY_DOWN_RAW,INPUT_TYPE.KEY_DOWN,INPUT_TYPE.KEY_UP];var MOUSE_RESPONSE_TYPE_NAMES=[INPUT_TYPE.CLICK,INPUT_TYPE.CONTEXT_MENU];var MOUSE_WHEEL_TYPE_NAMES=[INPUT_TYPE.MOUSE_WHEEL];var MOUSE_DRAG_TYPE_NAMES=[INPUT_TYPE.MOUSE_DOWN,INPUT_TYPE.MOUSE_MOVE,INPUT_TYPE.MOUSE_UP];var TAP_TYPE_NAMES=[INPUT_TYPE.TAP,INPUT_TYPE.TAP_CANCEL,INPUT_TYPE.TAP_DOWN];var PINCH_TYPE_NAMES=[INPUT_TYPE.PINCH_BEGIN,INPUT_TYPE.PINCH_END,INPUT_TYPE.PINCH_UPDATE];var FLING_TYPE_NAMES=[INPUT_TYPE.FLING_CANCEL,INPUT_TYPE.FLING_START];var TOUCH_TYPE_NAMES=[INPUT_TYPE.TOUCH_END,INPUT_TYPE.TOUCH_MOVE,INPUT_TYPE.TOUCH_START];var SCROLL_TYPE_NAMES=[INPUT_TYPE.SCROLL_BEGIN,INPUT_TYPE.SCROLL_END,INPUT_TYPE.SCROLL_UPDATE];var ALL_HANDLED_TYPE_NAMES=[].concat(KEYBOARD_TYPE_NAMES,MOUSE_RESPONSE_TYPE_NAMES,MOUSE_WHEEL_TYPE_NAMES,MOUSE_DRAG_TYPE_NAMES,PINCH_TYPE_NAMES,TAP_TYPE_NAMES,FLING_TYPE_NAMES,TOUCH_TYPE_NAMES,SCROLL_TYPE_NAMES);var RENDERER_FLING_TITLE='InputHandlerProxy::HandleGestureFling::started';var CSS_ANIMATION_TITLE='Animation';var INPUT_MERGE_THRESHOLD_MS=200;var ANIMATION_MERGE_THRESHOLD_MS=32;var MOUSE_WHEEL_THRESHOLD_MS=40;var MOUSE_MOVE_THRESHOLD_MS=40;var KEYBOARD_IR_NAME='Keyboard';var MOUSE_IR_NAME='Mouse';var MOUSEWHEEL_IR_NAME='MouseWheel';var TAP_IR_NAME='Tap';var PINCH_IR_NAME='Pinch';var FLING_IR_NAME='Fling';var TOUCH_IR_NAME='Touch';var SCROLL_IR_NAME='Scroll';var CSS_IR_NAME='CSS';function compareEvents(x,y){if(x.start!==y.start)
-return x.start-y.start;if(x.end!==y.end)
-return x.end-y.end;if(x.guid&&y.guid)
-return x.guid-y.guid;return 0;}
+for(const pid in model.processes){const process=model.processes[pid];for(const cid in process.counters){if(useInstead(cid,VSYNC_COUNTER_PRECISIONS)){const counter=process.counters[cid];for(let i=0;i<counter.series.length;i++){const series=counter.series[i];Array.prototype.push.apply(times,series.timestamps);}}}
+for(const tid in process.threads){const thread=process.threads[tid];for(let i=0;i<thread.sliceGroup.slices.length;i++){const slice=thread.sliceGroup.slices[i];if(useInstead(slice.title,VSYNC_SLICE_PRECISIONS)){times.push(slice.start);}else if(useInstead(slice.title,BEGIN_FRAME_SLICE_PRECISION)&&slice.args.args&&slice.args.args.frame_time_us){times.push(slice.args.args.frame_time_us/1000.0);}}}}
+times.sort(function(x,y){return x-y;});return filterDuplicateTimestamps(times);}};tr.c.Auditor.register(VSyncAuditor);return{VSyncAuditor,};});'use strict';tr.exportTo('tr.importer',function(){function EmptyImporter(events){this.importPriority=0;}
+EmptyImporter.canImport=function(eventData){if(eventData instanceof Array&&eventData.length===0){return true;}
+if(typeof(eventData)==='string'||eventData instanceof String){return eventData.length===0;}
+return false;};EmptyImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'EmptyImporter';}};tr.importer.Importer.register(EmptyImporter);return{EmptyImporter,};});'use strict';tr.exportTo('tr.model.um',function(){function AnimationExpectation(parentModel,initiatorTitle,start,duration){tr.model.um.UserExpectation.call(this,parentModel,initiatorTitle,start,duration);this.frameEvents_=undefined;}
+AnimationExpectation.prototype={__proto__:tr.model.um.UserExpectation.prototype,constructor:AnimationExpectation,get frameEvents(){if(this.frameEvents_){return this.frameEvents_;}
+this.frameEvents_=new tr.model.EventSet();this.associatedEvents.forEach(function(event){if(event.title===tr.model.helpers.IMPL_RENDERING_STATS){this.frameEvents_.push(event);}},this);return this.frameEvents_;}};tr.model.um.UserExpectation.subTypes.register(AnimationExpectation,{stageTitle:'Animation',colorId:tr.b.ColorScheme.getColorIdForReservedName('rail_animation')});return{AnimationExpectation,};});'use strict';tr.exportTo('tr.importer',function(){function ProtoExpectation(type,initiatorType){this.type=type;this.initiatorType=initiatorType;this.start=Infinity;this.end=-Infinity;this.associatedEvents=new tr.model.EventSet();this.isAnimationBegin=false;}
+ProtoExpectation.RESPONSE_TYPE='r';ProtoExpectation.ANIMATION_TYPE='a';ProtoExpectation.IGNORED_TYPE='ignored';const INITIATOR_HIERARCHY=[tr.model.um.INITIATOR_TYPE.PINCH,tr.model.um.INITIATOR_TYPE.FLING,tr.model.um.INITIATOR_TYPE.MOUSE_WHEEL,tr.model.um.INITIATOR_TYPE.SCROLL,tr.model.um.INITIATOR_TYPE.VR,tr.model.um.INITIATOR_TYPE.VIDEO,tr.model.um.INITIATOR_TYPE.WEBGL,tr.model.um.INITIATOR_TYPE.CSS,tr.model.um.INITIATOR_TYPE.MOUSE,tr.model.um.INITIATOR_TYPE.KEYBOARD,tr.model.um.INITIATOR_TYPE.TAP,tr.model.um.INITIATOR_TYPE.TOUCH];function combineInitiatorTypes(title1,title2){for(const item of INITIATOR_HIERARCHY){if(title1===item||title2===item)return item;}
+throw new Error('Invalid titles in combineInitiatorTypes');}
+ProtoExpectation.prototype={get isValid(){return this.end>this.start;},containsTypeNames(typeNames){return this.associatedEvents.some(x=>typeNames.indexOf(x.typeName)>=0);},containsSliceTitle(title){return this.associatedEvents.some(x=>title===x.title);},createInteractionRecord(model){if(this.type!==ProtoExpectation.IGNORED_TYPE&&!this.isValid){model.importWarning({type:'ProtoExpectation',message:'Please file a bug with this trace. '+this.debug(),showToUser:true});return undefined;}
+const duration=this.end-this.start;let ir=undefined;switch(this.type){case ProtoExpectation.RESPONSE_TYPE:ir=new tr.model.um.ResponseExpectation(model,this.initiatorType,this.start,duration,this.isAnimationBegin);break;case ProtoExpectation.ANIMATION_TYPE:ir=new tr.model.um.AnimationExpectation(model,this.initiatorType,this.start,duration);break;}
+if(!ir)return undefined;ir.sourceEvents.addEventSet(this.associatedEvents);function pushAssociatedEvents(event){ir.associatedEvents.push(event);if(event.associatedEvents){ir.associatedEvents.addEventSet(event.associatedEvents);}}
+this.associatedEvents.forEach(function(event){pushAssociatedEvents(event);if(event.subSlices){event.subSlices.forEach(pushAssociatedEvents);}});return ir;},merge(other){this.initiatorType=combineInitiatorTypes(this.initiatorType,other.initiatorType);this.associatedEvents.addEventSet(other.associatedEvents);this.start=Math.min(this.start,other.start);this.end=Math.max(this.end,other.end);if(other.isAnimationBegin){this.isAnimationBegin=true;}},pushEvent(event){this.start=Math.min(this.start,event.start);this.end=Math.max(this.end,event.end);this.associatedEvents.push(event);},pushSample(sample){this.start=Math.min(this.start,sample.timestamp);this.end=Math.max(this.end,sample.timestamp);this.associatedEvents.push(sample);},containsTimestampInclusive(timestamp){return(this.start<=timestamp)&&(timestamp<=this.end);},intersects(other){return(other.start<this.end)&&(other.end>this.start);},isNear(event,threshold){return(this.end+threshold)>event.start;},debug(){let debugString=this.type+'(';debugString+=parseInt(this.start)+' ';debugString+=parseInt(this.end);this.associatedEvents.forEach(function(event){debugString+=' '+event.typeName;});return debugString+')';}};return{ProtoExpectation,};});'use strict';tr.exportTo('tr.importer',function(){const ProtoExpectation=tr.importer.ProtoExpectation;const INITIATOR_TYPE=tr.model.um.INITIATOR_TYPE;const INPUT_TYPE=tr.e.cc.INPUT_EVENT_TYPE_NAMES;const KEYBOARD_TYPE_NAMES=[INPUT_TYPE.CHAR,INPUT_TYPE.KEY_DOWN_RAW,INPUT_TYPE.KEY_DOWN,INPUT_TYPE.KEY_UP];const MOUSE_RESPONSE_TYPE_NAMES=[INPUT_TYPE.CLICK,INPUT_TYPE.CONTEXT_MENU];const MOUSE_WHEEL_TYPE_NAMES=[INPUT_TYPE.MOUSE_WHEEL];const MOUSE_DRAG_TYPE_NAMES=[INPUT_TYPE.MOUSE_DOWN,INPUT_TYPE.MOUSE_MOVE,INPUT_TYPE.MOUSE_UP];const TAP_TYPE_NAMES=[INPUT_TYPE.TAP,INPUT_TYPE.TAP_CANCEL,INPUT_TYPE.TAP_DOWN];const PINCH_TYPE_NAMES=[INPUT_TYPE.PINCH_BEGIN,INPUT_TYPE.PINCH_END,INPUT_TYPE.PINCH_UPDATE];const FLING_TYPE_NAMES=[INPUT_TYPE.FLING_CANCEL,INPUT_TYPE.FLING_START];const TOUCH_TYPE_NAMES=[INPUT_TYPE.TOUCH_END,INPUT_TYPE.TOUCH_MOVE,INPUT_TYPE.TOUCH_START];const SCROLL_TYPE_NAMES=[INPUT_TYPE.SCROLL_BEGIN,INPUT_TYPE.SCROLL_END,INPUT_TYPE.SCROLL_UPDATE];const ALL_HANDLED_TYPE_NAMES=[].concat(KEYBOARD_TYPE_NAMES,MOUSE_RESPONSE_TYPE_NAMES,MOUSE_WHEEL_TYPE_NAMES,MOUSE_DRAG_TYPE_NAMES,PINCH_TYPE_NAMES,TAP_TYPE_NAMES,FLING_TYPE_NAMES,TOUCH_TYPE_NAMES,SCROLL_TYPE_NAMES);const RENDERER_FLING_TITLE='InputHandlerProxy::HandleGestureFling::started';const PLAYBACK_EVENT_TITLE='VideoPlayback';const CSS_ANIMATION_TITLE='Animation';const VR_COUNTER_NAMES=['gpu.WebVR FPS','gpu.WebVR frame time (ms)','gpu.WebVR pose prediction (ms)','gpu.WebXR FPS',];const VR_EXPECTATION_EVENTS={'Vr.AcquireGvrFrame':{'histogramName':'acquire_frame','description':'Duration acquire a frame from GVR','hasCpuTime':true,},'Vr.DrawFrame':{'histogramName':'draw_frame','description':'Duration to render one frame','hasCpuTime':true,},'Vr.PostSubmitDrawOnGpu':{'histogramName':'post_submit_draw_on_gpu','description':'Duration to draw a frame on GPU post submit to '+'GVR. Note this duration may include time spent on '+'reprojection','hasCpuTime':false,},'Vr.ProcessControllerInput':{'histogramName':'update_controller','description':'Duration to query input from the controller','hasCpuTime':true,},'Vr.ProcessControllerInputForWebXr':{'histogramName':'update_controller_webxr','description':'Duration to query input from the controller for WebXR','hasCpuTime':true,},'Vr.SubmitFrameNow':{'histogramName':'submit_frame','description':'Duration to submit a frame to GVR','hasCpuTime':true,}};const WEBXR_INSTANT_EVENTS={'WebXR frame time (ms)':{'javascript':{'histogramName':'webxr_frame_time_javascript','description':'WebXR frame time spent on JavaScript',},'rendering':{'histogramName':'webxr_frame_time_rendering','description':'WebXR frame time spent on rendering'}},'WebXR pose prediction':{'milliseconds':{'histogramName':'webxr_pose_prediction','description':'WebXR pose prediction in ms',},},};const XR_DEVICE_SERVICE_PROCESS='Service: xr_device_service';function isXrDeviceServiceProcess(process){if(process.name===XR_DEVICE_SERVICE_PROCESS)return true;return false;}
+const VR_RESPONSE_MS=1000;const INPUT_MERGE_THRESHOLD_MS=200;const ANIMATION_MERGE_THRESHOLD_MS=32;const MOUSE_WHEEL_THRESHOLD_MS=40;const MOUSE_MOVE_THRESHOLD_MS=40;function compareEvents(x,y){if(x.start!==y.start){return x.start-y.start;}
+if(x.end!==y.end){return x.end-y.end;}
+if(x.guid&&y.guid){return x.guid-y.guid;}
+return 0;}
 function forEventTypesIn(events,typeNames,cb,opt_this){events.forEach(function(event){if(typeNames.indexOf(event.typeName)>=0){cb.call(opt_this,event);}});}
-function causedFrame(event){for(var i=0;i<event.associatedEvents.length;++i){if(event.associatedEvents[i].title===tr.model.helpers.IMPL_RENDERING_STATS)
-return true;}
-return false;}
-function getSortedInputEvents(modelHelper){var inputEvents=[];var browserProcess=modelHelper.browserHelper.process;var mainThread=browserProcess.findAtMostOneThreadNamed('CrBrowserMain');mainThread.asyncSliceGroup.iterateAllEvents(function(slice){if(!slice.isTopLevel)
-return;if(!(slice instanceof tr.e.cc.InputLatencyAsyncSlice))
-return;if(isNaN(slice.start)||isNaN(slice.duration)||isNaN(slice.end))
-return;inputEvents.push(slice);});return inputEvents.sort(compareEvents);}
-function findProtoExpectations(modelHelper,sortedInputEvents){var protoExpectations=[];var handlers=[handleKeyboardEvents,handleMouseResponseEvents,handleMouseWheelEvents,handleMouseDragEvents,handleTapResponseEvents,handlePinchEvents,handleFlingEvents,handleTouchEvents,handleScrollEvents,handleCSSAnimations];handlers.forEach(function(handler){protoExpectations.push.apply(protoExpectations,handler(modelHelper,sortedInputEvents));});protoExpectations.sort(compareEvents);return protoExpectations;}
-function handleKeyboardEvents(modelHelper,sortedInputEvents){var protoExpectations=[];forEventTypesIn(sortedInputEvents,KEYBOARD_TYPE_NAMES,function(event){var pe=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,KEYBOARD_IR_NAME);pe.pushEvent(event);protoExpectations.push(pe);});return protoExpectations;}
-function handleMouseResponseEvents(modelHelper,sortedInputEvents){var protoExpectations=[];forEventTypesIn(sortedInputEvents,MOUSE_RESPONSE_TYPE_NAMES,function(event){var pe=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,MOUSE_IR_NAME);pe.pushEvent(event);protoExpectations.push(pe);});return protoExpectations;}
-function handleMouseWheelEvents(modelHelper,sortedInputEvents){var protoExpectations=[];var currentPE=undefined;var prevEvent_=undefined;forEventTypesIn(sortedInputEvents,MOUSE_WHEEL_TYPE_NAMES,function(event){var prevEvent=prevEvent_;prevEvent_=event;if(currentPE&&(prevEvent.start+MOUSE_WHEEL_THRESHOLD_MS)>=event.start){if(currentPE.irType===ProtoExpectation.ANIMATION_TYPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,MOUSEWHEEL_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
+function causedFrame(event){return event.associatedEvents.some(isImplFrameEvent);}
+function getSortedFrameEventsByProcess(modelHelper){const frameEventsByPid={};for(const[pid,rendererHelper]of
+Object.entries(modelHelper.rendererHelpers)){frameEventsByPid[pid]=rendererHelper.getFrameEventsInRange(tr.model.helpers.IMPL_FRAMETIME_TYPE,modelHelper.model.bounds);}
+return frameEventsByPid;}
+function getSortedInputEvents(modelHelper){const inputEvents=[];const browserProcess=modelHelper.browserHelper.process;const mainThread=browserProcess.findAtMostOneThreadNamed('CrBrowserMain');for(const slice of mainThread.asyncSliceGroup.getDescendantEvents()){if(!slice.isTopLevel)continue;if(!(slice instanceof tr.e.cc.InputLatencyAsyncSlice))continue;if(isNaN(slice.start)||isNaN(slice.duration)||isNaN(slice.end)){continue;}
+inputEvents.push(slice);}
+return inputEvents.sort(compareEvents);}
+function findProtoExpectations(modelHelper,sortedInputEvents,warn){const protoExpectations=[];const handlers=[handleKeyboardEvents,handleMouseResponseEvents,handleMouseWheelEvents,handleMouseDragEvents,handleTapResponseEvents,handlePinchEvents,handleFlingEvents,handleTouchEvents,handleScrollEvents,handleCSSAnimations,handleWebGLAnimations,handleVideoAnimations,handleVrAnimations,];handlers.forEach(function(handler){protoExpectations.push.apply(protoExpectations,handler(modelHelper,sortedInputEvents,warn));});protoExpectations.sort(compareEvents);return protoExpectations;}
+function handleKeyboardEvents(modelHelper,sortedInputEvents,warn){const protoExpectations=[];forEventTypesIn(sortedInputEvents,KEYBOARD_TYPE_NAMES,function(event){const pe=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.KEYBOARD);pe.pushEvent(event);protoExpectations.push(pe);});return protoExpectations;}
+function handleMouseResponseEvents(modelHelper,sortedInputEvents,warn){const protoExpectations=[];forEventTypesIn(sortedInputEvents,MOUSE_RESPONSE_TYPE_NAMES,function(event){const pe=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.MOUSE);pe.pushEvent(event);protoExpectations.push(pe);});return protoExpectations;}
+function handleMouseWheelEvents(modelHelper,sortedInputEvents,warn){const protoExpectations=[];let currentPE=undefined;let prevEvent_=undefined;forEventTypesIn(sortedInputEvents,MOUSE_WHEEL_TYPE_NAMES,function(event){const prevEvent=prevEvent_;prevEvent_=event;if(currentPE&&(prevEvent.start+MOUSE_WHEEL_THRESHOLD_MS)>=event.start){if(currentPE.type===ProtoExpectation.ANIMATION_TYPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.MOUSE_WHEEL);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
 return;}
-currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,MOUSEWHEEL_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);});return protoExpectations;}
-function handleMouseDragEvents(modelHelper,sortedInputEvents){var protoExpectations=[];var currentPE=undefined;var mouseDownEvent=undefined;forEventTypesIn(sortedInputEvents,MOUSE_DRAG_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.MOUSE_DOWN:if(causedFrame(event)){var pe=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,MOUSE_IR_NAME);pe.pushEvent(event);protoExpectations.push(pe);}else{mouseDownEvent=event;}
-break;case INPUT_TYPE.MOUSE_MOVE:if(!causedFrame(event)){var pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);}else if(!currentPE||!currentPE.isNear(event,MOUSE_MOVE_THRESHOLD_MS)){currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,MOUSE_IR_NAME);currentPE.pushEvent(event);if(mouseDownEvent){currentPE.associatedEvents.push(mouseDownEvent);mouseDownEvent=undefined;}
-protoExpectations.push(currentPE);}else{if(currentPE.irType===ProtoExpectation.ANIMATION_TYPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,MOUSE_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);}}
-break;case INPUT_TYPE.MOUSE_UP:if(!mouseDownEvent){var pe=new ProtoExpectation(causedFrame(event)?ProtoExpectation.RESPONSE_TYPE:ProtoExpectation.IGNORED_TYPE,MOUSE_IR_NAME);pe.pushEvent(event);protoExpectations.push(pe);break;}
-if(currentPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,MOUSE_IR_NAME);if(mouseDownEvent)
-currentPE.associatedEvents.push(mouseDownEvent);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
+currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.MOUSE_WHEEL);currentPE.pushEvent(event);protoExpectations.push(currentPE);});return protoExpectations;}
+function handleMouseDragEvents(modelHelper,sortedInputEvents,warn){const protoExpectations=[];let currentPE=undefined;let mouseDownEvent=undefined;forEventTypesIn(sortedInputEvents,MOUSE_DRAG_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.MOUSE_DOWN:if(causedFrame(event)){const pe=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.MOUSE);pe.pushEvent(event);protoExpectations.push(pe);}else{mouseDownEvent=event;}
+break;case INPUT_TYPE.MOUSE_MOVE:if(!causedFrame(event)){const pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);}else if(!currentPE||!currentPE.isNear(event,MOUSE_MOVE_THRESHOLD_MS)){currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.MOUSE);currentPE.pushEvent(event);if(mouseDownEvent){currentPE.associatedEvents.push(mouseDownEvent);mouseDownEvent=undefined;}
+protoExpectations.push(currentPE);}else{if(currentPE.type===ProtoExpectation.ANIMATION_TYPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.MOUSE);currentPE.pushEvent(event);protoExpectations.push(currentPE);}}
+break;case INPUT_TYPE.MOUSE_UP:if(!mouseDownEvent){const pe=new ProtoExpectation(causedFrame(event)?ProtoExpectation.RESPONSE_TYPE:ProtoExpectation.IGNORED_TYPE,INITIATOR_TYPE.MOUSE);pe.pushEvent(event);protoExpectations.push(pe);break;}
+if(currentPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.MOUSE);if(mouseDownEvent){currentPE.associatedEvents.push(mouseDownEvent);}
+currentPE.pushEvent(event);protoExpectations.push(currentPE);}
 mouseDownEvent=undefined;currentPE=undefined;break;}});if(mouseDownEvent){currentPE=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);currentPE.pushEvent(mouseDownEvent);protoExpectations.push(currentPE);}
 return protoExpectations;}
-function handleTapResponseEvents(modelHelper,sortedInputEvents){var protoExpectations=[];var currentPE=undefined;forEventTypesIn(sortedInputEvents,TAP_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.TAP_DOWN:currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,TAP_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);break;case INPUT_TYPE.TAP:if(currentPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,TAP_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
-currentPE=undefined;break;case INPUT_TYPE.TAP_CANCEL:if(!currentPE){var pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);break;}
-if(currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,TAP_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
+function handleTapResponseEvents(modelHelper,sortedInputEvents,warn){const protoExpectations=[];let currentPE=undefined;forEventTypesIn(sortedInputEvents,TAP_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.TAP_DOWN:currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.TAP);currentPE.pushEvent(event);protoExpectations.push(currentPE);break;case INPUT_TYPE.TAP:if(currentPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.TAP);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
+currentPE=undefined;break;case INPUT_TYPE.TAP_CANCEL:if(!currentPE){const pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);break;}
+if(currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.TAP);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
 currentPE=undefined;break;}});return protoExpectations;}
-function handlePinchEvents(modelHelper,sortedInputEvents){var protoExpectations=[];var currentPE=undefined;var sawFirstUpdate=false;var modelBounds=modelHelper.model.bounds;forEventTypesIn(sortedInputEvents,PINCH_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.PINCH_BEGIN:if(currentPE&&currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPE.pushEvent(event);break;}
-currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,PINCH_IR_NAME);currentPE.pushEvent(event);currentPE.isAnimationBegin=true;protoExpectations.push(currentPE);sawFirstUpdate=false;break;case INPUT_TYPE.PINCH_UPDATE:if(!currentPE||((currentPE.irType===ProtoExpectation.RESPONSE_TYPE)&&sawFirstUpdate)||!currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,PINCH_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);}else{currentPE.pushEvent(event);sawFirstUpdate=true;}
-break;case INPUT_TYPE.PINCH_END:if(currentPE){currentPE.pushEvent(event);}else{var pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);}
+function handlePinchEvents(modelHelper,sortedInputEvents,warn){const protoExpectations=[];let currentPE=undefined;let sawFirstUpdate=false;const modelBounds=modelHelper.model.bounds;forEventTypesIn(sortedInputEvents,PINCH_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.PINCH_BEGIN:if(currentPE&&currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPE.pushEvent(event);break;}
+currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.PINCH);currentPE.pushEvent(event);currentPE.isAnimationBegin=true;protoExpectations.push(currentPE);sawFirstUpdate=false;break;case INPUT_TYPE.PINCH_UPDATE:if(!currentPE||((currentPE.type===ProtoExpectation.RESPONSE_TYPE)&&sawFirstUpdate)||!currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.PINCH);currentPE.pushEvent(event);protoExpectations.push(currentPE);}else{currentPE.pushEvent(event);sawFirstUpdate=true;}
+break;case INPUT_TYPE.PINCH_END:if(currentPE){currentPE.pushEvent(event);}else{const pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);}
 currentPE=undefined;break;}});return protoExpectations;}
-function handleFlingEvents(modelHelper,sortedInputEvents){var protoExpectations=[];var currentPE=undefined;function isRendererFling(event){return event.title===RENDERER_FLING_TITLE;}
-var browserHelper=modelHelper.browserHelper;var flingEvents=browserHelper.getAllAsyncSlicesMatching(isRendererFling);forEventTypesIn(sortedInputEvents,FLING_TYPE_NAMES,function(event){flingEvents.push(event);});flingEvents.sort(compareEvents);flingEvents.forEach(function(event){if(event.title===RENDERER_FLING_TITLE){if(currentPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,FLING_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
+function handleFlingEvents(modelHelper,sortedInputEvents,warn){const protoExpectations=[];let currentPE=undefined;function isRendererFling(event){return event.title===RENDERER_FLING_TITLE;}
+const browserHelper=modelHelper.browserHelper;const flingEvents=browserHelper.getAllAsyncSlicesMatching(isRendererFling);forEventTypesIn(sortedInputEvents,FLING_TYPE_NAMES,function(event){flingEvents.push(event);});flingEvents.sort(compareEvents);flingEvents.forEach(function(event){if(event.title===RENDERER_FLING_TITLE){if(currentPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.FLING);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
 return;}
-switch(event.typeName){case INPUT_TYPE.FLING_START:if(currentPE){console.error('Another FlingStart? File a bug with this trace!');currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,FLING_IR_NAME);currentPE.pushEvent(event);currentPE.end=0;protoExpectations.push(currentPE);}
-break;case INPUT_TYPE.FLING_CANCEL:if(currentPE){currentPE.pushEvent(event);currentPE.end=event.start;currentPE=undefined;}else{var pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);}
-break;}});if(currentPE&&!currentPE.end)
-currentPE.end=modelHelper.model.bounds.max;return protoExpectations;}
-function handleTouchEvents(modelHelper,sortedInputEvents){var protoExpectations=[];var currentPE=undefined;var sawFirstMove=false;forEventTypesIn(sortedInputEvents,TOUCH_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.TOUCH_START:if(currentPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,TOUCH_IR_NAME);currentPE.pushEvent(event);currentPE.isAnimationBegin=true;protoExpectations.push(currentPE);sawFirstMove=false;}
-break;case INPUT_TYPE.TOUCH_MOVE:if(!currentPE){currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,TOUCH_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);break;}
-if((sawFirstMove&&(currentPE.irType===ProtoExpectation.RESPONSE_TYPE))||!currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){var prevEnd=currentPE.end;currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,TOUCH_IR_NAME);currentPE.pushEvent(event);currentPE.start=prevEnd;protoExpectations.push(currentPE);}else{currentPE.pushEvent(event);sawFirstMove=true;}
-break;case INPUT_TYPE.TOUCH_END:if(!currentPE){var pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);break;}
-if(currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPE.pushEvent(event);}else{var pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);}
+switch(event.typeName){case INPUT_TYPE.FLING_START:if(currentPE){warn({type:'UserModelBuilder',message:'Unexpected FlingStart',showToUser:false,});currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.FLING);currentPE.pushEvent(event);currentPE.end=0;protoExpectations.push(currentPE);}
+break;case INPUT_TYPE.FLING_CANCEL:if(currentPE){currentPE.pushEvent(event);currentPE.end=event.start;currentPE=undefined;}else{const pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);}
+break;}});if(currentPE&&!currentPE.end){currentPE.end=modelHelper.model.bounds.max;}
+return protoExpectations;}
+function handleTouchEvents(modelHelper,sortedInputEvents,warn){const protoExpectations=[];let currentPE=undefined;let sawFirstMove=false;forEventTypesIn(sortedInputEvents,TOUCH_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.TOUCH_START:if(currentPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.TOUCH);currentPE.pushEvent(event);currentPE.isAnimationBegin=true;protoExpectations.push(currentPE);sawFirstMove=false;}
+break;case INPUT_TYPE.TOUCH_MOVE:if(!currentPE){currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.TOUCH);currentPE.pushEvent(event);protoExpectations.push(currentPE);break;}
+if((sawFirstMove&&(currentPE.type===ProtoExpectation.RESPONSE_TYPE))||!currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){const prevEnd=currentPE.end;currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.TOUCH);currentPE.pushEvent(event);currentPE.start=prevEnd;protoExpectations.push(currentPE);}else{currentPE.pushEvent(event);sawFirstMove=true;}
+break;case INPUT_TYPE.TOUCH_END:if(!currentPE){const pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);break;}
+if(currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPE.pushEvent(event);}else{const pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);}
 currentPE=undefined;break;}});return protoExpectations;}
-function handleScrollEvents(modelHelper,sortedInputEvents){var protoExpectations=[];var currentPE=undefined;var sawFirstUpdate=false;forEventTypesIn(sortedInputEvents,SCROLL_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.SCROLL_BEGIN:currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,SCROLL_IR_NAME);currentPE.pushEvent(event);currentPE.isAnimationBegin=true;protoExpectations.push(currentPE);sawFirstUpdate=false;break;case INPUT_TYPE.SCROLL_UPDATE:if(currentPE){if(currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)&&((currentPE.irType===ProtoExpectation.ANIMATION_TYPE)||!sawFirstUpdate)){currentPE.pushEvent(event);sawFirstUpdate=true;}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,SCROLL_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);}}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,SCROLL_IR_NAME);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
-break;case INPUT_TYPE.SCROLL_END:if(!currentPE){console.error('ScrollEnd without ScrollUpdate? '+'File a bug with this trace!');var pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);break;}
+function handleScrollEvents(modelHelper,sortedInputEvents,warn){const protoExpectations=[];let currentPE=undefined;let sawFirstUpdate=false;forEventTypesIn(sortedInputEvents,SCROLL_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.SCROLL_BEGIN:currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.SCROLL);currentPE.pushEvent(event);currentPE.isAnimationBegin=true;protoExpectations.push(currentPE);sawFirstUpdate=false;break;case INPUT_TYPE.SCROLL_UPDATE:if(currentPE){if(currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)&&((currentPE.type===ProtoExpectation.ANIMATION_TYPE)||!sawFirstUpdate)){currentPE.pushEvent(event);sawFirstUpdate=true;}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.SCROLL);currentPE.pushEvent(event);protoExpectations.push(currentPE);}}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.SCROLL);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
+break;case INPUT_TYPE.SCROLL_END:if(!currentPE){warn({type:'UserModelBuilder',message:'Unexpected ScrollEnd',showToUser:false,});const pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);break;}
 currentPE.pushEvent(event);break;}});return protoExpectations;}
-function handleCSSAnimations(modelHelper,sortedInputEvents){var animationEvents=modelHelper.browserHelper.getAllAsyncSlicesMatching(function(event){return((event.title===CSS_ANIMATION_TITLE)&&event.isTopLevel&&(event.duration>0));});var framesForProcess={};function getFramesForAnimationProcess(animation){var frames=framesForProcess[animation.parentContainer.parent.guid];if(frames===undefined){var rendererHelper=new tr.model.helpers.ChromeRendererHelper(modelHelper,animation.parentContainer.parent);frames=rendererHelper.getFrameEventsInRange(tr.model.helpers.IMPL_FRAMETIME_TYPE,modelHelper.model.bounds);framesForProcess[animation.parentContainer.parent.guid]=frames;}
-return frames;}
-var animationRanges=[];function pushAnimationRange(start,end,animation){var range=tr.b.Range.fromExplicitRange(start,end);range.animation=animation;range.frames=range.filterArray(getFramesForAnimationProcess(animation),function(frameEvent){return frameEvent.start;});if(range.frames.length===0)
-return;animationRanges.push(range);}
-animationEvents.forEach(function(animation){if(animation.subSlices.length===0){pushAnimationRange(animation.start,animation.end,animation);}else{var start=undefined;animation.subSlices.forEach(function(sub){if((sub.args.state==='running')&&(start===undefined)){start=sub.start;}else if((sub.args.state==='paused')||(sub.args.state==='idle')||(sub.args.state==='finished')){if(start===undefined){start=modelHelper.model.bounds.min;}
-pushAnimationRange(start,sub.start,animation);start=undefined;}});if(start!==undefined)
-pushAnimationRange(start,modelHelper.model.bounds.max,animation);}});function merge(ranges){var protoExpectation=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,CSS_IR_NAME);ranges.forEach(function(range){protoExpectation.start=Math.min(protoExpectation.start,range.min);protoExpectation.end=Math.max(protoExpectation.end,range.max);protoExpectation.associatedEvents.push(range.animation);protoExpectation.associatedEvents.addEventSet(range.frames);});return protoExpectation;}
-return tr.b.mergeRanges(animationRanges,ANIMATION_MERGE_THRESHOLD_MS,merge);}
-function postProcessProtoExpectations(protoExpectations){protoExpectations=mergeIntersectingResponses(protoExpectations);protoExpectations=mergeIntersectingAnimations(protoExpectations);protoExpectations=fixResponseAnimationStarts(protoExpectations);protoExpectations=fixTapResponseTouchAnimations(protoExpectations);return protoExpectations;}
-function mergeIntersectingResponses(protoExpectations){var newPEs=[];while(protoExpectations.length){var pe=protoExpectations.shift();newPEs.push(pe);if(pe.irType!==ProtoExpectation.RESPONSE_TYPE)
-continue;for(var i=0;i<protoExpectations.length;++i){var otherPE=protoExpectations[i];if(otherPE.irType!==pe.irType)
-continue;if(!otherPE.intersects(pe))
-continue;var typeNames=pe.associatedEvents.map(function(event){return event.typeName;});if(otherPE.containsTypeNames(typeNames))
-continue;pe.merge(otherPE);protoExpectations.splice(i,1);--i;}}
+function handleVideoAnimations(modelHelper,sortedInputEvents,warn){const events=[];for(const pid in modelHelper.rendererHelpers){for(const tid in modelHelper.rendererHelpers[pid].process.threads){for(const asyncSlice of
+modelHelper.rendererHelpers[pid].process.threads[tid].asyncSliceGroup.slices){if(asyncSlice.title===PLAYBACK_EVENT_TITLE){events.push(asyncSlice);}}}}
+events.sort(tr.importer.compareEvents);const protoExpectations=[];for(const event of events){const currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.VIDEO);currentPE.start=event.start;currentPE.end=event.end;currentPE.pushEvent(event);protoExpectations.push(currentPE);}
+return protoExpectations;}
+function handleVrAnimations(modelHelper,sortedInputEvents,warn){const events=[];const processes=[];if(typeof modelHelper.gpuHelper!=='undefined'){processes.push(modelHelper.gpuHelper.process);}
+for(const helper of Object.values(modelHelper.rendererHelpers)){processes.push(helper.process);}
+for(const helper of Object.values(modelHelper.browserHelpers)){processes.push(helper.process);}
+for(const service of modelHelper.model.getAllProcesses(isXrDeviceServiceProcess)){processes.push(service);}
+let vrCounterStart=Number.MAX_SAFE_INTEGER;let vrEventStart=Number.MAX_SAFE_INTEGER;for(const proc of processes){for(const[counterName,counterSeries]of
+Object.entries(proc.counters)){if(VR_COUNTER_NAMES.includes(counterName)){for(const series of counterSeries.series){for(const sample of series.samples){events.push(sample);vrCounterStart=Math.min(vrCounterStart,sample.timestamp);}}}}
+for(const thread of Object.values(proc.threads)){for(const container of thread.childEventContainers()){for(const slice of container.slices){if(slice.title in VR_EXPECTATION_EVENTS||slice.title in WEBXR_INSTANT_EVENTS){events.push(slice);vrEventStart=Math.min(vrEventStart,slice.start);}}}}}
+if(events.length===0){return[];}
+events.sort(function(x,y){if(x.range.min!==y.range.min){return x.range.min-y.range.min;}
+return x.guid-y.guid;});vrCounterStart=(vrCounterStart===Number.MAX_SAFE_INTEGER)?0:vrCounterStart;vrEventStart=(vrEventStart===Number.MAX_SAFE_INTEGER)?0:vrEventStart;const vrAnimationStart=Math.max(vrCounterStart,vrEventStart)+
+VR_RESPONSE_MS;const responsePE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.VR);const animationPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.VR);let lastResponseEvent;for(const event of events){if(event.range.min<vrAnimationStart){if(event instanceof tr.model.CounterSample){responsePE.pushSample(event);}else{responsePE.pushEvent(event);}
+lastResponseEvent=event;}else{if(event instanceof tr.model.CounterSample){animationPE.pushSample(event);}else{animationPE.pushEvent(event);}}}
+if(lastResponseEvent instanceof tr.model.CounterSample){animationPE.pushSample(lastResponseEvent);}else{animationPE.pushEvent(lastResponseEvent);}
+return[responsePE,animationPE];}
+function handleCSSAnimations(modelHelper,sortedInputEvents,warn){const animationEvents=modelHelper.browserHelper.getAllAsyncSlicesMatching(function(event){return((event.title===CSS_ANIMATION_TITLE)&&event.isTopLevel&&(event.duration>0));});const animationRanges=[];function pushAnimationRange(start,end,animation){const range=tr.b.math.Range.fromExplicitRange(start,end);range.animation=animation;animationRanges.push(range);}
+animationEvents.forEach(function(animation){if(animation.subSlices.length===0){pushAnimationRange(animation.start,animation.end,animation);}else{let start=undefined;animation.subSlices.forEach(function(sub){if((sub.args.data.state==='running')&&(start===undefined)){start=sub.start;}else if((sub.args.data.state==='paused')||(sub.args.data.state==='idle')||(sub.args.data.state==='finished')){if(start===undefined){start=modelHelper.model.bounds.min;}
+pushAnimationRange(start,sub.start,animation);start=undefined;}});if(start!==undefined){pushAnimationRange(start,animation.end,animation);}}});return animationRanges.map(function(range){const protoExpectation=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.CSS);protoExpectation.start=range.min;protoExpectation.end=range.max;protoExpectation.associatedEvents.push(range.animation);return protoExpectation;});}
+function findWebGLEvents(modelHelper,mailboxEvents,animationEvents){for(const event of modelHelper.model.getDescendantEvents()){if(event.title==='DrawingBuffer::prepareMailbox'){mailboxEvents.push(event);}else if(event.title==='PageAnimator::serviceScriptedAnimations'){animationEvents.push(event);}}}
+function findMailboxEventsNearAnimationEvents(mailboxEvents,animationEvents){if(animationEvents.length===0)return[];mailboxEvents.sort(compareEvents);animationEvents.sort(compareEvents);const animationIterator=animationEvents[Symbol.iterator]();let animationEvent=animationIterator.next().value;const filteredEvents=[];for(const event of mailboxEvents){while(animationEvent&&(animationEvent.start<(event.start-ANIMATION_MERGE_THRESHOLD_MS))){animationEvent=animationIterator.next().value;}
+if(!animationEvent)break;if(animationEvent.start<(event.start+ANIMATION_MERGE_THRESHOLD_MS)){filteredEvents.push(event);}}
+return filteredEvents;}
+function createProtoExpectationsFromMailboxEvents(mailboxEvents){const protoExpectations=[];let currentPE=undefined;for(const event of mailboxEvents){if(currentPE===undefined||!currentPE.isNear(event,ANIMATION_MERGE_THRESHOLD_MS)){currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.WEBGL);currentPE.pushEvent(event);protoExpectations.push(currentPE);}else{currentPE.pushEvent(event);}}
+return protoExpectations;}
+function handleWebGLAnimations(modelHelper,sortedInputEvents,warn){const prepareMailboxEvents=[];const scriptedAnimationEvents=[];findWebGLEvents(modelHelper,prepareMailboxEvents,scriptedAnimationEvents);const webGLMailboxEvents=findMailboxEventsNearAnimationEvents(prepareMailboxEvents,scriptedAnimationEvents);return createProtoExpectationsFromMailboxEvents(webGLMailboxEvents);}
+function postProcessProtoExpectations(modelHelper,protoExpectations){protoExpectations=findFrameEventsForAnimations(modelHelper,protoExpectations);protoExpectations=mergeIntersectingResponses(protoExpectations);protoExpectations=mergeIntersectingAnimations(protoExpectations);protoExpectations=fixResponseAnimationStarts(protoExpectations);protoExpectations=fixTapResponseTouchAnimations(protoExpectations);return protoExpectations;}
+function mergeIntersectingResponses(protoExpectations){const newPEs=[];while(protoExpectations.length){const pe=protoExpectations.shift();newPEs.push(pe);if(pe.type!==ProtoExpectation.RESPONSE_TYPE)continue;for(let i=0;i<protoExpectations.length;++i){const otherPE=protoExpectations[i];if(otherPE.type!==pe.type)continue;if(!otherPE.intersects(pe))continue;const typeNames=pe.associatedEvents.map(function(event){return event.typeName;});if(otherPE.containsTypeNames(typeNames))continue;pe.merge(otherPE);protoExpectations.splice(i,1);--i;}}
 return newPEs;}
-function mergeIntersectingAnimations(protoExpectations){var newPEs=[];while(protoExpectations.length){var pe=protoExpectations.shift();newPEs.push(pe);if(pe.irType!==ProtoExpectation.ANIMATION_TYPE)
-continue;var isCSS=pe.containsSliceTitle(CSS_ANIMATION_TITLE);var isFling=pe.containsTypeNames([INPUT_TYPE.FLING_START]);for(var i=0;i<protoExpectations.length;++i){var otherPE=protoExpectations[i];if(otherPE.irType!==pe.irType)
-continue;if(isCSS!=otherPE.containsSliceTitle(CSS_ANIMATION_TITLE))
-continue;if(!otherPE.intersects(pe))
-continue;if(isFling!=otherPE.containsTypeNames([INPUT_TYPE.FLING_START]))
-continue;pe.merge(otherPE);protoExpectations.splice(i,1);--i;}}
+function mergeIntersectingAnimations(protoExpectations){const newPEs=[];while(protoExpectations.length){const pe=protoExpectations.shift();newPEs.push(pe);if(pe.type!==ProtoExpectation.ANIMATION_TYPE)continue;const isCSS=pe.initiatorType===INITIATOR_TYPE.CSS;const isFling=pe.containsTypeNames([INPUT_TYPE.FLING_START]);const isVideo=pe.initiatorType===INITIATOR_TYPE.VIDEO;for(let i=0;i<protoExpectations.length;++i){const otherPE=protoExpectations[i];if(otherPE.type!==pe.type)continue;if((isCSS&&otherPE.initiatorType!==INITIATOR_TYPE.CSS)||isFling!==otherPE.containsTypeNames([INPUT_TYPE.FLING_START])||isVideo&&otherPE.initiatorType!==INITIATOR_TYPE.VIDEO||otherPE.initiatorType===INITIATOR_TYPE.VR){continue;}
+if(isCSS){if(!pe.isNear(otherPE,ANIMATION_MERGE_THRESHOLD_MS)){continue;}}else if(!otherPE.intersects(pe)){continue;}
+pe.merge(otherPE);protoExpectations.splice(i,1);--i;}}
 return newPEs;}
-function fixResponseAnimationStarts(protoExpectations){protoExpectations.forEach(function(ape){if(ape.irType!==ProtoExpectation.ANIMATION_TYPE)
-return;protoExpectations.forEach(function(rpe){if(rpe.irType!==ProtoExpectation.RESPONSE_TYPE)
-return;if(!ape.containsTimestampInclusive(rpe.end))
-return;if(ape.containsTimestampInclusive(rpe.start))
-return;ape.start=rpe.end;});});return protoExpectations;}
-function fixTapResponseTouchAnimations(protoExpectations){function isTapResponse(pe){return(pe.irType===ProtoExpectation.RESPONSE_TYPE)&&pe.containsTypeNames([INPUT_TYPE.TAP]);}
-function isTouchAnimation(pe){return(pe.irType===ProtoExpectation.ANIMATION_TYPE)&&pe.containsTypeNames([INPUT_TYPE.TOUCH_MOVE])&&!pe.containsTypeNames([INPUT_TYPE.SCROLL_UPDATE,INPUT_TYPE.PINCH_UPDATE]);}
-var newPEs=[];while(protoExpectations.length){var pe=protoExpectations.shift();newPEs.push(pe);var peIsTapResponse=isTapResponse(pe);var peIsTouchAnimation=isTouchAnimation(pe);if(!peIsTapResponse&&!peIsTouchAnimation)
-continue;for(var i=0;i<protoExpectations.length;++i){var otherPE=protoExpectations[i];if(!otherPE.intersects(pe))
-continue;if(peIsTapResponse&&!isTouchAnimation(otherPE))
-continue;if(peIsTouchAnimation&&!isTapResponse(otherPE))
-continue;pe.irType=ProtoExpectation.RESPONSE_TYPE;pe.merge(otherPE);protoExpectations.splice(i,1);--i;}}
+function fixResponseAnimationStarts(protoExpectations){protoExpectations.forEach(function(ape){if(ape.type!==ProtoExpectation.ANIMATION_TYPE){return;}
+protoExpectations.forEach(function(rpe){if(rpe.type!==ProtoExpectation.RESPONSE_TYPE){return;}
+if(!ape.containsTimestampInclusive(rpe.end)){return;}
+if(ape.containsTimestampInclusive(rpe.start)){return;}
+ape.start=rpe.end;if(ape.associatedEvents!==undefined){ape.associatedEvents=ape.associatedEvents.filter(e=>(!isImplFrameEvent(e)||e.start>=ape.start));}});});return protoExpectations;}
+function isImplFrameEvent(event){return event.title===tr.model.helpers.IMPL_RENDERING_STATS;}
+function fixTapResponseTouchAnimations(protoExpectations){function isTapResponse(pe){return(pe.type===ProtoExpectation.RESPONSE_TYPE)&&pe.containsTypeNames([INPUT_TYPE.TAP]);}
+function isTouchAnimation(pe){return(pe.type===ProtoExpectation.ANIMATION_TYPE)&&pe.containsTypeNames([INPUT_TYPE.TOUCH_MOVE])&&!pe.containsTypeNames([INPUT_TYPE.SCROLL_UPDATE,INPUT_TYPE.PINCH_UPDATE]);}
+const newPEs=[];while(protoExpectations.length){const pe=protoExpectations.shift();newPEs.push(pe);const peIsTapResponse=isTapResponse(pe);const peIsTouchAnimation=isTouchAnimation(pe);if(!peIsTapResponse&&!peIsTouchAnimation){continue;}
+for(let i=0;i<protoExpectations.length;++i){const otherPE=protoExpectations[i];if(!otherPE.intersects(pe))continue;if(peIsTapResponse&&!isTouchAnimation(otherPE))continue;if(peIsTouchAnimation&&!isTapResponse(otherPE))continue;pe.type=ProtoExpectation.RESPONSE_TYPE;pe.merge(otherPE);protoExpectations.splice(i,1);--i;}}
 return newPEs;}
-function checkAllInputEventsHandled(sortedInputEvents,protoExpectations){var handledEvents=[];protoExpectations.forEach(function(protoExpectation){protoExpectation.associatedEvents.forEach(function(event){if((event.title===CSS_ANIMATION_TITLE)&&(event.subSlices.length>0))
-return;if(handledEvents.indexOf(event)>=0){console.error('double-handled event',event.typeName,parseInt(event.start),parseInt(event.end),protoExpectation);return;}
-handledEvents.push(event);});});sortedInputEvents.forEach(function(event){if(handledEvents.indexOf(event)<0){console.error('UNHANDLED INPUT EVENT!',event.typeName,parseInt(event.start),parseInt(event.end));}});}
-function findInputExpectations(modelHelper){var sortedInputEvents=getSortedInputEvents(modelHelper);var protoExpectations=findProtoExpectations(modelHelper,sortedInputEvents);protoExpectations=postProcessProtoExpectations(protoExpectations);checkAllInputEventsHandled(sortedInputEvents,protoExpectations);var irs=[];protoExpectations.forEach(function(protoExpectation){var ir=protoExpectation.createInteractionRecord(modelHelper.model);if(ir)
-irs.push(ir);});return irs;}
-return{findInputExpectations:findInputExpectations,compareEvents:compareEvents,CSS_ANIMATION_TITLE:CSS_ANIMATION_TITLE};});'use strict';tr.exportTo('tr.model.um',function(){var LOAD_SUBTYPE_NAMES={SUCCESSFUL:'Successful',FAILED:'Failed',STARTUP:'Startup'};var DOES_LOAD_SUBTYPE_NAME_EXIST={};for(var key in LOAD_SUBTYPE_NAMES){DOES_LOAD_SUBTYPE_NAME_EXIST[LOAD_SUBTYPE_NAMES[key]]=true;;}
-function LoadExpectation(parentModel,initiatorTitle,start,duration){if(!DOES_LOAD_SUBTYPE_NAME_EXIST[initiatorTitle])
-throw new Error(initiatorTitle+' is not in LOAD_SUBTYPE_NAMES');tr.model.um.UserExpectation.call(this,parentModel,initiatorTitle,start,duration);this.renderProcess=undefined;this.renderMainThread=undefined;this.routingId=undefined;this.parentRoutingId=undefined;this.loadFinishedEvent=undefined;}
-LoadExpectation.prototype={__proto__:tr.model.um.UserExpectation.prototype,constructor:LoadExpectation};tr.model.um.UserExpectation.register(LoadExpectation,{stageTitle:'Load',colorId:tr.b.ColorScheme.getColorIdForReservedName('rail_load')});return{LOAD_SUBTYPE_NAMES:LOAD_SUBTYPE_NAMES,LoadExpectation:LoadExpectation};});'use strict';tr.exportTo('tr.importer',function(){var NAVIGATION_START='NavigationTiming navigationStart';var FIRST_CONTENTFUL_PAINT_TITLE='firstContentfulPaint';function getAllFrameEvents(modelHelper){var frameEvents=[];frameEvents.push.apply(frameEvents,modelHelper.browserHelper.getFrameEventsInRange(tr.model.helpers.IMPL_FRAMETIME_TYPE,modelHelper.model.bounds));tr.b.iterItems(modelHelper.rendererHelpers,function(pid,renderer){frameEvents.push.apply(frameEvents,renderer.getFrameEventsInRange(tr.model.helpers.IMPL_FRAMETIME_TYPE,modelHelper.model.bounds));});return frameEvents.sort(tr.importer.compareEvents);}
-function getStartupEvents(modelHelper){function isStartupSlice(slice){return slice.title==='BrowserMainLoop::CreateThreads';}
-var events=modelHelper.browserHelper.getAllAsyncSlicesMatching(isStartupSlice);var deduper=new tr.model.EventSet();events.forEach(function(event){var sliceGroup=event.parentContainer.sliceGroup;var slice=sliceGroup&&sliceGroup.findFirstSlice();if(slice)
-deduper.push(slice);});return deduper.toArray();}
-function findLoadExpectationsInternal(modelHelper,subtypeName,openingEvents,closingEvents){var loads=[];openingEvents.forEach(function(openingEvent){closingEvents.forEach(function(closingEvent){if(openingEvent.closingEvent)
-return;if(closingEvent.openingEvent)
-return;if(closingEvent.start<=openingEvent.start)
-return;if(openingEvent.parentContainer.parent.pid!==closingEvent.parentContainer.parent.pid)
-return;openingEvent.closingEvent=closingEvent;closingEvent.openingEvent=openingEvent;var lir=new tr.model.um.LoadExpectation(modelHelper.model,subtypeName,openingEvent.start,closingEvent.end-openingEvent.start);lir.associatedEvents.push(openingEvent);lir.associatedEvents.push(closingEvent);loads.push(lir);});});return loads;}
-function findRenderLoadExpectations(modelHelper){var events=[];modelHelper.model.iterateAllEvents(function(event){if((event.title===NAVIGATION_START)||(event.title===FIRST_CONTENTFUL_PAINT_TITLE))
-events.push(event);});events.sort(tr.importer.compareEvents);var loads=[];var startEvent=undefined;events.forEach(function(event){if(event.title===NAVIGATION_START){startEvent=event;}else if(event.title===FIRST_CONTENTFUL_PAINT_TITLE){if(startEvent){loads.push(new tr.model.um.LoadExpectation(modelHelper.model,tr.model.um.LOAD_SUBTYPE_NAMES.SUCCESSFUL,startEvent.start,event.start-startEvent.start));startEvent=undefined;}}});if(startEvent){loads.push(new tr.model.um.LoadExpectation(modelHelper.model,tr.model.um.LOAD_SUBTYPE_NAMES.SUCCESSFUL,startEvent.start,modelHelper.model.bounds.max-startEvent.start));}
+function findFrameEventsForAnimations(modelHelper,protoExpectations){const newPEs=[];const frameEventsByPid=getSortedFrameEventsByProcess(modelHelper);for(const pe of protoExpectations){if(pe.type!==ProtoExpectation.ANIMATION_TYPE){newPEs.push(pe);continue;}
+const frameEvents=[];for(const pid of Object.keys(modelHelper.rendererHelpers)){const range=tr.b.math.Range.fromExplicitRange(pe.start,pe.end);frameEvents.push.apply(frameEvents,range.filterArray(frameEventsByPid[pid],e=>e.start));}
+if(frameEvents.length===0&&!(pe.initiatorType===INITIATOR_TYPE.WEBGL||pe.initiatorType===INITIATOR_TYPE.VR)){pe.type=ProtoExpectation.IGNORED_TYPE;newPEs.push(pe);continue;}
+pe.associatedEvents.addEventSet(frameEvents);newPEs.push(pe);}
+return newPEs;}
+function checkAllInputEventsHandled(modelHelper,sortedInputEvents,protoExpectations,warn){const handledEvents=[];protoExpectations.forEach(function(protoExpectation){protoExpectation.associatedEvents.forEach(function(event){if((event.title===CSS_ANIMATION_TITLE)&&(event.subSlices.length>0)){return;}
+if((handledEvents.indexOf(event)>=0)&&(!isImplFrameEvent(event))){warn({type:'UserModelBuilder',message:`double-handled event: ${event.typeName} @ ${event.start}`,showToUser:false,});return;}
+handledEvents.push(event);});});sortedInputEvents.forEach(function(event){if(handledEvents.indexOf(event)<0){warn({type:'UserModelBuilder',message:`double-handled event: ${event.typeName} @ ${event.start}`,showToUser:false,});}});}
+function findInputExpectations(modelHelper){let warning;function warn(w){if(warning)return;warning=w;}
+const sortedInputEvents=getSortedInputEvents(modelHelper);let protoExpectations=findProtoExpectations(modelHelper,sortedInputEvents,warn);protoExpectations=postProcessProtoExpectations(modelHelper,protoExpectations);checkAllInputEventsHandled(modelHelper,sortedInputEvents,protoExpectations,warn);if(warning)modelHelper.model.importWarning(warning);const expectations=[];protoExpectations.forEach(function(protoExpectation){const ir=protoExpectation.createInteractionRecord(modelHelper.model);if(ir){expectations.push(ir);}});return expectations;}
+return{findInputExpectations,compareEvents,CSS_ANIMATION_TITLE,VR_EXPECTATION_EVENTS,WEBXR_INSTANT_EVENTS,};});'use strict';tr.exportTo('tr.b',function(){class FixedColorScheme{constructor(namesToColors){this.namesToColors_=namesToColors;}
+static fromNames(names){const namesToColors=new Map();const generator=new tr.b.SinebowColorGenerator();for(const name of names){namesToColors.set(name,generator.colorForKey(name));}
+return new FixedColorScheme(namesToColors);}
+getColor(name){const color=this.namesToColors_.get(name);if(color===undefined)throw new Error('Unknown color: '+name);return color;}}
+const MemoryColumnColorScheme=new FixedColorScheme(new Map([['used_memory_column',new tr.b.Color(0,0,255)],['older_used_memory_column',new tr.b.Color(153,204,255)],['tracing_memory_column',new tr.b.Color(153,153,153)]]));function FixedColorSchemeRegistry(){}
+FixedColorSchemeRegistry.lookUp=function(name){const info=this.findTypeInfoMatching(info=>info.metadata.name===name);if(!info)return undefined;return info.constructor();};const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(FixedColorSchemeRegistry,options);return{MemoryColumnColorScheme,FixedColorScheme,FixedColorSchemeRegistry,};});'use strict';tr.exportTo('tr.e.chrome.chrome_processes',function(){const CHROME_PROCESS_NAMES={BROWSER:'browser_process',RENDERER:'renderer_processes',ALL:'all_processes',GPU:'gpu_process',PPAPI:'ppapi_process',UNKNOWN:'unknown_processes',};const PROCESS_COLOR_SCHEME_NAME='ChromeProcessNames';const PROCESS_COLOR_SCHEME=tr.b.FixedColorScheme.fromNames(Object.values(CHROME_PROCESS_NAMES));tr.b.FixedColorSchemeRegistry.register(()=>PROCESS_COLOR_SCHEME,{name:PROCESS_COLOR_SCHEME_NAME,});function canonicalizeName(name){return name.toLowerCase().replace(' ','_');}
+function canonicalizeProcessName(rawProcessName){if(!rawProcessName)return CHROME_PROCESS_NAMES.UNKNOWN;const baseCanonicalName=canonicalizeName(rawProcessName);switch(baseCanonicalName){case'renderer':return CHROME_PROCESS_NAMES.RENDERER;case'browser':return CHROME_PROCESS_NAMES.BROWSER;}
+if(Object.values(CHROME_PROCESS_NAMES).includes(baseCanonicalName)){return baseCanonicalName;}
+return CHROME_PROCESS_NAMES.UNKNOWN;}
+return{CHROME_PROCESS_NAMES,PROCESS_COLOR_SCHEME,PROCESS_COLOR_SCHEME_NAME,canonicalizeName,canonicalizeProcessName,};});'use strict';tr.exportTo('tr.metrics.sh',function(){function perceptualBlend(ir,index,score){return Math.exp(1-score);}
+function filterExpectationsByRange(irs,opt_range){const filteredExpectations=[];irs.forEach(function(ir){if(!(ir instanceof tr.model.um.UserExpectation))return;if(!opt_range||opt_range.intersectsExplicitRangeInclusive(ir.start,ir.end)){filteredExpectations.push(ir);}});return filteredExpectations;}
+function splitGlobalDumpsByBrowserName(model,opt_rangeOfInterest){const chromeModelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const browserNameToGlobalDumps=new Map();const globalDumpToBrowserHelper=new WeakMap();if(chromeModelHelper){chromeModelHelper.browserHelpers.forEach(function(helper){const globalDumps=skipDumpsThatDoNotIntersectRange(helper.process.memoryDumps.map(d=>d.globalMemoryDump),opt_rangeOfInterest);globalDumps.forEach(function(globalDump){const existingHelper=globalDumpToBrowserHelper.get(globalDump);if(existingHelper!==undefined){throw new Error('Memory dump ID clash across multiple browsers '+'with PIDs: '+existingHelper.pid+' and '+helper.pid);}
+globalDumpToBrowserHelper.set(globalDump,helper);});makeKeyUniqueAndSet(browserNameToGlobalDumps,tr.e.chrome.chrome_processes.canonicalizeName(helper.browserName),globalDumps);});}
+const unclassifiedGlobalDumps=skipDumpsThatDoNotIntersectRange(model.globalMemoryDumps.filter(g=>!globalDumpToBrowserHelper.has(g)),opt_rangeOfInterest);if(unclassifiedGlobalDumps.length>0){makeKeyUniqueAndSet(browserNameToGlobalDumps,'unknown_browser',unclassifiedGlobalDumps);}
+return browserNameToGlobalDumps;}
+function makeKeyUniqueAndSet(map,key,value){let uniqueKey=key;let nextIndex=2;while(map.has(uniqueKey)){uniqueKey=key+nextIndex;nextIndex++;}
+map.set(uniqueKey,value);}
+function skipDumpsThatDoNotIntersectRange(dumps,opt_range){if(!opt_range)return dumps;return dumps.filter(d=>opt_range.intersectsExplicitRangeInclusive(d.start,d.end));}
+function hasCategoryAndName(event,category,title){return event.title===title&&event.category&&tr.b.getCategoryParts(event.category).includes(category);}
+return{hasCategoryAndName,filterExpectationsByRange,perceptualBlend,splitGlobalDumpsByBrowserName};});'use strict';tr.exportTo('tr.e.chrome',function(){const CHROME_INTERNAL_URLS=['','about:blank','data:text/html,pluginplaceholderdata','chrome-error://chromewebdata/'];const SCHEDULER_TOP_LEVEL_TASK_TITLE='ThreadControllerImpl::RunTask';const SCHEDULER_TOP_LEVEL_TASKS=new Set([SCHEDULER_TOP_LEVEL_TASK_TITLE,'ThreadControllerImpl::DoWork','TaskQueueManager::ProcessTaskFromWorkQueue']);class EventFinderUtils{static hasCategoryAndName(event,category,title){return event.title===title&&event.category&&tr.b.getCategoryParts(event.category).includes(category);}
+static*getMainThreadEvents(rendererHelper,eventTitle,eventCategory){if(!rendererHelper.mainThread)return;for(const ev of rendererHelper.mainThread.sliceGroup.childEvents()){if(rendererHelper.isTelemetryInternalEvent(ev))continue;if(!this.hasCategoryAndName(ev,eventCategory,eventTitle)){continue;}
+yield ev;}}
+static getNetworkEventsInRange(process,range){const networkEvents=[];for(const thread of Object.values(process.threads)){const threadHelper=new tr.model.helpers.ChromeThreadHelper(thread);const events=threadHelper.getNetworkEvents();for(const event of events){if(range.intersectsExplicitRangeInclusive(event.start,event.end)){networkEvents.push(event);}}}
+return networkEvents;}
+static getSortedMainThreadEventsByFrame(rendererHelper,eventTitle,eventCategory){const eventsByFrame=new Map();const events=this.getMainThreadEvents(rendererHelper,eventTitle,eventCategory);for(const ev of events){const frameIdRef=ev.args.frame;if(frameIdRef===undefined)continue;if(!eventsByFrame.has(frameIdRef)){eventsByFrame.set(frameIdRef,[]);}
+eventsByFrame.get(frameIdRef).push(ev);}
+return eventsByFrame;}
+static getSortedMainThreadEventsByNavId(rendererHelper,eventTitle,eventCategory){const eventsByNavId=new Map();const events=this.getMainThreadEvents(rendererHelper,eventTitle,eventCategory);for(const ev of events){if(ev.args.data===undefined)continue;const navIdRef=ev.args.data.navigationId;if(navIdRef===undefined)continue;eventsByNavId.set(navIdRef,ev);}
+return eventsByNavId;}
+static findLastEventStartingOnOrBeforeTimestamp(sortedEvents,timestamp){const firstIndexAfterTimestamp=tr.b.findFirstTrueIndexInSortedArray(sortedEvents,e=>e.start>timestamp);if(firstIndexAfterTimestamp===0)return undefined;return sortedEvents[firstIndexAfterTimestamp-1];}
+static findLastEventStartingBeforeTimestamp(sortedEvents,timestamp){const firstIndexAfterTimestamp=tr.b.findFirstTrueIndexInSortedArray(sortedEvents,e=>e.start>=timestamp);if(firstIndexAfterTimestamp===0)return undefined;return sortedEvents[firstIndexAfterTimestamp-1];}
+static findNextEventStartingOnOrAfterTimestamp(sortedEvents,timestamp){const firstIndexOnOrAfterTimestamp=tr.b.findFirstTrueIndexInSortedArray(sortedEvents,e=>e.start>=timestamp);if(firstIndexOnOrAfterTimestamp===sortedEvents.length){return undefined;}
+return sortedEvents[firstIndexOnOrAfterTimestamp];}
+static findNextEventStartingAfterTimestamp(sortedEvents,timestamp){const firstIndexOnOrAfterTimestamp=tr.b.findFirstTrueIndexInSortedArray(sortedEvents,e=>e.start>timestamp);if(firstIndexOnOrAfterTimestamp===sortedEvents.length){return undefined;}
+return sortedEvents[firstIndexOnOrAfterTimestamp];}
+static findToplevelSchedulerTasks(mainThread){const tasks=[];for(const task of mainThread.findTopmostSlices(slice=>slice.category==='toplevel'&&SCHEDULER_TOP_LEVEL_TASKS.has(slice.title))){tasks.push(task);}
+return tasks;}}
+return{EventFinderUtils,CHROME_INTERNAL_URLS,SCHEDULER_TOP_LEVEL_TASK_TITLE,};});'use strict';tr.exportTo('tr.e.chrome',function(){const TIME_TO_INTERACTIVE_WINDOW_SIZE_MS=5000;const ACTIVE_REQUEST_TOLERANCE=2;const FCI_MIN_CLUSTER_SEPARATION_MS=1000;const TASK_CLUSTER_HEAVINESS_THRESHOLD_MS=250;const ENDPOINT_TYPES={LONG_TASK_START:'LONG_TASK_START',LONG_TASK_END:'LONG_TASK_END',REQUEST_START:'REQUEST_START',REQUEST_END:'REQUEST_END'};function getEndpoints_(events,startType,endType){const endpoints=[];for(const event of events){endpoints.push({time:event.start,type:startType});endpoints.push({time:event.end,type:endType});}
+return endpoints;}
+function reachedTTIQuiscence_(timestamp,networkQuietWindowStart,mainThreadQuietWindowStart){if(networkQuietWindowStart===undefined||mainThreadQuietWindowStart===undefined){return false;}
+const mainThreadQuietForLongEnough=timestamp-mainThreadQuietWindowStart>=TIME_TO_INTERACTIVE_WINDOW_SIZE_MS;const networkQuietForLongEnough=timestamp-networkQuietWindowStart>=TIME_TO_INTERACTIVE_WINDOW_SIZE_MS;return mainThreadQuietForLongEnough&&networkQuietForLongEnough;}
+function findInteractiveTime(searchBegin,searchEnd,domContentLoadedEnd,longTasksInWindow,networkRequests){const longTaskEndpoints=getEndpoints_(longTasksInWindow,ENDPOINT_TYPES.LONG_TASK_START,ENDPOINT_TYPES.LONG_TASK_END);const networkRequestEndpoints=getEndpoints_(networkRequests,ENDPOINT_TYPES.REQUEST_START,ENDPOINT_TYPES.REQUEST_END);const endpoints=longTaskEndpoints.concat(networkRequestEndpoints);endpoints.sort((a,b)=>a.time-b.time);let networkQuietWindowStart=searchBegin;let mainThreadQuietWindowStart=searchBegin;let interactiveCandidate=undefined;let activeRequests=0;for(const endpoint of endpoints){if(reachedTTIQuiscence_(endpoint.time,networkQuietWindowStart,mainThreadQuietWindowStart)){interactiveCandidate=mainThreadQuietWindowStart;break;}
+switch(endpoint.type){case ENDPOINT_TYPES.LONG_TASK_START:mainThreadQuietWindowStart=undefined;break;case ENDPOINT_TYPES.LONG_TASK_END:mainThreadQuietWindowStart=endpoint.time;break;case ENDPOINT_TYPES.REQUEST_START:activeRequests++;if(activeRequests>ACTIVE_REQUEST_TOLERANCE){networkQuietWindowStart=undefined;}
+break;case ENDPOINT_TYPES.REQUEST_END:activeRequests--;if(activeRequests===ACTIVE_REQUEST_TOLERANCE){networkQuietWindowStart=endpoint.time;}
+break;default:throw new Error('Internal Error: Unhandled endpoint type.');}}
+if(interactiveCandidate===undefined&&reachedTTIQuiscence_(searchEnd,networkQuietWindowStart,mainThreadQuietWindowStart)){interactiveCandidate=mainThreadQuietWindowStart;}
+if(interactiveCandidate===undefined)return undefined;return Math.max(interactiveCandidate,domContentLoadedEnd);}
+function requiredFCIWindowSizeMs(timeSinceSearchBeginMs){const timeCoefficient=1/15*Math.log(2);const timeSinceSearchBeginSeconds=tr.b.convertUnit(timeSinceSearchBeginMs,tr.b.UnitPrefixScale.METRIC.MILLI,tr.b.UnitPrefixScale.METRIC.NONE);const windowSizeSeconds=4*Math.exp(-timeCoefficient*timeSinceSearchBeginSeconds)+1;return tr.b.convertUnit(windowSizeSeconds,tr.b.UnitPrefixScale.METRIC.NONE,tr.b.UnitPrefixScale.METRIC.MILLI);}
+class TaskCluster{constructor(tasksInClusterSorted){if(tasksInClusterSorted.length===0){throw new Error('Internal Error: TaskCluster must have non zero tasks');}
+for(let i=0;i<tasksInClusterSorted.length-1;i++){const durationBetweenTasks=tasksInClusterSorted[i+1].start-
+tasksInClusterSorted[i].end;if(durationBetweenTasks>=FCI_MIN_CLUSTER_SEPARATION_MS){throw new Error('Internal Error: Tasks in a TaskCluster cannot be '+'more than '+FCI_MIN_CLUSTER_SEPARATION_MS+' miliseconds apart');}
+if(durationBetweenTasks<-1e7){throw new Error('Internal Error: List of tasks used to construct '+'TaskCluster must be sorted.');}}
+this._clusterTasks=tasksInClusterSorted;}
+get start(){return this._clusterTasks[0].start;}
+get end(){return this._clusterTasks[this._clusterTasks.length-1].end;}
+isHeavy(){return this.end-this.start>TASK_CLUSTER_HEAVINESS_THRESHOLD_MS;}}
+function findFCITaskClusters(sortedLongTasks){const clusters=[];if(sortedLongTasks.length===0)return clusters;const firstTask=sortedLongTasks[0];const restOfTasks=sortedLongTasks.slice(1);let currentClusterTasks=[firstTask];for(const currTask of restOfTasks){const prevTask=currentClusterTasks[currentClusterTasks.length-1];if(currTask.start-prevTask.end<FCI_MIN_CLUSTER_SEPARATION_MS){currentClusterTasks.push(currTask);}else{clusters.push(new TaskCluster(currentClusterTasks));currentClusterTasks=[currTask];}}
+clusters.push(new TaskCluster(currentClusterTasks));return clusters;}
+function reachedFCIQuiescence_(timestamp,mainThreadQuietWindowStart,searchBegin){const quietWindowSize=timestamp-mainThreadQuietWindowStart;const timeSinceSearchBegin=mainThreadQuietWindowStart-searchBegin;const requiredWindowSize=requiredFCIWindowSizeMs(timeSinceSearchBegin);return quietWindowSize>requiredWindowSize;}
+function findFirstCpuIdleTime(searchBegin,searchEnd,domContentLoadedEnd,longTasksInWindow){const sortedLongTasks=longTasksInWindow.sort((a,b)=>a.start-b.start);const taskClusters=findFCITaskClusters(sortedLongTasks);const heavyTaskClusters=taskClusters.filter(cluster=>cluster.isHeavy());let quietWindowBegin=searchBegin;let fiCandidate=undefined;for(const cluster of heavyTaskClusters){if(reachedFCIQuiescence_(cluster.start,quietWindowBegin,searchBegin)){fiCandidate=quietWindowBegin;break;}
+quietWindowBegin=cluster.end;}
+if(fiCandidate===undefined){if(reachedFCIQuiescence_(searchEnd,quietWindowBegin,searchBegin)){fiCandidate=quietWindowBegin;}else{return undefined;}}
+return Math.max(fiCandidate,domContentLoadedEnd);}
+return{findInteractiveTime,findFirstCpuIdleTime,requiredFCIWindowSizeMs,findFCITaskClusters,};});'use strict';tr.exportTo('tr.model.um',function(){const LOAD_SUBTYPE_NAMES={SUCCESSFUL:'Successful',FAILED:'Failed',};const DOES_LOAD_SUBTYPE_NAME_EXIST={};for(const key in LOAD_SUBTYPE_NAMES){DOES_LOAD_SUBTYPE_NAME_EXIST[LOAD_SUBTYPE_NAMES[key]]=true;}
+function LoadExpectation(parentModel,initiatorTitle,start,duration,renderer,navigationStart,fmpEvent,dclEndEvent,cpuIdleTime,timeToInteractive,url,frameId){if(!DOES_LOAD_SUBTYPE_NAME_EXIST[initiatorTitle]){throw new Error(initiatorTitle+' is not in LOAD_SUBTYPE_NAMES');}
+tr.model.um.UserExpectation.call(this,parentModel,initiatorTitle,start,duration);this.renderProcess=renderer;this.renderMainThread=undefined;this.routingId=undefined;this.parentRoutingId=undefined;this.loadFinishedEvent=undefined;this.navigationStart=navigationStart;this.fmpEvent=fmpEvent;this.domContentLoadedEndEvent=dclEndEvent;this.firstCpuIdleTime=cpuIdleTime;this.timeToInteractive=timeToInteractive;this.url=url;this.frameId=frameId;}
+LoadExpectation.prototype={__proto__:tr.model.um.UserExpectation.prototype,constructor:LoadExpectation};tr.model.um.UserExpectation.subTypes.register(LoadExpectation,{stageTitle:'Load',colorId:tr.b.ColorScheme.getColorIdForReservedName('rail_load')});return{LOAD_SUBTYPE_NAMES,LoadExpectation,};});'use strict';tr.exportTo('tr.importer',function(){const LONG_TASK_THRESHOLD_MS=50;const IGNORE_URLS=['','about:blank',];function findFrameLoaderSnapshotAt(rendererHelper,frameIdRef,ts){const objects=rendererHelper.process.objects;const frameLoaderInstances=objects.instancesByTypeName_.FrameLoader;if(frameLoaderInstances===undefined)return undefined;let snapshot;for(const instance of frameLoaderInstances){if(!instance.isAliveAt(ts))continue;const maybeSnapshot=instance.getSnapshotAt(ts);if(frameIdRef!==maybeSnapshot.args.frame.id_ref)continue;snapshot=maybeSnapshot;}
+return snapshot;}
+function findFirstMeaningfulPaintCandidates(rendererHelper){const candidatesForFrameId={};for(const ev of rendererHelper.process.getDescendantEvents()){if(!tr.e.chrome.EventFinderUtils.hasCategoryAndName(ev,'loading','firstMeaningfulPaintCandidate')){continue;}
+if(rendererHelper.isTelemetryInternalEvent(ev))continue;const frameIdRef=ev.args.frame;if(frameIdRef===undefined)continue;let list=candidatesForFrameId[frameIdRef];if(list===undefined){candidatesForFrameId[frameIdRef]=list=[];}
+list.push(ev);}
+return candidatesForFrameId;}
+function computeInteractivityMetricSample_(rendererHelper,navigationStart,fmpEvent,domContentLoadedEndEvent,searchWindowEnd){if(domContentLoadedEndEvent===undefined||fmpEvent===undefined){return{interactiveTime:undefined,firstCpuIdleTime:undefined};}
+const firstMeaningfulPaintTime=fmpEvent.start;const mainThreadTasks=tr.e.chrome.EventFinderUtils.findToplevelSchedulerTasks(rendererHelper.mainThread);const longTasks=mainThreadTasks.filter(task=>task.duration>=LONG_TASK_THRESHOLD_MS);const longTasksInWindow=longTasks.filter(task=>task.range.intersectsExplicitRangeInclusive(firstMeaningfulPaintTime,searchWindowEnd));const resourceLoadEvents=tr.e.chrome.EventFinderUtils.getNetworkEventsInRange(rendererHelper.process,tr.b.math.Range.fromExplicitRange(navigationStart.start,searchWindowEnd));const firstCpuIdleTime=tr.e.chrome.findFirstCpuIdleTime(firstMeaningfulPaintTime,searchWindowEnd,domContentLoadedEndEvent.start,longTasksInWindow);const interactiveTime=resourceLoadEvents.length>0?tr.e.chrome.findInteractiveTime(firstMeaningfulPaintTime,searchWindowEnd,domContentLoadedEndEvent.start,longTasksInWindow,resourceLoadEvents):undefined;return{interactiveTime,firstCpuIdleTime};}
+function constructLoadingExpectation_(rendererHelper,frameToDomContentLoadedEndEvents,navigationStart,fmpEvent,searchWindowEnd,url,frameId){const dclTimesForFrame=frameToDomContentLoadedEndEvents.get(frameId)||[];const dclSearchRange=tr.b.math.Range.fromExplicitRange(navigationStart.start,searchWindowEnd);const dclTimesInWindow=dclSearchRange.filterArray(dclTimesForFrame,event=>event.start);let domContentLoadedEndEvent=undefined;if(dclTimesInWindow.length!==0){domContentLoadedEndEvent=dclTimesInWindow[dclTimesInWindow.length-1];}
+const{interactiveTime,firstCpuIdleTime}=computeInteractivityMetricSample_(rendererHelper,navigationStart,fmpEvent,domContentLoadedEndEvent,searchWindowEnd);const duration=(interactiveTime===undefined)?searchWindowEnd-navigationStart.start:interactiveTime-navigationStart.start;return new tr.model.um.LoadExpectation(rendererHelper.modelHelper.model,tr.model.um.LOAD_SUBTYPE_NAMES.SUCCESSFUL,navigationStart.start,duration,rendererHelper.process,navigationStart,fmpEvent,domContentLoadedEndEvent,firstCpuIdleTime,interactiveTime,url,frameId);}
+function collectLoadExpectationsForRenderer(rendererHelper){const samples=[];const frameToNavStartEvents=tr.e.chrome.EventFinderUtils.getSortedMainThreadEventsByFrame(rendererHelper,'navigationStart','blink.user_timing');const frameToDomContentLoadedEndEvents=tr.e.chrome.EventFinderUtils.getSortedMainThreadEventsByFrame(rendererHelper,'domContentLoadedEventEnd','blink.user_timing');function addSamples(frameIdRef,navigationStart,fmpCandidateEvents,searchWindowEnd,url){let fmpMarkerEvent=tr.e.chrome.EventFinderUtils.findLastEventStartingOnOrBeforeTimestamp(fmpCandidateEvents,searchWindowEnd);if(fmpMarkerEvent!==undefined&&navigationStart.start>fmpMarkerEvent.start){fmpMarkerEvent=undefined;}
+samples.push(constructLoadingExpectation_(rendererHelper,frameToDomContentLoadedEndEvents,navigationStart,fmpMarkerEvent,searchWindowEnd,url,frameIdRef));}
+const candidatesForFrameId=findFirstMeaningfulPaintCandidates(rendererHelper);for(const[frameIdRef,navStartEvents]of frameToNavStartEvents){const fmpCandidateEvents=candidatesForFrameId[frameIdRef]||[];let prevNavigation={navigationEvent:undefined,url:undefined};for(let index=0;index<navStartEvents.length;index++){const currNavigation=navStartEvents[index];let url;let isLoadingMainFrame=false;if(currNavigation.args.data){url=currNavigation.args.data.documentLoaderURL;isLoadingMainFrame=currNavigation.args.data.isLoadingMainFrame;}else{const snapshot=findFrameLoaderSnapshotAt(rendererHelper,frameIdRef,currNavigation.start);if(snapshot){url=snapshot.args.documentLoaderURL;isLoadingMainFrame=snapshot.args.isLoadingMainFrame;}}
+if(!isLoadingMainFrame)continue;if(url===undefined||IGNORE_URLS.includes(url))continue;if(prevNavigation.navigationEvent!==undefined){addSamples(frameIdRef,prevNavigation.navigationEvent,fmpCandidateEvents,currNavigation.start,prevNavigation.url);}
+prevNavigation={navigationEvent:currNavigation,url};}
+if(prevNavigation.navigationEvent!==undefined){addSamples(frameIdRef,prevNavigation.navigationEvent,fmpCandidateEvents,rendererHelper.modelHelper.chromeBounds.max,prevNavigation.url);}}
+return samples;}
+function findLoadExpectations(modelHelper){const loads=[];const chromeHelper=modelHelper.model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);for(const pid in chromeHelper.rendererHelpers){const rendererHelper=chromeHelper.rendererHelpers[pid];if(rendererHelper.isChromeTracingUI)continue;loads.push.apply(loads,collectLoadExpectationsForRenderer(rendererHelper));}
 return loads;}
-function findLoadExpectations(modelHelper){var loads=[];var commitLoadEvents=modelHelper.browserHelper.getCommitProvisionalLoadEventsInRange(modelHelper.model.bounds);var startupEvents=getStartupEvents(modelHelper);var frameEvents=getAllFrameEvents(modelHelper);var startupLoads=findLoadExpectationsInternal(modelHelper,tr.model.um.LOAD_SUBTYPE_NAMES.STARTUP,startupEvents,frameEvents);loads.push.apply(loads,startupLoads);loads.push.apply(loads,findRenderLoadExpectations(modelHelper));return loads;}
-return{findLoadExpectations:findLoadExpectations};});'use strict';tr.exportTo('tr.model',function(){function getAssociatedEvents(irs){var allAssociatedEvents=new tr.model.EventSet();irs.forEach(function(ir){ir.associatedEvents.forEach(function(event){if(event instanceof tr.model.FlowEvent)
-return;allAssociatedEvents.push(event);});});return allAssociatedEvents;}
-function getUnassociatedEvents(model,associatedEvents){var unassociatedEvents=new tr.model.EventSet();model.getAllProcesses().forEach(function(process){for(var tid in process.threads){var thread=process.threads[tid];thread.sliceGroup.iterateAllEvents(function(event){if(!associatedEvents.contains(event))
-unassociatedEvents.push(event);});}});return unassociatedEvents;}
-function getTotalCpuDuration(events){var cpuMs=0;events.forEach(function(event){if(event.cpuSelfTime)
-cpuMs+=event.cpuSelfTime;});return cpuMs;}
-function getIRCoverageFromModel(model){var associatedEvents=getAssociatedEvents(model.userModel.expectations);if(!associatedEvents.length)
-return undefined;var unassociatedEvents=getUnassociatedEvents(model,associatedEvents);var associatedCpuMs=getTotalCpuDuration(associatedEvents);var unassociatedCpuMs=getTotalCpuDuration(unassociatedEvents);var totalEventCount=associatedEvents.length+unassociatedEvents.length;var totalCpuMs=associatedCpuMs+unassociatedCpuMs;var coveredEventsCpuTimeRatio=undefined;if(totalCpuMs!==0)
-coveredEventsCpuTimeRatio=associatedCpuMs/totalCpuMs;return{associatedEventsCount:associatedEvents.length,unassociatedEventsCount:unassociatedEvents.length,associatedEventsCpuTimeMs:associatedCpuMs,unassociatedEventsCpuTimeMs:unassociatedCpuMs,coveredEventsCountRatio:associatedEvents.length/totalEventCount,coveredEventsCpuTimeRatio:coveredEventsCpuTimeRatio};}
-return{getIRCoverageFromModel:getIRCoverageFromModel,getAssociatedEvents:getAssociatedEvents,getUnassociatedEvents:getUnassociatedEvents};});'use strict';tr.exportTo('tr.model.um',function(){function IdleExpectation(parentModel,start,duration){var initiatorTitle='';tr.model.um.UserExpectation.call(this,parentModel,initiatorTitle,start,duration);}
-IdleExpectation.prototype={__proto__:tr.model.um.UserExpectation.prototype,constructor:IdleExpectation};tr.model.um.UserExpectation.register(IdleExpectation,{stageTitle:'Idle',colorId:tr.b.ColorScheme.getColorIdForReservedName('rail_idle')});return{IdleExpectation:IdleExpectation};});'use strict';tr.exportTo('tr.importer',function(){var INSIGNIFICANT_MS=1;function UserModelBuilder(model){this.model=model;this.modelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);};UserModelBuilder.supportsModelHelper=function(modelHelper){return modelHelper.browserHelper!==undefined;};UserModelBuilder.prototype={buildUserModel:function(){if(!this.modelHelper||!this.modelHelper.browserHelper)
-return;var expectations=undefined;try{expectations=this.findUserExpectations();}catch(error){this.model.importWarning({type:'UserModelBuilder',message:error,showToUser:true});return;}
-expectations.forEach(function(expectation){this.model.userModel.expectations.push(expectation);},this);},findUserExpectations:function(){var expectations=[];expectations.push.apply(expectations,tr.importer.findLoadExpectations(this.modelHelper));expectations.push.apply(expectations,tr.importer.findInputExpectations(this.modelHelper));expectations.push.apply(expectations,this.findIdleExpectations(expectations));this.collectUnassociatedEvents_(expectations);return expectations;},collectUnassociatedEvents_:function(rirs){var vacuumIRs=[];rirs.forEach(function(ir){if(ir instanceof tr.model.um.LoadExpectation||ir instanceof tr.model.um.IdleExpectation)
-vacuumIRs.push(ir);});if(vacuumIRs.length===0)
-return;var allAssociatedEvents=tr.model.getAssociatedEvents(rirs);var unassociatedEvents=tr.model.getUnassociatedEvents(this.model,allAssociatedEvents);unassociatedEvents.forEach(function(event){if(!(event instanceof tr.model.ThreadSlice))
-return;if(!event.isTopLevel)
-return;for(var iri=0;iri<vacuumIRs.length;++iri){var ir=vacuumIRs[iri];if((event.start>=ir.start)&&(event.start<ir.end)){ir.associatedEvents.addEventSet(event.entireHierarchy);return;}}});},findIdleExpectations:function(otherIRs){if(this.model.bounds.isEmpty)
-return;var emptyRanges=tr.b.findEmptyRangesBetweenRanges(tr.b.convertEventsToRanges(otherIRs),this.model.bounds);var irs=[];var model=this.model;emptyRanges.forEach(function(range){if(range.max<(range.min+INSIGNIFICANT_MS))
-return;irs.push(new tr.model.um.IdleExpectation(model,range.min,range.max-range.min));});return irs;}};function createCustomizeModelLinesFromModel(model){var modelLines=[];modelLines.push('      audits.addEvent(model.browserMain,');modelLines.push('          {title: \'model start\', start: 0, end: 1});');var typeNames={};for(var typeName in tr.e.cc.INPUT_EVENT_TYPE_NAMES){typeNames[tr.e.cc.INPUT_EVENT_TYPE_NAMES[typeName]]=typeName;}
-var modelEvents=new tr.model.EventSet();model.userModel.expectations.forEach(function(ir,index){modelEvents.addEventSet(ir.sourceEvents);});modelEvents=modelEvents.toArray();modelEvents.sort(tr.importer.compareEvents);modelEvents.forEach(function(event){var startAndEnd='start: '+parseInt(event.start)+', '+'end: '+parseInt(event.end)+'});';if(event instanceof tr.e.cc.InputLatencyAsyncSlice){modelLines.push('      audits.addInputEvent(model, INPUT_TYPE.'+
-typeNames[event.typeName]+',');}else if(event.title==='RenderFrameImpl::didCommitProvisionalLoad'){modelLines.push('      audits.addCommitLoadEvent(model,');}else if(event.title==='InputHandlerProxy::HandleGestureFling::started'){modelLines.push('      audits.addFlingAnimationEvent(model,');}else if(event.title===tr.model.helpers.IMPL_RENDERING_STATS){modelLines.push('      audits.addFrameEvent(model,');}else if(event.title===tr.importer.CSS_ANIMATION_TITLE){modelLines.push('      audits.addEvent(model.rendererMain, {');modelLines.push('        title: \'Animation\', '+startAndEnd);return;}else{throw('You must extend createCustomizeModelLinesFromModel()'+'to support this event:\n'+event.title+'\n');}
-modelLines.push('          {'+startAndEnd);});modelLines.push('      audits.addEvent(model.browserMain,');modelLines.push('          {'+'title: \'model end\', '+'start: '+(parseInt(model.bounds.max)-1)+', '+'end: '+parseInt(model.bounds.max)+'});');return modelLines;}
-function createExpectedIRLinesFromModel(model){var expectedLines=[];var irCount=model.userModel.expectations.length;model.userModel.expectations.forEach(function(ir,index){var irString='      {';irString+='title: \''+ir.title+'\', ';irString+='start: '+parseInt(ir.start)+', ';irString+='end: '+parseInt(ir.end)+', ';irString+='eventCount: '+ir.sourceEvents.length;irString+='}';if(index<(irCount-1))
-irString+=',';expectedLines.push(irString);});return expectedLines;}
-function createIRFinderTestCaseStringFromModel(model){var filename=window.location.hash.substr(1);var testName=filename.substr(filename.lastIndexOf('/')+1);testName=testName.substr(0,testName.indexOf('.'));try{var testLines=[];testLines.push('  /*');testLines.push('    This test was generated from');testLines.push('    '+filename+'');testLines.push('   */');testLines.push('  test(\''+testName+'\', function() {');testLines.push('    var verifier = new UserExpectationVerifier();');testLines.push('    verifier.customizeModelCallback = function(model) {');testLines.push.apply(testLines,createCustomizeModelLinesFromModel(model));testLines.push('    };');testLines.push('    verifier.expectedIRs = [');testLines.push.apply(testLines,createExpectedIRLinesFromModel(model));testLines.push('    ];');testLines.push('    verifier.verify();');testLines.push('  });');return testLines.join('\n');}catch(error){return error;}}
-return{UserModelBuilder:UserModelBuilder,createIRFinderTestCaseStringFromModel:createIRFinderTestCaseStringFromModel};});'use strict';tr.exportTo('tr.importer',function(){var Timing=tr.b.Timing;function ImportOptions(){this.shiftWorldToZero=true;this.pruneEmptyContainers=true;this.showImportWarnings=true;this.trackDetailedModelStats=false;this.customizeModelCallback=undefined;var auditorTypes=tr.c.Auditor.getAllRegisteredTypeInfos();this.auditorConstructors=auditorTypes.map(function(typeInfo){return typeInfo.constructor;});}
-function Import(model,opt_options){if(model===undefined)
-throw new Error('Must provide model to import into.');this.importing_=false;this.importOptions_=opt_options||new ImportOptions();this.model_=model;this.model_.importOptions=this.importOptions_;}
-Import.prototype={__proto__:Object.prototype,importTraces:function(traces){var progressMeter={update:function(msg){}};tr.b.Task.RunSynchronously(this.createImportTracesTask(progressMeter,traces));},importTracesWithProgressDialog:function(traces){if(tr.isHeadless)
-throw new Error('Cannot use this method in headless mode.');var overlay=tr.ui.b.Overlay();overlay.title='Importing...';overlay.userCanClose=false;overlay.msgEl=document.createElement('div');overlay.appendChild(overlay.msgEl);overlay.msgEl.style.margin='20px';overlay.update=function(msg){this.msgEl.textContent=msg;};overlay.visible=true;var promise=tr.b.Task.RunWhenIdle(this.createImportTracesTask(overlay,traces));promise.then(function(){overlay.visible=false;},function(err){overlay.visible=false;});return promise;},createImportTracesTask:function(progressMeter,traces){if(this.importing_)
-throw new Error('Already importing.');this.importing_=true;var importTask=new tr.b.Task(function prepareImport(){progressMeter.update('I will now import your traces for you...');},this);var lastTask=importTask;var importers=[];lastTask=lastTask.timedAfter('TraceImport',function createImports(){traces=traces.slice(0);progressMeter.update('Creating importers...');for(var i=0;i<traces.length;++i)
-importers.push(this.createImporter_(traces[i]));for(var i=0;i<importers.length;i++){var subtraces=importers[i].extractSubtraces();for(var j=0;j<subtraces.length;j++){try{traces.push(subtraces[j]);importers.push(this.createImporter_(subtraces[j]));}catch(error){console.warn(error.name+': '+error.message);continue;}}}
+return{findLoadExpectations,};});'use strict';tr.exportTo('tr.model.um',function(){function StartupExpectation(parentModel,start,duration){tr.model.um.UserExpectation.call(this,parentModel,'',start,duration);}
+StartupExpectation.prototype={__proto__:tr.model.um.UserExpectation.prototype,constructor:StartupExpectation};tr.model.um.UserExpectation.subTypes.register(StartupExpectation,{stageTitle:'Startup',colorId:tr.b.ColorScheme.getColorIdForReservedName('startup')});return{StartupExpectation,};});'use strict';tr.exportTo('tr.importer',function(){function getAllFrameEvents(modelHelper){const frameEvents=[];frameEvents.push.apply(frameEvents,modelHelper.browserHelper.getFrameEventsInRange(tr.model.helpers.IMPL_FRAMETIME_TYPE,modelHelper.model.bounds));for(const renderer of Object.values(modelHelper.rendererHelpers)){frameEvents.push.apply(frameEvents,renderer.getFrameEventsInRange(tr.model.helpers.IMPL_FRAMETIME_TYPE,modelHelper.model.bounds));}
+return frameEvents.sort(tr.importer.compareEvents);}
+function getStartupEvents(modelHelper){function isStartupSlice(slice){return slice.title==='BrowserMainLoop::CreateThreads';}
+const events=modelHelper.browserHelper.getAllAsyncSlicesMatching(isStartupSlice);const deduper=new tr.model.EventSet();events.forEach(function(event){const sliceGroup=event.parentContainer.sliceGroup;const slice=sliceGroup&&sliceGroup.findFirstSlice();if(slice){deduper.push(slice);}});return deduper.toArray();}
+function findStartupExpectations(modelHelper){const openingEvents=getStartupEvents(modelHelper);const closingEvents=getAllFrameEvents(modelHelper);const startups=[];openingEvents.forEach(function(openingEvent){closingEvents.forEach(function(closingEvent){if(openingEvent.closingEvent)return;if(closingEvent.openingEvent)return;if(closingEvent.start<=openingEvent.start)return;if(openingEvent.parentContainer.parent.pid!==closingEvent.parentContainer.parent.pid){return;}
+openingEvent.closingEvent=closingEvent;closingEvent.openingEvent=openingEvent;const se=new tr.model.um.StartupExpectation(modelHelper.model,openingEvent.start,closingEvent.end-openingEvent.start);se.associatedEvents.push(openingEvent);se.associatedEvents.push(closingEvent);startups.push(se);});});return startups;}
+return{findStartupExpectations,};});'use strict';tr.exportTo('tr.model',function(){function getAssociatedEvents(irs){const allAssociatedEvents=new tr.model.EventSet();irs.forEach(function(ir){ir.associatedEvents.forEach(function(event){if(event instanceof tr.model.FlowEvent)return;allAssociatedEvents.push(event);});});return allAssociatedEvents;}
+function getUnassociatedEvents(model,associatedEvents){const unassociatedEvents=new tr.model.EventSet();for(const proc of model.getAllProcesses()){for(const thread of Object.values(proc.threads)){for(const event of thread.sliceGroup.getDescendantEvents()){if(!associatedEvents.contains(event)){unassociatedEvents.push(event);}}}}
+return unassociatedEvents;}
+function getTotalCpuDuration(events){let cpuMs=0;events.forEach(function(event){if(event.cpuSelfTime){cpuMs+=event.cpuSelfTime;}});return cpuMs;}
+function getIRCoverageFromModel(model){const associatedEvents=getAssociatedEvents(model.userModel.expectations);if(!associatedEvents.length)return undefined;const unassociatedEvents=getUnassociatedEvents(model,associatedEvents);const associatedCpuMs=getTotalCpuDuration(associatedEvents);const unassociatedCpuMs=getTotalCpuDuration(unassociatedEvents);const totalEventCount=associatedEvents.length+unassociatedEvents.length;const totalCpuMs=associatedCpuMs+unassociatedCpuMs;let coveredEventsCpuTimeRatio=undefined;if(totalCpuMs!==0){coveredEventsCpuTimeRatio=associatedCpuMs/totalCpuMs;}
+return{associatedEventsCount:associatedEvents.length,unassociatedEventsCount:unassociatedEvents.length,associatedEventsCpuTimeMs:associatedCpuMs,unassociatedEventsCpuTimeMs:unassociatedCpuMs,coveredEventsCountRatio:associatedEvents.length/totalEventCount,coveredEventsCpuTimeRatio};}
+return{getIRCoverageFromModel,getAssociatedEvents,getUnassociatedEvents,};});'use strict';tr.exportTo('tr.model.um',function(){function IdleExpectation(parentModel,start,duration){const initiatorTitle='';tr.model.um.UserExpectation.call(this,parentModel,initiatorTitle,start,duration);}
+IdleExpectation.prototype={__proto__:tr.model.um.UserExpectation.prototype,constructor:IdleExpectation};tr.model.um.UserExpectation.subTypes.register(IdleExpectation,{stageTitle:'Idle',colorId:tr.b.ColorScheme.getColorIdForReservedName('rail_idle')});return{IdleExpectation,};});'use strict';tr.exportTo('tr.importer',function(){const INSIGNIFICANT_MS=1;class UserModelBuilder{constructor(model){this.model=model;this.modelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);}
+static supportsModelHelper(modelHelper){return modelHelper.browserHelper!==undefined;}
+buildUserModel(){if(!this.modelHelper||!this.modelHelper.browserHelper)return;try{for(const ue of this.findUserExpectations()){this.model.userModel.expectations.push(ue);}
+this.model.userModel.segments.push(...this.findSegments());}catch(error){this.model.importWarning({type:'UserModelBuilder',message:error,showToUser:true});}}
+findSegments(){let timestamps=new Set();for(const expectation of this.model.userModel.expectations){timestamps.add(expectation.start);timestamps.add(expectation.end);}
+timestamps=[...timestamps];timestamps.sort((x,y)=>x-y);const segments=[];for(let i=0;i<timestamps.length-1;++i){const segment=new tr.model.um.Segment(timestamps[i],timestamps[i+1]-timestamps[i]);segments.push(segment);const segmentRange=tr.b.math.Range.fromExplicitRange(segment.start,segment.end);for(const expectation of this.model.userModel.expectations){const expectationRange=tr.b.math.Range.fromExplicitRange(expectation.start,expectation.end);if(segmentRange.intersectsRangeExclusive(expectationRange)){segment.expectations.push(expectation);}}}
+return segments;}
+findUserExpectations(){const expectations=[];expectations.push.apply(expectations,tr.importer.findStartupExpectations(this.modelHelper));expectations.push.apply(expectations,tr.importer.findLoadExpectations(this.modelHelper));expectations.push.apply(expectations,tr.importer.findInputExpectations(this.modelHelper));expectations.push.apply(expectations,this.findIdleExpectations(expectations));this.collectUnassociatedEvents_(expectations);return expectations;}
+collectUnassociatedEvents_(expectations){const vacuumUEs=[];for(const expectation of expectations){if(expectation instanceof tr.model.um.IdleExpectation||expectation instanceof tr.model.um.LoadExpectation||expectation instanceof tr.model.um.StartupExpectation){vacuumUEs.push(expectation);}}
+if(vacuumUEs.length===0)return;const allAssociatedEvents=tr.model.getAssociatedEvents(expectations);const unassociatedEvents=tr.model.getUnassociatedEvents(this.model,allAssociatedEvents);for(const event of unassociatedEvents){if(!(event instanceof tr.model.ThreadSlice))continue;if(!event.isTopLevel)continue;for(let index=0;index<vacuumUEs.length;++index){const expectation=vacuumUEs[index];if((event.start>=expectation.start)&&(event.start<expectation.end)){expectation.associatedEvents.addEventSet(event.entireHierarchy);break;}}}}
+findIdleExpectations(otherUEs){if(this.model.bounds.isEmpty)return;const emptyRanges=tr.b.math.findEmptyRangesBetweenRanges(tr.b.math.convertEventsToRanges(otherUEs),this.model.bounds);const expectations=[];const model=this.model;for(const range of emptyRanges){if(range.max<(range.min+INSIGNIFICANT_MS))continue;expectations.push(new tr.model.um.IdleExpectation(model,range.min,range.max-range.min));}
+return expectations;}}
+function createCustomizeModelLinesFromModel(model){const modelLines=[];modelLines.push('      audits.addEvent(model.browserMain,');modelLines.push('          {title: \'model start\', start: 0, end: 1});');const typeNames={};for(const typeName in tr.e.cc.INPUT_EVENT_TYPE_NAMES){typeNames[tr.e.cc.INPUT_EVENT_TYPE_NAMES[typeName]]=typeName;}
+let modelEvents=new tr.model.EventSet();for(const ue of model.userModel.expectations){modelEvents.addEventSet(ue.sourceEvents);}
+modelEvents=modelEvents.toArray();modelEvents.sort(tr.importer.compareEvents);for(const event of modelEvents){const startAndEnd='start: '+parseInt(event.start)+', '+'end: '+parseInt(event.end)+'});';if(event instanceof tr.e.cc.InputLatencyAsyncSlice){modelLines.push('      audits.addInputEvent(model, INPUT_TYPE.'+
+typeNames[event.typeName]+',');}else if(event.title==='RenderFrameImpl::didCommitProvisionalLoad'){modelLines.push('      audits.addCommitLoadEvent(model,');}else if(event.title==='InputHandlerProxy::HandleGestureFling::started'){modelLines.push('      audits.addFlingAnimationEvent(model,');}else if(event.title===tr.model.helpers.IMPL_RENDERING_STATS){modelLines.push('      audits.addFrameEvent(model,');}else if(event.title===tr.importer.CSS_ANIMATION_TITLE){modelLines.push('      audits.addEvent(model.rendererMain, {');modelLines.push('        title: \'Animation\', '+startAndEnd);return;}else{throw new Error('You must extend createCustomizeModelLinesFromModel()'+'to support this event:\n'+event.title+'\n');}
+modelLines.push('          {'+startAndEnd);}
+modelLines.push('      audits.addEvent(model.browserMain,');modelLines.push('          {'+'title: \'model end\', '+'start: '+(parseInt(model.bounds.max)-1)+', '+'end: '+parseInt(model.bounds.max)+'});');return modelLines;}
+function createExpectedUELinesFromModel(model){const expectedLines=[];const ueCount=model.userModel.expectations.length;for(let index=0;index<ueCount;++index){const expectation=model.userModel.expectations[index];let ueString='      {';ueString+='title: \''+expectation.title+'\', ';ueString+='start: '+parseInt(expectation.start)+', ';ueString+='end: '+parseInt(expectation.end)+', ';ueString+='eventCount: '+expectation.sourceEvents.length;ueString+='}';if(index<(ueCount-1))ueString+=',';expectedLines.push(ueString);}
+return expectedLines;}
+function createUEFinderTestCaseStringFromModel(model){const filename=window.location.hash.substr(1);let testName=filename.substr(filename.lastIndexOf('/')+1);testName=testName.substr(0,testName.indexOf('.'));try{const testLines=[];testLines.push('  /*');testLines.push('    This test was generated from');testLines.push('    '+filename+'');testLines.push('   */');testLines.push('  test(\''+testName+'\', function() {');testLines.push('    const verifier = new UserExpectationVerifier();');testLines.push('    verifier.customizeModelCallback = function(model) {');testLines.push.apply(testLines,createCustomizeModelLinesFromModel(model));testLines.push('    };');testLines.push('    verifier.expectedUEs = [');testLines.push.apply(testLines,createExpectedUELinesFromModel(model));testLines.push('    ];');testLines.push('    verifier.verify();');testLines.push('  });');return testLines.join('\n');}catch(error){return error;}}
+return{UserModelBuilder,createUEFinderTestCaseStringFromModel,};});'use strict';tr.exportTo('tr.ui.b',function(){function decorate(source,constr){let elements;if(typeof source==='string'){elements=Polymer.dom(tr.doc).querySelectorAll(source);}else{elements=[source];}
+for(let i=0,el;el=elements[i];i++){if(!(el instanceof constr)){constr.decorate(el);}}}
+function define(className,opt_parentConstructor,opt_tagNS){if(typeof className==='function'){throw new Error('Passing functions as className is deprecated. Please '+'use (className, opt_parentConstructor) to subclass');}
+className=className.toLowerCase();if(opt_parentConstructor&&!opt_parentConstructor.tagName){throw new Error('opt_parentConstructor was not '+'created by tr.ui.b.define');}
+let tagName=className;let tagNS=undefined;if(opt_parentConstructor){if(opt_tagNS){throw new Error('Must not specify tagNS if parentConstructor is given');}
+let parent=opt_parentConstructor;while(parent&&parent.tagName){tagName=parent.tagName;tagNS=parent.tagNS;parent=parent.parentConstructor;}}else{tagNS=opt_tagNS;}
+function f(){if(opt_parentConstructor&&f.prototype.__proto__!==opt_parentConstructor.prototype){throw new Error(className+' prototye\'s __proto__ field is messed up. '+'It MUST be the prototype of '+opt_parentConstructor.tagName);}
+let el;if(tagNS===undefined){el=tr.doc.createElement(tagName);}else{el=tr.doc.createElementNS(tagNS,tagName);}
+f.decorate.call(this,el,arguments);return el;}
+f.decorate=function(el){el.__proto__=f.prototype;el.decorate.apply(el,arguments[1]);el.constructor=f;};f.className=className;f.tagName=tagName;f.tagNS=tagNS;f.parentConstructor=(opt_parentConstructor?opt_parentConstructor:undefined);f.toString=function(){if(!f.parentConstructor){return f.tagName;}
+return f.parentConstructor.toString()+'::'+f.className;};return f;}
+function elementIsChildOf(el,potentialParent){if(el===potentialParent)return false;let cur=el;while(Polymer.dom(cur).parentNode){if(cur===potentialParent)return true;cur=Polymer.dom(cur).parentNode;}
+return false;}
+return{decorate,define,elementIsChildOf,};});'use strict';tr.exportTo('tr.b.math',function(){function Rect(){this.x=0;this.y=0;this.width=0;this.height=0;}
+Rect.fromXYWH=function(x,y,w,h){const rect=new Rect();rect.x=x;rect.y=y;rect.width=w;rect.height=h;return rect;};Rect.fromArray=function(ary){if(ary.length!==4){throw new Error('ary.length must be 4');}
+const rect=new Rect();rect.x=ary[0];rect.y=ary[1];rect.width=ary[2];rect.height=ary[3];return rect;};Rect.prototype={__proto__:Object.prototype,get left(){return this.x;},get top(){return this.y;},get right(){return this.x+this.width;},get bottom(){return this.y+this.height;},toString(){return'Rect('+this.x+', '+this.y+', '+
+this.width+', '+this.height+')';},toArray(){return[this.x,this.y,this.width,this.height];},clone(){const rect=new Rect();rect.x=this.x;rect.y=this.y;rect.width=this.width;rect.height=this.height;return rect;},enlarge(pad){const rect=new Rect();this.enlargeFast(rect,pad);return rect;},enlargeFast(out,pad){out.x=this.x-pad;out.y=this.y-pad;out.width=this.width+2*pad;out.height=this.height+2*pad;return out;},size(){return{width:this.width,height:this.height};},scale(s){const rect=new Rect();this.scaleFast(rect,s);return rect;},scaleSize(s){return Rect.fromXYWH(this.x,this.y,this.width*s,this.height*s);},scaleFast(out,s){out.x=this.x*s;out.y=this.y*s;out.width=this.width*s;out.height=this.height*s;return out;},translate(v){const rect=new Rect();this.translateFast(rect,v);return rect;},translateFast(out,v){out.x=this.x+v[0];out.y=this.x+v[1];out.width=this.width;out.height=this.height;return out;},asUVRectInside(containingRect){const rect=new Rect();rect.x=(this.x-containingRect.x)/containingRect.width;rect.y=(this.y-containingRect.y)/containingRect.height;rect.width=this.width/containingRect.width;rect.height=this.height/containingRect.height;return rect;},intersects(that){let ok=true;ok&=this.x<that.right;ok&=this.right>that.x;ok&=this.y<that.bottom;ok&=this.bottom>that.y;return ok;},equalTo(rect){return rect&&(this.x===rect.x)&&(this.y===rect.y)&&(this.width===rect.width)&&(this.height===rect.height);}};return{Rect,};});'use strict';tr.exportTo('tr.ui.b',function(){function instantiateTemplate(selector,doc){doc=doc||document;const el=Polymer.dom(doc).querySelector(selector);if(!el){throw new Error('Element not found: '+selector);}
+return doc.importNode(el.content,true);}
+function windowRectForElement(element){const position=[element.offsetLeft,element.offsetTop];const size=[element.offsetWidth,element.offsetHeight];let node=element.offsetParent;while(node){position[0]+=node.offsetLeft;position[1]+=node.offsetTop;node=node.offsetParent;}
+return tr.b.math.Rect.fromXYWH(position[0],position[1],size[0],size[1]);}
+function scrollIntoViewIfNeeded(el){const pr=el.parentElement.getBoundingClientRect();const cr=el.getBoundingClientRect();if(cr.top<pr.top){el.scrollIntoView(true);}else if(cr.bottom>pr.bottom){el.scrollIntoView(false);}}
+function extractUrlString(url){let extracted=url.replace(/url\((.*)\)/,'$1');extracted=extracted.replace(/\"(.*)\"/,'$1');return extracted;}
+function toThreeDigitLocaleString(value){return value.toLocaleString(undefined,{minimumFractionDigits:3,maximumFractionDigits:3});}
+function isUnknownElementName(name){return document.createElement(name)instanceof HTMLUnknownElement;}
+return{isUnknownElementName,toThreeDigitLocaleString,instantiateTemplate,windowRectForElement,scrollIntoViewIfNeeded,extractUrlString,};});'use strict';tr.exportTo('tr.ui.b',function(){if(tr.isHeadless)return{};const THIS_DOC=document.currentScript.ownerDocument;const Overlay=tr.ui.b.define('overlay');Overlay.prototype={__proto__:HTMLDivElement.prototype,decorate(){Polymer.dom(this).classList.add('overlay');this.parentEl_=this.ownerDocument.body;this.visible_=false;this.userCanClose_=true;this.onKeyDown_=this.onKeyDown_.bind(this);this.onClick_=this.onClick_.bind(this);this.onFocusIn_=this.onFocusIn_.bind(this);this.onDocumentClick_=this.onDocumentClick_.bind(this);this.onClose_=this.onClose_.bind(this);this.addEventListener('visible-change',tr.ui.b.Overlay.prototype.onVisibleChange_.bind(this),true);const createShadowRoot=this.createShadowRoot||this.webkitCreateShadowRoot;this.shadow_=createShadowRoot.call(this);Polymer.dom(this.shadow_).appendChild(tr.ui.b.instantiateTemplate('#overlay-template',THIS_DOC));this.closeBtn_=Polymer.dom(this.shadow_).querySelector('close-button');this.closeBtn_.addEventListener('click',this.onClose_);Polymer.dom(this.shadow_).querySelector('overlay-frame').addEventListener('click',this.onClick_);this.observer_=new WebKitMutationObserver(this.didButtonBarMutate_.bind(this));this.observer_.observe(Polymer.dom(this.shadow_).querySelector('button-bar'),{childList:true});Object.defineProperty(this,'title',{get(){return Polymer.dom(Polymer.dom(this.shadow_).querySelector('title')).textContent;},set(title){Polymer.dom(Polymer.dom(this.shadow_).querySelector('title')).textContent=title;}});},set userCanClose(userCanClose){this.userCanClose_=userCanClose;this.closeBtn_.style.display=userCanClose?'block':'none';},get buttons(){return Polymer.dom(this.shadow_).querySelector('button-bar');},get visible(){return this.visible_;},set visible(newValue){if(this.visible_===newValue)return;this.visible_=newValue;const e=new tr.b.Event('visible-change');this.dispatchEvent(e);},onVisibleChange_(){this.visible_?this.show_():this.hide_();},show_(){Polymer.dom(this.parentEl_).appendChild(this);if(this.userCanClose_){this.addEventListener('keydown',this.onKeyDown_.bind(this));this.addEventListener('click',this.onDocumentClick_.bind(this));this.closeBtn_.addEventListener('click',this.onClose_);}
+this.parentEl_.addEventListener('focusin',this.onFocusIn_);this.tabIndex=0;const elList=Polymer.dom(this).querySelectorAll('button, input, list, select, a');if(elList.length>0){if(elList[0]===this.closeBtn_){if(elList.length>1)return elList[1].focus();}else{return elList[0].focus();}}
+this.focus();},hide_(){Polymer.dom(this.parentEl_).removeChild(this);this.parentEl_.removeEventListener('focusin',this.onFocusIn_);if(this.closeBtn_){this.closeBtn_.removeEventListener('click',this.onClose_);}
+document.removeEventListener('keydown',this.onKeyDown_);document.removeEventListener('click',this.onDocumentClick_);},onClose_(e){this.visible=false;if((e.type!=='keydown')||(e.type==='keydown'&&e.keyCode===27)){e.stopPropagation();}
+e.preventDefault();tr.b.dispatchSimpleEvent(this,'closeclick');},onFocusIn_(e){let node=e.target;while(node){if(node===this){return;}
+node=node.parentNode;}
+tr.b.timeout(0).then(()=>this.focus());e.preventDefault();e.stopPropagation();},didButtonBarMutate_(e){const hasButtons=this.buttons.children.length>0;if(hasButtons){Polymer.dom(this.shadow_).querySelector('button-bar').style.display=undefined;}else{Polymer.dom(this.shadow_).querySelector('button-bar').style.display='none';}},onKeyDown_(e){if(e.keyCode===9&&e.shiftKey&&e.target===this){e.preventDefault();return;}
+if(e.keyCode!==27)return;this.onClose_(e);},onClick_(e){e.stopPropagation();},onDocumentClick_(e){if(!this.userCanClose_)return;this.onClose_(e);}};Overlay.showError=function(msg,opt_err){const o=new Overlay();o.title='Error';Polymer.dom(o).textContent=msg;if(opt_err){const e=tr.b.normalizeException(opt_err);const stackDiv=document.createElement('pre');Polymer.dom(stackDiv).textContent=e.stack;stackDiv.style.paddingLeft='8px';stackDiv.style.margin=0;Polymer.dom(o).appendChild(stackDiv);}
+const b=document.createElement('button');Polymer.dom(b).textContent='OK';b.addEventListener('click',function(){o.visible=false;});Polymer.dom(o.buttons).appendChild(b);o.visible=true;return o;};return{Overlay,};});'use strict';tr.exportTo('tr.importer',function(){const Timing=tr.b.Timing;function ImportOptions(){this.shiftWorldToZero=true;this.pruneEmptyContainers=true;this.showImportWarnings=true;this.trackDetailedModelStats=false;this.customizeModelCallback=undefined;const auditorTypes=tr.c.Auditor.getAllRegisteredTypeInfos();this.auditorConstructors=auditorTypes.map(function(typeInfo){return typeInfo.constructor;});}
+function Import(model,opt_options){if(model===undefined){throw new Error('Must provide model to import into.');}
+this.importing_=false;this.importOptions_=opt_options||new ImportOptions();this.model_=model;this.model_.importOptions=this.importOptions_;}
+Import.prototype={__proto__:Object.prototype,importTraces(traces){const progressMeter={update(msg){}};tr.b.Task.RunSynchronously(this.createImportTracesTask(progressMeter,traces));},importTracesWithProgressDialog(traces){if(tr.isHeadless){throw new Error('Cannot use this method in headless mode.');}
+const overlay=tr.ui.b.Overlay();overlay.title='Importing...';overlay.userCanClose=false;overlay.msgEl=document.createElement('div');Polymer.dom(overlay).appendChild(overlay.msgEl);overlay.msgEl.style.margin='20px';overlay.update=function(msg){Polymer.dom(this.msgEl).textContent=msg;};overlay.visible=true;const promise=tr.b.Task.RunWhenIdle(this.createImportTracesTask(overlay,traces));promise.then(function(){overlay.visible=false;},function(err){overlay.visible=false;});return promise;},createImportTracesTask(progressMeter,traces){const importStartTimeMs=tr.b.Timing.getCurrentTimeMs();if(this.importing_){throw new Error('Already importing.');}
+this.importing_=true;const importTask=new tr.b.Task(function prepareImport(){progressMeter.update('I will now import your traces for you...');},this);let lastTask=importTask;const importers=[];function addImportStage(title,callback){lastTask=lastTask.after(()=>progressMeter.update(title));lastTask.updatesUi=true;lastTask=lastTask.after(callback);}
+function addStageForEachImporter(title,callback){lastTask=lastTask.after((task)=>{importers.forEach((importer,index)=>{const uiSubTask=task.subTask(()=>{progressMeter.update(`${title} ${index + 1} of ${importers.length}`);});uiSubTask.updatesUi=true;task.subTask(()=>callback(importer));});});}
+addImportStage('Creating importers...',()=>{traces=traces.slice(0);progressMeter.update('Creating importers...');for(let i=0;i<traces.length;++i){importers.push(this.createImporter_(traces[i]));}
+for(let i=0;i<importers.length;i++){const subtraces=importers[i].extractSubtraces();for(let j=0;j<subtraces.length;j++){try{traces.push(subtraces[j]);importers.push(this.createImporter_(subtraces[j]));}catch(error){this.model_.importWarning({type:error.name,message:error.message,showToUser:true,});continue;}}}
 if(traces.length&&!this.hasEventDataDecoder_(importers)){throw new Error('Could not find an importer for the provided eventData.');}
-importers.sort(function(x,y){return x.importPriority-y.importPriority;});},this);lastTask=lastTask.timedAfter('TraceImport',function importClockSyncMarkers(task){importers.forEach(function(importer,index){task.subTask(Timing.wrapNamedFunction('TraceImport',importer.importerName,function runImportClockSyncMarkersOnOneImporter(){progressMeter.update('Importing clock sync markers '+(index+1)+' of '+
-importers.length);importer.importClockSyncMarkers();}),this);},this);},this);lastTask=lastTask.timedAfter('TraceImport',function runImport(task){importers.forEach(function(importer,index){task.subTask(Timing.wrapNamedFunction('TraceImport',importer.importerName,function runImportEventsOnOneImporter(){progressMeter.update('Importing '+(index+1)+' of '+importers.length);importer.importEvents();}),this);},this);},this);if(this.importOptions_.customizeModelCallback){lastTask=lastTask.timedAfter('TraceImport',function runCustomizeCallbacks(task){this.importOptions_.customizeModelCallback(this.model_);},this);}
-lastTask=lastTask.timedAfter('TraceImport',function importSampleData(task){importers.forEach(function(importer,index){progressMeter.update('Importing sample data '+(index+1)+'/'+importers.length);importer.importSampleData();},this);},this);lastTask=lastTask.timedAfter('TraceImport',function runAutoclosers(){progressMeter.update('Autoclosing open slices...');this.model_.autoCloseOpenSlices();this.model_.createSubSlices();},this);lastTask=lastTask.timedAfter('TraceImport',function finalizeImport(task){importers.forEach(function(importer,index){progressMeter.update('Finalizing import '+(index+1)+'/'+importers.length);importer.finalizeImport();},this);},this);lastTask=lastTask.timedAfter('TraceImport',function runPreinits(){progressMeter.update('Initializing objects (step 1/2)...');this.model_.preInitializeObjects();},this);if(this.importOptions_.pruneEmptyContainers){lastTask=lastTask.timedAfter('TraceImport',function runPruneEmptyContainers(){progressMeter.update('Pruning empty containers...');this.model_.pruneEmptyContainers();},this);}
-lastTask=lastTask.timedAfter('TraceImport',function runMergeKernelWithuserland(){progressMeter.update('Merging kernel with userland...');this.model_.mergeKernelWithUserland();},this);var auditors=[];lastTask=lastTask.timedAfter('TraceImport',function createAuditorsAndRunAnnotate(){progressMeter.update('Adding arbitrary data to model...');auditors=this.importOptions_.auditorConstructors.map(function(auditorConstructor){return new auditorConstructor(this.model_);},this);auditors.forEach(function(auditor){auditor.runAnnotate();auditor.installUserFriendlyCategoryDriverIfNeeded();});},this);lastTask=lastTask.timedAfter('TraceImport',function computeWorldBounds(){progressMeter.update('Computing final world bounds...');this.model_.computeWorldBounds(this.importOptions_.shiftWorldToZero);},this);lastTask=lastTask.timedAfter('TraceImport',function buildFlowEventIntervalTree(){progressMeter.update('Building flow event map...');this.model_.buildFlowEventIntervalTree();},this);lastTask=lastTask.timedAfter('TraceImport',function joinRefs(){progressMeter.update('Joining object refs...');this.model_.joinRefs();},this);lastTask=lastTask.timedAfter('TraceImport',function cleanupUndeletedObjects(){progressMeter.update('Cleaning up undeleted objects...');this.model_.cleanupUndeletedObjects();},this);lastTask=lastTask.timedAfter('TraceImport',function sortMemoryDumps(){progressMeter.update('Sorting memory dumps...');this.model_.sortMemoryDumps();},this);lastTask=lastTask.timedAfter('TraceImport',function finalizeMemoryGraphs(){progressMeter.update('Finalizing memory dump graphs...');this.model_.finalizeMemoryGraphs();},this);lastTask=lastTask.timedAfter('TraceImport',function initializeObjects(){progressMeter.update('Initializing objects (step 2/2)...');this.model_.initializeObjects();},this);lastTask=lastTask.timedAfter('TraceImport',function buildEventIndices(){progressMeter.update('Building event indices...');this.model_.buildEventIndices();},this);lastTask=lastTask.timedAfter('TraceImport',function buildUserModel(){progressMeter.update('Building UserModel...');var userModelBuilder=new tr.importer.UserModelBuilder(this.model_);userModelBuilder.buildUserModel();},this);lastTask=lastTask.timedAfter('TraceImport',function sortExpectations(){progressMeter.update('Sorting user expectations...');this.model_.userModel.sortExpectations();},this);lastTask=lastTask.timedAfter('TraceImport',function runAudits(){progressMeter.update('Running auditors...');auditors.forEach(function(auditor){auditor.runAudit();});},this);lastTask=lastTask.timedAfter('TraceImport',function sortAlerts(){progressMeter.update('Updating alerts...');this.model_.sortAlerts();},this);lastTask=lastTask.timedAfter('TraceImport',function lastUpdateBounds(){progressMeter.update('Update bounds...');this.model_.updateBounds();},this);lastTask=lastTask.timedAfter('TraceImport',function addModelWarnings(){progressMeter.update('Looking for warnings...');if(!this.model_.isTimeHighResolution){this.model_.importWarning({type:'low_resolution_timer',message:'Trace time is low resolution, trace may be unusable.',showToUser:true});}},this);lastTask.after(function(){this.importing_=false;},this);return importTask;},createImporter_:function(eventData){var importerConstructor=tr.importer.Importer.findImporterFor(eventData);if(!importerConstructor){throw new Error('Couldn\'t create an importer for the provided '+'eventData.');}
-return new importerConstructor(this.model_,eventData);},hasEventDataDecoder_:function(importers){for(var i=0;i<importers.length;++i){if(!importers[i].isTraceDataContainer())
-return true;}
-return false;}};return{ImportOptions:ImportOptions,Import:Import};});'use strict';tr.exportTo('tr.e.cc',function(){function PictureAsImageData(picture,errorOrImageData){this.picture_=picture;if(errorOrImageData instanceof ImageData){this.error_=undefined;this.imageData_=errorOrImageData;}else{this.error_=errorOrImageData;this.imageData_=undefined;}};PictureAsImageData.Pending=function(picture){return new PictureAsImageData(picture,undefined);};PictureAsImageData.prototype={get picture(){return this.picture_;},get error(){return this.error_;},get imageData(){return this.imageData_;},isPending:function(){return this.error_===undefined&&this.imageData_===undefined;},asCanvas:function(){if(!this.imageData_)
-return;var canvas=document.createElement('canvas');var ctx=canvas.getContext('2d');canvas.width=this.imageData_.width;canvas.height=this.imageData_.height;ctx.putImageData(this.imageData_,0,0);return canvas;}};return{PictureAsImageData:PictureAsImageData};});'use strict';tr.exportTo('tr.e.cc',function(){var convertedNameCache={};function convertNameToJSConvention(name){if(name in convertedNameCache)
-return convertedNameCache[name];if(name[0]=='_'||name[name.length-1]=='_'){convertedNameCache[name]=name;return name;}
-var words=name.split('_');if(words.length==1){convertedNameCache[name]=words[0];return words[0];}
-for(var i=1;i<words.length;i++)
-words[i]=words[i][0].toUpperCase()+words[i].substring(1);convertedNameCache[name]=words.join('');return convertedNameCache[name];}
-function convertObjectFieldNamesToJSConventions(object){tr.b.iterObjectFieldsRecursively(object,function(object,fieldName,fieldValue){delete object[fieldName];object[newFieldName]=fieldValue;return newFieldName;});}
-function convertQuadSuffixedTypesToQuads(object){tr.b.iterObjectFieldsRecursively(object,function(object,fieldName,fieldValue){});}
-function convertObject(object){convertObjectFieldNamesToJSConventions(object);convertQuadSuffixedTypesToQuads(object);}
-function moveRequiredFieldsFromArgsToToplevel(object,fields){for(var i=0;i<fields.length;i++){var key=fields[i];if(object.args[key]===undefined)
-throw Error('Expected field '+key+' not found in args');if(object[key]!==undefined)
-throw Error('Field '+key+' already in object');object[key]=object.args[key];delete object.args[key];}}
-function moveOptionalFieldsFromArgsToToplevel(object,fields){for(var i=0;i<fields.length;i++){var key=fields[i];if(object.args[key]===undefined)
-continue;if(object[key]!==undefined)
-throw Error('Field '+key+' already in object');object[key]=object.args[key];delete object.args[key];}}
+importers.sort(function(x,y){return x.importPriority-y.importPriority;});});addStageForEachImporter('Importing clock sync markers',importer=>importer.importClockSyncMarkers());addStageForEachImporter('Importing',importer=>importer.importEvents());if(this.importOptions_.customizeModelCallback){addImportStage('Customizing',()=>{this.importOptions_.customizeModelCallback(this.model_);});}
+addStageForEachImporter('Importing sample data',importer=>importer.importSampleData());addImportStage('Autoclosing open slices...',()=>{this.model_.autoCloseOpenSlices();this.model_.createSubSlices();});addStageForEachImporter('Finalizing import',importer=>importer.finalizeImport());addImportStage('Initializing objects (step 1/2)...',()=>this.model_.preInitializeObjects());if(this.importOptions_.pruneEmptyContainers){addImportStage('Pruning empty containers...',()=>this.model_.pruneEmptyContainers());}
+addImportStage('Merging kernel with userland...',()=>this.model_.mergeKernelWithUserland());let auditors=[];addImportStage('Adding arbitrary data to model...',()=>{auditors=this.importOptions_.auditorConstructors.map(auditorConstructor=>new auditorConstructor(this.model_));auditors.forEach((auditor)=>{auditor.runAnnotate();auditor.installUserFriendlyCategoryDriverIfNeeded();});});addImportStage('Computing final world bounds...',()=>{this.model_.computeWorldBounds(this.importOptions_.shiftWorldToZero);});addImportStage('Building flow event map...',()=>this.model_.buildFlowEventIntervalTree());addImportStage('Joining object refs...',()=>this.model_.joinRefs());addImportStage('Cleaning up undeleted objects...',()=>this.model_.cleanupUndeletedObjects());addImportStage('Sorting memory dumps...',()=>this.model_.sortMemoryDumps());addImportStage('Finalizing memory dump graphs...',()=>this.model_.finalizeMemoryGraphs());addImportStage('Initializing objects (step 2/2)...',()=>this.model_.initializeObjects());addImportStage('Building event indices...',()=>this.model_.buildEventIndices());addImportStage('Building UserModel...',()=>{const userModelBuilder=new tr.importer.UserModelBuilder(this.model_);userModelBuilder.buildUserModel();});addImportStage('Sorting user expectations...',()=>this.model_.userModel.sortExpectations());addImportStage('Running auditors...',()=>{auditors.forEach(auditor=>auditor.runAudit());});addImportStage('Updating alerts...',()=>this.model_.sortAlerts());addImportStage('Update bounds...',()=>this.model_.updateBounds());addImportStage('Looking for warnings...',()=>{if(!this.model_.isTimeHighResolution){this.model_.importWarning({type:'low_resolution_timer',message:'Trace time is low resolution, trace may be unusable.',showToUser:true});}});lastTask.after(()=>{this.importing_=false;this.model_.stats.traceImportDurationMs=tr.b.Timing.getCurrentTimeMs()-importStartTimeMs;});return importTask;},createImporter_(eventData){const importerConstructor=tr.importer.Importer.findImporterFor(eventData);if(!importerConstructor){throw new Error('Couldn\'t create an importer for the provided '+'eventData.');}
+return new importerConstructor(this.model_,eventData);},hasEventDataDecoder_(importers){for(let i=0;i<importers.length;++i){if(!importers[i].isTraceDataContainer())return true;}
+return false;}};return{ImportOptions,Import,};});'use strict';tr.exportTo('tr.e.v8',function(){const ThreadSlice=tr.model.ThreadSlice;function V8GCStatsThreadSlice(){ThreadSlice.apply(this,arguments);this.liveObjects_=JSON.parse(this.args.live);delete this.args.live;this.deadObjects_=JSON.parse(this.args.dead);delete this.args.dead;}
+V8GCStatsThreadSlice.prototype={__proto__:ThreadSlice.prototype,get liveObjects(){return this.liveObjects_;},get deadObjects(){return this.deadObjects_;}};ThreadSlice.subTypes.register(V8GCStatsThreadSlice,{categoryParts:['disabled-by-default-v8.gc_stats'],name:'v8 gc stats slice',pluralName:'v8 gc stats slices'});return{V8GCStatsThreadSlice,};});'use strict';tr.exportTo('tr.e.v8',function(){const ThreadSlice=tr.model.ThreadSlice;function V8ICStatsThreadSlice(){ThreadSlice.apply(this,arguments);this.icStats_=undefined;if(this.args['ic-stats']){this.icStats_=this.args['ic-stats'].data;delete this.args['ic-stats'];}}
+V8ICStatsThreadSlice.prototype={__proto__:ThreadSlice.prototype,get icStats(){return this.icStats_;}};ThreadSlice.subTypes.register(V8ICStatsThreadSlice,{categoryParts:['disabled-by-default-v8.ic_stats'],name:'v8 ic stats slice',pluralName:'v8 ic stats slices'});return{V8ICStatsThreadSlice,};});'use strict';tr.exportTo('tr.e.v8',function(){const ThreadSlice=tr.model.ThreadSlice;function V8ThreadSlice(){ThreadSlice.apply(this,arguments);this.runtimeCallStats_=undefined;}
+V8ThreadSlice.prototype={__proto__:ThreadSlice.prototype,get runtimeCallStats(){if('runtime-call-stats'in this.args){this.runtimeCallStats_=this.args['runtime-call-stats'];delete this.args['runtime-call-stats'];}
+return this.runtimeCallStats_;}};ThreadSlice.subTypes.register(V8ThreadSlice,{categoryParts:['v8','disabled-by-default-v8.runtime_stats'],name:'v8 slice',pluralName:'v8 slices'});return{V8ThreadSlice,};});'use strict';tr.exportTo('tr.e.cc',function(){function PictureAsImageData(picture,errorOrImageData){this.picture_=picture;if(errorOrImageData instanceof ImageData){this.error_=undefined;this.imageData_=errorOrImageData;}else{this.error_=errorOrImageData;this.imageData_=undefined;}}
+PictureAsImageData.Pending=function(picture){return new PictureAsImageData(picture,undefined);};PictureAsImageData.prototype={get picture(){return this.picture_;},get error(){return this.error_;},get imageData(){return this.imageData_;},isPending(){return this.error_===undefined&&this.imageData_===undefined;},asCanvas(){if(!this.imageData_)return;const canvas=document.createElement('canvas');const ctx=canvas.getContext('2d');canvas.width=this.imageData_.width;canvas.height=this.imageData_.height;ctx.putImageData(this.imageData_,0,0);return canvas;}};return{PictureAsImageData,};});'use strict';tr.exportTo('tr.e.cc',function(){const convertedNameCache={};function convertNameToJSConvention(name){if(name in convertedNameCache){return convertedNameCache[name];}
+if(name[0]==='_'||name[name.length-1]==='_'){convertedNameCache[name]=name;return name;}
+const words=name.split('_');if(words.length===1){convertedNameCache[name]=words[0];return words[0];}
+for(let i=1;i<words.length;i++){words[i]=words[i][0].toUpperCase()+words[i].substring(1);}
+convertedNameCache[name]=words.join('');return convertedNameCache[name];}
+function moveRequiredFieldsFromArgsToToplevel(object,fields){for(let i=0;i<fields.length;i++){const key=fields[i];if(object.args[key]===undefined){throw Error('Expected field '+key+' not found in args');}
+if(object[key]!==undefined){throw Error('Field '+key+' already in object');}
+object[key]=object.args[key];delete object.args[key];}}
+function moveOptionalFieldsFromArgsToToplevel(object,fields){for(let i=0;i<fields.length;i++){const key=fields[i];if(object.args[key]===undefined)continue;if(object[key]!==undefined){throw Error('Field '+key+' already in object');}
+object[key]=object.args[key];delete object.args[key];}}
 function preInitializeObject(object){preInitializeObjectInner(object.args,false);}
-function preInitializeObjectInner(object,hasRecursed){if(!(object instanceof Object))
-return;if(object instanceof Array){for(var i=0;i<object.length;i++)
-preInitializeObjectInner(object[i],true);return;}
-if(hasRecursed&&(object instanceof tr.model.ObjectSnapshot||object instanceof tr.model.ObjectInstance))
-return;for(var key in object){var newKey=convertNameToJSConvention(key);if(newKey!=key){var value=object[key];delete object[key];object[newKey]=value;key=newKey;}
-if(/Quad$/.test(key)&&!(object[key]instanceof tr.b.Quad)){var q;try{q=tr.b.Quad.from8Array(object[key]);}catch(e){console.log(e);}
+function preInitializeObjectInner(object,hasRecursed){if(!(object instanceof Object))return;if(object instanceof Array){for(let i=0;i<object.length;i++){preInitializeObjectInner(object[i],true);}
+return;}
+if(hasRecursed&&(object instanceof tr.model.ObjectSnapshot||object instanceof tr.model.ObjectInstance)){return;}
+for(let key in object){const newKey=convertNameToJSConvention(key);if(newKey!==key){const value=object[key];delete object[key];object[newKey]=value;key=newKey;}
+if(/Quad$/.test(key)&&!(object[key]instanceof tr.b.math.Quad)){let q;try{q=tr.b.math.Quad.from8Array(object[key]);}catch(e){}
 object[key]=q;continue;}
-if(/Rect$/.test(key)&&!(object[key]instanceof tr.b.Rect)){var r;try{r=tr.b.Rect.fromArray(object[key]);}catch(e){console.log(e);}
+if(/Rect$/.test(key)&&!(object[key]instanceof tr.b.math.Rect)){let r;try{r=tr.b.math.Rect.fromArray(object[key]);}catch(e){}
 object[key]=r;}
 preInitializeObjectInner(object[key],true);}}
-function bytesToRoundedMegabytes(bytes){return Math.round(bytes/100000.0)/10.0;}
-return{preInitializeObject:preInitializeObject,convertNameToJSConvention:convertNameToJSConvention,moveRequiredFieldsFromArgsToToplevel:moveRequiredFieldsFromArgsToToplevel,moveOptionalFieldsFromArgsToToplevel:moveOptionalFieldsFromArgsToToplevel,bytesToRoundedMegabytes:bytesToRoundedMegabytes};});'use strict';tr.exportTo('tr.e.cc',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;var PictureCount=0;var OPS_TIMING_ITERATIONS=3;function Picture(skp64,layerRect){this.skp64_=skp64;this.layerRect_=layerRect;this.guid_=tr.b.GUID.allocate();}
-Picture.prototype={get canSave(){return true;},get layerRect(){return this.layerRect_;},get guid(){return this.guid_;},getBase64SkpData:function(){return this.skp64_;},getOps:function(){if(!PictureSnapshot.CanGetOps()){console.error(PictureSnapshot.HowToEnablePictureDebugging());return undefined;}
-var ops=window.chrome.skiaBenchmarking.getOps({skp64:this.skp64_,params:{layer_rect:this.layerRect_.toArray()}});if(!ops)
-console.error('Failed to get picture ops.');return ops;},getOpTimings:function(){if(!PictureSnapshot.CanGetOpTimings()){console.error(PictureSnapshot.HowToEnablePictureDebugging());return undefined;}
-var opTimings=window.chrome.skiaBenchmarking.getOpTimings({skp64:this.skp64_,params:{layer_rect:this.layerRect_.toArray()}});if(!opTimings)
-console.error('Failed to get picture op timings.');return opTimings;},tagOpsWithTimings:function(ops){var opTimings=new Array();for(var iteration=0;iteration<OPS_TIMING_ITERATIONS;iteration++){opTimings[iteration]=this.getOpTimings();if(!opTimings[iteration]||!opTimings[iteration].cmd_times)
-return ops;if(opTimings[iteration].cmd_times.length!=ops.length)
-return ops;}
-for(var opIndex=0;opIndex<ops.length;opIndex++){var min=Number.MAX_VALUE;for(var i=0;i<OPS_TIMING_ITERATIONS;i++)
-min=Math.min(min,opTimings[i].cmd_times[opIndex]);ops[opIndex].cmd_time=min;}
-return ops;},rasterize:function(params,rasterCompleteCallback){if(!PictureSnapshot.CanRasterize()||!PictureSnapshot.CanGetOps()){rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,tr.e.cc.PictureSnapshot.HowToEnablePictureDebugging()));return;}
-var raster=window.chrome.skiaBenchmarking.rasterize({skp64:this.skp64_,params:{layer_rect:this.layerRect_.toArray()}},{stop:params.stopIndex===undefined?-1:params.stopIndex,overdraw:!!params.showOverdraw,params:{}});if(raster){var canvas=document.createElement('canvas');var ctx=canvas.getContext('2d');canvas.width=raster.width;canvas.height=raster.height;var imageData=ctx.createImageData(raster.width,raster.height);imageData.data.set(new Uint8ClampedArray(raster.data));rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,imageData));}else{var error='Failed to rasterize picture. '+'Your recording may be from an old Chrome version. '+'The SkPicture format is not backward compatible.';rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,error));}}};function LayeredPicture(pictures){this.guid_=tr.b.GUID.allocate();this.pictures_=pictures;this.layerRect_=undefined;}
-LayeredPicture.prototype={__proto__:Picture.prototype,get canSave(){return false;},get typeName(){return'cc::LayeredPicture';},get layerRect(){if(this.layerRect_!==undefined)
-return this.layerRect_;this.layerRect_={x:0,y:0,width:0,height:0};for(var i=0;i<this.pictures_.length;++i){var rect=this.pictures_[i].layerRect;this.layerRect_.x=Math.min(this.layerRect_.x,rect.x);this.layerRect_.y=Math.min(this.layerRect_.y,rect.y);this.layerRect_.width=Math.max(this.layerRect_.width,rect.x+rect.width);this.layerRect_.height=Math.max(this.layerRect_.height,rect.y+rect.height);}
-return this.layerRect_;},get guid(){return this.guid_;},getBase64SkpData:function(){throw new Error('Not available with a LayeredPicture.');},getOps:function(){var ops=[];for(var i=0;i<this.pictures_.length;++i)
-ops=ops.concat(this.pictures_[i].getOps());return ops;},getOpTimings:function(){var opTimings=this.pictures_[0].getOpTimings();for(var i=1;i<this.pictures_.length;++i){var timings=this.pictures_[i].getOpTimings();opTimings.cmd_times=opTimings.cmd_times.concat(timings.cmd_times);opTimings.total_time+=timings.total_time;}
-return opTimings;},tagOpsWithTimings:function(ops){var opTimings=new Array();for(var iteration=0;iteration<OPS_TIMING_ITERATIONS;iteration++){opTimings[iteration]=this.getOpTimings();if(!opTimings[iteration]||!opTimings[iteration].cmd_times)
-return ops;}
-for(var opIndex=0;opIndex<ops.length;opIndex++){var min=Number.MAX_VALUE;for(var i=0;i<OPS_TIMING_ITERATIONS;i++)
-min=Math.min(min,opTimings[i].cmd_times[opIndex]);ops[opIndex].cmd_time=min;}
-return ops;},rasterize:function(params,rasterCompleteCallback){this.picturesAsImageData_=[];var rasterCallback=function(pictureAsImageData){this.picturesAsImageData_.push(pictureAsImageData);if(this.picturesAsImageData_.length!==this.pictures_.length)
-return;var canvas=document.createElement('canvas');var ctx=canvas.getContext('2d');canvas.width=this.layerRect.width;canvas.height=this.layerRect.height;for(var i=0;i<this.picturesAsImageData_.length;++i){ctx.putImageData(this.picturesAsImageData_[i].imageData,this.pictures_[i].layerRect.x,this.pictures_[i].layerRect.y);}
-this.picturesAsImageData_=[];rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,ctx.getImageData(this.layerRect.x,this.layerRect.y,this.layerRect.width,this.layerRect.height)));}.bind(this);for(var i=0;i<this.pictures_.length;++i)
-this.pictures_[i].rasterize(params,rasterCallback);}};function PictureSnapshot(){ObjectSnapshot.apply(this,arguments);}
-PictureSnapshot.HasSkiaBenchmarking=function(){return tr.isExported('chrome.skiaBenchmarking');}
-PictureSnapshot.CanRasterize=function(){if(!PictureSnapshot.HasSkiaBenchmarking())
-return false;if(!window.chrome.skiaBenchmarking.rasterize)
-return false;return true;}
-PictureSnapshot.CanGetOps=function(){if(!PictureSnapshot.HasSkiaBenchmarking())
-return false;if(!window.chrome.skiaBenchmarking.getOps)
-return false;return true;}
-PictureSnapshot.CanGetOpTimings=function(){if(!PictureSnapshot.HasSkiaBenchmarking())
-return false;if(!window.chrome.skiaBenchmarking.getOpTimings)
-return false;return true;}
-PictureSnapshot.CanGetInfo=function(){if(!PictureSnapshot.HasSkiaBenchmarking())
-return false;if(!window.chrome.skiaBenchmarking.getInfo)
-return false;return true;}
-PictureSnapshot.HowToEnablePictureDebugging=function(){if(tr.isHeadless)
-return'Pictures only work in chrome';var usualReason=['For pictures to show up, you need to have Chrome running with ','--enable-skia-benchmarking. Please restart chrome with this flag ','and try again.'].join('');if(!tr.isExported('global.chrome.skiaBenchmarking'))
-return usualReason;if(!global.chrome.skiaBenchmarking.rasterize)
-return'Your chrome is old';if(!global.chrome.skiaBenchmarking.getOps)
-return'Your chrome is old: skiaBenchmarking.getOps not found';if(!global.chrome.skiaBenchmarking.getOpTimings)
-return'Your chrome is old: skiaBenchmarking.getOpTimings not found';if(!global.chrome.skiaBenchmarking.getInfo)
-return'Your chrome is old: skiaBenchmarking.getInfo not found';return'Rasterizing is on';}
-PictureSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);this.rasterResult_=undefined;},initialize:function(){if(this.args.alias)
-this.args=this.args.alias.args;if(!this.args.params.layerRect)
-throw new Error('Missing layer rect');this.layerRect_=this.args.params.layerRect;this.picture_=new Picture(this.args.skp64,this.args.params.layerRect);},set picture(picture){this.picture_=picture;},get canSave(){return this.picture_.canSave;},get layerRect(){return this.layerRect_?this.layerRect_:this.picture_.layerRect;},get guid(){return this.picture_.guid;},getBase64SkpData:function(){return this.picture_.getBase64SkpData();},getOps:function(){return this.picture_.getOps();},getOpTimings:function(){return this.picture_.getOpTimings();},tagOpsWithTimings:function(ops){return this.picture_.tagOpsWithTimings(ops);},rasterize:function(params,rasterCompleteCallback){this.picture_.rasterize(params,rasterCompleteCallback);}};ObjectSnapshot.register(PictureSnapshot,{typeNames:['cc::Picture']});return{PictureSnapshot:PictureSnapshot,Picture:Picture,LayeredPicture:LayeredPicture};});'use strict';tr.exportTo('tr.e.cc',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function DisplayItemList(skp64,layerRect){tr.e.cc.Picture.apply(this,arguments);}
+return{preInitializeObject,convertNameToJSConvention,moveRequiredFieldsFromArgsToToplevel,moveOptionalFieldsFromArgsToToplevel,};});'use strict';tr.exportTo('tr.e.cc',function(){const ObjectSnapshot=tr.model.ObjectSnapshot;const PictureCount=0;const OPS_TIMING_ITERATIONS=3;function Picture(skp64,layerRect){this.skp64_=skp64;this.layerRect_=layerRect;this.guid_=tr.b.GUID.allocateSimple();}
+Picture.prototype={get canSave(){return true;},get layerRect(){return this.layerRect_;},get guid(){return this.guid_;},getBase64SkpData(){return this.skp64_;},getOps(){if(!PictureSnapshot.CanGetOps()){console.error(PictureSnapshot.HowToEnablePictureDebugging());return undefined;}
+const ops=window.chrome.skiaBenchmarking.getOps({skp64:this.skp64_,params:{layer_rect:this.layerRect_.toArray()}});if(!ops){console.error('Failed to get picture ops.');}
+return ops;},getOpTimings(){if(!PictureSnapshot.CanGetOpTimings()){console.error(PictureSnapshot.HowToEnablePictureDebugging());return undefined;}
+const opTimings=window.chrome.skiaBenchmarking.getOpTimings({skp64:this.skp64_,params:{layer_rect:this.layerRect_.toArray()}});if(!opTimings){console.error('Failed to get picture op timings.');}
+return opTimings;},tagOpsWithTimings(ops){const opTimings=[];for(let iteration=0;iteration<OPS_TIMING_ITERATIONS;iteration++){opTimings[iteration]=this.getOpTimings();if(!opTimings[iteration]||!opTimings[iteration].cmd_times){return ops;}
+if(opTimings[iteration].cmd_times.length!==ops.length){return ops;}}
+for(let opIndex=0;opIndex<ops.length;opIndex++){let min=Number.MAX_VALUE;for(let i=0;i<OPS_TIMING_ITERATIONS;i++){min=Math.min(min,opTimings[i].cmd_times[opIndex]);}
+ops[opIndex].cmd_time=min;}
+return ops;},rasterize(params,rasterCompleteCallback){if(!PictureSnapshot.CanRasterize()||!PictureSnapshot.CanGetOps()){rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,tr.e.cc.PictureSnapshot.HowToEnablePictureDebugging()));return;}
+if(!this.layerRect_.width||!this.layerRect_.height){rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,null));return;}
+const raster=window.chrome.skiaBenchmarking.rasterize({skp64:this.skp64_,params:{layer_rect:this.layerRect_.toArray()}},{stop:params.stopIndex===undefined?-1:params.stopIndex,overdraw:!!params.showOverdraw,params:{}});if(raster){const canvas=document.createElement('canvas');const ctx=canvas.getContext('2d');canvas.width=raster.width;canvas.height=raster.height;const imageData=ctx.createImageData(raster.width,raster.height);imageData.data.set(new Uint8ClampedArray(raster.data));rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,imageData));}else{const error='Failed to rasterize picture. '+'Your recording may be from an old Chrome version. '+'The SkPicture format is not backward compatible.';rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,error));}}};function LayeredPicture(pictures){this.guid_=tr.b.GUID.allocateSimple();this.pictures_=pictures;this.layerRect_=undefined;}
+LayeredPicture.prototype={__proto__:Picture.prototype,get canSave(){return false;},get typeName(){return'cc::LayeredPicture';},get layerRect(){if(this.layerRect_!==undefined){return this.layerRect_;}
+this.layerRect_={x:0,y:0,width:0,height:0};for(let i=0;i<this.pictures_.length;++i){const rect=this.pictures_[i].layerRect;this.layerRect_.x=Math.min(this.layerRect_.x,rect.x);this.layerRect_.y=Math.min(this.layerRect_.y,rect.y);this.layerRect_.width=Math.max(this.layerRect_.width,rect.x+rect.width);this.layerRect_.height=Math.max(this.layerRect_.height,rect.y+rect.height);}
+return this.layerRect_;},get guid(){return this.guid_;},getBase64SkpData(){throw new Error('Not available with a LayeredPicture.');},getOps(){let ops=[];for(let i=0;i<this.pictures_.length;++i){ops=ops.concat(this.pictures_[i].getOps());}
+return ops;},getOpTimings(){const opTimings=this.pictures_[0].getOpTimings();for(let i=1;i<this.pictures_.length;++i){const timings=this.pictures_[i].getOpTimings();opTimings.cmd_times=opTimings.cmd_times.concat(timings.cmd_times);opTimings.total_time+=timings.total_time;}
+return opTimings;},tagOpsWithTimings(ops){const opTimings=[];for(let iteration=0;iteration<OPS_TIMING_ITERATIONS;iteration++){opTimings[iteration]=this.getOpTimings();if(!opTimings[iteration]||!opTimings[iteration].cmd_times){return ops;}}
+for(let opIndex=0;opIndex<ops.length;opIndex++){let min=Number.MAX_VALUE;for(let i=0;i<OPS_TIMING_ITERATIONS;i++){min=Math.min(min,opTimings[i].cmd_times[opIndex]);}
+ops[opIndex].cmd_time=min;}
+return ops;},rasterize(params,rasterCompleteCallback){this.picturesAsImageData_=[];const rasterCallback=function(pictureAsImageData){this.picturesAsImageData_.push(pictureAsImageData);if(this.picturesAsImageData_.length!==this.pictures_.length){return;}
+const canvas=document.createElement('canvas');const ctx=canvas.getContext('2d');canvas.width=this.layerRect.width;canvas.height=this.layerRect.height;for(let i=0;i<this.picturesAsImageData_.length;++i){ctx.putImageData(this.picturesAsImageData_[i].imageData,this.pictures_[i].layerRect.x,this.pictures_[i].layerRect.y);}
+this.picturesAsImageData_=[];rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,ctx.getImageData(this.layerRect.x,this.layerRect.y,this.layerRect.width,this.layerRect.height)));}.bind(this);for(let i=0;i<this.pictures_.length;++i){this.pictures_[i].rasterize(params,rasterCallback);}}};function PictureSnapshot(){ObjectSnapshot.apply(this,arguments);}
+PictureSnapshot.HasSkiaBenchmarking=function(){return tr.isExported('chrome.skiaBenchmarking');};PictureSnapshot.CanRasterize=function(){if(!PictureSnapshot.HasSkiaBenchmarking()){return false;}
+if(!window.chrome.skiaBenchmarking.rasterize){return false;}
+return true;};PictureSnapshot.CanGetOps=function(){if(!PictureSnapshot.HasSkiaBenchmarking()){return false;}
+if(!window.chrome.skiaBenchmarking.getOps){return false;}
+return true;};PictureSnapshot.CanGetOpTimings=function(){if(!PictureSnapshot.HasSkiaBenchmarking()){return false;}
+if(!window.chrome.skiaBenchmarking.getOpTimings){return false;}
+return true;};PictureSnapshot.CanGetInfo=function(){if(!PictureSnapshot.HasSkiaBenchmarking()){return false;}
+if(!window.chrome.skiaBenchmarking.getInfo){return false;}
+return true;};PictureSnapshot.HowToEnablePictureDebugging=function(){if(tr.isHeadless){return'Pictures only work in chrome';}
+const usualReason=['For pictures to show up, the Chrome browser displaying the trace ','needs to be running with --enable-skia-benchmarking. Please restart ','chrome with this flag and try loading the trace again.'].join('');if(!PictureSnapshot.HasSkiaBenchmarking()){return usualReason;}
+if(!PictureSnapshot.CanRasterize()){return'Your chrome is old: chrome.skipBenchmarking.rasterize not found';}
+if(!PictureSnapshot.CanGetOps()){return'Your chrome is old: chrome.skiaBenchmarking.getOps not found';}
+if(!PictureSnapshot.CanGetOpTimings()){return'Your chrome is old: '+'chrome.skiaBenchmarking.getOpTimings not found';}
+if(!PictureSnapshot.CanGetInfo()){return'Your chrome is old: chrome.skiaBenchmarking.getInfo not found';}
+return undefined;};PictureSnapshot.CanDebugPicture=function(){return PictureSnapshot.HowToEnablePictureDebugging()===undefined;};PictureSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize(){tr.e.cc.preInitializeObject(this);this.rasterResult_=undefined;},initialize(){if(this.args.alias){this.args=this.args.alias.args;}
+if(!this.args.params.layerRect){throw new Error('Missing layer rect');}
+this.layerRect_=this.args.params.layerRect;this.picture_=new Picture(this.args.skp64,this.args.params.layerRect);},set picture(picture){this.picture_=picture;},get canSave(){return this.picture_.canSave;},get layerRect(){return this.layerRect_?this.layerRect_:this.picture_.layerRect;},get guid(){return this.picture_.guid;},getBase64SkpData(){return this.picture_.getBase64SkpData();},getOps(){return this.picture_.getOps();},getOpTimings(){return this.picture_.getOpTimings();},tagOpsWithTimings(ops){return this.picture_.tagOpsWithTimings(ops);},rasterize(params,rasterCompleteCallback){this.picture_.rasterize(params,rasterCompleteCallback);}};ObjectSnapshot.subTypes.register(PictureSnapshot,{typeNames:['cc::Picture']});return{PictureSnapshot,Picture,LayeredPicture,};});'use strict';tr.exportTo('tr.e.cc',function(){const ObjectSnapshot=tr.model.ObjectSnapshot;function DisplayItemList(skp64,layerRect){tr.e.cc.Picture.apply(this,arguments);}
 DisplayItemList.prototype={__proto__:tr.e.cc.Picture.prototype};function DisplayItemListSnapshot(){tr.e.cc.PictureSnapshot.apply(this,arguments);}
-DisplayItemListSnapshot.prototype={__proto__:tr.e.cc.PictureSnapshot.prototype,initialize:function(){tr.e.cc.PictureSnapshot.prototype.initialize.call(this);this.displayItems_=this.args.params.items;},get items(){return this.displayItems_;}};ObjectSnapshot.register(DisplayItemListSnapshot,{typeNames:['cc::DisplayItemList']});return{DisplayItemListSnapshot:DisplayItemListSnapshot,DisplayItemList:DisplayItemList};});'use strict';tr.exportTo('tr.e.cc',function(){var constants={};constants.ACTIVE_TREE=0;constants.PENDING_TREE=1;constants.HIGH_PRIORITY_BIN=0;constants.LOW_PRIORITY_BIN=1;constants.SEND_BEGIN_FRAME_EVENT='ThreadProxy::ScheduledActionSendBeginMainFrame';constants.BEGIN_MAIN_FRAME_EVENT='ThreadProxy::BeginMainFrame';return{constants:constants};});'use strict';tr.exportTo('tr.e.cc',function(){function Region(){this.rects=[];}
-Region.fromArray=function(array){if(array.length%4!=0)
-throw new Error('Array must consist be a multiple of 4 in length');var r=new Region();for(var i=0;i<array.length;i+=4){r.rects.push(tr.b.Rect.fromXYWH(array[i],array[i+1],array[i+2],array[i+3]));}
-return r;}
-Region.fromArrayOrUndefined=function(array){if(array===undefined)
-return new Region();return Region.fromArray(array);};Region.prototype={__proto__:Region.prototype,rectIntersects:function(r){for(var i=0;i<this.rects.length;i++){if(this.rects[i].intersects(r))
-return true;}
-return false;},addRect:function(r){this.rects.push(r);}};return{Region:Region};});'use strict';tr.exportTo('tr.e.cc',function(){function TileCoverageRect(rect,tile){this.geometryRect=rect;this.tile=tile;}
-return{TileCoverageRect:TileCoverageRect};});'use strict';tr.exportTo('tr.e.cc',function(){var constants=tr.e.cc.constants;var ObjectSnapshot=tr.model.ObjectSnapshot;function LayerImplSnapshot(){ObjectSnapshot.apply(this,arguments);}
-LayerImplSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);this.layerTreeImpl_=undefined;this.parentLayer=undefined;},initialize:function(){this.invalidation=new tr.e.cc.Region();this.annotatedInvalidation=new tr.e.cc.Region();this.unrecordedRegion=new tr.e.cc.Region();this.pictures=[];tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['layerId','children','layerQuad']);tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['maskLayer','replicaLayer','idealContentsScale','geometryContentsScale','layoutRects','usingGpuRasterization']);this.gpuMemoryUsageInBytes=this.args.gpuMemoryUsage;this.bounds=tr.b.Rect.fromXYWH(0,0,this.args.bounds.width,this.args.bounds.height);if(this.args.animationBounds){this.animationBoundsRect=tr.b.Rect.fromXYWH(this.args.animationBounds[0],this.args.animationBounds[1],this.args.animationBounds[3],this.args.animationBounds[4]);}
-for(var i=0;i<this.children.length;i++)
-this.children[i].parentLayer=this;if(this.maskLayer)
-this.maskLayer.parentLayer=this;if(this.replicaLayer)
-this.replicaLayer.parentLayer=this;if(!this.geometryContentsScale)
-this.geometryContentsScale=1.0;if(!this.idealContentsScale)
-this.idealContentsScale=1.0;this.touchEventHandlerRegion=tr.e.cc.Region.fromArrayOrUndefined(this.args.touchEventHandlerRegion);this.wheelEventHandlerRegion=tr.e.cc.Region.fromArrayOrUndefined(this.args.wheelEventHandlerRegion);this.nonFastScrollableRegion=tr.e.cc.Region.fromArrayOrUndefined(this.args.nonFastScrollableRegion);},get layerTreeImpl(){if(this.layerTreeImpl_)
-return this.layerTreeImpl_;if(this.parentLayer)
-return this.parentLayer.layerTreeImpl;return undefined;},set layerTreeImpl(layerTreeImpl){this.layerTreeImpl_=layerTreeImpl;},get activeLayer(){if(this.layerTreeImpl.whichTree==constants.ACTIVE_TREE)
-return this;var activeTree=this.layerTreeImpl.layerTreeHostImpl.activeTree;return activeTree.findLayerWithId(this.layerId);},get pendingLayer(){if(this.layerTreeImpl.whichTree==constants.PENDING_TREE)
-return this;var pendingTree=this.layerTreeImpl.layerTreeHostImpl.pendingTree;return pendingTree.findLayerWithId(this.layerId);}};function PictureLayerImplSnapshot(){LayerImplSnapshot.apply(this,arguments);}
-PictureLayerImplSnapshot.prototype={__proto__:LayerImplSnapshot.prototype,initialize:function(){LayerImplSnapshot.prototype.initialize.call(this);if(this.args.invalidation){this.invalidation=tr.e.cc.Region.fromArray(this.args.invalidation);delete this.args.invalidation;}
-if(this.args.annotatedInvalidationRects){this.annotatedInvalidation=new tr.e.cc.Region();for(var i=0;i<this.args.annotatedInvalidationRects.length;++i){var annotatedRect=this.args.annotatedInvalidationRects[i];var rect=annotatedRect.geometryRect;rect.reason=annotatedRect.reason;this.annotatedInvalidation.addRect(rect);}
-delete this.args.annotatedInvalidationRects;}
-if(this.args.unrecordedRegion){this.unrecordedRegion=tr.e.cc.Region.fromArray(this.args.unrecordedRegion);delete this.args.unrecordedRegion;}
+DisplayItemListSnapshot.prototype={__proto__:tr.e.cc.PictureSnapshot.prototype,initialize(){tr.e.cc.PictureSnapshot.prototype.initialize.call(this);this.displayItems_=this.args.params.items;},get items(){return this.displayItems_;}};ObjectSnapshot.subTypes.register(DisplayItemListSnapshot,{typeNames:['cc::DisplayItemList']});return{DisplayItemListSnapshot,DisplayItemList,};});'use strict';tr.exportTo('tr.b.math',function(){function BBox2(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;}
+BBox2.prototype={__proto__:Object.prototype,reset(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;},get isEmpty(){return this.isEmpty_;},addBBox2(bbox2){if(bbox2.isEmpty)return;this.addVec2(bbox2.min_);this.addVec2(bbox2.max_);},clone(){const bbox=new BBox2();bbox.addBBox2(this);return bbox;},addXY(x,y){if(this.isEmpty_){this.max_=vec2.create();this.min_=vec2.create();vec2.set(this.max_,x,y);vec2.set(this.min_,x,y);this.isEmpty_=false;return;}
+this.max_[0]=Math.max(this.max_[0],x);this.max_[1]=Math.max(this.max_[1],y);this.min_[0]=Math.min(this.min_[0],x);this.min_[1]=Math.min(this.min_[1],y);},addVec2(value){if(this.isEmpty_){this.max_=vec2.create();this.min_=vec2.create();vec2.set(this.max_,value[0],value[1]);vec2.set(this.min_,value[0],value[1]);this.isEmpty_=false;return;}
+this.max_[0]=Math.max(this.max_[0],value[0]);this.max_[1]=Math.max(this.max_[1],value[1]);this.min_[0]=Math.min(this.min_[0],value[0]);this.min_[1]=Math.min(this.min_[1],value[1]);},addQuad(quad){this.addVec2(quad.p1);this.addVec2(quad.p2);this.addVec2(quad.p3);this.addVec2(quad.p4);},get minVec2(){if(this.isEmpty_)return undefined;return this.min_;},get maxVec2(){if(this.isEmpty_)return undefined;return this.max_;},get sizeAsVec2(){if(this.isEmpty_){throw new Error('Empty BBox2 has no size');}
+const size=vec2.create();vec2.subtract(size,this.max_,this.min_);return size;},get size(){if(this.isEmpty_){throw new Error('Empty BBox2 has no size');}
+return{width:this.max_[0]-this.min_[0],height:this.max_[1]-this.min_[1]};},get width(){if(this.isEmpty_){throw new Error('Empty BBox2 has no width');}
+return this.max_[0]-this.min_[0];},get height(){if(this.isEmpty_){throw new Error('Empty BBox2 has no width');}
+return this.max_[1]-this.min_[1];},toString(){if(this.isEmpty_)return'empty';return'min=('+this.min_[0]+','+this.min_[1]+') '+'max=('+this.max_[0]+','+this.max_[1]+')';},asRect(){return tr.b.math.Rect.fromXYWH(this.min_[0],this.min_[1],this.max_[0]-this.min_[0],this.max_[1]-this.min_[1]);}};return{BBox2,};});'use strict';tr.exportTo('tr.e.cc',function(){const constants={};constants.ACTIVE_TREE=0;constants.PENDING_TREE=1;constants.HIGH_PRIORITY_BIN=0;constants.LOW_PRIORITY_BIN=1;constants.SEND_BEGIN_FRAME_EVENT='ThreadProxy::ScheduledActionSendBeginMainFrame';constants.BEGIN_MAIN_FRAME_EVENT='ThreadProxy::BeginMainFrame';return{constants};});'use strict';tr.exportTo('tr.e.cc',function(){function Region(){this.rects=[];}
+Region.fromArray=function(array){if(array.length%4!==0){throw new Error('Array must consist be a multiple of 4 in length');}
+const r=new Region();for(let i=0;i<array.length;i+=4){r.rects.push(tr.b.math.Rect.fromXYWH(array[i],array[i+1],array[i+2],array[i+3]));}
+return r;};Region.fromArrayOrUndefined=function(array){if(array===undefined)return new Region();return Region.fromArray(array);};Region.prototype={__proto__:Region.prototype,rectIntersects(r){for(let i=0;i<this.rects.length;i++){if(this.rects[i].intersects(r))return true;}
+return false;},addRect(r){this.rects.push(r);}};return{Region,};});'use strict';tr.exportTo('tr.e.cc',function(){function TileCoverageRect(rect,tile){this.geometryRect=rect;this.tile=tile;}
+return{TileCoverageRect,};});'use strict';tr.exportTo('tr.e.cc',function(){const constants=tr.e.cc.constants;const ObjectSnapshot=tr.model.ObjectSnapshot;function LayerImplSnapshot(){ObjectSnapshot.apply(this,arguments);}
+LayerImplSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize(){tr.e.cc.preInitializeObject(this);this.layerTreeImpl_=undefined;this.parentLayer=undefined;},initialize(){this.invalidation=new tr.e.cc.Region();this.unrecordedRegion=new tr.e.cc.Region();this.pictures=[];tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['layerId','layerQuad']);tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['children','maskLayer','replicaLayer','idealContentsScale','geometryContentsScale','layoutRects','usingGpuRasterization']);this.gpuMemoryUsageInBytes=this.args.gpuMemoryUsage;this.bounds=tr.b.math.Rect.fromXYWH(0,0,this.args.bounds.width,this.args.bounds.height);if(this.args.animationBounds){this.animationBoundsRect=tr.b.math.Rect.fromXYWH(this.args.animationBounds[0],this.args.animationBounds[1],this.args.animationBounds[3],this.args.animationBounds[4]);}
+if(this.children){for(let i=0;i<this.children.length;i++){this.children[i].parentLayer=this;}}
+if(this.maskLayer){this.maskLayer.parentLayer=this;}
+if(this.replicaLayer){this.replicaLayer.parentLayer=this;}
+if(!this.geometryContentsScale){this.geometryContentsScale=1.0;}
+if(!this.idealContentsScale){this.idealContentsScale=1.0;}
+this.touchEventHandlerRegion=tr.e.cc.Region.fromArrayOrUndefined(this.args.touchEventHandlerRegion);this.wheelEventHandlerRegion=tr.e.cc.Region.fromArrayOrUndefined(this.args.wheelEventHandlerRegion);this.nonFastScrollableRegion=tr.e.cc.Region.fromArrayOrUndefined(this.args.nonFastScrollableRegion);},get layerTreeImpl(){if(this.layerTreeImpl_){return this.layerTreeImpl_;}
+if(this.parentLayer){return this.parentLayer.layerTreeImpl;}
+return undefined;},set layerTreeImpl(layerTreeImpl){this.layerTreeImpl_=layerTreeImpl;},get activeLayer(){if(this.layerTreeImpl.whichTree===constants.ACTIVE_TREE){return this;}
+const activeTree=this.layerTreeImpl.layerTreeHostImpl.activeTree;return activeTree.findLayerWithId(this.layerId);},get pendingLayer(){if(this.layerTreeImpl.whichTree===constants.PENDING_TREE){return this;}
+const pendingTree=this.layerTreeImpl.layerTreeHostImpl.pendingTree;return pendingTree.findLayerWithId(this.layerId);}};function PictureLayerImplSnapshot(){LayerImplSnapshot.apply(this,arguments);}
+PictureLayerImplSnapshot.prototype={__proto__:LayerImplSnapshot.prototype,initialize(){LayerImplSnapshot.prototype.initialize.call(this);if(this.args.debugInfo){for(const i in this.args.debugInfo){this.args[i]=this.args.debugInfo[i];}
+delete this.args.debugInfo;}
+if(this.args.annotatedInvalidationRects){this.invalidation=new tr.e.cc.Region();for(const annotatedRect of this.args.annotatedInvalidationRects){const rect=annotatedRect.geometryRect;rect.reason=annotatedRect.reason;rect.client=annotatedRect.client;this.invalidation.addRect(rect);}
+delete this.args.annotatedInvalidationRects;}else if(this.args.invalidation){this.invalidation=tr.e.cc.Region.fromArray(this.args.invalidation);}
+delete this.args.invalidation;if(this.args.unrecordedRegion){this.unrecordedRegion=tr.e.cc.Region.fromArray(this.args.unrecordedRegion);delete this.args.unrecordedRegion;}
 if(this.args.pictures){this.pictures=this.args.pictures;this.pictures.sort(function(a,b){return a.ts-b.ts;});}
-this.tileCoverageRects=[];if(this.args.coverageTiles){for(var i=0;i<this.args.coverageTiles.length;++i){var rect=this.args.coverageTiles[i].geometryRect.scale(this.idealContentsScale);var tile=this.args.coverageTiles[i].tile;this.tileCoverageRects.push(new tr.e.cc.TileCoverageRect(rect,tile));}
-delete this.args.coverageTiles;}}};ObjectSnapshot.register(PictureLayerImplSnapshot,{typeName:'cc::PictureLayerImpl'});ObjectSnapshot.register(LayerImplSnapshot,{typeNames:['cc::LayerImpl','cc::DelegatedRendererLayerImpl','cc::HeadsUpDisplayLayerImpl','cc::IOSurfaceLayerImpl','cc::NinePatchLayerImpl','cc::PictureImageLayerImpl','cc::ScrollbarLayerImpl','cc::SolidColorLayerImpl','cc::SurfaceLayerImpl','cc::TextureLayerImpl','cc::TiledLayerImpl','cc::VideoLayerImpl','cc::PaintedScrollbarLayerImpl','ClankPatchLayer','TabBorderLayer','CounterLayer']});return{LayerImplSnapshot:LayerImplSnapshot,PictureLayerImplSnapshot:PictureLayerImplSnapshot};});'use strict';tr.exportTo('tr.e.cc',function(){var constants=tr.e.cc.constants;var ObjectSnapshot=tr.model.ObjectSnapshot;function LayerTreeImplSnapshot(){ObjectSnapshot.apply(this,arguments);}
-LayerTreeImplSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);this.layerTreeHostImpl=undefined;this.whichTree=undefined;this.sourceFrameNumber=undefined;},initialize:function(){tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['rootLayer','renderSurfaceLayerList']);if(this.args.sourceFrameNumber)
-this.sourceFrameNumber=this.args.sourceFrameNumber;this.rootLayer.layerTreeImpl=this;if(this.args.swapPromiseTraceIds&&this.args.swapPromiseTraceIds.length){this.tracedInputLatencies=[];var ownProcess=this.objectInstance.parent;var modelHelper=ownProcess.model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(modelHelper)
-this._initializeTracedInputLatencies(modelHelper);}},_initializeTracedInputLatencies:function(modelHelper){var latencyEvents=modelHelper.browserHelper.getLatencyEventsInRange(modelHelper.model.bounds);latencyEvents.forEach(function(event){for(var i=0;i<this.args.swapPromiseTraceIds.length;i++){if(!event.args.data||!event.args.data.trace_id)
-continue;if(parseInt(event.args.data.trace_id)===this.args.swapPromiseTraceIds[i])
-this.tracedInputLatencies.push(event);}},this);},get hasSourceFrameBeenDrawnBefore(){if(this.whichTree==tr.e.cc.constants.PENDING_TREE)
-return false;if(this.sourceFrameNumber===undefined)
-return;var thisLTHI=this.layerTreeHostImpl;var thisLTHIIndex=thisLTHI.objectInstance.snapshots.indexOf(thisLTHI);var prevLTHIIndex=thisLTHIIndex-1;if(prevLTHIIndex<0||prevLTHIIndex>=thisLTHI.objectInstance.snapshots.length)
-return false;var prevLTHI=thisLTHI.objectInstance.snapshots[prevLTHIIndex];if(!prevLTHI.activeTree)
-return false;if(prevLTHI.activeTree.sourceFrameNumber===undefined)
-return;return prevLTHI.activeTree.sourceFrameNumber==this.sourceFrameNumber;},get otherTree(){var other=this.whichTree==constants.ACTIVE_TREE?constants.PENDING_TREE:constants.ACTIVE_TREE;return this.layerTreeHostImpl.getTree(other);},get gpuMemoryUsageInBytes(){var totalBytes=0;this.iterLayers(function(layer){if(layer.gpuMemoryUsageInBytes!==undefined)
-totalBytes+=layer.gpuMemoryUsageInBytes;});return totalBytes;},iterLayers:function(func,thisArg){var visitedLayers={};function visitLayer(layer,depth,isMask,isReplica){if(visitedLayers[layer.layerId])
-return;visitedLayers[layer.layerId]=true;func.call(thisArg,layer,depth,isMask,isReplica);if(layer.children){for(var i=0;i<layer.children.length;i++)
-visitLayer(layer.children[i],depth+1);}
-if(layer.maskLayer)
-visitLayer(layer.maskLayer,depth+1,true,false);if(layer.replicaLayer)
-visitLayer(layer.replicaLayer,depth+1,false,true);}
-visitLayer(this.rootLayer,0,false,false);},findLayerWithId:function(id){var foundLayer=undefined;function visitLayer(layer){if(layer.layerId==id)
-foundLayer=layer;}
-this.iterLayers(visitLayer);return foundLayer;}};ObjectSnapshot.register(LayerTreeImplSnapshot,{typeName:'cc::LayerTreeImpl'});return{LayerTreeImplSnapshot:LayerTreeImplSnapshot};});'use strict';tr.exportTo('tr.b',function(){function BBox2(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;};BBox2.prototype={__proto__:Object.prototype,reset:function(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;},get isEmpty(){return this.isEmpty_;},addBBox2:function(bbox2){if(bbox2.isEmpty)
-return;this.addVec2(bbox2.min_);this.addVec2(bbox2.max_);},clone:function(){var bbox=new BBox2();bbox.addBBox2(this);return bbox;},addXY:function(x,y){if(this.isEmpty_){this.max_=vec2.create();this.min_=vec2.create();vec2.set(this.max_,x,y);vec2.set(this.min_,x,y);this.isEmpty_=false;return;}
-this.max_[0]=Math.max(this.max_[0],x);this.max_[1]=Math.max(this.max_[1],y);this.min_[0]=Math.min(this.min_[0],x);this.min_[1]=Math.min(this.min_[1],y);},addVec2:function(value){if(this.isEmpty_){this.max_=vec2.create();this.min_=vec2.create();vec2.set(this.max_,value[0],value[1]);vec2.set(this.min_,value[0],value[1]);this.isEmpty_=false;return;}
-this.max_[0]=Math.max(this.max_[0],value[0]);this.max_[1]=Math.max(this.max_[1],value[1]);this.min_[0]=Math.min(this.min_[0],value[0]);this.min_[1]=Math.min(this.min_[1],value[1]);},addQuad:function(quad){this.addVec2(quad.p1);this.addVec2(quad.p2);this.addVec2(quad.p3);this.addVec2(quad.p4);},get minVec2(){if(this.isEmpty_)
-return undefined;return this.min_;},get maxVec2(){if(this.isEmpty_)
-return undefined;return this.max_;},get sizeAsVec2(){if(this.isEmpty_)
-throw new Error('Empty BBox2 has no size');var size=vec2.create();vec2.subtract(size,this.max_,this.min_);return size;},get size(){if(this.isEmpty_)
-throw new Error('Empty BBox2 has no size');return{width:this.max_[0]-this.min_[0],height:this.max_[1]-this.min_[1]};},get width(){if(this.isEmpty_)
-throw new Error('Empty BBox2 has no width');return this.max_[0]-this.min_[0];},get height(){if(this.isEmpty_)
-throw new Error('Empty BBox2 has no width');return this.max_[1]-this.min_[1];},toString:function(){if(this.isEmpty_)
-return'empty';return'min=('+this.min_[0]+','+this.min_[1]+') '+'max=('+this.max_[0]+','+this.max_[1]+')';},asRect:function(){return tr.b.Rect.fromXYWH(this.min_[0],this.min_[1],this.max_[0]-this.min_[0],this.max_[1]-this.min_[1]);}};return{BBox2:BBox2};});'use strict';tr.exportTo('tr.e.cc',function(){var constants=tr.e.cc.constants;var ObjectSnapshot=tr.model.ObjectSnapshot;var ObjectInstance=tr.model.ObjectInstance;function LayerTreeHostImplSnapshot(){ObjectSnapshot.apply(this,arguments);}
-LayerTreeHostImplSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);},initialize:function(){tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['deviceViewportSize','activeTree']);tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['pendingTree']);if(this.args.activeTiles!==undefined){this.activeTiles=this.args.activeTiles;delete this.args.activeTiles;}else if(this.args.tiles!==undefined){this.activeTiles=this.args.tiles;delete this.args.tiles;}
-if(!this.activeTiles)
-this.activeTiles=[];this.activeTree.layerTreeHostImpl=this;this.activeTree.whichTree=constants.ACTIVE_TREE;if(this.pendingTree){this.pendingTree.layerTreeHostImpl=this;this.pendingTree.whichTree=constants.PENDING_TREE;}},getContentsScaleNames:function(){var scales={};for(var i=0;i<this.activeTiles.length;++i){var tile=this.activeTiles[i];scales[tile.contentsScale]=tile.resolution;}
-return scales;},getTree:function(whichTree){if(whichTree==constants.ACTIVE_TREE)
-return this.activeTree;if(whichTree==constants.PENDING_TREE)
-return this.pendingTree;throw new Exception('Unknown tree type + '+whichTree);},get tilesHaveGpuMemoryUsageInfo(){if(this.tilesHaveGpuMemoryUsageInfo_!==undefined)
-return this.tilesHaveGpuMemoryUsageInfo_;for(var i=0;i<this.activeTiles.length;i++){if(this.activeTiles[i].gpuMemoryUsageInBytes===undefined)
-continue;this.tilesHaveGpuMemoryUsageInfo_=true;return true;}
-this.tilesHaveGpuMemoryUsageInfo_=false;return false;},get gpuMemoryUsageInBytes(){if(!this.tilesHaveGpuMemoryUsageInfo)
-return;var usage=0;for(var i=0;i<this.activeTiles.length;i++){var u=this.activeTiles[i].gpuMemoryUsageInBytes;if(u!==undefined)
-usage+=u;}
-return usage;},get userFriendlyName(){var frameNumber;if(!this.activeTree){frameNumber=this.objectInstance.snapshots.indexOf(this);}else{if(this.activeTree.sourceFrameNumber===undefined)
-frameNumber=this.objectInstance.snapshots.indexOf(this);else
-frameNumber=this.activeTree.sourceFrameNumber;}
-return'cc::LayerTreeHostImpl frame '+frameNumber;}};ObjectSnapshot.register(LayerTreeHostImplSnapshot,{typeName:'cc::LayerTreeHostImpl'});function LayerTreeHostImplInstance(){ObjectInstance.apply(this,arguments);this.allLayersBBox_=undefined;}
-LayerTreeHostImplInstance.prototype={__proto__:ObjectInstance.prototype,get allContentsScales(){if(this.allContentsScales_)
-return this.allContentsScales_;var scales={};for(var tileID in this.allTileHistories_){var tileHistory=this.allTileHistories_[tileID];scales[tileHistory.contentsScale]=true;}
-this.allContentsScales_=tr.b.dictionaryKeys(scales);return this.allContentsScales_;},get allLayersBBox(){if(this.allLayersBBox_)
-return this.allLayersBBox_;var bbox=new tr.b.BBox2();function handleTree(tree){tree.renderSurfaceLayerList.forEach(function(layer){bbox.addQuad(layer.layerQuad);});}
-this.snapshots.forEach(function(lthi){handleTree(lthi.activeTree);if(lthi.pendingTree)
-handleTree(lthi.pendingTree);});this.allLayersBBox_=bbox;return this.allLayersBBox_;}};ObjectInstance.register(LayerTreeHostImplInstance,{typeName:'cc::LayerTreeHostImpl'});return{LayerTreeHostImplSnapshot:LayerTreeHostImplSnapshot,LayerTreeHostImplInstance:LayerTreeHostImplInstance};});'use strict';tr.exportTo('tr.e.cc',function(){var tileTypes={highRes:'highRes',lowRes:'lowRes',extraHighRes:'extraHighRes',extraLowRes:'extraLowRes',missing:'missing',culled:'culled',solidColor:'solidColor',picture:'picture',directPicture:'directPicture',unknown:'unknown'};var tileBorder={highRes:{color:'rgba(80, 200, 200, 0.7)',width:1},lowRes:{color:'rgba(212, 83, 192, 0.7)',width:2},extraHighRes:{color:'rgba(239, 231, 20, 0.7)',width:2},extraLowRes:{color:'rgba(93, 186, 18, 0.7)',width:2},missing:{color:'rgba(255, 0, 0, 0.7)',width:1},culled:{color:'rgba(160, 100, 0, 0.8)',width:1},solidColor:{color:'rgba(128, 128, 128, 0.7)',width:1},picture:{color:'rgba(64, 64, 64, 0.7)',width:1},directPicture:{color:'rgba(127, 255, 0, 1.0)',width:1},unknown:{color:'rgba(0, 0, 0, 1.0)',width:2}};return{tileTypes:tileTypes,tileBorder:tileBorder};});'use strict';tr.exportTo('tr.e.cc',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function TileSnapshot(){ObjectSnapshot.apply(this,arguments);}
-TileSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);},initialize:function(){tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['layerId','contentsScale','contentRect']);if(this.args.managedState){this.resolution=this.args.managedState.resolution;this.isSolidColor=this.args.managedState.isSolidColor;this.isUsingGpuMemory=this.args.managedState.isUsingGpuMemory;this.hasResource=this.args.managedState.hasResource;this.scheduledPriority=this.args.scheduledPriority;this.gpuMemoryUsageInBytes=this.args.gpuMemoryUsage;}else{this.resolution=this.args.resolution;this.isSolidColor=this.args.drawInfo.isSolidColor;this.isUsingGpuMemory=this.args.isUsingGpuMemory;this.hasResource=this.args.hasResource;this.scheduledPriority=this.args.scheduledPriority;this.gpuMemoryUsageInBytes=this.args.gpuMemoryUsage;}
-if(this.contentRect)
-this.layerRect=this.contentRect.scale(1.0/this.contentsScale);if(this.isSolidColor)
-this.type_=tr.e.cc.tileTypes.solidColor;else if(!this.hasResource)
-this.type_=tr.e.cc.tileTypes.missing;else if(this.resolution==='HIGH_RESOLUTION')
-this.type_=tr.e.cc.tileTypes.highRes;else if(this.resolution==='LOW_RESOLUTION')
-this.type_=tr.e.cc.tileTypes.lowRes;else
-this.type_=tr.e.cc.tileTypes.unknown;},getTypeForLayer:function(layer){var type=this.type_;if(type==tr.e.cc.tileTypes.unknown){if(this.contentsScale<layer.idealContentsScale)
-type=tr.e.cc.tileTypes.extraLowRes;else if(this.contentsScale>layer.idealContentsScale)
-type=tr.e.cc.tileTypes.extraHighRes;}
-return type;}};ObjectSnapshot.register(TileSnapshot,{typeName:'cc::Tile'});return{TileSnapshot:TileSnapshot};});'use strict';tr.exportTo('tr.ui.b',function(){var EventSet=tr.model.EventSet;var SelectionState=tr.model.SelectionState;function BrushingState(){this.guid_=tr.b.GUID.allocate();this.selection_=new EventSet();this.findMatches_=new EventSet();this.analysisViewRelatedEvents_=new EventSet();this.analysisLinkHoveredEvents_=new EventSet();this.appliedToModel_=undefined;this.viewSpecificBrushingStates_={};}
-BrushingState.prototype={get guid(){return this.guid_;},clone:function(){var that=new BrushingState();that.selection_=this.selection_;that.findMatches_=this.findMatches_;that.analysisViewRelatedEvents_=this.analysisViewRelatedEvents_;that.analysisLinkHoveredEvents_=this.analysisLinkHoveredEvents_;that.viewSpecificBrushingStates_=this.viewSpecificBrushingStates_;return that;},equals:function(that){if(!this.selection_.equals(that.selection_))
-return false;if(!this.findMatches_.equals(that.findMatches_))
-return false;if(!this.analysisViewRelatedEvents_.equals(that.analysisViewRelatedEvents_)){return false;}
+this.tileCoverageRects=[];if(this.args.coverageTiles){for(let i=0;i<this.args.coverageTiles.length;++i){const rect=this.args.coverageTiles[i].geometryRect.scale(this.idealContentsScale);const tile=this.args.coverageTiles[i].tile;this.tileCoverageRects.push(new tr.e.cc.TileCoverageRect(rect,tile));}
+delete this.args.coverageTiles;}}};ObjectSnapshot.subTypes.register(PictureLayerImplSnapshot,{typeName:'cc::PictureLayerImpl'});ObjectSnapshot.subTypes.register(LayerImplSnapshot,{typeNames:['cc::LayerImpl','cc::DelegatedRendererLayerImpl','cc::HeadsUpDisplayLayerImpl','cc::IOSurfaceLayerImpl','cc::NinePatchLayerImpl','cc::PictureImageLayerImpl','cc::ScrollbarLayerImpl','cc::SolidColorLayerImpl','cc::SolidColorScrollbarLayerImpl','cc::SurfaceLayerImpl','cc::TextureLayerImpl','cc::TiledLayerImpl','cc::VideoLayerImpl','cc::PaintedScrollbarLayerImpl','ClankPatchLayer','TabBorderLayer','CounterLayer']});return{LayerImplSnapshot,PictureLayerImplSnapshot,};});'use strict';tr.exportTo('tr.e.cc',function(){const constants=tr.e.cc.constants;const ObjectSnapshot=tr.model.ObjectSnapshot;function LayerTreeImplSnapshot(){ObjectSnapshot.apply(this,arguments);}
+LayerTreeImplSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize(){tr.e.cc.preInitializeObject(this);this.layerTreeHostImpl=undefined;this.whichTree=undefined;this.sourceFrameNumber=undefined;},initialize(){tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['renderSurfaceLayerList']);tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['rootLayer','layers']);if(this.args.sourceFrameNumber){this.sourceFrameNumber=this.args.sourceFrameNumber;}
+if(this.rootLayer){this.rootLayer.layerTreeImpl=this;}else{for(let i=0;i<this.layers.length;i++){this.layers[i].layerTreeImpl=this;}}
+if(this.args.swapPromiseTraceIds&&this.args.swapPromiseTraceIds.length){this.tracedInputLatencies=[];const ownProcess=this.objectInstance.parent;const modelHelper=ownProcess.model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(modelHelper){this._initializeTracedInputLatencies(modelHelper);}}},_initializeTracedInputLatencies(modelHelper){const latencyEvents=modelHelper.browserHelper.getLatencyEventsInRange(modelHelper.model.bounds);latencyEvents.forEach(function(event){for(let i=0;i<this.args.swapPromiseTraceIds.length;i++){if(!event.args.data||!event.args.data.trace_id){continue;}
+if(parseInt(event.args.data.trace_id)===this.args.swapPromiseTraceIds[i]){this.tracedInputLatencies.push(event);}}},this);},get hasSourceFrameBeenDrawnBefore(){if(this.whichTree===tr.e.cc.constants.PENDING_TREE){return false;}
+if(this.sourceFrameNumber===undefined)return;const thisLTHI=this.layerTreeHostImpl;const thisLTHIIndex=thisLTHI.objectInstance.snapshots.indexOf(thisLTHI);const prevLTHIIndex=thisLTHIIndex-1;if(prevLTHIIndex<0||prevLTHIIndex>=thisLTHI.objectInstance.snapshots.length){return false;}
+const prevLTHI=thisLTHI.objectInstance.snapshots[prevLTHIIndex];if(!prevLTHI.activeTree)return false;if(prevLTHI.activeTree.sourceFrameNumber===undefined)return;return prevLTHI.activeTree.sourceFrameNumber===this.sourceFrameNumber;},get otherTree(){const other=this.whichTree===constants.ACTIVE_TREE?constants.PENDING_TREE:constants.ACTIVE_TREE;return this.layerTreeHostImpl.getTree(other);},get gpuMemoryUsageInBytes(){let totalBytes=0;this.iterLayers(function(layer){if(layer.gpuMemoryUsageInBytes!==undefined){totalBytes+=layer.gpuMemoryUsageInBytes;}});return totalBytes;},iterLayers(func,thisArg){const visitedLayers={};function visitLayer(layer,depth,isMask,isReplica){if(visitedLayers[layer.layerId])return;visitedLayers[layer.layerId]=true;func.call(thisArg,layer,depth,isMask,isReplica);if(layer.children){for(let i=0;i<layer.children.length;i++){visitLayer(layer.children[i],depth+1);}}
+if(layer.maskLayer){visitLayer(layer.maskLayer,depth+1,true,false);}
+if(layer.replicaLayer){visitLayer(layer.replicaLayer,depth+1,false,true);}}
+if(this.rootLayer){visitLayer(this.rootLayer,0,false,false);}else{for(let i=0;i<this.layers.length;i++){visitLayer(this.layers[i],0,false,false);}}},findLayerWithId(id){let foundLayer=undefined;function visitLayer(layer){if(layer.layerId===id){foundLayer=layer;}}
+this.iterLayers(visitLayer);return foundLayer;}};ObjectSnapshot.subTypes.register(LayerTreeImplSnapshot,{typeName:'cc::LayerTreeImpl'});return{LayerTreeImplSnapshot,};});'use strict';tr.exportTo('tr.e.cc',function(){const constants=tr.e.cc.constants;const ObjectSnapshot=tr.model.ObjectSnapshot;const ObjectInstance=tr.model.ObjectInstance;function LayerTreeHostImplSnapshot(){ObjectSnapshot.apply(this,arguments);}
+LayerTreeHostImplSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize(){tr.e.cc.preInitializeObject(this);},initialize(){tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['deviceViewportSize','activeTree']);tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['pendingTree']);if(this.args.activeTiles!==undefined){this.activeTiles=this.args.activeTiles;delete this.args.activeTiles;}else if(this.args.tiles!==undefined){this.activeTiles=this.args.tiles;delete this.args.tiles;}
+if(!this.activeTiles){this.activeTiles=[];}
+this.activeTree.layerTreeHostImpl=this;this.activeTree.whichTree=constants.ACTIVE_TREE;if(this.pendingTree){this.pendingTree.layerTreeHostImpl=this;this.pendingTree.whichTree=constants.PENDING_TREE;}},getContentsScaleNames(){const scales={};for(let i=0;i<this.activeTiles.length;++i){const tile=this.activeTiles[i];scales[tile.contentsScale]=tile.resolution;}
+return scales;},getTree(whichTree){if(whichTree===constants.ACTIVE_TREE){return this.activeTree;}
+if(whichTree===constants.PENDING_TREE){return this.pendingTree;}
+throw new Exception('Unknown tree type + '+whichTree);},get tilesHaveGpuMemoryUsageInfo(){if(this.tilesHaveGpuMemoryUsageInfo_!==undefined){return this.tilesHaveGpuMemoryUsageInfo_;}
+for(let i=0;i<this.activeTiles.length;i++){if(this.activeTiles[i].gpuMemoryUsageInBytes===undefined){continue;}
+this.tilesHaveGpuMemoryUsageInfo_=true;return true;}
+this.tilesHaveGpuMemoryUsageInfo_=false;return false;},get gpuMemoryUsageInBytes(){if(!this.tilesHaveGpuMemoryUsageInfo)return;let usage=0;for(let i=0;i<this.activeTiles.length;i++){const u=this.activeTiles[i].gpuMemoryUsageInBytes;if(u!==undefined)usage+=u;}
+return usage;},get userFriendlyName(){let frameNumber;if(!this.activeTree){frameNumber=this.objectInstance.snapshots.indexOf(this);}else{if(this.activeTree.sourceFrameNumber===undefined){frameNumber=this.objectInstance.snapshots.indexOf(this);}else{frameNumber=this.activeTree.sourceFrameNumber;}}
+return'cc::LayerTreeHostImpl frame '+frameNumber;}};ObjectSnapshot.subTypes.register(LayerTreeHostImplSnapshot,{typeName:'cc::LayerTreeHostImpl'});function LayerTreeHostImplInstance(){ObjectInstance.apply(this,arguments);this.allLayersBBox_=undefined;}
+LayerTreeHostImplInstance.prototype={__proto__:ObjectInstance.prototype,get allContentsScales(){if(this.allContentsScales_){return this.allContentsScales_;}
+const scales={};for(const tileID in this.allTileHistories_){const tileHistory=this.allTileHistories_[tileID];scales[tileHistory.contentsScale]=true;}
+this.allContentsScales_=Object.keys(scales);return this.allContentsScales_;},get allLayersBBox(){if(this.allLayersBBox_){return this.allLayersBBox_;}
+const bbox=new tr.b.math.BBox2();function handleTree(tree){tree.renderSurfaceLayerList.forEach(function(layer){bbox.addQuad(layer.layerQuad);});}
+this.snapshots.forEach(function(lthi){handleTree(lthi.activeTree);if(lthi.pendingTree){handleTree(lthi.pendingTree);}});this.allLayersBBox_=bbox;return this.allLayersBBox_;}};ObjectInstance.subTypes.register(LayerTreeHostImplInstance,{typeName:'cc::LayerTreeHostImpl'});return{LayerTreeHostImplSnapshot,LayerTreeHostImplInstance,};});'use strict';tr.exportTo('tr.e.cc',function(){const tileTypes={highRes:'highRes',lowRes:'lowRes',extraHighRes:'extraHighRes',extraLowRes:'extraLowRes',missing:'missing',culled:'culled',solidColor:'solidColor',picture:'picture',directPicture:'directPicture',unknown:'unknown'};const tileBorder={highRes:{color:'rgba(80, 200, 200, 0.7)',width:1},lowRes:{color:'rgba(212, 83, 192, 0.7)',width:2},extraHighRes:{color:'rgba(239, 231, 20, 0.7)',width:2},extraLowRes:{color:'rgba(93, 186, 18, 0.7)',width:2},missing:{color:'rgba(255, 0, 0, 0.7)',width:1},culled:{color:'rgba(160, 100, 0, 0.8)',width:1},solidColor:{color:'rgba(128, 128, 128, 0.7)',width:1},picture:{color:'rgba(64, 64, 64, 0.7)',width:1},directPicture:{color:'rgba(127, 255, 0, 1.0)',width:1},unknown:{color:'rgba(0, 0, 0, 1.0)',width:2}};return{tileTypes,tileBorder};});'use strict';tr.exportTo('tr.e.cc',function(){const ObjectSnapshot=tr.model.ObjectSnapshot;function TileSnapshot(){ObjectSnapshot.apply(this,arguments);}
+TileSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize(){tr.e.cc.preInitializeObject(this);},initialize(){tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['layerId','contentsScale','contentRect']);if(this.args.managedState){this.resolution=this.args.managedState.resolution;this.isSolidColor=this.args.managedState.isSolidColor;this.isUsingGpuMemory=this.args.managedState.isUsingGpuMemory;this.hasResource=this.args.managedState.hasResource;this.scheduledPriority=this.args.scheduledPriority;this.gpuMemoryUsageInBytes=this.args.gpuMemoryUsage;}else{this.resolution=this.args.resolution;this.isSolidColor=this.args.drawInfo.isSolidColor;this.isUsingGpuMemory=this.args.isUsingGpuMemory;this.hasResource=this.args.hasResource;this.scheduledPriority=this.args.scheduledPriority;this.gpuMemoryUsageInBytes=this.args.gpuMemoryUsage;}
+if(this.contentRect){this.layerRect=this.contentRect.scale(1.0/this.contentsScale);}
+if(this.isSolidColor){this.type_=tr.e.cc.tileTypes.solidColor;}else if(!this.hasResource){this.type_=tr.e.cc.tileTypes.missing;}else if(this.resolution==='HIGH_RESOLUTION'){this.type_=tr.e.cc.tileTypes.highRes;}else if(this.resolution==='LOW_RESOLUTION'){this.type_=tr.e.cc.tileTypes.lowRes;}else{this.type_=tr.e.cc.tileTypes.unknown;}},getTypeForLayer(layer){let type=this.type_;if(type===tr.e.cc.tileTypes.unknown){if(this.contentsScale<layer.idealContentsScale){type=tr.e.cc.tileTypes.extraLowRes;}else if(this.contentsScale>layer.idealContentsScale){type=tr.e.cc.tileTypes.extraHighRes;}}
+return type;}};ObjectSnapshot.subTypes.register(TileSnapshot,{typeName:'cc::Tile'});return{TileSnapshot,};});'use strict';tr.exportTo('tr.ui.b',function(){const Location=tr.model.Location;function UIState(location,scaleX){this.location_=location;this.scaleX_=scaleX;}
+UIState.fromUserFriendlyString=function(model,viewport,stateString){const navByFinderPattern=/^(-?\d+(\.\d+)?)@(.+)x(\d+(\.\d+)?)$/g;const match=navByFinderPattern.exec(stateString);if(!match)return;const timestamp=parseFloat(match[1]);const stableId=match[3];const scaleX=parseFloat(match[4]);if(scaleX<=0){throw new Error('Invalid ScaleX value in UI State string.');}
+if(!viewport.containerToTrackMap.getTrackByStableId(stableId)){throw new Error('Invalid StableID given in UI State String.');}
+const loc=tr.model.Location.fromStableIdAndTimestamp(viewport,stableId,timestamp);return new UIState(loc,scaleX);};UIState.prototype={get location(){return this.location_;},get scaleX(){return this.scaleX_;},toUserFriendlyString(viewport){const timestamp=this.location_.xWorld;const stableId=this.location_.getContainingTrack(viewport).eventContainer.stableId;const scaleX=this.scaleX_;return timestamp.toFixed(5)+'@'+stableId+'x'+scaleX.toFixed(5);},toDict(){return{location:this.location_.toDict(),scaleX:this.scaleX_};}};return{UIState,};});'use strict';tr.exportTo('tr.ui.b',function(){const EventSet=tr.model.EventSet;const SelectionState=tr.model.SelectionState;function BrushingState(){this.guid_=tr.b.GUID.allocateSimple();this.selection_=new EventSet();this.findMatches_=new EventSet();this.analysisViewRelatedEvents_=new EventSet();this.analysisLinkHoveredEvents_=new EventSet();this.appliedToModel_=undefined;this.viewSpecificBrushingStates_={};}
+BrushingState.prototype={get guid(){return this.guid_;},clone(){const that=new BrushingState();that.selection_=this.selection_;that.findMatches_=this.findMatches_;that.analysisViewRelatedEvents_=this.analysisViewRelatedEvents_;that.analysisLinkHoveredEvents_=this.analysisLinkHoveredEvents_;that.viewSpecificBrushingStates_=this.viewSpecificBrushingStates_;return that;},equals(that){if(!this.selection_.equals(that.selection_)){return false;}
+if(!this.findMatches_.equals(that.findMatches_)){return false;}
+if(!this.analysisViewRelatedEvents_.equals(that.analysisViewRelatedEvents_)){return false;}
 if(!this.analysisLinkHoveredEvents_.equals(that.analysisLinkHoveredEvents_)){return false;}
-return true;},get selectionOfInterest(){if(this.selection_.length)
-return this.selection_;if(this.highlight_.length)
-return this.highlight_;if(this.analysisViewRelatedEvents_.length)
-return this.analysisViewRelatedEvents_;if(this.analysisLinkHoveredEvents_.length)
-return this.analysisLinkHoveredEvents_;return this.selection_;},get selection(){return this.selection_;},set selection(selection){if(this.appliedToModel_)
-throw new Error('Cannot mutate this state right now');if(selection===undefined)
-selection=new EventSet();this.selection_=selection;},get findMatches(){return this.findMatches_;},set findMatches(findMatches){if(this.appliedToModel_)
-throw new Error('Cannot mutate this state right now');if(findMatches===undefined)
-findMatches=new EventSet();this.findMatches_=findMatches;},get analysisViewRelatedEvents(){return this.analysisViewRelatedEvents_;},set analysisViewRelatedEvents(analysisViewRelatedEvents){if(this.appliedToModel_)
-throw new Error('Cannot mutate this state right now');if(analysisViewRelatedEvents===undefined)
-analysisViewRelatedEvents=new EventSet();this.analysisViewRelatedEvents_=analysisViewRelatedEvents;},get analysisLinkHoveredEvents(){return this.analysisLinkHoveredEvents_;},set analysisLinkHoveredEvents(analysisLinkHoveredEvents){if(this.appliedToModel_)
-throw new Error('Cannot mutate this state right now');if(analysisLinkHoveredEvents===undefined)
-analysisLinkHoveredEvents=new EventSet();this.analysisLinkHoveredEvents_=analysisLinkHoveredEvents;},get isAppliedToModel(){return this.appliedToModel_!==undefined;},get viewSpecificBrushingStates(){return this.viewSpecificBrushingStates_;},set viewSpecificBrushingStates(viewSpecificBrushingStates){this.viewSpecificBrushingStates_=viewSpecificBrushingStates;},get causesDimming_(){return this.findMatches_.length>0||this.analysisViewRelatedEvents_.length>0;},get brightenedEvents_(){var brightenedEvents=new EventSet();brightenedEvents.addEventSet(this.selection_);brightenedEvents.addEventSet(this.analysisLinkHoveredEvents_);return brightenedEvents;},applyToModelSelectionState:function(model){this.appliedToModel_=model;if(!this.causesDimming_){this.brightenedEvents_.forEach(function(e){var score;score=0;if(this.selection_.contains(e))
-score++;if(this.analysisLinkHoveredEvents_.contains(e))
-score++;e.selectionState=SelectionState.getFromBrighteningLevel(score);},this);return;}
-var brightenedEvents=this.brightenedEvents_;model.iterateAllEvents(function(e){var score;if(brightenedEvents.contains(e)){score=0;if(this.selection_.contains(e))
-score++;if(this.analysisLinkHoveredEvents_.contains(e))
-score++;e.selectionState=SelectionState.getFromBrighteningLevel(score);}else{score=0;if(this.findMatches_.contains(e))
-score++;if(this.analysisViewRelatedEvents_.contains(e))
-score++;e.selectionState=SelectionState.getFromDimmingLevel(score);}}.bind(this));},transferModelOwnershipToClone:function(that){if(!this.appliedToModel_)
-throw new Error('Not applied');that.appliedToModel_=this.appliedToModel_;this.appliedToModel_=undefined;},unapplyFromModelSelectionState:function(){if(!this.appliedToModel_)
-throw new Error('Not applied');var model=this.appliedToModel_;this.appliedToModel_=undefined;if(!this.causesDimming_){this.brightenedEvents_.forEach(function(e){e.selectionState=SelectionState.NONE;});return;}
-model.iterateAllEvents(function(e){e.selectionState=SelectionState.NONE;});}};return{BrushingState:BrushingState};});'use strict';tr.exportTo('tr.ui.b',function(){function Animation(){}
-Animation.prototype={canTakeOverFor:function(existingAnimation){throw new Error('Not implemented');},takeOverFor:function(existingAnimation,newStartTimestamp,target){throw new Error('Not implemented');},start:function(timestamp,target){throw new Error('Not implemented');},didStopEarly:function(timestamp,target,willBeTakenOverByAnotherAnimation){},tick:function(timestamp,target){throw new Error('Not implemented');}};return{Animation:Animation};});'use strict';tr.exportTo('tr.ui.b',function(){function AnimationController(){tr.b.EventTarget.call(this);this.target_=undefined;this.activeAnimation_=undefined;this.tickScheduled_=false;}
-AnimationController.prototype={__proto__:tr.b.EventTarget.prototype,get target(){return this.target_;},set target(target){if(this.activeAnimation_)
-throw new Error('Cannot change target while animation is running.');if(target.cloneAnimationState===undefined||typeof target.cloneAnimationState!=='function')
-throw new Error('target must have a cloneAnimationState function');this.target_=target;},get activeAnimation(){return this.activeAnimation_;},get hasActiveAnimation(){return!!this.activeAnimation_;},queueAnimation:function(animation,opt_now){if(this.target_===undefined)
-throw new Error('Cannot queue animations without a target');var now;if(opt_now!==undefined)
-now=opt_now;else
-now=window.performance.now();if(this.activeAnimation_){var done=this.activeAnimation_.tick(now,this.target_);if(done)
-this.activeAnimation_=undefined;}
+return true;},get selectionOfInterest(){if(this.selection_.length){return this.selection_;}
+if(this.highlight_.length){return this.highlight_;}
+if(this.analysisViewRelatedEvents_.length){return this.analysisViewRelatedEvents_;}
+if(this.analysisLinkHoveredEvents_.length){return this.analysisLinkHoveredEvents_;}
+return this.selection_;},get selection(){return this.selection_;},set selection(selection){if(this.appliedToModel_){throw new Error('Cannot mutate this state right now');}
+if(selection===undefined){selection=new EventSet();}
+this.selection_=selection;},get findMatches(){return this.findMatches_;},set findMatches(findMatches){if(this.appliedToModel_){throw new Error('Cannot mutate this state right now');}
+if(findMatches===undefined){findMatches=new EventSet();}
+this.findMatches_=findMatches;},get analysisViewRelatedEvents(){return this.analysisViewRelatedEvents_;},set analysisViewRelatedEvents(analysisViewRelatedEvents){if(this.appliedToModel_){throw new Error('Cannot mutate this state right now');}
+if(!(analysisViewRelatedEvents instanceof EventSet)){analysisViewRelatedEvents=new EventSet();}
+this.analysisViewRelatedEvents_=analysisViewRelatedEvents;},get analysisLinkHoveredEvents(){return this.analysisLinkHoveredEvents_;},set analysisLinkHoveredEvents(analysisLinkHoveredEvents){if(this.appliedToModel_){throw new Error('Cannot mutate this state right now');}
+if(!(analysisLinkHoveredEvents instanceof EventSet)){analysisLinkHoveredEvents=new EventSet();}
+this.analysisLinkHoveredEvents_=analysisLinkHoveredEvents;},get isAppliedToModel(){return this.appliedToModel_!==undefined;},get viewSpecificBrushingStates(){return this.viewSpecificBrushingStates_;},set viewSpecificBrushingStates(viewSpecificBrushingStates){this.viewSpecificBrushingStates_=viewSpecificBrushingStates;},get defaultState_(){const standoutEventExists=(this.analysisLinkHoveredEvents_.length>0||this.analysisViewRelatedEvents_.length>0||this.findMatches_.length>0);return(standoutEventExists?SelectionState.DIMMED0:SelectionState.NONE);},get brightenedEvents_(){const brightenedEvents=new EventSet();brightenedEvents.addEventSet(this.findMatches);brightenedEvents.addEventSet(this.analysisViewRelatedEvents_);brightenedEvents.addEventSet(this.selection_);brightenedEvents.addEventSet(this.analysisLinkHoveredEvents_);return brightenedEvents;},applyToEventSelectionStates(model){this.appliedToModel_=model;if(model){const newDefaultState=this.defaultState_;const currentDefaultState=tr.b.getFirstElement(model.getDescendantEvents()).selectionState;if(currentDefaultState!==newDefaultState){for(const e of model.getDescendantEvents()){e.selectionState=newDefaultState;}}}
+let level;for(const e of this.brightenedEvents_){level=0;if(this.analysisViewRelatedEvents_.contains(e)||this.findMatches_.contains(e)){level++;}
+if(this.analysisLinkHoveredEvents_.contains(e)){level++;}
+if(this.selection_.contains(e)){level++;}
+e.selectionState=SelectionState.getFromBrighteningLevel(level);}},transferModelOwnershipToClone(that){if(!this.appliedToModel_){throw new Error('Not applied');}
+that.appliedToModel_=this.appliedToModel_;this.appliedToModel_=undefined;},unapplyFromEventSelectionStates(){if(!this.appliedToModel_){throw new Error('Not applied');}
+const model=this.appliedToModel_;this.appliedToModel_=undefined;const defaultState=this.defaultState_;for(const e of this.brightenedEvents_){e.selectionState=defaultState;}
+return defaultState;}};return{BrushingState,};});'use strict';tr.exportTo('tr.ui.b',function(){function Animation(){}
+Animation.prototype={canTakeOverFor(existingAnimation){throw new Error('Not implemented');},takeOverFor(existingAnimation,newStartTimestamp,target){throw new Error('Not implemented');},start(timestamp,target){throw new Error('Not implemented');},didStopEarly(timestamp,target,willBeTakenOverByAnotherAnimation){},tick(timestamp,target){throw new Error('Not implemented');}};return{Animation,};});'use strict';tr.exportTo('tr.ui.b',function(){function AnimationController(){tr.b.EventTarget.call(this);this.target_=undefined;this.activeAnimation_=undefined;this.tickScheduled_=false;}
+AnimationController.prototype={__proto__:tr.b.EventTarget.prototype,get target(){return this.target_;},set target(target){if(this.activeAnimation_){throw new Error('Cannot change target while animation is running.');}
+if(target.cloneAnimationState===undefined||typeof target.cloneAnimationState!=='function'){throw new Error('target must have a cloneAnimationState function');}
+this.target_=target;},get activeAnimation(){return this.activeAnimation_;},get hasActiveAnimation(){return!!this.activeAnimation_;},queueAnimation(animation,opt_now){if(this.target_===undefined){throw new Error('Cannot queue animations without a target');}
+let now;if(opt_now!==undefined){now=opt_now;}else{now=window.performance.now();}
+if(this.activeAnimation_){const done=this.activeAnimation_.tick(now,this.target_);if(done){this.activeAnimation_=undefined;}}
 if(this.activeAnimation_){if(animation.canTakeOverFor(this.activeAnimation_)){this.activeAnimation_.didStopEarly(now,this.target_,true);animation.takeOverFor(this.activeAnimation_,now,this.target_);}else{this.activeAnimation_.didStopEarly(now,this.target_,false);}}
-this.activeAnimation_=animation;this.activeAnimation_.start(now,this.target_);if(this.tickScheduled_)
-return;this.tickScheduled_=true;tr.b.requestAnimationFrame(this.tickActiveAnimation_,this);},cancelActiveAnimation:function(opt_now){if(!this.activeAnimation_)
-return;var now;if(opt_now!==undefined)
-now=opt_now;else
-now=window.performance.now();this.activeAnimation_.didStopEarly(now,this.target_,false);this.activeAnimation_=undefined;},tickActiveAnimation_:function(frameBeginTime){this.tickScheduled_=false;if(!this.activeAnimation_)
-return;if(this.target_===undefined){this.activeAnimation_.didStopEarly(frameBeginTime,this.target_,false);return;}
-var oldTargetState=this.target_.cloneAnimationState();var done=this.activeAnimation_.tick(frameBeginTime,this.target_);if(done)
-this.activeAnimation_=undefined;if(this.activeAnimation_){this.tickScheduled_=true;tr.b.requestAnimationFrame(this.tickActiveAnimation_,this);}
-if(oldTargetState){var e=new tr.b.Event('didtick');e.oldTargetState=oldTargetState;this.dispatchEvent(e,false,false);}}};return{AnimationController:AnimationController};});'use strict';tr.exportTo('tr.b',function(){function Settings(){return Settings;};if(tr.b.unittest&&tr.b.unittest.TestRunner){tr.b.unittest.TestRunner.addEventListener('tr-unittest-will-run',function(){if(tr.isHeadless)
-Settings.setAlternativeStorageInstance(new HeadlessStorage());else
-Settings.setAlternativeStorageInstance(global.sessionStorage);});}
+this.activeAnimation_=animation;this.activeAnimation_.start(now,this.target_);if(this.tickScheduled_)return;this.tickScheduled_=true;tr.b.requestAnimationFrame(this.tickActiveAnimation_,this);},cancelActiveAnimation(opt_now){if(!this.activeAnimation_)return;let now;if(opt_now!==undefined){now=opt_now;}else{now=window.performance.now();}
+this.activeAnimation_.didStopEarly(now,this.target_,false);this.activeAnimation_=undefined;},tickActiveAnimation_(frameBeginTime){this.tickScheduled_=false;if(!this.activeAnimation_)return;if(this.target_===undefined){this.activeAnimation_.didStopEarly(frameBeginTime,this.target_,false);return;}
+const oldTargetState=this.target_.cloneAnimationState();const done=this.activeAnimation_.tick(frameBeginTime,this.target_);if(done){this.activeAnimation_=undefined;}
+if(this.activeAnimation_){this.tickScheduled_=true;tr.b.requestAnimationFrame(this.tickActiveAnimation_,this);}
+if(oldTargetState){const e=new tr.b.Event('didtick');e.oldTargetState=oldTargetState;this.dispatchEvent(e,false,false);}}};return{AnimationController,};});'use strict';tr.exportTo('tr.b',function(){function Settings(){return Settings;}
+if(tr.b.unittest&&tr.b.unittest.TestRunner){tr.b.unittest.TestRunner.addEventListener('tr-unittest-will-run',function(){if(tr.isHeadless){Settings.setAlternativeStorageInstance(new HeadlessStorage());}else{Settings.setAlternativeStorageInstance(global.sessionStorage);global.sessionStorage.clear();}});}
 function SessionSettings(){return SessionSettings;}
-function AddStaticStorageFunctionsToClass_(input_class,storage){input_class.storage_=storage;input_class.get=function(key,opt_default,opt_namespace){key=input_class.namespace_(key,opt_namespace);var rawVal=input_class.storage_.getItem(key);if(rawVal===null||rawVal===undefined)
-return opt_default;try{return JSON.parse(rawVal).value;}catch(e){input_class.storage_.removeItem(key);return opt_default;}};input_class.set=function(key,value,opt_namespace){if(value===undefined)
-throw new Error('Settings.set: value must not be undefined');var v=JSON.stringify({value:value});input_class.storage_.setItem(input_class.namespace_(key,opt_namespace),v);};input_class.keys=function(opt_namespace){var result=[];opt_namespace=opt_namespace||'';for(var i=0;i<input_class.storage_.length;i++){var key=input_class.storage_.key(i);if(input_class.isnamespaced_(key,opt_namespace))
-result.push(input_class.unnamespace_(key,opt_namespace));}
-return result;};input_class.isnamespaced_=function(key,opt_namespace){return key.indexOf(input_class.normalize_(opt_namespace))==0;};input_class.namespace_=function(key,opt_namespace){return input_class.normalize_(opt_namespace)+key;};input_class.unnamespace_=function(key,opt_namespace){return key.replace(input_class.normalize_(opt_namespace),'');};input_class.normalize_=function(opt_namespace){return input_class.NAMESPACE+(opt_namespace?opt_namespace+'.':'');};input_class.setAlternativeStorageInstance=function(instance){input_class.storage_=instance;};input_class.getAlternativeStorageInstance=function(){if(!tr.isHeadless&&input_class.storage_===localStorage)
-return undefined;return input_class.storage_;};input_class.NAMESPACE='trace-viewer';};function HeadlessStorage(){this.length=0;this.hasItem_={};this.items_={};this.itemsAsArray_=undefined;}
-HeadlessStorage.prototype={key:function(index){return this.itemsAsArray[index];},get itemsAsArray(){if(this.itemsAsArray_!==undefined)
-return this.itemsAsArray_;var itemsAsArray=[];for(var k in this.items_)
-itemsAsArray.push(k);this.itemsAsArray_=itemsAsArray;return this.itemsAsArray_;},getItem:function(key){if(!this.hasItem_[key])
-return null;return this.items_[key];},removeItem:function(key){if(!this.hasItem_[key])
-return;var value=this.items_[key];delete this.hasItem_[key];delete this.items_[key];this.length--;this.itemsAsArray_=undefined;return value;},setItem:function(key,value){if(this.hasItem_[key]){this.items_[key]=value;return;}
+function AddStaticStorageFunctionsToClass_(inputClass,storage){inputClass.storage_=storage;inputClass.get=function(key,opt_default,opt_namespace){key=inputClass.namespace_(key,opt_namespace);const rawVal=inputClass.storage_.getItem(key);if(rawVal===null||rawVal===undefined){return opt_default;}
+try{return JSON.parse(rawVal).value;}catch(e){inputClass.storage_.removeItem(key);return opt_default;}};inputClass.set=function(key,value,opt_namespace){if(value===undefined){throw new Error('Settings.set: value must not be undefined');}
+const v=JSON.stringify({value});inputClass.storage_.setItem(inputClass.namespace_(key,opt_namespace),v);};inputClass.keys=function(opt_namespace){const result=[];opt_namespace=opt_namespace||'';for(let i=0;i<inputClass.storage_.length;i++){const key=inputClass.storage_.key(i);if(inputClass.isnamespaced_(key,opt_namespace)){result.push(inputClass.unnamespace_(key,opt_namespace));}}
+return result;};inputClass.isnamespaced_=function(key,opt_namespace){return key.indexOf(inputClass.normalize_(opt_namespace))===0;};inputClass.namespace_=function(key,opt_namespace){return inputClass.normalize_(opt_namespace)+key;};inputClass.unnamespace_=function(key,opt_namespace){return key.replace(inputClass.normalize_(opt_namespace),'');};inputClass.normalize_=function(opt_namespace){return inputClass.NAMESPACE+(opt_namespace?opt_namespace+'.':'');};inputClass.setAlternativeStorageInstance=function(instance){inputClass.storage_=instance;};inputClass.getAlternativeStorageInstance=function(){if(!tr.isHeadless&&inputClass.storage_===localStorage){return undefined;}
+return inputClass.storage_;};inputClass.NAMESPACE='trace-viewer';}
+function HeadlessStorage(){this.length=0;this.hasItem_={};this.items_={};this.itemsAsArray_=undefined;}
+HeadlessStorage.prototype={key(index){return this.itemsAsArray[index];},get itemsAsArray(){if(this.itemsAsArray_!==undefined){return this.itemsAsArray_;}
+const itemsAsArray=[];for(const k in this.items_){itemsAsArray.push(k);}
+this.itemsAsArray_=itemsAsArray;return this.itemsAsArray_;},getItem(key){if(!this.hasItem_[key]){return null;}
+return this.items_[key];},removeItem(key){if(!this.hasItem_[key]){return;}
+const value=this.items_[key];delete this.hasItem_[key];delete this.items_[key];this.length--;this.itemsAsArray_=undefined;return value;},setItem(key,value){if(this.hasItem_[key]){this.items_[key]=value;return;}
 this.items_[key]=value;this.hasItem_[key]=true;this.length++;this.itemsAsArray_=undefined;return value;}};if(tr.isHeadless){AddStaticStorageFunctionsToClass_(Settings,new HeadlessStorage());AddStaticStorageFunctionsToClass_(SessionSettings,new HeadlessStorage());}else{AddStaticStorageFunctionsToClass_(Settings,localStorage);AddStaticStorageFunctionsToClass_(SessionSettings,sessionStorage);}
-return{Settings:Settings,SessionSettings:SessionSettings};});'use strict';tr.exportTo('tr.ui.b',function(){function createSpan(opt_dictionary){var ownerDocument=document;if(opt_dictionary&&opt_dictionary.ownerDocument)
-ownerDocument=opt_dictionary.ownerDocument;var spanEl=ownerDocument.createElement('span');if(opt_dictionary){if(opt_dictionary.className)
-spanEl.className=opt_dictionary.className;if(opt_dictionary.textContent)
-spanEl.textContent=opt_dictionary.textContent;if(opt_dictionary.tooltip)
-spanEl.title=opt_dictionary.tooltip;if(opt_dictionary.parent)
-opt_dictionary.parent.appendChild(spanEl);if(opt_dictionary.bold)
-spanEl.style.fontWeight='bold';if(opt_dictionary.italic)
-spanEl.style.fontStyle='italic';if(opt_dictionary.marginLeft)
-spanEl.style.marginLeft=opt_dictionary.marginLeft;if(opt_dictionary.marginRight)
-spanEl.style.marginRight=opt_dictionary.marginRight;if(opt_dictionary.backgroundColor)
-spanEl.style.backgroundColor=opt_dictionary.backgroundColor;if(opt_dictionary.color)
-spanEl.style.color=opt_dictionary.color;}
-return spanEl;};function createDiv(opt_dictionary){var divEl=document.createElement('div');if(opt_dictionary){if(opt_dictionary.className)
-divEl.className=opt_dictionary.className;if(opt_dictionary.parent)
-opt_dictionary.parent.appendChild(divEl);if(opt_dictionary.textContent)
-divEl.textContent=opt_dictionary.textContent;if(opt_dictionary.maxWidth)
-divEl.style.maxWidth=opt_dictionary.maxWidth;}
-return divEl;};function createScopedStyle(styleContent){var styleEl=document.createElement('style');styleEl.scoped=true;styleEl.innerHTML=styleContent;return styleEl;}
-function valuesEqual(a,b){if(a instanceof Array&&b instanceof Array)
-return a.length===b.length&&JSON.stringify(a)===JSON.stringify(b);return a===b;}
-function createSelector(targetEl,targetElProperty,settingsKey,defaultValue,items,opt_namespace){var defaultValueIndex;for(var i=0;i<items.length;i++){var item=items[i];if(valuesEqual(item.value,defaultValue)){defaultValueIndex=i;break;}}
-if(defaultValueIndex===undefined)
-throw new Error('defaultValue must be in the items list');var selectorEl=document.createElement('select');selectorEl.addEventListener('change',onChange);for(var i=0;i<items.length;i++){var item=items[i];var optionEl=document.createElement('option');optionEl.textContent=item.label;optionEl.targetPropertyValue=item.value;optionEl.item=item;selectorEl.appendChild(optionEl);}
-function onChange(e){var value=selectorEl.selectedOptions[0].targetPropertyValue;tr.b.Settings.set(settingsKey,value,opt_namespace);targetEl[targetElProperty]=value;}
-var oldSetter=targetEl.__lookupSetter__('selectedIndex');selectorEl.__defineGetter__('selectedValue',function(v){return selectorEl.children[selectorEl.selectedIndex].targetPropertyValue;});selectorEl.__defineGetter__('selectedItem',function(v){return selectorEl.children[selectorEl.selectedIndex].item;});selectorEl.__defineSetter__('selectedValue',function(v){for(var i=0;i<selectorEl.children.length;i++){var value=selectorEl.children[i].targetPropertyValue;if(valuesEqual(value,v)){var changed=selectorEl.selectedIndex!=i;if(changed){selectorEl.selectedIndex=i;onChange();}
+return{Settings,SessionSettings,};});'use strict';tr.exportTo('tr.ui.b',function(){function createSpan(opt_dictionary){let ownerDocument=document;if(opt_dictionary&&opt_dictionary.ownerDocument){ownerDocument=opt_dictionary.ownerDocument;}
+const spanEl=ownerDocument.createElement('span');if(opt_dictionary){if(opt_dictionary.className){spanEl.className=opt_dictionary.className;}
+if(opt_dictionary.textContent){Polymer.dom(spanEl).textContent=opt_dictionary.textContent;}
+if(opt_dictionary.tooltip){spanEl.title=opt_dictionary.tooltip;}
+if(opt_dictionary.parent){Polymer.dom(opt_dictionary.parent).appendChild(spanEl);}
+if(opt_dictionary.bold){spanEl.style.fontWeight='bold';}
+if(opt_dictionary.italic){spanEl.style.fontStyle='italic';}
+if(opt_dictionary.marginLeft){spanEl.style.marginLeft=opt_dictionary.marginLeft;}
+if(opt_dictionary.marginRight){spanEl.style.marginRight=opt_dictionary.marginRight;}
+if(opt_dictionary.backgroundColor){spanEl.style.backgroundColor=opt_dictionary.backgroundColor;}
+if(opt_dictionary.color){spanEl.style.color=opt_dictionary.color;}}
+return spanEl;}
+function createLink(opt_args){let ownerDocument=document;if(opt_args&&opt_args.ownerDocument){ownerDocument=opt_args.ownerDocument;}
+const linkEl=ownerDocument.createElement('a');if(opt_args){if(opt_args.href)linkEl.href=opt_args.href;if(opt_args.tooltip)linkEl.title=opt_args.tooltip;if(opt_args.color)linkEl.style.color=opt_args.color;if(opt_args.bold)linkEl.style.fontWeight='bold';if(opt_args.italic)linkEl.style.fontStyle='italic';if(opt_args.className)linkEl.className=opt_args.className;if(opt_args.parent)Polymer.dom(opt_args.parent).appendChild(linkEl);if(opt_args.marginLeft)linkEl.style.marginLeft=opt_args.marginLeft;if(opt_args.marginRight)linkEl.style.marginRight=opt_args.marginRight;if(opt_args.backgroundColor){linkEl.style.backgroundColor=opt_args.backgroundColor;}
+if(opt_args.textContent){Polymer.dom(linkEl).textContent=opt_args.textContent;}}
+return linkEl;}
+function createDiv(opt_dictionary){const divEl=document.createElement('div');if(opt_dictionary){if(opt_dictionary.className){divEl.className=opt_dictionary.className;}
+if(opt_dictionary.parent){Polymer.dom(opt_dictionary.parent).appendChild(divEl);}
+if(opt_dictionary.textContent){Polymer.dom(divEl).textContent=opt_dictionary.textContent;}
+if(opt_dictionary.maxWidth){divEl.style.maxWidth=opt_dictionary.maxWidth;}}
+return divEl;}
+function createScopedStyle(styleContent){const styleEl=document.createElement('style');styleEl.scoped=true;Polymer.dom(styleEl).innerHTML=styleContent;return styleEl;}
+function valuesEqual(a,b){if(a instanceof Array&&b instanceof Array){return a.length===b.length&&JSON.stringify(a)===JSON.stringify(b);}
+return a===b;}
+function createSelector(targetEl,targetElProperty,settingsKey,defaultValue,items,opt_namespace){let defaultValueIndex;for(let i=0;i<items.length;i++){const item=items[i];if(valuesEqual(item.value,defaultValue)){defaultValueIndex=i;break;}}
+if(defaultValueIndex===undefined){throw new Error('defaultValue must be in the items list');}
+const selectorEl=document.createElement('select');selectorEl.addEventListener('change',onChange);for(let i=0;i<items.length;i++){const item=items[i];const optionEl=document.createElement('option');Polymer.dom(optionEl).textContent=item.label;optionEl.targetPropertyValue=item.value;optionEl.item=item;Polymer.dom(selectorEl).appendChild(optionEl);}
+function onChange(e){const value=selectorEl.selectedOptions[0].targetPropertyValue;tr.b.Settings.set(settingsKey,value,opt_namespace);targetEl[targetElProperty]=value;}
+const oldSetter=targetEl.__lookupSetter__('selectedIndex');selectorEl.__defineGetter__('selectedValue',function(v){return selectorEl.children[selectorEl.selectedIndex].targetPropertyValue;});selectorEl.__defineGetter__('selectedItem',function(v){return selectorEl.children[selectorEl.selectedIndex].item;});selectorEl.__defineSetter__('selectedValue',function(v){for(let i=0;i<selectorEl.children.length;i++){const value=selectorEl.children[i].targetPropertyValue;if(valuesEqual(value,v)){const changed=selectorEl.selectedIndex!==i;if(changed){selectorEl.selectedIndex=i;onChange();}
 return;}}
-throw new Error('Not a valid value');});var initialValue=tr.b.Settings.get(settingsKey,defaultValue,opt_namespace);var didSet=false;for(var i=0;i<selectorEl.children.length;i++){if(valuesEqual(selectorEl.children[i].targetPropertyValue,initialValue)){didSet=true;targetEl[targetElProperty]=initialValue;selectorEl.selectedIndex=i;break;}}
+throw new Error('Not a valid value');});const initialValue=tr.b.Settings.get(settingsKey,defaultValue,opt_namespace);let didSet=false;for(let i=0;i<selectorEl.children.length;i++){if(valuesEqual(selectorEl.children[i].targetPropertyValue,initialValue)){didSet=true;targetEl[targetElProperty]=initialValue;selectorEl.selectedIndex=i;break;}}
 if(!didSet){selectorEl.selectedIndex=defaultValueIndex;targetEl[targetElProperty]=defaultValue;}
 return selectorEl;}
-function createEditCategorySpan(optionGroupEl,targetEl){var spanEl=createSpan({className:'edit-categories'});spanEl.textContent='Edit categories';spanEl.classList.add('labeled-option');spanEl.addEventListener('click',function(){targetEl.onClickEditCategories();});return spanEl;}
-function createOptionGroup(targetEl,targetElProperty,settingsKey,defaultValue,items){function onChange(){var value=[];if(this.value.length)
-value=this.value.split(',');tr.b.Settings.set(settingsKey,value);targetEl[targetElProperty]=value;}
-var optionGroupEl=createSpan({className:'labeled-option-group'});var initialValue=tr.b.Settings.get(settingsKey,defaultValue);for(var i=0;i<items.length;++i){var item=items[i];var id='category-preset-'+item.label.replace(/ /g,'-');var radioEl=document.createElement('input');radioEl.type='radio';radioEl.setAttribute('id',id);radioEl.setAttribute('name','category-presets-group');radioEl.setAttribute('value',item.value);radioEl.addEventListener('change',onChange.bind(radioEl,targetEl,targetElProperty,settingsKey));if(valuesEqual(initialValue,item.value))
-radioEl.checked=true;var labelEl=document.createElement('label');labelEl.textContent=item.label;labelEl.setAttribute('for',id);var spanEl=createSpan({className:'labeled-option'});spanEl.appendChild(radioEl);spanEl.appendChild(labelEl);spanEl.__defineSetter__('checked',function(opt_bool){var changed=radioEl.checked!==(!!opt_bool);if(!changed)
-return;radioEl.checked=!!opt_bool;onChange();});spanEl.__defineGetter__('checked',function(){return radioEl.checked;});optionGroupEl.appendChild(spanEl);}
-optionGroupEl.appendChild(createEditCategorySpan(optionGroupEl,targetEl));if(!initialValue.length)
-optionGroupEl.classList.add('categories-expanded');targetEl[targetElProperty]=initialValue;return optionGroupEl;}
-var nextCheckboxId=1;function createCheckBox(targetEl,targetElProperty,settingsKey,defaultValue,label,opt_changeCb){var buttonEl=document.createElement('input');buttonEl.type='checkbox';var initialValue=tr.b.Settings.get(settingsKey,defaultValue);buttonEl.checked=!!initialValue;if(targetEl)
-targetEl[targetElProperty]=initialValue;function onChange(){tr.b.Settings.set(settingsKey,buttonEl.checked);if(targetEl)
-targetEl[targetElProperty]=buttonEl.checked;if(opt_changeCb)
-opt_changeCb.call();}
-buttonEl.addEventListener('change',onChange);var id='#checkbox-'+nextCheckboxId++;var spanEl=createSpan({className:'labeled-checkbox'});buttonEl.setAttribute('id',id);var labelEl=document.createElement('label');labelEl.textContent=label;labelEl.setAttribute('for',id);spanEl.appendChild(buttonEl);spanEl.appendChild(labelEl);spanEl.__defineSetter__('checked',function(opt_bool){var changed=buttonEl.checked!==(!!opt_bool);if(!changed)
-return;buttonEl.checked=!!opt_bool;onChange();});spanEl.__defineGetter__('checked',function(){return buttonEl.checked;});return spanEl;}
-function createButton(targetEl,targetElProperty,label,opt_changeCb){var buttonEl=document.createElement('input');buttonEl.type='button';function onClick(){if(opt_changeCb)
-opt_changeCb.call();}
-buttonEl.addEventListener('click',onClick);buttonEl.value=label;return buttonEl;}
-function createTextInput(targetEl,targetElProperty,settingsKey,defaultValue){var initialValue=tr.b.Settings.get(settingsKey,defaultValue);var el=document.createElement('input');el.type='text';function onChange(e){tr.b.Settings.set(settingsKey,el.value);targetEl[targetElProperty]=el.value;}
+function createEditCategorySpan(optionGroupEl,targetEl){const spanEl=createSpan({className:'edit-categories'});Polymer.dom(spanEl).textContent='Edit categories';Polymer.dom(spanEl).classList.add('labeled-option');spanEl.addEventListener('click',function(){targetEl.onClickEditCategories();});return spanEl;}
+function createOptionGroup(targetEl,targetElProperty,settingsKey,defaultValue,items){function onChange(){let value=[];if(this.value.length){value=this.value.split(',');}
+tr.b.Settings.set(settingsKey,value);targetEl[targetElProperty]=value;}
+const optionGroupEl=createSpan({className:'labeled-option-group'});const initialValue=tr.b.Settings.get(settingsKey,defaultValue);for(let i=0;i<items.length;++i){const item=items[i];const id='category-preset-'+item.label.replace(/ /g,'-');const radioEl=document.createElement('input');radioEl.type='radio';Polymer.dom(radioEl).setAttribute('id',id);Polymer.dom(radioEl).setAttribute('name','category-presets-group');Polymer.dom(radioEl).setAttribute('value',item.value);radioEl.addEventListener('change',onChange.bind(radioEl,targetEl,targetElProperty,settingsKey));if(valuesEqual(initialValue,item.value)){radioEl.checked=true;}
+const labelEl=document.createElement('label');Polymer.dom(labelEl).textContent=item.label;Polymer.dom(labelEl).setAttribute('for',id);const spanEl=createSpan({className:'labeled-option'});Polymer.dom(spanEl).appendChild(radioEl);Polymer.dom(spanEl).appendChild(labelEl);spanEl.__defineSetter__('checked',function(opt_bool){const changed=radioEl.checked!==(!!opt_bool);if(!changed)return;radioEl.checked=!!opt_bool;onChange();});spanEl.__defineGetter__('checked',function(){return radioEl.checked;});Polymer.dom(optionGroupEl).appendChild(spanEl);}
+Polymer.dom(optionGroupEl).appendChild(createEditCategorySpan(optionGroupEl,targetEl));if(!initialValue.length){Polymer.dom(optionGroupEl).classList.add('categories-expanded');}
+targetEl[targetElProperty]=initialValue;return optionGroupEl;}
+let nextCheckboxId=1;function createCheckBox(targetEl,targetElProperty,settingsKey,defaultValue,label,opt_changeCb){const buttonEl=document.createElement('input');buttonEl.type='checkbox';let initialValue=defaultValue;if(settingsKey!==undefined){initialValue=tr.b.Settings.get(settingsKey,defaultValue);buttonEl.checked=!!initialValue;}
+if(targetEl){targetEl[targetElProperty]=initialValue;}
+function onChange(){if(settingsKey!==undefined){tr.b.Settings.set(settingsKey,buttonEl.checked);}
+if(targetEl){targetEl[targetElProperty]=buttonEl.checked;}
+if(opt_changeCb){opt_changeCb.call();}}
+buttonEl.addEventListener('change',onChange);const id='#checkbox-'+nextCheckboxId++;const spanEl=createSpan();spanEl.style.display='flex';spanEl.style.whiteSpace='nowrap';Polymer.dom(buttonEl).setAttribute('id',id);const labelEl=document.createElement('label');Polymer.dom(labelEl).textContent=label;Polymer.dom(labelEl).setAttribute('for',id);Polymer.dom(spanEl).appendChild(buttonEl);Polymer.dom(spanEl).appendChild(labelEl);spanEl.__defineSetter__('checked',function(opt_bool){const changed=buttonEl.checked!==(!!opt_bool);if(!changed)return;buttonEl.checked=!!opt_bool;onChange();});spanEl.__defineGetter__('checked',function(){return buttonEl.checked;});return spanEl;}
+function createButton(label,opt_callback,opt_this){const buttonEl=document.createElement('input');buttonEl.type='button';buttonEl.value=label;function onClick(){opt_callback.call(opt_this||buttonEl);}
+if(opt_callback){buttonEl.addEventListener('click',onClick);}
+return buttonEl;}
+function createTextInput(targetEl,targetElProperty,settingsKey,defaultValue){const initialValue=tr.b.Settings.get(settingsKey,defaultValue);const el=document.createElement('input');el.type='text';function onChange(e){tr.b.Settings.set(settingsKey,el.value);targetEl[targetElProperty]=el.value;}
 el.addEventListener('input',onChange);el.value=initialValue;targetEl[targetElProperty]=initialValue;return el;}
-function isElementAttachedToDocument(el){var cur=el;while(cur.parentNode)
-cur=cur.parentNode;return(cur===el.ownerDocument||cur.nodeName==='#document-fragment');}
-function asHTMLOrTextNode(value,opt_ownerDocument){if(value instanceof Node)
-return value;var ownerDocument=opt_ownerDocument||document;return ownerDocument.createTextNode(value);}
-return{createSpan:createSpan,createDiv:createDiv,createScopedStyle:createScopedStyle,createSelector:createSelector,createOptionGroup:createOptionGroup,createCheckBox:createCheckBox,createButton:createButton,createTextInput:createTextInput,isElementAttachedToDocument:isElementAttachedToDocument,asHTMLOrTextNode:asHTMLOrTextNode};});'use strict';tr.exportTo('tr.ui.b',function(){var ColorScheme=tr.b.ColorScheme;var colors=ColorScheme.colors;var colorsAsStrings=ColorScheme.colorsAsStrings;var numColorsPerVariant=ColorScheme.properties.numColorsPerVariant;var SelectionState=tr.model.SelectionState;var EventPresenter={getSelectableItemColorAsString:function(item){var colorId=item.colorId+this.getColorIdOffset_(item);return colorsAsStrings[colorId];},getColorIdOffset_:function(event){return event.selectionState;},getTextColor:function(event){if(event.selectionState===SelectionState.DIMMED)
-return'rgb(60,60,60)';return'rgb(0,0,0)';},getSliceColorId:function(slice){return slice.colorId+this.getColorIdOffset_(slice);},getSliceAlpha:function(slice,async){var alpha=1;if(async)
-alpha*=0.3;return alpha;},getInstantSliceColor:function(instant){var colorId=instant.colorId+this.getColorIdOffset_(instant);return colors[colorId].toStringWithAlphaOverride(1.0);},getObjectInstanceColor:function(instance){var colorId=instance.colorId+this.getColorIdOffset_(instance);return colors[colorId].toStringWithAlphaOverride(0.25);},getObjectSnapshotColor:function(snapshot){var colorId=snapshot.objectInstance.colorId+this.getColorIdOffset_(snapshot);return colors[colorId];},getCounterSeriesColor:function(colorId,selectionState,opt_alphaMultiplier){var event={selectionState:selectionState};var c=colors[colorId+this.getColorIdOffset_(event)];return c.toStringWithAlphaOverride(opt_alphaMultiplier!==undefined?opt_alphaMultiplier:1.0);},getBarSnapshotColor:function(snapshot,offset){var colorId=(snapshot.objectInstance.colorId+offset)%numColorsPerVariant;colorId+=this.getColorIdOffset_(snapshot);return colors[colorId].toStringWithAlphaOverride(1.0);}};return{EventPresenter:EventPresenter};});'use strict';tr.exportTo('tr.ui.b',function(){var elidedTitleCacheDict={};var elidedTitleCache=new ElidedTitleCache();function ElidedTitleCache(){this.textWidthMap={};}
-ElidedTitleCache.prototype={get:function(ctx,pixWidth,title,width,sliceDuration){var elidedDict=elidedTitleCacheDict[title];if(!elidedDict){elidedDict={};elidedTitleCacheDict[title]=elidedDict;}
-var elidedDictForPixWidth=elidedDict[pixWidth];if(!elidedDictForPixWidth){elidedDict[pixWidth]={};elidedDictForPixWidth=elidedDict[pixWidth];}
-var stringWidthPair=elidedDictForPixWidth[sliceDuration];if(stringWidthPair===undefined){var newtitle=title;var elided=false;while(this.labelWidthWorld(ctx,newtitle,pixWidth)>sliceDuration){if(newtitle.length*0.75<1)
-break;newtitle=newtitle.substring(0,newtitle.length*0.75);elided=true;}
-if(elided&&newtitle.length>3)
-newtitle=newtitle.substring(0,newtitle.length-3)+'...';stringWidthPair=new ElidedStringWidthPair(newtitle,this.labelWidth(ctx,newtitle));elidedDictForPixWidth[sliceDuration]=stringWidthPair;}
-return stringWidthPair;},quickMeasureText_:function(ctx,text){var w=this.textWidthMap[text];if(!w){w=ctx.measureText(text).width;this.textWidthMap[text]=w;}
-return w;},labelWidth:function(ctx,title){return this.quickMeasureText_(ctx,title)+2;},labelWidthWorld:function(ctx,title,pixWidth){return this.labelWidth(ctx,title)*pixWidth;}};function ElidedStringWidthPair(string,width){this.string=string;this.width=width;}
-return{ElidedTitleCache:ElidedTitleCache};});'use strict';tr.exportTo('tr.ui.b',function(){var elidedTitleCache=new tr.ui.b.ElidedTitleCache();var ColorScheme=tr.b.ColorScheme;var colorsAsStrings=ColorScheme.colorsAsStrings;var EventPresenter=tr.ui.b.EventPresenter;var blackColorId=ColorScheme.getColorIdForReservedName('black');var THIN_SLICE_HEIGHT=4;var SLICE_WAITING_WIDTH_DRAW_THRESHOLD=3;var SLICE_ACTIVE_WIDTH_DRAW_THRESHOLD=1;var SHOULD_ELIDE_TEXT=true;function drawLine(ctx,x1,y1,x2,y2){ctx.moveTo(x1,y1);ctx.lineTo(x2,y2);}
+function isElementAttachedToDocument(el){let cur=el;while(Polymer.dom(cur).parentNode){cur=Polymer.dom(cur).parentNode;}
+return(cur===el.ownerDocument||cur.nodeName==='#document-fragment');}
+function asHTMLOrTextNode(value,opt_ownerDocument){if(value instanceof Node){return value;}
+const ownerDocument=opt_ownerDocument||document;return ownerDocument.createTextNode(value);}
+return{createSpan,createLink,createDiv,createScopedStyle,createSelector,createOptionGroup,createCheckBox,createButton,createTextInput,isElementAttachedToDocument,asHTMLOrTextNode,};});'use strict';tr.exportTo('tr.ui.b',function(){const elidedTitleCacheDict=new Map();const elidedTitleCache=new ElidedTitleCache();function ElidedTitleCache(){this.textWidthMap=new Map();}
+ElidedTitleCache.prototype={get(ctx,pixWidth,title,width,sliceDuration){let elidedDict=elidedTitleCacheDict.get(title);if(!elidedDict){elidedDict=new Map();elidedTitleCacheDict.set(title,elidedDict);}
+let elidedDictForPixWidth=elidedDict.get(pixWidth);if(!elidedDictForPixWidth){elidedDict.set(pixWidth,new Map());elidedDictForPixWidth=elidedDict.get(pixWidth);}
+let stringWidthPair=elidedDictForPixWidth.get(sliceDuration);if(stringWidthPair===undefined){let newtitle=title;let elided=false;while(this.labelWidthWorld(ctx,newtitle,pixWidth)>sliceDuration){if(newtitle.length*0.75<1)break;newtitle=newtitle.substring(0,newtitle.length*0.75);elided=true;}
+if(elided&&newtitle.length>3){newtitle=newtitle.substring(0,newtitle.length-3)+'...';}
+stringWidthPair=new ElidedStringWidthPair(newtitle,this.labelWidth(ctx,newtitle));elidedDictForPixWidth.set(sliceDuration,stringWidthPair);}
+return stringWidthPair;},quickMeasureText_(ctx,text){let w=this.textWidthMap.get(text);if(!w){w=ctx.measureText(text).width;this.textWidthMap.set(text,w);}
+return w;},labelWidth(ctx,title){return this.quickMeasureText_(ctx,title)+2;},labelWidthWorld(ctx,title,pixWidth){return this.labelWidth(ctx,title)*pixWidth;}};function ElidedStringWidthPair(string,width){this.string=string;this.width=width;}
+return{ElidedTitleCache,};});'use strict';tr.exportTo('tr.ui.b',function(){const ColorScheme=tr.b.ColorScheme;const colors=ColorScheme.colors;const colorsAsStrings=ColorScheme.colorsAsStrings;const SelectionState=tr.model.SelectionState;const EventPresenter={getSelectableItemColorAsString(item){const offset=this.getColorIdOffset_(item);const colorId=ColorScheme.getVariantColorId(item.colorId,offset);return colorsAsStrings[colorId];},getColorIdOffset_(event){return event.selectionState;},getTextColor(event){if(event.selectionState===SelectionState.DIMMED){return'rgb(60,60,60)';}
+return'rgb(0,0,0)';},getSliceColorId(slice){const offset=this.getColorIdOffset_(slice);return ColorScheme.getVariantColorId(slice.colorId,offset);},getSliceAlpha(slice,async){let alpha=1;if(async){alpha*=0.3;}
+return alpha;},getInstantSliceColor(instant){const offset=this.getColorIdOffset_(instant);const colorId=ColorScheme.getVariantColorId(instant.colorId,offset);return colors[colorId].toStringWithAlphaOverride(1.0);},getObjectInstanceColor(instance){const offset=this.getColorIdOffset_(instance);const colorId=ColorScheme.getVariantColorId(instance.colorId,offset);return colors[colorId].toStringWithAlphaOverride(0.25);},getObjectSnapshotColor(snapshot){const offset=this.getColorIdOffset_(snapshot);let colorId=snapshot.objectInstance.colorId;colorId=ColorScheme.getVariantColorId(colorId,offset);return colors[colorId];},getCounterSeriesColor(colorId,selectionState,opt_alphaMultiplier){const event={selectionState};const offset=this.getColorIdOffset_(event);const c=colors[ColorScheme.getVariantColorId(colorId,offset)];return c.toStringWithAlphaOverride(opt_alphaMultiplier!==undefined?opt_alphaMultiplier:1.0);},getBarSnapshotColor(snapshot,offset){const snapshotOffset=this.getColorIdOffset_(snapshot);let colorId=snapshot.objectInstance.colorId;colorId=ColorScheme.getAnotherColorId(colorId,offset);colorId=ColorScheme.getVariantColorId(colorId,snapshotOffset);return colors[colorId].toStringWithAlphaOverride(1.0);}};return{EventPresenter,};});'use strict';tr.exportTo('tr.ui.b',function(){const elidedTitleCache=new tr.ui.b.ElidedTitleCache();const ColorScheme=tr.b.ColorScheme;const colorsAsStrings=ColorScheme.colorsAsStrings;const EventPresenter=tr.ui.b.EventPresenter;const blackColorId=ColorScheme.getColorIdForReservedName('black');const THIN_SLICE_HEIGHT=4;const SLICE_WAITING_WIDTH_DRAW_THRESHOLD=3;const SLICE_ACTIVE_WIDTH_DRAW_THRESHOLD=1;const SHOULD_ELIDE_TEXT=true;function drawLine(ctx,x1,y1,x2,y2){ctx.moveTo(x1,y1);ctx.lineTo(x2,y2);}
 function drawTriangle(ctx,x1,y1,x2,y2,x3,y3){ctx.beginPath();ctx.moveTo(x1,y1);ctx.lineTo(x2,y2);ctx.lineTo(x3,y3);ctx.closePath();}
-function drawArrow(ctx,x1,y1,x2,y2,arrowLength,arrowWidth){var dx=x2-x1;var dy=y2-y1;var len=Math.sqrt(dx*dx+dy*dy);var perc=(len-arrowLength)/len;var bx=x1+perc*dx;var by=y1+perc*dy;var ux=dx/len;var uy=dy/len;var ax=uy*arrowWidth;var ay=-ux*arrowWidth;ctx.beginPath();drawLine(ctx,x1,y1,x2,y2);ctx.stroke();drawTriangle(ctx,bx+ax,by+ay,x2,y2,bx-ax,by-ay);ctx.fill();}
-function drawSlices(ctx,dt,viewLWorld,viewRWorld,viewHeight,slices,async){var pixelRatio=window.devicePixelRatio||1;var pixWidth=dt.xViewVectorToWorld(1);var height=viewHeight*pixelRatio;var darkRectHeight=THIN_SLICE_HEIGHT*pixelRatio;if(height<darkRectHeight)
-darkRectHeight=0;var lightRectHeight=height-darkRectHeight;ctx.save();dt.applyTransformToCanvas(ctx);var rect=new tr.ui.b.FastRectRenderer(ctx,2*pixWidth,2*pixWidth,colorsAsStrings);rect.setYandH(0,height);var lowSlice=tr.b.findLowIndexInSortedArray(slices,function(slice){return slice.start+slice.duration;},viewLWorld);var hadTopLevel=false;for(var i=lowSlice;i<slices.length;++i){var slice=slices[i];var x=slice.start;if(x>viewRWorld)
-break;var w=pixWidth;if(slice.duration>0){w=Math.max(slice.duration,0.000001);if(w<pixWidth)
-w=pixWidth;}
-var colorId=EventPresenter.getSliceColorId(slice);var alpha=EventPresenter.getSliceAlpha(slice,async);var lightAlpha=alpha*0.70;if(async&&slice.isTopLevel){rect.setYandH(3,height-3);hadTopLevel=true;}else{rect.setYandH(0,height);}
-if(!slice.cpuDuration){rect.fillRect(x,w,colorId,alpha);continue;}
-var activeWidth=w*(slice.cpuDuration/slice.duration);var waitingWidth=w-activeWidth;if(activeWidth<SLICE_ACTIVE_WIDTH_DRAW_THRESHOLD*pixWidth){activeWidth=0;waitingWidth=w;}
-if(waitingWidth<SLICE_WAITING_WIDTH_DRAW_THRESHOLD*pixWidth){activeWidth=w;waitingWidth=0;}
-if(activeWidth>0){rect.fillRect(x,activeWidth,colorId,alpha);}
-if(waitingWidth>0){rect.setYandH(0,lightRectHeight);rect.fillRect(x+activeWidth-pixWidth,waitingWidth+pixWidth,colorId,lightAlpha);rect.setYandH(lightRectHeight,darkRectHeight);rect.fillRect(x+activeWidth-pixWidth,waitingWidth+pixWidth,colorId,alpha);rect.setYandH(0,height);}}
-rect.flush();if(async&&hadTopLevel){rect.setYandH(2,1);for(var i=lowSlice;i<slices.length;++i){var slice=slices[i];var x=slice.start;if(x>viewRWorld)
-break;if(!slice.isTopLevel)
-continue;var w=pixWidth;if(slice.duration>0){w=Math.max(slice.duration,0.000001);if(w<pixWidth)
-w=pixWidth;}
-rect.fillRect(x,w,blackColorId,0.7);}
+function drawArrow(ctx,x1,y1,x2,y2,arrowLength,arrowWidth){const dx=x2-x1;const dy=y2-y1;const len=Math.sqrt(dx*dx+dy*dy);const perc=(len-arrowLength)/len;const bx=x1+perc*dx;const by=y1+perc*dy;const ux=dx/len;const uy=dy/len;const ax=uy*arrowWidth;const ay=-ux*arrowWidth;ctx.beginPath();drawLine(ctx,x1,y1,x2,y2);ctx.stroke();drawTriangle(ctx,bx+ax,by+ay,x2,y2,bx-ax,by-ay);ctx.fill();}
+function drawSlices(ctx,dt,viewLWorld,viewRWorld,viewHeight,slices,async){const pixelRatio=window.devicePixelRatio||1;const height=viewHeight*pixelRatio;const viewL=dt.xWorldToView(viewLWorld);const viewR=dt.xWorldToView(viewRWorld);let darkRectHeight=THIN_SLICE_HEIGHT*pixelRatio;if(height<darkRectHeight){darkRectHeight=0;}
+const lightRectHeight=height-darkRectHeight;ctx.save();const rect=new tr.ui.b.FastRectRenderer(ctx,viewL,viewR,2,2,colorsAsStrings);rect.setYandH(0,height);const lowSlice=tr.b.findLowIndexInSortedArray(slices,function(slice){return slice.start+slice.duration;},viewLWorld);let hadTopLevel=false;for(let i=lowSlice;i<slices.length;++i){const slice=slices[i];const x=slice.start;if(x>viewRWorld)break;const xView=dt.xWorldToView(x);let wView=1;if(slice.duration>0){const w=Math.max(slice.duration,0.000001);wView=Math.max(dt.xWorldVectorToView(w),1);}
+const colorId=EventPresenter.getSliceColorId(slice);const alpha=EventPresenter.getSliceAlpha(slice,async);const lightAlpha=alpha*0.70;if(async&&slice.isTopLevel){rect.setYandH(3,height-3);hadTopLevel=true;}else{rect.setYandH(0,height);}
+if(!slice.cpuDuration){rect.fillRect(xView,wView,colorId,alpha);continue;}
+let activeWidth=wView*(slice.cpuDuration/slice.duration);let waitingWidth=wView-activeWidth;if(activeWidth<SLICE_ACTIVE_WIDTH_DRAW_THRESHOLD){activeWidth=0;waitingWidth=wView;}
+if(waitingWidth<SLICE_WAITING_WIDTH_DRAW_THRESHOLD){activeWidth=wView;waitingWidth=0;}
+if(activeWidth>0){rect.fillRect(xView,activeWidth,colorId,alpha);}
+if(waitingWidth>0){rect.setYandH(0,lightRectHeight);rect.fillRect(xView+activeWidth-1,waitingWidth+1,colorId,lightAlpha);rect.setYandH(lightRectHeight,darkRectHeight);rect.fillRect(xView+activeWidth-1,waitingWidth+1,colorId,alpha);rect.setYandH(0,height);}}
+rect.flush();if(async&&hadTopLevel){rect.setYandH(2,1);for(let i=lowSlice;i<slices.length;++i){const slice=slices[i];const x=slice.start;if(x>viewRWorld)break;if(!slice.isTopLevel)continue;const xView=dt.xWorldToView(x);let wView=1;if(slice.duration>0){const w=Math.max(slice.duration,0.000001);wView=Math.max(dt.xWorldVectorToView(w),1);}
+rect.fillRect(xView,wView,blackColorId,0.7);}
 rect.flush();}
 ctx.restore();}
-function drawInstantSlicesAsLines(ctx,dt,viewLWorld,viewRWorld,viewHeight,slices,lineWidthInPixels){var pixelRatio=window.devicePixelRatio||1;var height=viewHeight*pixelRatio;var pixWidth=dt.xViewVectorToWorld(1);ctx.save();ctx.lineWidth=pixWidth*lineWidthInPixels*pixelRatio;dt.applyTransformToCanvas(ctx);ctx.beginPath();var lowSlice=tr.b.findLowIndexInSortedArray(slices,function(slice){return slice.start;},viewLWorld);for(var i=lowSlice;i<slices.length;++i){var slice=slices[i];var x=slice.start;if(x>viewRWorld)
-break;ctx.strokeStyle=EventPresenter.getInstantSliceColor(slice);ctx.beginPath();ctx.moveTo(x,0);ctx.lineTo(x,height);ctx.stroke();}
+function drawInstantSlicesAsLines(ctx,dt,viewLWorld,viewRWorld,viewHeight,slices,lineWidthInPixels){const pixelRatio=window.devicePixelRatio||1;const height=viewHeight*pixelRatio;ctx.save();ctx.lineWidth=lineWidthInPixels*pixelRatio;const lowSlice=tr.b.findLowIndexInSortedArray(slices,function(slice){return slice.start;},viewLWorld);for(let i=lowSlice;i<slices.length;++i){const slice=slices[i];const x=slice.start;if(x>viewRWorld)break;ctx.strokeStyle=EventPresenter.getInstantSliceColor(slice);const xView=dt.xWorldToView(x);ctx.beginPath();ctx.moveTo(xView,0);ctx.lineTo(xView,height);ctx.stroke();}
 ctx.restore();}
-function drawLabels(ctx,dt,viewLWorld,viewRWorld,slices,async,fontSize,yOffset){var pixelRatio=window.devicePixelRatio||1;var pixWidth=dt.xViewVectorToWorld(1);ctx.save();ctx.textAlign='center';ctx.textBaseline='top';ctx.font=(fontSize*pixelRatio)+'px sans-serif';if(async)
-ctx.font='italic '+ctx.font;var cY=yOffset*pixelRatio;var lowSlice=tr.b.findLowIndexInSortedArray(slices,function(slice){return slice.start+slice.duration;},viewLWorld);var quickDiscardThresshold=pixWidth*20;for(var i=lowSlice;i<slices.length;++i){var slice=slices[i];if(slice.start>viewRWorld)
-break;if(slice.duration<=quickDiscardThresshold)
-continue;var title=slice.title+
-(slice.didNotFinish?' (Did Not Finish)':'');var drawnTitle=title;var drawnWidth=elidedTitleCache.labelWidth(ctx,drawnTitle);var fullLabelWidth=elidedTitleCache.labelWidthWorld(ctx,drawnTitle,pixWidth);if(SHOULD_ELIDE_TEXT&&fullLabelWidth>slice.duration){var elidedValues=elidedTitleCache.get(ctx,pixWidth,drawnTitle,drawnWidth,slice.duration);drawnTitle=elidedValues.string;drawnWidth=elidedValues.width;}
-if(drawnWidth*pixWidth<slice.duration){ctx.fillStyle=EventPresenter.getTextColor(slice);var cX=dt.xWorldToView(slice.start+0.5*slice.duration);ctx.fillText(drawnTitle,cX,cY,drawnWidth);}}
+function drawLabels(ctx,dt,viewLWorld,viewRWorld,slices,async,fontSize,yOffset){const pixelRatio=window.devicePixelRatio||1;const pixWidth=dt.xViewVectorToWorld(1);ctx.save();ctx.textAlign='center';ctx.textBaseline='top';ctx.font=(fontSize*pixelRatio)+'px sans-serif';if(async){ctx.font='italic '+ctx.font;}
+const cY=yOffset*pixelRatio;const lowSlice=tr.b.findLowIndexInSortedArray(slices,function(slice){return slice.start+slice.duration;},viewLWorld);const quickDiscardThreshold=pixWidth*20;for(let i=lowSlice;i<slices.length;++i){const slice=slices[i];if(slice.start>viewRWorld)break;if(slice.duration<=quickDiscardThreshold)continue;const xLeftClipped=Math.max(slice.start,viewLWorld);const xRightClipped=Math.min(slice.start+slice.duration,viewRWorld);const visibleWidth=xRightClipped-xLeftClipped;const title=slice.title+
+(slice.didNotFinish?' (Did Not Finish)':'');let drawnTitle=title;let drawnWidth=elidedTitleCache.labelWidth(ctx,drawnTitle);const fullLabelWidth=elidedTitleCache.labelWidthWorld(ctx,drawnTitle,pixWidth);if(SHOULD_ELIDE_TEXT&&fullLabelWidth>visibleWidth){const elidedValues=elidedTitleCache.get(ctx,pixWidth,drawnTitle,drawnWidth,visibleWidth);drawnTitle=elidedValues.string;drawnWidth=elidedValues.width;}
+if(drawnWidth*pixWidth<visibleWidth){ctx.fillStyle=EventPresenter.getTextColor(slice);const cX=dt.xWorldToView((xLeftClipped+xRightClipped)/2);ctx.fillText(drawnTitle,cX,cY,drawnWidth);}}
 ctx.restore();}
-return{drawSlices:drawSlices,drawInstantSlicesAsLines:drawInstantSlicesAsLines,drawLabels:drawLabels,drawLine:drawLine,drawTriangle:drawTriangle,drawArrow:drawArrow,elidedTitleCache_:elidedTitleCache,THIN_SLICE_HEIGHT:THIN_SLICE_HEIGHT};});'use strict';tr.exportTo('tr.ui',function(){function SnapIndicator(y,height){this.y=y;this.height=height;}
-function TimelineInterestRange(vp){this.viewport_=vp;this.range_=new tr.b.Range();this.leftSelected_=false;this.rightSelected_=false;this.leftSnapIndicator_=undefined;this.rightSnapIndicator_=undefined;}
-TimelineInterestRange.prototype={get isEmpty(){return this.range_.isEmpty;},reset:function(){this.range_.reset();this.leftSelected_=false;this.rightSelected_=false;this.leftSnapIndicator_=undefined;this.rightSnapIndicator_=undefined;this.viewport_.dispatchChangeEvent();},get min(){return this.range_.min;},set min(min){this.range_.min=min;this.viewport_.dispatchChangeEvent();},get max(){return this.range_.max;},set max(max){this.range_.max=max;this.viewport_.dispatchChangeEvent();},set:function(range){this.range_.reset();this.range_.addRange(range);this.viewport_.dispatchChangeEvent();},setMinAndMax:function(min,max){this.range_.min=min;this.range_.max=max;this.viewport_.dispatchChangeEvent();},get range(){return this.range_.range;},asRangeObject:function(){var range=new tr.b.Range();range.addRange(this.range_);return range;},get leftSelected(){return this.leftSelected_;},set leftSelected(leftSelected){if(this.leftSelected_==leftSelected)
-return;this.leftSelected_=leftSelected;this.viewport_.dispatchChangeEvent();},get rightSelected(){return this.rightSelected_;},set rightSelected(rightSelected){if(this.rightSelected_==rightSelected)
-return;this.rightSelected_=rightSelected;this.viewport_.dispatchChangeEvent();},get leftSnapIndicator(){return this.leftSnapIndicator_;},set leftSnapIndicator(leftSnapIndicator){this.leftSnapIndicator_=leftSnapIndicator;this.viewport_.dispatchChangeEvent();},get rightSnapIndicator(){return this.rightSnapIndicator_;},set rightSnapIndicator(rightSnapIndicator){this.rightSnapIndicator_=rightSnapIndicator;this.viewport_.dispatchChangeEvent();},draw:function(ctx,viewLWorld,viewRWorld){if(this.range_.isEmpty)
-return;var dt=this.viewport_.currentDisplayTransform;var markerLWorld=this.min;var markerRWorld=this.max;var markerLView=Math.round(dt.xWorldToView(markerLWorld));var markerRView=Math.round(dt.xWorldToView(markerRWorld));ctx.fillStyle='rgba(0, 0, 0, 0.2)';if(markerLWorld>viewLWorld){ctx.fillRect(dt.xWorldToView(viewLWorld),0,markerLView,ctx.canvas.height);}
-if(markerRWorld<viewRWorld){ctx.fillRect(markerRView,0,dt.xWorldToView(viewRWorld),ctx.canvas.height);}
-var pixelRatio=window.devicePixelRatio||1;ctx.lineWidth=Math.round(pixelRatio);if(this.range_.range>0){this.drawLine_(ctx,viewLWorld,viewRWorld,ctx.canvas.height,this.min,this.leftSelected_);this.drawLine_(ctx,viewLWorld,viewRWorld,ctx.canvas.height,this.max,this.rightSelected_);}else{this.drawLine_(ctx,viewLWorld,viewRWorld,ctx.canvas.height,this.min,this.leftSelected_||this.rightSelected_);}
-ctx.lineWidth=1;},drawLine_:function(ctx,viewLWorld,viewRWorld,height,ts,selected){if(ts<viewLWorld||ts>=viewRWorld)
-return;var dt=this.viewport_.currentDisplayTransform;var viewX=Math.round(dt.xWorldToView(ts));ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);ctx.beginPath();tr.ui.b.drawLine(ctx,viewX,0,viewX,height);if(selected)
-ctx.strokeStyle='rgb(255, 0, 0)';else
-ctx.strokeStyle='rgb(0, 0, 0)';ctx.stroke();ctx.restore();},drawIndicators:function(ctx,viewLWorld,viewRWorld){if(this.leftSnapIndicator_){this.drawIndicator_(ctx,viewLWorld,viewRWorld,this.range_.min,this.leftSnapIndicator_,this.leftSelected_);}
-if(this.rightSnapIndicator_){this.drawIndicator_(ctx,viewLWorld,viewRWorld,this.range_.max,this.rightSnapIndicator_,this.rightSelected_);}},drawIndicator_:function(ctx,viewLWorld,viewRWorld,xWorld,si,selected){var dt=this.viewport_.currentDisplayTransform;var viewX=Math.round(dt.xWorldToView(xWorld));ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);var pixelRatio=window.devicePixelRatio||1;var viewY=si.y*devicePixelRatio;var viewHeight=si.height*devicePixelRatio;var arrowSize=4*pixelRatio;if(selected)
-ctx.fillStyle='rgb(255, 0, 0)';else
-ctx.fillStyle='rgb(0, 0, 0)';tr.ui.b.drawTriangle(ctx,viewX-arrowSize*0.75,viewY,viewX+arrowSize*0.75,viewY,viewX,viewY+arrowSize);ctx.fill();tr.ui.b.drawTriangle(ctx,viewX-arrowSize*0.75,viewY+viewHeight,viewX+arrowSize*0.75,viewY+viewHeight,viewX,viewY+viewHeight-arrowSize);ctx.fill();ctx.restore();}};return{SnapIndicator:SnapIndicator,TimelineInterestRange:TimelineInterestRange};});'use strict';tr.exportTo('tr.ui',function(){function TimelineDisplayTransform(opt_that){if(opt_that){this.set(opt_that);return;}
+return{drawSlices,drawInstantSlicesAsLines,drawLabels,drawLine,drawTriangle,drawArrow,elidedTitleCache_:elidedTitleCache,THIN_SLICE_HEIGHT,};});'use strict';tr.exportTo('tr.ui',function(){function TimelineDisplayTransform(opt_that){if(opt_that){this.set(opt_that);return;}
 this.scaleX=1;this.panX=0;this.panY=0;}
-TimelineDisplayTransform.prototype={set:function(that){this.scaleX=that.scaleX;this.panX=that.panX;this.panY=that.panY;},clone:function(){return new TimelineDisplayTransform(this);},equals:function(that){var eq=true;if(that===undefined||that===null)
-return false;eq&=this.panX===that.panX;eq&=this.panY===that.panY;eq&=this.scaleX===that.scaleX;return!!eq;},almostEquals:function(that){var eq=true;if(that===undefined||that===null)
-return false;eq&=Math.abs(this.panX-that.panX)<0.001;eq&=Math.abs(this.panY-that.panY)<0.001;eq&=Math.abs(this.scaleX-that.scaleX)<0.001;return!!eq;},incrementPanXInViewUnits:function(xDeltaView){this.panX+=this.xViewVectorToWorld(xDeltaView);},xPanWorldPosToViewPos:function(worldX,viewX,viewWidth){if(typeof viewX=='string'){if(viewX==='left'){viewX=0;}else if(viewX==='center'){viewX=viewWidth/2;}else if(viewX==='right'){viewX=viewWidth-1;}else{throw new Error('viewX must be left|center|right or number.');}}
-this.panX=(viewX/this.scaleX)-worldX;},xPanWorldBoundsIntoView:function(worldMin,worldMax,viewWidth){if(this.xWorldToView(worldMin)<0)
-this.xPanWorldPosToViewPos(worldMin,'left',viewWidth);else if(this.xWorldToView(worldMax)>viewWidth)
-this.xPanWorldPosToViewPos(worldMax,'right',viewWidth);},xSetWorldBounds:function(worldMin,worldMax,viewWidth){var worldWidth=worldMax-worldMin;var scaleX=viewWidth/worldWidth;var panX=-worldMin;this.setPanAndScale(panX,scaleX);},setPanAndScale:function(p,s){this.scaleX=s;this.panX=p;},xWorldToView:function(x){return(x+this.panX)*this.scaleX;},xWorldVectorToView:function(x){return x*this.scaleX;},xViewToWorld:function(x){return(x/this.scaleX)-this.panX;},xViewVectorToWorld:function(x){return x/this.scaleX;},applyTransformToCanvas:function(ctx){ctx.transform(this.scaleX,0,0,1,this.panX*this.scaleX,0);}};return{TimelineDisplayTransform:TimelineDisplayTransform};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ContainerToTrackMap(){this.stableIdToTrackMap_={};}
-ContainerToTrackMap.prototype={addContainer:function(container,track){if(!track)
-throw new Error('Must provide a track.');this.stableIdToTrackMap_[container.stableId]=track;},clear:function(){this.stableIdToTrackMap_={};},getTrackByStableId:function(stableId){return this.stableIdToTrackMap_[stableId];}};return{ContainerToTrackMap:ContainerToTrackMap};});'use strict';tr.exportTo('tr.ui.tracks',function(){function EventToTrackMap(){}
-EventToTrackMap.prototype={addEvent:function(event,track){if(!track)
-throw new Error('Must provide a track.');this[event.guid]=track;}};return{EventToTrackMap:EventToTrackMap};});'use strict';tr.exportTo('tr.ui',function(){var TimelineDisplayTransform=tr.ui.TimelineDisplayTransform;var TimelineInterestRange=tr.ui.TimelineInterestRange;function TimelineViewport(parentEl){this.parentEl_=parentEl;this.modelTrackContainer_=undefined;this.currentDisplayTransform_=new TimelineDisplayTransform();this.initAnimationController_();this.showFlowEvents_=false;this.highlightVSync_=false;this.highDetails_=false;this.gridTimebase_=0;this.gridStep_=1000/60;this.gridEnabled_=false;this.hasCalledSetupFunction_=false;this.onResize_=this.onResize_.bind(this);this.onModelTrackControllerScroll_=this.onModelTrackControllerScroll_.bind(this);this.checkForAttachInterval_=setInterval(this.checkForAttach_.bind(this),250);this.majorMarkPositions=[];this.interestRange_=new TimelineInterestRange(this);this.eventToTrackMap_=new tr.ui.tracks.EventToTrackMap();this.containerToTrackMap=new tr.ui.tracks.ContainerToTrackMap();}
-TimelineViewport.prototype={__proto__:tr.b.EventTarget.prototype,setWhenPossible:function(fn){this.pendingSetFunction_=fn;},get isAttachedToDocumentOrInTestMode(){if(this.parentEl_===undefined)
-return;return tr.ui.b.isElementAttachedToDocument(this.parentEl_);},onResize_:function(){this.dispatchChangeEvent();},checkForAttach_:function(){if(!this.isAttachedToDocumentOrInTestMode||this.clientWidth==0)
-return;if(!this.iframe_){this.iframe_=document.createElement('iframe');this.iframe_.style.cssText='position:absolute;width:100%;height:0;border:0;visibility:hidden;';this.parentEl_.appendChild(this.iframe_);this.iframe_.contentWindow.addEventListener('resize',this.onResize_);}
-var curSize=this.parentEl_.clientWidth+'x'+
-this.parentEl_.clientHeight;if(this.pendingSetFunction_){this.lastSize_=curSize;try{this.pendingSetFunction_();}catch(ex){console.log('While running setWhenPossible:',ex.message?ex.message+'\n'+ex.stack:ex.stack);}
-this.pendingSetFunction_=undefined;}
-window.clearInterval(this.checkForAttachInterval_);this.checkForAttachInterval_=undefined;},dispatchChangeEvent:function(){tr.b.dispatchSimpleEvent(this,'change');},detach:function(){if(this.checkForAttachInterval_){window.clearInterval(this.checkForAttachInterval_);this.checkForAttachInterval_=undefined;}
-if(this.iframe_){this.iframe_.removeEventListener('resize',this.onResize_);this.parentEl_.removeChild(this.iframe_);}},initAnimationController_:function(){this.dtAnimationController_=new tr.ui.b.AnimationController();this.dtAnimationController_.addEventListener('didtick',function(e){this.onCurentDisplayTransformChange_(e.oldTargetState);}.bind(this));var that=this;this.dtAnimationController_.target={get panX(){return that.currentDisplayTransform_.panX;},set panX(panX){that.currentDisplayTransform_.panX=panX;},get panY(){return that.currentDisplayTransform_.panY;},set panY(panY){that.currentDisplayTransform_.panY=panY;},get scaleX(){return that.currentDisplayTransform_.scaleX;},set scaleX(scaleX){that.currentDisplayTransform_.scaleX=scaleX;},cloneAnimationState:function(){return that.currentDisplayTransform_.clone();},xPanWorldPosToViewPos:function(xWorld,xView){that.currentDisplayTransform_.xPanWorldPosToViewPos(xWorld,xView,that.modelTrackContainer_.canvas.clientWidth);}};},get currentDisplayTransform(){return this.currentDisplayTransform_;},setDisplayTransformImmediately:function(displayTransform){this.dtAnimationController_.cancelActiveAnimation();var oldDisplayTransform=this.dtAnimationController_.target.cloneAnimationState();this.currentDisplayTransform_.set(displayTransform);this.onCurentDisplayTransformChange_(oldDisplayTransform);},queueDisplayTransformAnimation:function(animation){if(!(animation instanceof tr.ui.b.Animation))
-throw new Error('animation must be instanceof tr.ui.b.Animation');this.dtAnimationController_.queueAnimation(animation);},onCurentDisplayTransformChange_:function(oldDisplayTransform){if(this.modelTrackContainer_){this.currentDisplayTransform.panY=tr.b.clamp(this.currentDisplayTransform.panY,0,this.modelTrackContainer_.scrollHeight-
+TimelineDisplayTransform.prototype={set(that){this.scaleX=that.scaleX;this.panX=that.panX;this.panY=that.panY;},clone(){return new TimelineDisplayTransform(this);},equals(that){let eq=true;if(that===undefined||that===null){return false;}
+eq&=this.panX===that.panX;eq&=this.panY===that.panY;eq&=this.scaleX===that.scaleX;return!!eq;},almostEquals(that){let eq=true;if(that===undefined||that===null){return false;}
+eq&=Math.abs(this.panX-that.panX)<0.001;eq&=Math.abs(this.panY-that.panY)<0.001;eq&=Math.abs(this.scaleX-that.scaleX)<0.001;return!!eq;},incrementPanXInViewUnits(xDeltaView){this.panX+=this.xViewVectorToWorld(xDeltaView);},xPanWorldPosToViewPos(worldX,viewX,viewWidth){if(typeof viewX==='string'){if(viewX==='left'){viewX=0;}else if(viewX==='center'){viewX=viewWidth/2;}else if(viewX==='right'){viewX=viewWidth-1;}else{throw new Error('viewX must be left|center|right or number.');}}
+this.panX=(viewX/this.scaleX)-worldX;},xPanWorldBoundsIntoView(worldMin,worldMax,viewWidth){if(this.xWorldToView(worldMin)<0){this.xPanWorldPosToViewPos(worldMin,'left',viewWidth);}else if(this.xWorldToView(worldMax)>viewWidth){this.xPanWorldPosToViewPos(worldMax,'right',viewWidth);}},xSetWorldBounds(worldMin,worldMax,viewWidth){const worldWidth=worldMax-worldMin;const scaleX=viewWidth/worldWidth;const panX=-worldMin;this.setPanAndScale(panX,scaleX);},setPanAndScale(p,s){this.scaleX=s;this.panX=p;},xWorldToView(x){return(x+this.panX)*this.scaleX;},xWorldVectorToView(x){return x*this.scaleX;},xViewToWorld(x){return(x/this.scaleX)-this.panX;},xViewVectorToWorld(x){return x/this.scaleX;}};return{TimelineDisplayTransform,};});'use strict';tr.exportTo('tr.ui',function(){function SnapIndicator(y,height){this.y=y;this.height=height;}
+function TimelineInterestRange(vp){this.viewport_=vp;this.range_=new tr.b.math.Range();this.leftSelected_=false;this.rightSelected_=false;this.leftSnapIndicator_=undefined;this.rightSnapIndicator_=undefined;}
+TimelineInterestRange.prototype={get isEmpty(){return this.range_.isEmpty;},reset(){this.range_.reset();this.leftSelected_=false;this.rightSelected_=false;this.leftSnapIndicator_=undefined;this.rightSnapIndicator_=undefined;this.viewport_.dispatchChangeEvent();},get min(){return this.range_.min;},set min(min){this.range_.min=min;this.viewport_.dispatchChangeEvent();},get max(){return this.range_.max;},set max(max){this.range_.max=max;this.viewport_.dispatchChangeEvent();},set(range){this.range_.reset();this.range_.addRange(range);this.viewport_.dispatchChangeEvent();},setMinAndMax(min,max){this.range_.min=min;this.range_.max=max;this.viewport_.dispatchChangeEvent();},get range(){return this.range_.range;},asRangeObject(){const range=new tr.b.math.Range();range.addRange(this.range_);return range;},get leftSelected(){return this.leftSelected_;},set leftSelected(leftSelected){if(this.leftSelected_===leftSelected)return;this.leftSelected_=leftSelected;this.viewport_.dispatchChangeEvent();},get rightSelected(){return this.rightSelected_;},set rightSelected(rightSelected){if(this.rightSelected_===rightSelected)return;this.rightSelected_=rightSelected;this.viewport_.dispatchChangeEvent();},get leftSnapIndicator(){return this.leftSnapIndicator_;},set leftSnapIndicator(leftSnapIndicator){this.leftSnapIndicator_=leftSnapIndicator;this.viewport_.dispatchChangeEvent();},get rightSnapIndicator(){return this.rightSnapIndicator_;},set rightSnapIndicator(rightSnapIndicator){this.rightSnapIndicator_=rightSnapIndicator;this.viewport_.dispatchChangeEvent();},draw(ctx,viewLWorld,viewRWorld,viewHeight){if(this.range_.isEmpty)return;const dt=this.viewport_.currentDisplayTransform;const markerLWorld=this.min;const markerRWorld=this.max;const markerLView=Math.round(dt.xWorldToView(markerLWorld));const markerRView=Math.round(dt.xWorldToView(markerRWorld));ctx.fillStyle='rgba(0, 0, 0, 0.2)';if(markerLWorld>viewLWorld){ctx.fillRect(dt.xWorldToView(viewLWorld),0,markerLView,viewHeight);}
+if(markerRWorld<viewRWorld){ctx.fillRect(markerRView,0,dt.xWorldToView(viewRWorld),viewHeight);}
+const pixelRatio=window.devicePixelRatio||1;ctx.lineWidth=Math.round(pixelRatio);if(this.range_.range>0){this.drawLine_(ctx,viewLWorld,viewRWorld,viewHeight,this.min,this.leftSelected_);this.drawLine_(ctx,viewLWorld,viewRWorld,viewHeight,this.max,this.rightSelected_);}else{this.drawLine_(ctx,viewLWorld,viewRWorld,viewHeight,this.min,this.leftSelected_||this.rightSelected_);}
+ctx.lineWidth=1;},drawLine_(ctx,viewLWorld,viewRWorld,height,ts,selected){if(ts<viewLWorld||ts>=viewRWorld)return;const dt=this.viewport_.currentDisplayTransform;const viewX=Math.round(dt.xWorldToView(ts));ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);ctx.beginPath();tr.ui.b.drawLine(ctx,viewX,0,viewX,height);if(selected){ctx.strokeStyle='rgb(255, 0, 0)';}else{ctx.strokeStyle='rgb(0, 0, 0)';}
+ctx.stroke();ctx.restore();},drawIndicators(ctx,viewLWorld,viewRWorld){if(this.leftSnapIndicator_){this.drawIndicator_(ctx,viewLWorld,viewRWorld,this.range_.min,this.leftSnapIndicator_,this.leftSelected_);}
+if(this.rightSnapIndicator_){this.drawIndicator_(ctx,viewLWorld,viewRWorld,this.range_.max,this.rightSnapIndicator_,this.rightSelected_);}},drawIndicator_(ctx,viewLWorld,viewRWorld,xWorld,si,selected){const dt=this.viewport_.currentDisplayTransform;const viewX=Math.round(dt.xWorldToView(xWorld));ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);const pixelRatio=window.devicePixelRatio||1;const viewY=si.y*devicePixelRatio;const viewHeight=si.height*devicePixelRatio;const arrowSize=4*pixelRatio;if(selected){ctx.fillStyle='rgb(255, 0, 0)';}else{ctx.fillStyle='rgb(0, 0, 0)';}
+tr.ui.b.drawTriangle(ctx,viewX-arrowSize*0.75,viewY,viewX+arrowSize*0.75,viewY,viewX,viewY+arrowSize);ctx.fill();tr.ui.b.drawTriangle(ctx,viewX-arrowSize*0.75,viewY+viewHeight,viewX+arrowSize*0.75,viewY+viewHeight,viewX,viewY+viewHeight-arrowSize);ctx.fill();ctx.restore();}};return{SnapIndicator,TimelineInterestRange,};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ContainerToTrackMap(){this.stableIdToTrackMap_={};}
+ContainerToTrackMap.prototype={addContainer(container,track){if(!track){throw new Error('Must provide a track.');}
+this.stableIdToTrackMap_[container.stableId]=track;},clear(){this.stableIdToTrackMap_={};},getTrackByStableId(stableId){return this.stableIdToTrackMap_[stableId];}};return{ContainerToTrackMap,};});'use strict';tr.exportTo('tr.ui.tracks',function(){function EventToTrackMap(){}
+EventToTrackMap.prototype={addEvent(event,track){if(!track){throw new Error('Must provide a track.');}
+this[event.guid]=track;}};return{EventToTrackMap,};});'use strict';tr.exportTo('tr.ui',function(){const TimelineDisplayTransform=tr.ui.TimelineDisplayTransform;const TimelineInterestRange=tr.ui.TimelineInterestRange;const IDEAL_MAJOR_MARK_DISTANCE_PX=150;const MAJOR_MARK_ROUNDING_FACTOR=100000;class AnimationControllerProxy{constructor(target){this.target_=target;}
+get panX(){return this.target_.currentDisplayTransform_.panX;}
+set panX(panX){this.target_.currentDisplayTransform_.panX=panX;}
+get panY(){return this.target_.currentDisplayTransform_.panY;}
+set panY(panY){this.target_.currentDisplayTransform_.panY=panY;}
+get scaleX(){return this.target_.currentDisplayTransform_.scaleX;}
+set scaleX(scaleX){this.target_.currentDisplayTransform_.scaleX=scaleX;}
+cloneAnimationState(){return this.target_.currentDisplayTransform_.clone();}
+xPanWorldPosToViewPos(xWorld,xView){this.target_.currentDisplayTransform_.xPanWorldPosToViewPos(xWorld,xView,this.target_.modelTrackContainer_.canvas.clientWidth);}}
+function TimelineViewport(parentEl){this.parentEl_=parentEl;this.modelTrackContainer_=undefined;this.currentDisplayTransform_=new TimelineDisplayTransform();this.initAnimationController_();this.showFlowEvents_=false;this.highlightVSync_=false;this.highDetails_=false;this.gridTimebase_=0;this.gridStep_=1000/60;this.gridEnabled_=false;this.hasCalledSetupFunction_=false;this.onResize_=this.onResize_.bind(this);this.onModelTrackControllerScroll_=this.onModelTrackControllerScroll_.bind(this);this.timeMode_=TimelineViewport.TimeMode.TIME_IN_MS;this.majorMarkWorldPositions_=[];this.majorMarkUnit_=undefined;this.interestRange_=new TimelineInterestRange(this);this.eventToTrackMap_=new tr.ui.tracks.EventToTrackMap();this.containerToTrackMap=new tr.ui.tracks.ContainerToTrackMap();this.dispatchChangeEvent=this.dispatchChangeEvent.bind(this);}
+TimelineViewport.TimeMode={TIME_IN_MS:0,REVISIONS:1};TimelineViewport.prototype={__proto__:tr.b.EventTarget.prototype,get isAttachedToDocumentOrInTestMode(){if(this.parentEl_===undefined)return;return tr.ui.b.isElementAttachedToDocument(this.parentEl_);},onResize_(){this.dispatchChangeEvent();},dispatchChangeEvent(){tr.b.dispatchSimpleEvent(this,'change');},detach(){window.removeEventListener('resize',this.dispatchChangeEvent);},initAnimationController_(){this.dtAnimationController_=new tr.ui.b.AnimationController();this.dtAnimationController_.addEventListener('didtick',function(e){this.onCurentDisplayTransformChange_(e.oldTargetState);}.bind(this));this.dtAnimationController_.target=new AnimationControllerProxy(this);},get currentDisplayTransform(){return this.currentDisplayTransform_;},setDisplayTransformImmediately(displayTransform){this.dtAnimationController_.cancelActiveAnimation();const oldDisplayTransform=this.dtAnimationController_.target.cloneAnimationState();this.currentDisplayTransform_.set(displayTransform);this.onCurentDisplayTransformChange_(oldDisplayTransform);},queueDisplayTransformAnimation(animation){if(!(animation instanceof tr.ui.b.Animation)){throw new Error('animation must be instanceof tr.ui.b.Animation');}
+this.dtAnimationController_.queueAnimation(animation);},onCurentDisplayTransformChange_(oldDisplayTransform){if(this.modelTrackContainer_){this.currentDisplayTransform.panY=tr.b.math.clamp(this.currentDisplayTransform.panY,0,this.modelTrackContainer_.scrollHeight-
 this.modelTrackContainer_.clientHeight);}
-var changed=!this.currentDisplayTransform.equals(oldDisplayTransform);var yChanged=this.currentDisplayTransform.panY!==oldDisplayTransform.panY;if(yChanged)
-this.modelTrackContainer_.scrollTop=this.currentDisplayTransform.panY;if(changed)
-this.dispatchChangeEvent();},onModelTrackControllerScroll_:function(e){if(this.dtAnimationController_.activeAnimation&&this.dtAnimationController_.activeAnimation.affectsPanY)
-this.dtAnimationController_.cancelActiveAnimation();var panY=this.modelTrackContainer_.scrollTop;this.currentDisplayTransform_.panY=panY;},get modelTrackContainer(){return this.modelTrackContainer_;},set modelTrackContainer(m){if(this.modelTrackContainer_)
-this.modelTrackContainer_.removeEventListener('scroll',this.onModelTrackControllerScroll_);this.modelTrackContainer_=m;this.modelTrackContainer_.addEventListener('scroll',this.onModelTrackControllerScroll_);},get showFlowEvents(){return this.showFlowEvents_;},set showFlowEvents(showFlowEvents){this.showFlowEvents_=showFlowEvents;this.dispatchChangeEvent();},get highlightVSync(){return this.highlightVSync_;},set highlightVSync(highlightVSync){this.highlightVSync_=highlightVSync;this.dispatchChangeEvent();},get highDetails(){return this.highDetails_;},set highDetails(highDetails){this.highDetails_=highDetails;this.dispatchChangeEvent();},get gridEnabled(){return this.gridEnabled_;},set gridEnabled(enabled){if(this.gridEnabled_==enabled)
-return;this.gridEnabled_=enabled&&true;this.dispatchChangeEvent();},get gridTimebase(){return this.gridTimebase_;},set gridTimebase(timebase){if(this.gridTimebase_==timebase)
-return;this.gridTimebase_=timebase;this.dispatchChangeEvent();},get gridStep(){return this.gridStep_;},get interestRange(){return this.interestRange_;},drawMajorMarkLines:function(ctx){ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);ctx.beginPath();for(var idx in this.majorMarkPositions){var x=Math.floor(this.majorMarkPositions[idx]);tr.ui.b.drawLine(ctx,x,0,x,ctx.canvas.height);}
-ctx.strokeStyle='#ddd';ctx.stroke();ctx.restore();},drawGridLines:function(ctx,viewLWorld,viewRWorld){if(!this.gridEnabled)
-return;var dt=this.currentDisplayTransform;var x=this.gridTimebase;ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);ctx.beginPath();while(x<viewRWorld){if(x>=viewLWorld){var vx=Math.floor(dt.xWorldToView(x));tr.ui.b.drawLine(ctx,vx,0,vx,ctx.canvas.height);}
+const changed=!this.currentDisplayTransform.equals(oldDisplayTransform);const yChanged=this.currentDisplayTransform.panY!==oldDisplayTransform.panY;if(yChanged){this.modelTrackContainer_.scrollTop=this.currentDisplayTransform.panY;}
+if(changed){this.dispatchChangeEvent();}},onModelTrackControllerScroll_(e){if(this.dtAnimationController_.activeAnimation&&this.dtAnimationController_.activeAnimation.affectsPanY){this.dtAnimationController_.cancelActiveAnimation();}
+const panY=this.modelTrackContainer_.scrollTop;this.currentDisplayTransform_.panY=panY;},get modelTrackContainer(){return this.modelTrackContainer_;},set modelTrackContainer(m){if(this.modelTrackContainer_){this.modelTrackContainer_.removeEventListener('scroll',this.onModelTrackControllerScroll_);}
+this.modelTrackContainer_=m;this.modelTrackContainer_.addEventListener('scroll',this.onModelTrackControllerScroll_);},get showFlowEvents(){return this.showFlowEvents_;},set showFlowEvents(showFlowEvents){this.showFlowEvents_=showFlowEvents;this.dispatchChangeEvent();},get highlightVSync(){return this.highlightVSync_;},set highlightVSync(highlightVSync){this.highlightVSync_=highlightVSync;this.dispatchChangeEvent();},get highDetails(){return this.highDetails_;},set highDetails(highDetails){this.highDetails_=highDetails;this.dispatchChangeEvent();},get gridEnabled(){return this.gridEnabled_;},set gridEnabled(enabled){if(this.gridEnabled_===enabled)return;this.gridEnabled_=enabled&&true;this.dispatchChangeEvent();},get gridTimebase(){return this.gridTimebase_;},set gridTimebase(timebase){if(this.gridTimebase_===timebase)return;this.gridTimebase_=timebase;this.dispatchChangeEvent();},get gridStep(){return this.gridStep_;},get interestRange(){return this.interestRange_;},get majorMarkWorldPositions(){return this.majorMarkWorldPositions_;},get majorMarkUnit(){switch(this.timeMode_){case TimelineViewport.TimeMode.TIME_IN_MS:return tr.b.Unit.byName.timeInMsAutoFormat;case TimelineViewport.TimeMode.REVISIONS:return tr.b.Unit.byName.count;default:throw new Error('Cannot get Unit for unsupported time mode '+this.timeMode_);}},get timeMode(){return this.timeMode_;},set timeMode(mode){this.timeMode_=mode;this.dispatchChangeEvent();},updateMajorMarkData(viewLWorld,viewRWorld){const pixelRatio=window.devicePixelRatio||1;const dt=this.currentDisplayTransform;const idealMajorMarkDistancePix=IDEAL_MAJOR_MARK_DISTANCE_PX*pixelRatio;const idealMajorMarkDistanceWorld=dt.xViewVectorToWorld(idealMajorMarkDistancePix);const majorMarkDistanceWorld=tr.b.math.preferredNumberLargerThanMin(idealMajorMarkDistanceWorld);const firstMajorMark=Math.floor(viewLWorld/majorMarkDistanceWorld)*majorMarkDistanceWorld;this.majorMarkWorldPositions_=[];for(let curX=firstMajorMark;curX<viewRWorld;curX+=majorMarkDistanceWorld){this.majorMarkWorldPositions_.push(Math.floor(MAJOR_MARK_ROUNDING_FACTOR*curX)/MAJOR_MARK_ROUNDING_FACTOR);}},drawMajorMarkLines(ctx,viewHeight){ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);ctx.beginPath();for(const majorMark of this.majorMarkWorldPositions_){const x=this.currentDisplayTransform.xWorldToView(majorMark);tr.ui.b.drawLine(ctx,x,0,x,viewHeight);}
+ctx.strokeStyle='#ddd';ctx.stroke();ctx.restore();},drawGridLines(ctx,viewLWorld,viewRWorld,viewHeight){if(!this.gridEnabled)return;const dt=this.currentDisplayTransform;let x=this.gridTimebase;ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);ctx.beginPath();while(x<viewRWorld){if(x>=viewLWorld){const vx=Math.floor(dt.xWorldToView(x));tr.ui.b.drawLine(ctx,vx,0,vx,viewHeight);}
 x+=this.gridStep;}
-ctx.strokeStyle='rgba(255, 0, 0, 0.25)';ctx.stroke();ctx.restore();},getShiftedSelection:function(selection,offset){var newSelection=new tr.model.EventSet();for(var i=0;i<selection.length;i++){var event=selection[i];if(event instanceof tr.model.FlowEvent){if(offset>0){newSelection.push(event.endSlice);}else if(offset<0){newSelection.push(event.startSlice);}else{}
+ctx.strokeStyle='rgba(255, 0, 0, 0.25)';ctx.stroke();ctx.restore();},getShiftedSelection(selection,offset){const newSelection=new tr.model.EventSet();for(const event of selection){if(event instanceof tr.model.FlowEvent){if(offset>0){newSelection.push(event.endSlice);}else if(offset<0){newSelection.push(event.startSlice);}else{}
 continue;}
-var track=this.trackForEvent(event);track.addEventNearToProvidedEventToSelection(event,offset,newSelection);}
-if(newSelection.length==0)
-return undefined;return newSelection;},rebuildEventToTrackMap:function(){this.eventToTrackMap_=new tr.ui.tracks.EventToTrackMap();this.modelTrackContainer_.addEventsToTrackMap(this.eventToTrackMap_);},rebuildContainerToTrackMap:function(){this.containerToTrackMap.clear();this.modelTrackContainer_.addContainersToTrackMap(this.containerToTrackMap);},trackForEvent:function(event){return this.eventToTrackMap_[event.guid];}};return{TimelineViewport:TimelineViewport};});'use strict';tr.exportTo('tr.ui.b',function(){var Location=tr.model.Location;function UIState(location,scaleX){this.location_=location;this.scaleX_=scaleX;};UIState.fromUserFriendlyString=function(model,viewport,stateString){var navByFinderPattern=/^(-?\d+(\.\d+)?)@(.+)x(\d+(\.\d+)?)$/g;var match=navByFinderPattern.exec(stateString);if(!match)
-return;var timestamp=parseFloat(match[1]);var stableId=match[3];var scaleX=parseFloat(match[4]);if(scaleX<=0)
-throw new Error('Invalid ScaleX value in UI State string.');if(!viewport.containerToTrackMap.getTrackByStableId(stableId))
-throw new Error('Invalid StableID given in UI State String.');var loc=tr.model.Location.fromStableIdAndTimestamp(viewport,stableId,timestamp);return new UIState(loc,scaleX);}
-UIState.prototype={get location(){return this.location_;},get scaleX(){return this.scaleX_;},toUserFriendlyString:function(viewport){var timestamp=this.location_.xWorld;var stableId=this.location_.getContainingTrack(viewport).eventContainer.stableId;var scaleX=this.scaleX_;return timestamp.toFixed(5)+'@'+stableId+'x'+scaleX.toFixed(5);},toDict:function(){return{location:this.location_.toDict(),scaleX:this.scaleX_};}};return{UIState:UIState};});'use strict';tr.exportTo('tr.c',function(){var BrushingState=tr.ui.b.BrushingState;var EventSet=tr.model.EventSet;var SelectionState=tr.model.SelectionState;var Viewport=tr.ui.TimelineViewport;function BrushingStateController(timelineView){tr.b.EventTarget.call(this);this.timelineView_=timelineView;this.currentBrushingState_=new BrushingState();this.onPopState_=this.onPopState_.bind(this);this.historyEnabled_=false;this.selections_={};}
-BrushingStateController.prototype={__proto__:tr.b.EventTarget.prototype,dispatchChangeEvent_:function(){var e=new tr.b.Event('change',false,false);this.dispatchEvent(e);},get model(){if(!this.timelineView_)
-return undefined;return this.timelineView_.model;},get trackView(){if(!this.timelineView_)
-return undefined;return this.timelineView_.trackView;},get viewport(){if(!this.timelineView_)
-return undefined;if(!this.timelineView_.trackView)
-return undefined;return this.timelineView_.trackView.viewport;},get historyEnabled(){return this.historyEnabled_;},set historyEnabled(historyEnabled){this.historyEnabled_=!!historyEnabled;if(historyEnabled)
-window.addEventListener('popstate',this.onPopState_);else
-window.removeEventListener('popstate',this.onPopState_);},modelWillChange:function(){if(this.currentBrushingState_.isAppliedToModel)
-this.currentBrushingState_.unapplyFromModelSelectionState();},modelDidChange:function(){this.selections_={};this.currentBrushingState_=new BrushingState();this.currentBrushingState_.applyToModelSelectionState(this.model);var e=new tr.b.Event('model-changed',false,false);this.dispatchEvent(e);this.dispatchChangeEvent_();},onUserInitiatedSelectionChange_:function(){var selection=this.selection;if(this.historyEnabled){this.selections_[selection.guid]=selection;var state={selection_guid:selection.guid};window.history.pushState(state,document.title);}},onPopState_:function(e){if(e.state===null)
-return;var selection=this.selections_[e.state.selection_guid];if(selection){var newState=this.currentBrushingState_.clone();newState.selection=selection;this.currentBrushingState=newState;}
-e.stopPropagation();},get selection(){return this.currentBrushingState_.selection;},get findMatches(){return this.currentBrushingState_.findMatches;},get selectionOfInterest(){return this.currentBrushingState_.selectionOfInterest;},get currentBrushingState(){return this.currentBrushingState_;},set currentBrushingState(newBrushingState){if(newBrushingState.isAppliedToModel)
-throw new Error('Cannot apply this state, it is applied');var hasValueChanged=!this.currentBrushingState_.equals(newBrushingState);if(newBrushingState!==this.currentBrushingState_&&!hasValueChanged){if(this.currentBrushingState_.isAppliedToModel){this.currentBrushingState_.transferModelOwnershipToClone(newBrushingState);}
+const track=this.trackForEvent(event);track.addEventNearToProvidedEventToSelection(event,offset,newSelection);}
+if(newSelection.length===0)return undefined;return newSelection;},rebuildEventToTrackMap(){this.eventToTrackMap_=new tr.ui.tracks.EventToTrackMap();this.modelTrackContainer_.addEventsToTrackMap(this.eventToTrackMap_);},rebuildContainerToTrackMap(){this.containerToTrackMap.clear();this.modelTrackContainer_.addContainersToTrackMap(this.containerToTrackMap);},trackForEvent(event){return this.eventToTrackMap_[event.guid];}};return{TimelineViewport,};});'use strict';tr.exportTo('tr.c',function(){const BrushingState=tr.ui.b.BrushingState;const EventSet=tr.model.EventSet;const SelectionState=tr.model.SelectionState;const Viewport=tr.ui.TimelineViewport;function BrushingStateController(timelineView){tr.b.EventTarget.call(this);this.timelineView_=timelineView;this.currentBrushingState_=new BrushingState();this.onPopState_=this.onPopState_.bind(this);this.historyEnabled_=false;this.selections_={};}
+BrushingStateController.prototype={__proto__:tr.b.EventTarget.prototype,dispatchChangeEvent_(){const e=new tr.b.Event('change',false,false);this.dispatchEvent(e);},get model(){if(!this.timelineView_){return undefined;}
+return this.timelineView_.model;},get trackView(){if(!this.timelineView_){return undefined;}
+return this.timelineView_.trackView;},get viewport(){if(!this.timelineView_){return undefined;}
+if(!this.timelineView_.trackView){return undefined;}
+return this.timelineView_.trackView.viewport;},get historyEnabled(){return this.historyEnabled_;},set historyEnabled(historyEnabled){this.historyEnabled_=!!historyEnabled;if(historyEnabled){window.addEventListener('popstate',this.onPopState_);}else{window.removeEventListener('popstate',this.onPopState_);}},modelWillChange(){if(this.currentBrushingState_.isAppliedToModel){this.currentBrushingState_.unapplyFromEventSelectionStates();}},modelDidChange(){this.selections_={};this.currentBrushingState_=new BrushingState();this.currentBrushingState_.applyToEventSelectionStates(this.model);const e=new tr.b.Event('model-changed',false,false);this.dispatchEvent(e);this.dispatchChangeEvent_();},onUserInitiatedSelectionChange_(){const selection=this.selection;if(this.historyEnabled){this.selections_[selection.guid]=selection;const state={selection_guid:selection.guid};window.history.pushState(state,document.title);}},onPopState_(e){if(e.state===null)return;const selection=this.selections_[e.state.selection_guid];if(selection){const newState=this.currentBrushingState_.clone();newState.selection=selection;this.currentBrushingState=newState;}
+e.stopPropagation();},get selection(){return this.currentBrushingState_.selection;},get findMatches(){return this.currentBrushingState_.findMatches;},get selectionOfInterest(){return this.currentBrushingState_.selectionOfInterest;},get currentBrushingState(){return this.currentBrushingState_;},set currentBrushingState(newBrushingState){if(newBrushingState.isAppliedToModel){throw new Error('Cannot apply this state, it is applied');}
+const hasValueChanged=!this.currentBrushingState_.equals(newBrushingState);if(newBrushingState!==this.currentBrushingState_&&!hasValueChanged){if(this.currentBrushingState_.isAppliedToModel){this.currentBrushingState_.transferModelOwnershipToClone(newBrushingState);}
 this.currentBrushingState_=newBrushingState;return;}
-if(this.currentBrushingState_.isAppliedToModel)
-this.currentBrushingState_.unapplyFromModelSelectionState();this.currentBrushingState_=newBrushingState;if(this.model)
-this.currentBrushingState_.applyToModelSelectionState(this.model);this.dispatchChangeEvent_();},addAllEventsMatchingFilterToSelectionAsTask:function(filter,selection){var timelineView=this.timelineView_.trackView;if(!timelineView)
-return new tr.b.Task();return timelineView.addAllEventsMatchingFilterToSelectionAsTask(filter,selection);},findTextChangedTo:function(allPossibleMatches){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.findMatches=allPossibleMatches;this.currentBrushingState=newBrushingState;},findFocusChangedTo:function(currentFocus){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=currentFocus;this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},findTextCleared:function(){if(this.xNavStringMarker_!==undefined){this.model.removeAnnotation(this.xNavStringMarker_);this.xNavStringMarker_=undefined;}
+if(this.currentBrushingState_.isAppliedToModel){this.currentBrushingState_.unapplyFromEventSelectionStates();}
+this.currentBrushingState_=newBrushingState;this.currentBrushingState_.applyToEventSelectionStates(this.model);this.dispatchChangeEvent_();},addAllEventsMatchingFilterToSelectionAsTask(filter,selection){const timelineView=this.timelineView_.trackView;if(!timelineView){return new tr.b.Task();}
+return timelineView.addAllEventsMatchingFilterToSelectionAsTask(filter,selection);},findTextChangedTo(allPossibleMatches){const newBrushingState=this.currentBrushingState_.clone();newBrushingState.findMatches=allPossibleMatches;this.currentBrushingState=newBrushingState;},findFocusChangedTo(currentFocus){const newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=currentFocus;this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},findTextCleared(){if(this.xNavStringMarker_!==undefined){this.model.removeAnnotation(this.xNavStringMarker_);this.xNavStringMarker_=undefined;}
 if(this.guideLineAnnotation_!==undefined){this.model.removeAnnotation(this.guideLineAnnotation_);this.guideLineAnnotation_=undefined;}
-var newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=new EventSet();newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},uiStateFromString:function(string){return tr.ui.b.UIState.fromUserFriendlyString(this.model,this.viewport,string);},navToPosition:function(uiState,showNavLine){this.trackView.navToPosition(uiState,showNavLine);},changeSelectionFromTimeline:function(selection){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=selection;newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},showScriptControlSelection:function(selection){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=selection;newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;},changeSelectionFromRequestSelectionChangeEvent:function(selection){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=selection;newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},changeAnalysisViewRelatedEvents:function(eventSet){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.analysisViewRelatedEvents=eventSet;this.currentBrushingState=newBrushingState;},changeAnalysisLinkHoveredEvents:function(eventSet){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.analysisLinkHoveredEvents=eventSet;this.currentBrushingState=newBrushingState;},getViewSpecificBrushingState:function(viewId){return this.currentBrushingState.viewSpecificBrushingStates[viewId];},changeViewSpecificBrushingState:function(viewId,newState){var oldStates=this.currentBrushingState_.viewSpecificBrushingStates;var newStates={};for(var id in oldStates)
-newStates[id]=oldStates[id];if(newState===undefined)
-delete newStates[viewId];else
-newStates[viewId]=newState;var newBrushingState=this.currentBrushingState_.clone();newBrushingState.viewSpecificBrushingStates=newStates;this.currentBrushingState=newBrushingState;}};BrushingStateController.getControllerForElement=function(element){if(tr.isHeadless)
-throw new Error('Unsupported');var currentElement=element;while(currentElement){if(currentElement.brushingStateController)
-return currentElement.brushingStateController;if(currentElement.parentElement){currentElement=currentElement.parentElement;continue;}
-var currentNode=currentElement;while(currentNode.parentNode)
-currentNode=currentNode.parentNode;currentElement=currentNode.host;}
-return undefined;};return{BrushingStateController:BrushingStateController};});'use strict';Polymer('tr-ui-a-analysis-link',{ready:function(){this.selection_=undefined;},attached:function(){this.controller_=tr.c.BrushingStateController.getControllerForElement(this);},detached:function(){this.clearHighlight_();this.controller_=undefined;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;this.textContent=selection.userFriendlyName;},setSelectionAndContent:function(selection,opt_textContent){this.selection_=selection;if(opt_textContent)
-this.textContent=opt_textContent;},getCurrentSelection_:function(){if(typeof this.selection_==='function')
-return this.selection_();return this.selection_;},setHighlight_:function(opt_eventSet){if(this.controller_)
-this.controller_.changeAnalysisLinkHoveredEvents(opt_eventSet);},clearHighlight_:function(opt_eventSet){this.setHighlight_();},onClicked_:function(){if(!this.selection_)
-return;var event=new tr.model.RequestSelectionChangeEvent();event.selection=this.getCurrentSelection_();this.dispatchEvent(event);},onMouseEnter_:function(){this.setHighlight_(this.getCurrentSelection_());},onMouseLeave_:function(){this.clearHighlight_();}});'use strict';tr.exportTo('tr.ui.b',function(){var TableFormat={};TableFormat.SelectionMode={NONE:0,ROW:1,CELL:2};TableFormat.HighlightStyle={DEFAULT:0,NONE:1,LIGHT:2,DARK:3};return{TableFormat:TableFormat};});'use strict';(function(){var RIGHT_ARROW=String.fromCharCode(0x25b6);var UNSORTED_ARROW=String.fromCharCode(0x25BF);var ASCENDING_ARROW=String.fromCharCode(0x25B4);var DESCENDING_ARROW=String.fromCharCode(0x25BE);var BASIC_INDENTATION=8;var SelectionMode=tr.ui.b.TableFormat.SelectionMode;var HighlightStyle=tr.ui.b.TableFormat.HighlightStyle;Polymer('tr-ui-b-table',{created:function(){this.selectionMode_=SelectionMode.NONE;this.rowHighlightStyle_=HighlightStyle.DEFAULT;this.cellHighlightStyle_=HighlightStyle.DEFAULT;this.selectedTableRowInfo_=undefined;this.selectedColumnIndex_=undefined;this.tableColumns_=[];this.tableRows_=[];this.tableRowsInfo_=new WeakMap();this.tableFooterRows_=[];this.tableFooterRowsInfo_=new WeakMap();this.sortColumnIndex_=undefined;this.sortDescending_=false;this.columnsWithExpandButtons_=[];this.headerCells_=[];this.showHeader_=true;this.emptyValue_=undefined;this.subRowsPropertyName_='subRows';this.customizeTableRowCallback_=undefined;},ready:function(){this.$.body.addEventListener('keydown',this.onKeyDown_.bind(this),true);},clear:function(){this.selectionMode_=SelectionMode.NONE;this.rowHighlightStyle_=HighlightStyle.DEFAULT;this.cellHighlightStyle_=HighlightStyle.DEFAULT;this.selectedTableRowInfo_=undefined;this.selectedColumnIndex_=undefined;this.textContent='';this.tableColumns_=[];this.tableRows_=[];this.tableRowsInfo_=new WeakMap();this.tableFooterRows_=[];this.tableFooterRowsInfo_=new WeakMap();this.sortColumnIndex_=undefined;this.sortDescending_=false;this.columnsWithExpandButtons_=[];this.headerCells_=[];this.subRowsPropertyName_='subRows';this.defaultExpansionStateCallback_=undefined;},get showHeader(){return this.showHeader_;},set showHeader(showHeader){this.showHeader_=showHeader;this.scheduleRebuildHeaders_();},set subRowsPropertyName(name){this.subRowsPropertyName_=name;},set defaultExpansionStateCallback(cb){this.defaultExpansionStateCallback_=cb;this.scheduleRebuildBody_();},set customizeTableRowCallback(cb){this.customizeTableRowCallback_=cb;this.scheduleRebuildBody_();},get emptyValue(){return this.emptyValue_;},set emptyValue(emptyValue){var previousEmptyValue=this.emptyValue_;this.emptyValue_=emptyValue;if(this.tableRows_.length===0&&emptyValue!==previousEmptyValue)
-this.scheduleRebuildBody_();},set tableColumns(columns){var columnsWithExpandButtons=[];for(var i=0;i<columns.length;i++){if(columns[i].showExpandButtons)
-columnsWithExpandButtons.push(i);}
+const newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=new EventSet();newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},uiStateFromString(string){return tr.ui.b.UIState.fromUserFriendlyString(this.model,this.viewport,string);},navToPosition(uiState,showNavLine){this.trackView.navToPosition(uiState,showNavLine);},changeSelectionFromTimeline(selection){const newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=selection;newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},showScriptControlSelection(selection){const newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=selection;newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;},changeSelectionFromRequestSelectionChangeEvent(selection){const newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=selection;newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},changeAnalysisViewRelatedEvents(eventSet){const newBrushingState=this.currentBrushingState_.clone();newBrushingState.analysisViewRelatedEvents=eventSet;this.currentBrushingState=newBrushingState;},changeAnalysisLinkHoveredEvents(eventSet){const newBrushingState=this.currentBrushingState_.clone();newBrushingState.analysisLinkHoveredEvents=eventSet;this.currentBrushingState=newBrushingState;},getViewSpecificBrushingState(viewId){return this.currentBrushingState.viewSpecificBrushingStates[viewId];},changeViewSpecificBrushingState(viewId,newState){const oldStates=this.currentBrushingState_.viewSpecificBrushingStates;const newStates={};for(const id in oldStates){newStates[id]=oldStates[id];}
+if(newState===undefined){delete newStates[viewId];}else{newStates[viewId]=newState;}
+const newBrushingState=this.currentBrushingState_.clone();newBrushingState.viewSpecificBrushingStates=newStates;this.currentBrushingState=newBrushingState;}};BrushingStateController.getControllerForElement=function(element){if(tr.isHeadless){throw new Error('Unsupported');}
+let currentElement=element;while(currentElement){if(currentElement.brushingStateController){return currentElement.brushingStateController;}
+if(currentElement.parentElement){currentElement=currentElement.parentElement;continue;}
+let currentNode=currentElement;while(Polymer.dom(currentNode).parentNode){currentNode=Polymer.dom(currentNode).parentNode;}
+currentElement=currentNode.host;}
+return undefined;};return{BrushingStateController,};});'use strict';Polymer({is:'tr-ui-a-analysis-link',properties:{href:{type:String}},listeners:{'click':'onClicked_','mouseenter':'onMouseEnter_','mouseleave':'onMouseLeave_'},ready(){this.selection_=undefined;},attached(){this.controller_=tr.c.BrushingStateController.getControllerForElement(this);},detached(){this.clearHighlight_();this.controller_=undefined;},set color(c){this.style.color=c;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;Polymer.dom(this).textContent=selection.userFriendlyName;},setSelectionAndContent(selection,opt_textContent){this.selection_=selection;if(opt_textContent){Polymer.dom(this).textContent=opt_textContent;}},getCurrentSelection_(){if(typeof this.selection_==='function'){return this.selection_();}
+return this.selection_;},setHighlight_(opt_eventSet){if(this.controller_){this.controller_.changeAnalysisLinkHoveredEvents(opt_eventSet);}},clearHighlight_(opt_eventSet){this.setHighlight_();},onClicked_(clickEvent){if(!this.selection_)return;clickEvent.stopPropagation();const event=new tr.model.RequestSelectionChangeEvent();event.selection=this.getCurrentSelection_();this.dispatchEvent(event);},onMouseEnter_(){this.setHighlight_(this.getCurrentSelection_());},onMouseLeave_(){this.clearHighlight_();}});'use strict';tr.exportTo('tr.ui.b',function(){const TableFormat={};TableFormat.SelectionMode={NONE:0,ROW:1,CELL:2};TableFormat.HighlightStyle={DEFAULT:0,NONE:1,LIGHT:2,DARK:3};TableFormat.ColumnAlignment={LEFT:0,RIGHT:1};return{TableFormat,};});'use strict';(function(){const RIGHT_ARROW=String.fromCharCode(0x25b6);const UNSORTED_ARROW=String.fromCharCode(0x25BF);const ASCENDING_ARROW=String.fromCharCode(0x25B4);const DESCENDING_ARROW=String.fromCharCode(0x25BE);const SelectionMode=tr.ui.b.TableFormat.SelectionMode;const SelectionModeValues=new Set(Object.values(SelectionMode));const HighlightStyle=tr.ui.b.TableFormat.HighlightStyle;const HighlightStyleValues=new Set(Object.values(HighlightStyle));const ColumnAlignment=tr.ui.b.TableFormat.ColumnAlignment;const ColumnAlignmentValues=new Set(Object.values(ColumnAlignment));Polymer({is:'tr-ui-b-table',created(){this.selectionMode_=SelectionMode.NONE;this.rowHighlightStyle_=HighlightStyle.DEFAULT;this.cellHighlightStyle_=HighlightStyle.DEFAULT;this.selectedTableRowInfo_=undefined;this.selectedColumnIndex_=undefined;this.tableColumns_=[];this.tableRows_=[];this.tableRowsInfo_=new WeakMap();this.tableFooterRows_=[];this.tableFooterRowsInfo_=new WeakMap();this.sortColumnIndex_=undefined;this.sortDescending_=false;this.columnsWithExpandButtons_=[];this.headerCells_=[];this.showHeader_=true;this.emptyValue_=undefined;this.subRowsPropertyName_='subRows';this.customizeTableRowCallback_=undefined;this.defaultExpansionStateCallback_=undefined;this.userCanModifySortOrder_=true;this.computedFontSizePx_=undefined;},ready(){this.$.body.addEventListener('keydown',this.onKeyDown_.bind(this),true);this.$.body.addEventListener('focus',this.onFocus_.bind(this),true);},clear(){this.selectionMode_=SelectionMode.NONE;this.rowHighlightStyle_=HighlightStyle.DEFAULT;this.cellHighlightStyle_=HighlightStyle.DEFAULT;this.selectedTableRowInfo_=undefined;this.selectedColumnIndex_=undefined;Polymer.dom(this).textContent='';this.tableColumns_=[];this.tableRows_=[];this.tableRowsInfo_=new WeakMap();this.tableFooterRows_=[];this.tableFooterRowsInfo_=new WeakMap();this.sortColumnIndex_=undefined;this.sortDescending_=false;this.columnsWithExpandButtons_=[];this.headerCells_=[];this.showHeader_=true;this.emptyValue_=undefined;this.subRowsPropertyName_='subRows';this.defaultExpansionStateCallback_=undefined;this.userCanModifySortOrder_=true;},set zebra(zebra){if(zebra){this.setAttribute('zebra',true);}else{this.removeAttribute('zebra');}},get zebra(){return this.getAttribute('zebra');},get showHeader(){return this.showHeader_;},set showHeader(showHeader){this.showHeader_=showHeader;this.scheduleRebuildHeaders_();},set subRowsPropertyName(name){this.subRowsPropertyName_=name;},set defaultExpansionStateCallback(cb){this.defaultExpansionStateCallback_=cb;this.scheduleRebuildBody_();},set customizeTableRowCallback(cb){this.customizeTableRowCallback_=cb;this.scheduleRebuildBody_();},get emptyValue(){return this.emptyValue_;},set emptyValue(emptyValue){const previousEmptyValue=this.emptyValue_;this.emptyValue_=emptyValue;if(this.tableRows_.length===0&&emptyValue!==previousEmptyValue){this.scheduleRebuildBody_();}},set tableColumns(columns){let columnsWithExpandButtons=[];for(let i=0;i<columns.length;i++){if(columns[i].showExpandButtons){columnsWithExpandButtons.push(i);}}
 if(columnsWithExpandButtons.length===0){columnsWithExpandButtons=[0];}
-for(var i=0;i<columns.length;i++){var colInfo=columns[i];if(colInfo.width===undefined)
-continue;var hasExpandButton=columnsWithExpandButtons.indexOf(i)!==-1;var w=colInfo.width;if(w){if(/\d+px/.test(w)){continue;}else if(/\d+%/.test(w)){if(hasExpandButton){throw new Error('Columns cannot be %-sized and host '+' an expand button');}}else{throw new Error('Unrecognized width string');}}}
-this.tableColumns_=columns;this.headerCells_=[];this.columnsWithExpandButtons_=columnsWithExpandButtons;this.sortColumnIndex=undefined;this.scheduleRebuildHeaders_();this.tableRows=this.tableRows_;},get tableColumns(){return this.tableColumns_;},set tableRows(rows){this.selectedTableRowInfo_=undefined;this.selectedColumnIndex_=undefined;this.maybeUpdateSelectedRow_();this.tableRows_=rows;this.tableRowsInfo_=new WeakMap();this.scheduleRebuildBody_();},get tableRows(){return this.tableRows_;},set footerRows(rows){this.tableFooterRows_=rows;this.tableFooterRowsInfo_=new WeakMap();this.scheduleRebuildFooter_();},get footerRows(){return this.tableFooterRows_;},set sortColumnIndex(number){if(number===this.sortColumnIndex_)
-return;if(number===undefined){this.sortColumnIndex_=undefined;this.updateHeaderArrows_();this.dispatchSortingChangedEvent_();return;}
-if(this.tableColumns_.length<=number)
-throw new Error('Column number '+number+' is out of bounds.');if(!this.tableColumns_[number].cmp)
-throw new Error('Column '+number+' does not have a comparator.');this.sortColumnIndex_=number;this.updateHeaderArrows_();this.scheduleRebuildBody_();this.dispatchSortingChangedEvent_();},get sortColumnIndex(){return this.sortColumnIndex_;},set sortDescending(value){var newValue=!!value;if(newValue!==this.sortDescending_){this.sortDescending_=newValue;this.updateHeaderArrows_();this.scheduleRebuildBody_();this.dispatchSortingChangedEvent_();}},get sortDescending(){return this.sortDescending_;},updateHeaderArrows_:function(){for(var i=0;i<this.headerCells_.length;i++){if(!this.tableColumns_[i].cmp){this.headerCells_[i].sideContent='';continue;}
-if(i!==this.sortColumnIndex_){this.headerCells_[i].sideContent=UNSORTED_ARROW;continue;}
-this.headerCells_[i].sideContent=this.sortDescending_?DESCENDING_ARROW:ASCENDING_ARROW;}},sortRows_:function(rows){rows.sort(function(rowA,rowB){if(this.sortDescending_)
-return this.tableColumns_[this.sortColumnIndex_].cmp(rowB.userRow,rowA.userRow);return this.tableColumns_[this.sortColumnIndex_].cmp(rowA.userRow,rowB.userRow);}.bind(this));for(var i=0;i<rows.length;i++){if(this.getExpandedForUserRow_(rows[i]))
-this.sortRows_(rows[i][this.subRowsPropertyName_]);}},generateHeaderColumns_:function(){this.headerCells_=[];this.$.head.textContent='';if(!this.showHeader_)
-return;var tr=this.appendNewElement_(this.$.head,'tr');for(var i=0;i<this.tableColumns_.length;i++){var td=this.appendNewElement_(tr,'td');var headerCell=document.createElement('tr-ui-b-table-header-cell');if(this.showHeader)
-headerCell.cellTitle=this.tableColumns_[i].title;else
-headerCell.cellTitle='';if(this.tableColumns_[i].cmp){td.classList.add('sensitive');headerCell.tapCallback=this.createSortCallback_(i);if(this.sortColumnIndex_===i)
-headerCell.sideContent=this.sortDescending_?DESCENDING_ARROW:ASCENDING_ARROW;else
-headerCell.sideContent=UNSORTED_ARROW;}
-td.appendChild(headerCell);this.headerCells_.push(headerCell);}},applySizes_:function(){if(this.tableRows_.length===0&&!this.showHeader)
-return;var rowToRemoveSizing;var rowToSize;if(this.showHeader){rowToSize=this.$.head.children[0];rowToRemoveSizing=this.$.body.children[0];}else{rowToSize=this.$.body.children[0];rowToRemoveSizing=this.$.head.children[0];}
-for(var i=0;i<this.tableColumns_.length;i++){if(rowToRemoveSizing&&rowToRemoveSizing.children[i]){var tdToRemoveSizing=rowToRemoveSizing.children[i];tdToRemoveSizing.style.minWidth='';tdToRemoveSizing.style.width='';}
-var td=rowToSize.children[i];var delta;if(this.columnsWithExpandButtons_.indexOf(i)!==-1){td.style.paddingLeft=BASIC_INDENTATION+'px';delta=BASIC_INDENTATION+'px';}else{delta=undefined;}
-function calc(base,delta){if(delta)
-return'calc('+base+' - '+delta+')';else
+for(let i=0;i<columns.length;i++){const colInfo=columns[i];if(colInfo.width===undefined)continue;const hasExpandButton=columnsWithExpandButtons.includes(i);const w=colInfo.width;if(w){if(/\d+px/.test(w)){continue;}else if(/\d+%/.test(w)){if(hasExpandButton){throw new Error('Columns cannot be %-sized and host '+' an expand button');}}else{throw new Error('Unrecognized width string');}}}
+let sortIndex=undefined;const currentSortColumn=this.tableColumns[this.sortColumnIndex_];if(currentSortColumn){for(const[i,column]of columns.entries()){if(currentSortColumn.title===column.title){sortIndex=i;break;}}}
+this.tableColumns_=columns;this.headerCells_=[];this.columnsWithExpandButtons_=columnsWithExpandButtons;this.scheduleRebuildHeaders_();this.sortColumnIndex=sortIndex;this.tableRows=this.tableRows_;},get tableColumns(){return this.tableColumns_;},set tableRows(rows){this.selectedTableRowInfo_=undefined;this.selectedColumnIndex_=undefined;this.tableRows_=rows;this.tableRowsInfo_=new WeakMap();this.scheduleRebuildBody_();},get tableRows(){return this.tableRows_;},set footerRows(rows){this.tableFooterRows_=rows;this.tableFooterRowsInfo_=new WeakMap();this.scheduleRebuildFooter_();},get footerRows(){return this.tableFooterRows_;},get userCanModifySortOrder(){return this.userCanModifySortOrder_;},set userCanModifySortOrder(userCanModifySortOrder){const newUserCanModifySortOrder=!!userCanModifySortOrder;if(newUserCanModifySortOrder===this.userCanModifySortOrder_){return;}
+this.userCanModifySortOrder_=newUserCanModifySortOrder;this.scheduleRebuildHeaders_();},set sortColumnIndex(number){if(number===this.sortColumnIndex_)return;if(number!==undefined){if(this.tableColumns_.length<=number){throw new Error('Column number '+number+' is out of bounds.');}
+if(!this.tableColumns_[number].cmp){throw new Error('Column '+number+' does not have a comparator.');}}
+this.sortColumnIndex_=number;this.updateHeaderArrows_();this.scheduleRebuildBody_();this.dispatchSortingChangedEvent_();},get sortColumnIndex(){return this.sortColumnIndex_;},set sortDescending(value){const newValue=!!value;if(newValue!==this.sortDescending_){this.sortDescending_=newValue;this.updateHeaderArrows_();this.scheduleRebuildBody_();this.dispatchSortingChangedEvent_();}},get sortDescending(){return this.sortDescending_;},updateHeaderArrows_(){for(let i=0;i<this.headerCells_.length;i++){const headerCell=this.headerCells_[i];const isColumnCurrentlySorted=i===this.sortColumnIndex_;if(!this.tableColumns_[i].cmp||(!this.userCanModifySortOrder_&&!isColumnCurrentlySorted)){headerCell.sideContent='';continue;}
+if(!isColumnCurrentlySorted){headerCell.sideContent=UNSORTED_ARROW;headerCell.sideContentDisabled=false;continue;}
+headerCell.sideContent=this.sortDescending_?DESCENDING_ARROW:ASCENDING_ARROW;headerCell.sideContentDisabled=!this.userCanModifySortOrder_;}},generateHeaderColumns_(){const selectedTableColumnIndex=this.selectedTableColumnIndex;Polymer.dom(this.$.cols).textContent='';for(let i=0;i<this.tableColumns_.length;++i){const colElement=document.createElement('col');if(i===selectedTableColumnIndex){colElement.setAttribute('selected',true);}
+Polymer.dom(this.$.cols).appendChild(colElement);}
+this.headerCells_=[];Polymer.dom(this.$.head).textContent='';if(!this.showHeader_)return;const tr=this.appendNewElement_(this.$.head,'tr');for(let i=0;i<this.tableColumns_.length;i++){const td=this.appendNewElement_(tr,'td');const headerCell=document.createElement('tr-ui-b-table-header-cell');headerCell.column=this.tableColumns_[i];if(this.tableColumns_[i].cmp){const isColumnCurrentlySorted=i===this.sortColumnIndex_;if(isColumnCurrentlySorted){headerCell.sideContent=this.sortDescending_?DESCENDING_ARROW:ASCENDING_ARROW;if(!this.userCanModifySortOrder_){headerCell.sideContentDisabled=true;}}
+if(this.userCanModifySortOrder_){Polymer.dom(td).classList.add('sensitive');if(!isColumnCurrentlySorted){headerCell.sideContent=UNSORTED_ARROW;}
+headerCell.tapCallback=this.createSortCallback_(i);}}
+Polymer.dom(td).appendChild(headerCell);this.headerCells_.push(headerCell);}},applySizes_(){if(this.tableRows_.length===0&&!this.showHeader)return;let rowToRemoveSizing;let rowToSize;if(this.showHeader){rowToSize=Polymer.dom(this.$.head).children[0];rowToRemoveSizing=Polymer.dom(this.$.body).children[0];}else{rowToSize=Polymer.dom(this.$.body).children[0];rowToRemoveSizing=Polymer.dom(this.$.head).children[0];}
+for(let i=0;i<this.tableColumns_.length;i++){if(rowToRemoveSizing&&Polymer.dom(rowToRemoveSizing).children[i]){const tdToRemoveSizing=Polymer.dom(rowToRemoveSizing).children[i];tdToRemoveSizing.style.minWidth='';tdToRemoveSizing.style.width='';}
+const td=Polymer.dom(rowToSize).children[i];let delta;if(this.columnsWithExpandButtons_.includes(i)){td.style.paddingLeft=this.basicIndentation_+'px';delta=this.basicIndentation_+'px';}else{delta=undefined;}
+function calc(base,delta){if(delta){return'calc('+base+' - '+delta+')';}
 return base;}
-var w=this.tableColumns_[i].width;if(w){if(/\d+px/.test(w)){td.style.minWidth=calc(w,delta);}else if(/\d+%/.test(w)){td.style.width=w;}else{throw new Error('Unrecognized width string: '+w);}}}},createSortCallback_:function(columnNumber){return function(){var previousIndex=this.sortColumnIndex;this.sortColumnIndex=columnNumber;if(previousIndex!==columnNumber)
-this.sortDescending=false;else
-this.sortDescending=!this.sortDescending;}.bind(this);},generateTableRowNodes_:function(tableSection,userRows,rowInfoMap,indentation,lastAddedRow,parentRowInfo){if(this.sortColumnIndex_!==undefined&&tableSection===this.$.body){userRows=userRows.slice();userRows.sort(function(rowA,rowB){var c=this.tableColumns_[this.sortColumnIndex_].cmp(rowA,rowB);if(this.sortDescending_)
-c=-c;return c;}.bind(this));}
-for(var i=0;i<userRows.length;i++){var userRow=userRows[i];var rowInfo=this.getOrCreateRowInfoFor_(rowInfoMap,userRow,parentRowInfo);var htmlNode=this.getHTMLNodeForRowInfo_(tableSection,rowInfo,rowInfoMap,indentation);if(lastAddedRow===undefined){tableSection.insertBefore(htmlNode,tableSection.firstChild);}else{var nextSiblingOfLastAdded=lastAddedRow.nextSibling;tableSection.insertBefore(htmlNode,nextSiblingOfLastAdded);}
-this.updateTabIndexForTableRowNode_(htmlNode);lastAddedRow=htmlNode;if(!rowInfo.isExpanded)
-continue;lastAddedRow=this.generateTableRowNodes_(tableSection,userRow[this.subRowsPropertyName_],rowInfoMap,indentation+1,lastAddedRow,rowInfo);}
-return lastAddedRow;},getOrCreateRowInfoFor_:function(rowInfoMap,userRow,parentRowInfo){var rowInfo=undefined;if(rowInfoMap.has(userRow)){rowInfo=rowInfoMap.get(userRow);}else{rowInfo={userRow:userRow,htmlNode:undefined,parentRowInfo:parentRowInfo};rowInfoMap.set(userRow,rowInfo);}
-rowInfo.isExpanded=this.getExpandedForUserRow_(userRow);return rowInfo;},customizeTableRow_:function(userRow,trElement){if(!this.customizeTableRowCallback_)
-return;this.customizeTableRowCallback_(userRow,trElement);},getHTMLNodeForRowInfo_:function(tableSection,rowInfo,rowInfoMap,indentation){if(rowInfo.htmlNode){this.customizeTableRow_(rowInfo.userRow,rowInfo.htmlNode);return rowInfo.htmlNode;}
-var INDENT_SPACE=indentation*16;var INDENT_SPACE_NO_BUTTON=indentation*16+BASIC_INDENTATION;var trElement=this.ownerDocument.createElement('tr');rowInfo.htmlNode=trElement;rowInfo.indentation=indentation;trElement.rowInfo=rowInfo;this.customizeTableRow_(rowInfo.userRow,trElement);for(var i=0;i<this.tableColumns_.length;){var td=this.appendNewElement_(trElement,'td');td.columnIndex=i;var column=this.tableColumns_[i];var value=column.value(rowInfo.userRow);var colSpan=column.colSpan?column.colSpan:1;td.style.colSpan=colSpan;if(column.textAlign){td.style.textAlign=column.textAlign;}
-if(this.doesColumnIndexSupportSelection(i))
-td.classList.add('supports-selection');if(this.columnsWithExpandButtons_.indexOf(i)!=-1){if(rowInfo.userRow[this.subRowsPropertyName_]&&rowInfo.userRow[this.subRowsPropertyName_].length>0){td.style.paddingLeft=INDENT_SPACE+'px';var expandButton=this.appendNewElement_(td,'expand-button');expandButton.textContent=RIGHT_ARROW;if(rowInfo.isExpanded)
-expandButton.classList.add('button-expanded');}else{td.style.paddingLeft=INDENT_SPACE_NO_BUTTON+'px';}}
-if(value!==undefined)
-td.appendChild(tr.ui.b.asHTMLOrTextNode(value,this.ownerDocument));i+=colSpan;}
-var isSelectable=tableSection===this.$.body;var isExpandable=rowInfo.userRow[this.subRowsPropertyName_]&&rowInfo.userRow[this.subRowsPropertyName_].length;if(isSelectable||isExpandable){trElement.addEventListener('click',function(e){e.stopPropagation();if(e.target.tagName=='EXPAND-BUTTON'){this.setExpandedForUserRow_(tableSection,rowInfoMap,rowInfo.userRow,!rowInfo.isExpanded);return;}
-function getTD(cur){if(cur===trElement)
-throw new Error('woah');if(cur.parentElement===trElement)
-return cur;return getTD(cur.parentElement);}
-if(isSelectable&&this.selectionMode_!==SelectionMode.NONE){var shouldSelect=false;var columnIndex=getTD(e.target).columnIndex;switch(this.selectionMode_){case SelectionMode.ROW:shouldSelect=this.selectedTableRowInfo_!==rowInfo;break;case SelectionMode.CELL:if(this.doesColumnIndexSupportSelection(columnIndex)){shouldSelect=this.selectedTableRowInfo_!==rowInfo||this.selectedColumnIndex_!==columnIndex;}
+const w=this.tableColumns_[i].width;if(w){if(/\d+px/.test(w)){td.style.minWidth=calc(w,delta);}else if(/\d+%/.test(w)){td.style.width=w;}else{throw new Error('Unrecognized width string: '+w);}}}},createSortCallback_(columnNumber){return function(){if(!this.userCanModifySortOrder_)return;const previousIndex=this.sortColumnIndex;this.sortColumnIndex=columnNumber;if(previousIndex!==columnNumber){this.sortDescending=false;}else{this.sortDescending=!this.sortDescending;}}.bind(this);},generateTableRowNodes_(tableSection,userRows,rowInfoMap,indentation,lastAddedRow,parentRowInfo){if(this.sortColumnIndex_!==undefined&&tableSection===this.$.body){userRows=userRows.slice();userRows.sort(function(rowA,rowB){let c=this.tableColumns_[this.sortColumnIndex_].cmp(rowA,rowB);if(this.sortDescending_){c=-c;}
+return c;}.bind(this));}
+for(let i=0;i<userRows.length;i++){const userRow=userRows[i];const rowInfo=this.getOrCreateRowInfoFor_(rowInfoMap,userRow,parentRowInfo);const htmlNode=this.getHTMLNodeForRowInfo_(tableSection,rowInfo,rowInfoMap,indentation);if(lastAddedRow===undefined){Polymer.dom(tableSection).insertBefore(htmlNode,Polymer.dom(tableSection).firstChild);}else{const nextSiblingOfLastAdded=Polymer.dom(lastAddedRow).nextSibling;Polymer.dom(tableSection).insertBefore(htmlNode,nextSiblingOfLastAdded);}
+lastAddedRow=htmlNode;if(!rowInfo.isExpanded)continue;lastAddedRow=this.generateTableRowNodes_(tableSection,userRow[this.subRowsPropertyName_],rowInfoMap,indentation+1,lastAddedRow,rowInfo);}
+return lastAddedRow;},getOrCreateRowInfoFor_(rowInfoMap,userRow,parentRowInfo){let rowInfo=undefined;if(rowInfoMap.has(userRow)){rowInfo=rowInfoMap.get(userRow);}else{rowInfo={userRow,htmlNode:undefined,parentRowInfo};rowInfoMap.set(userRow,rowInfo);}
+rowInfo.isExpanded=this.getExpandedForUserRow_(userRow);return rowInfo;},customizeTableRow_(userRow,trElement){if(!this.customizeTableRowCallback_)return;this.customizeTableRowCallback_(userRow,trElement);},get basicIndentation_(){if(this.computedFontSizePx_===undefined){this.computedFontSizePx_=parseInt(getComputedStyle(this).fontSize)||16;}
+return this.computedFontSizePx_-2;},getHTMLNodeForRowInfo_(tableSection,rowInfo,rowInfoMap,indentation){if(rowInfo.htmlNode){this.customizeTableRow_(rowInfo.userRow,rowInfo.htmlNode);return rowInfo.htmlNode;}
+const INDENT_SPACE=indentation*16;const INDENT_SPACE_NO_BUTTON=indentation*16+this.basicIndentation_;const trElement=this.ownerDocument.createElement('tr');rowInfo.htmlNode=trElement;rowInfo.indentation=indentation;trElement.rowInfo=rowInfo;this.customizeTableRow_(rowInfo.userRow,trElement);const isBodyRow=tableSection===this.$.body;const isExpandableRow=rowInfo.userRow[this.subRowsPropertyName_]&&rowInfo.userRow[this.subRowsPropertyName_].length;for(let i=0;i<this.tableColumns_.length;){const td=this.appendNewElement_(trElement,'td');td.columnIndex=i;const column=this.tableColumns_[i];const value=column.value(rowInfo.userRow);const colSpan=column.colSpan?column.colSpan:1;td.style.colSpan=colSpan;switch(column.align){case undefined:case ColumnAlignment.LEFT:break;case ColumnAlignment.RIGHT:td.style.textAlign='right';break;default:throw new Error('Invalid alignment of column at index='+i+': '+column.align);}
+if(this.doesColumnIndexSupportSelection(i)){Polymer.dom(td).classList.add('supports-selection');}
+if(this.columnsWithExpandButtons_.includes(i)){if(rowInfo.userRow[this.subRowsPropertyName_]&&rowInfo.userRow[this.subRowsPropertyName_].length>0){td.style.paddingLeft=INDENT_SPACE+'px';td.style.display='flex';const expandButton=this.appendNewElement_(td,'expand-button');Polymer.dom(expandButton).textContent=RIGHT_ARROW;if(rowInfo.isExpanded){Polymer.dom(expandButton).classList.add('button-expanded');}}else{td.style.paddingLeft=INDENT_SPACE_NO_BUTTON+'px';}}
+if(value!==undefined){Polymer.dom(td).appendChild(tr.ui.b.asHTMLOrTextNode(value,this.ownerDocument));}
+td.addEventListener('click',function(i,clickEvent){clickEvent.preventDefault();if(!isBodyRow&&!isExpandableRow)return;clickEvent.stopPropagation();if(clickEvent.target.tagName==='EXPAND-BUTTON'){this.setExpandedForUserRow_(tableSection,rowInfoMap,rowInfo.userRow,!rowInfo.isExpanded);return;}
+if(isBodyRow&&this.selectionMode_!==SelectionMode.NONE){let shouldSelect=false;let shouldFocus=false;switch(this.selectionMode_){case SelectionMode.ROW:shouldSelect=this.selectedTableRowInfo_!==rowInfo;shouldFocus=true;break;case SelectionMode.CELL:if(this.doesColumnIndexSupportSelection(i)){shouldSelect=this.selectedTableRowInfo_!==rowInfo||this.selectedColumnIndex_!==i;shouldFocus=true;}
 break;default:throw new Error('Invalid selection mode '+
 this.selectionMode_);}
-if(shouldSelect){this.didTableRowInfoGetClicked_(rowInfo,columnIndex);return;}}
-if(isExpandable){this.setExpandedForUserRow_(tableSection,rowInfoMap,rowInfo.userRow,!rowInfo.isExpanded);}}.bind(this));}
-return rowInfo.htmlNode;},removeSubNodes_:function(tableSection,rowInfo,rowInfoMap){if(rowInfo.userRow[this.subRowsPropertyName_]===undefined)
-return;for(var i=0;i<rowInfo.userRow[this.subRowsPropertyName_].length;i++){var subRow=rowInfo.userRow[this.subRowsPropertyName_][i];var subRowInfo=rowInfoMap.get(subRow);if(!subRowInfo)
-continue;var subNode=subRowInfo.htmlNode;if(subNode&&subNode.parentNode===tableSection){tableSection.removeChild(subNode);this.removeSubNodes_(tableSection,subRowInfo,rowInfoMap);}}},scheduleRebuildHeaders_:function(){this.headerDirty_=true;this.scheduleRebuild_();},scheduleRebuildBody_:function(){this.bodyDirty_=true;this.scheduleRebuild_();},scheduleRebuildFooter_:function(){this.footerDirty_=true;this.scheduleRebuild_();},scheduleRebuild_:function(){if(this.rebuildPending_)
-return;this.rebuildPending_=true;setTimeout(function(){this.rebuildPending_=false;this.rebuild();}.bind(this),0);},rebuildIfNeeded_:function(){this.rebuild();},rebuild:function(){var wasBodyOrHeaderDirty=this.headerDirty_||this.bodyDirty_;if(this.headerDirty_){this.generateHeaderColumns_();this.headerDirty_=false;}
-if(this.bodyDirty_){this.$.body.textContent='';this.generateTableRowNodes_(this.$.body,this.tableRows_,this.tableRowsInfo_,0,undefined,undefined);if(this.tableRows_.length===0&&this.emptyValue_!==undefined){var trElement=this.ownerDocument.createElement('tr');this.$.body.appendChild(trElement);trElement.classList.add('empty-row');var td=this.ownerDocument.createElement('td');trElement.appendChild(td);td.colSpan=this.tableColumns_.length;var emptyValue=this.emptyValue_;td.appendChild(tr.ui.b.asHTMLOrTextNode(emptyValue,this.ownerDocument));}
+if(shouldFocus){this.focus();}
+if(shouldSelect){this.didTableRowInfoGetClicked_(rowInfo,i);return;}}
+if(isExpandableRow){this.setExpandedForUserRow_(tableSection,rowInfoMap,rowInfo.userRow,!rowInfo.isExpanded);}}.bind(this,i));if(isBodyRow){td.addEventListener('dblclick',function(i,e){e.stopPropagation();this.dispatchStepIntoEvent_(rowInfo,i);}.bind(this,i));}
+i+=colSpan;}
+return rowInfo.htmlNode;},removeSubNodes_(tableSection,rowInfo,rowInfoMap){if(rowInfo.userRow[this.subRowsPropertyName_]===undefined)return;for(let i=0;i<rowInfo.userRow[this.subRowsPropertyName_].length;i++){const subRow=rowInfo.userRow[this.subRowsPropertyName_][i];const subRowInfo=rowInfoMap.get(subRow);if(!subRowInfo)continue;const subNode=subRowInfo.htmlNode;if(subNode&&Polymer.dom(subNode).parentNode===tableSection){Polymer.dom(tableSection).removeChild(subNode);this.removeSubNodes_(tableSection,subRowInfo,rowInfoMap);}}},scheduleRebuildHeaders_(){this.headerDirty_=true;this.scheduleRebuild_();},scheduleRebuildBody_(){this.bodyDirty_=true;this.scheduleRebuild_();},scheduleRebuildFooter_(){this.footerDirty_=true;this.scheduleRebuild_();},scheduleRebuild_(){if(this.rebuildPending_)return;this.rebuildPending_=true;setTimeout(function(){this.rebuildPending_=false;this.rebuild();}.bind(this),0);},rebuildIfNeeded_(){this.rebuild();},rebuild(){const wasBodyOrHeaderDirty=this.headerDirty_||this.bodyDirty_;if(this.headerDirty_){this.generateHeaderColumns_();this.headerDirty_=false;}
+if(this.bodyDirty_){Polymer.dom(this.$.body).textContent='';this.generateTableRowNodes_(this.$.body,this.tableRows_,this.tableRowsInfo_,0,undefined,undefined);if(this.tableRows_.length===0&&this.emptyValue_!==undefined){const trElement=this.ownerDocument.createElement('tr');Polymer.dom(this.$.body).appendChild(trElement);Polymer.dom(trElement).classList.add('empty-row');const td=this.ownerDocument.createElement('td');Polymer.dom(trElement).appendChild(td);td.colSpan=this.tableColumns_.length;const emptyValue=this.emptyValue_;Polymer.dom(td).appendChild(tr.ui.b.asHTMLOrTextNode(emptyValue,this.ownerDocument));}
 this.bodyDirty_=false;}
-if(wasBodyOrHeaderDirty)
-this.applySizes_();if(this.footerDirty_){this.$.foot.textContent='';this.generateTableRowNodes_(this.$.foot,this.tableFooterRows_,this.tableFooterRowsInfo_,0,undefined,undefined);if(this.tableFooterRowsInfo_.length){this.$.body.classList.add('has-footer');}else{this.$.body.classList.remove('has-footer');}
-this.footerDirty_=false;}},appendNewElement_:function(parent,tagName){var element=parent.ownerDocument.createElement(tagName);parent.appendChild(element);return element;},getExpandedForTableRow:function(userRow){this.rebuildIfNeeded_();var rowInfo=this.tableRowsInfo_.get(userRow);if(rowInfo===undefined)
-throw new Error('Row has not been seen, must expand its parents');return rowInfo.isExpanded;},getExpandedForUserRow_:function(userRow){if(userRow[this.subRowsPropertyName_]===undefined)
-return false;if(userRow[this.subRowsPropertyName_].length===0)
-return false;if(userRow.isExpanded)
-return true;if(userRow.isExpanded===false)
-return false;if(this.defaultExpansionStateCallback_===undefined)
-return false;var parentUserRow=undefined;var rowInfo=this.tableRowsInfo_.get(userRow);if(rowInfo&&rowInfo.parentRowInfo)
-parentUserRow=rowInfo.parentRowInfo.userRow;return this.defaultExpansionStateCallback_(userRow,parentUserRow);},setExpandedForTableRow:function(userRow,expanded){this.rebuildIfNeeded_();var rowInfo=this.tableRowsInfo_.get(userRow);if(rowInfo===undefined)
-throw new Error('Row has not been seen, must expand its parents');return this.setExpandedForUserRow_(this.$.body,this.tableRowsInfo_,userRow,expanded);},setExpandedForUserRow_:function(tableSection,rowInfoMap,userRow,expanded){this.rebuildIfNeeded_();var rowInfo=rowInfoMap.get(userRow);if(rowInfo===undefined)
-throw new Error('Row has not been seen, must expand its parents');rowInfo.isExpanded=!!expanded;if(rowInfo.htmlNode===undefined)
-return;if(rowInfo.htmlNode.parentElement!==tableSection)
-return;var expandButton=rowInfo.htmlNode.querySelector('expand-button');if(rowInfo.isExpanded){expandButton.classList.add('button-expanded');var lastAddedRow=rowInfo.htmlNode;if(rowInfo.userRow[this.subRowsPropertyName_]){this.generateTableRowNodes_(tableSection,rowInfo.userRow[this.subRowsPropertyName_],rowInfoMap,rowInfo.indentation+1,lastAddedRow,rowInfo);}}else{expandButton.classList.remove('button-expanded');this.removeSubNodes_(tableSection,rowInfo,rowInfoMap);}
-this.maybeUpdateSelectedRow_();},get selectionMode(){return this.selectionMode_;},set selectionMode(selectionMode){if(!tr.b.dictionaryContainsValue(SelectionMode,selectionMode))
-throw new Error('Invalid selection mode '+selectionMode);this.rebuildIfNeeded_();this.selectionMode_=selectionMode;this.didSelectionStateChange_();},get rowHighlightStyle(){return this.rowHighlightStyle_;},set rowHighlightStyle(rowHighlightStyle){if(!tr.b.dictionaryContainsValue(HighlightStyle,rowHighlightStyle))
-throw new Error('Invalid row highlight style '+rowHighlightStyle);this.rebuildIfNeeded_();this.rowHighlightStyle_=rowHighlightStyle;this.didSelectionStateChange_();},get resolvedRowHighlightStyle(){if(this.rowHighlightStyle_!==HighlightStyle.DEFAULT)
-return this.rowHighlightStyle_;switch(this.selectionMode_){case SelectionMode.NONE:return HighlightStyle.NONE;case SelectionMode.ROW:return HighlightStyle.DARK;case SelectionMode.CELL:return HighlightStyle.LIGHT;default:throw new Error('Invalid selection mode '+selectionMode);}},get cellHighlightStyle(){return this.cellHighlightStyle_;},set cellHighlightStyle(cellHighlightStyle){if(!tr.b.dictionaryContainsValue(HighlightStyle,cellHighlightStyle))
-throw new Error('Invalid cell highlight style '+cellHighlightStyle);this.rebuildIfNeeded_();this.cellHighlightStyle_=cellHighlightStyle;this.didSelectionStateChange_();},get resolvedCellHighlightStyle(){if(this.cellHighlightStyle_!==HighlightStyle.DEFAULT)
-return this.cellHighlightStyle_;switch(this.selectionMode_){case SelectionMode.NONE:case SelectionMode.ROW:return HighlightStyle.NONE;case SelectionMode.CELL:return HighlightStyle.DARK;default:throw new Error('Invalid selection mode '+selectionMode);}},setHighlightStyle_:function(highlightAttribute,resolvedHighlightStyle){switch(resolvedHighlightStyle){case HighlightStyle.NONE:this.$.body.removeAttribute(highlightAttribute);break;case HighlightStyle.LIGHT:this.$.body.setAttribute(highlightAttribute,'light');break;case HighlightStyle.DARK:this.$.body.setAttribute(highlightAttribute,'dark');break;default:throw new Error('Invalid resolved highlight style '+
-resolvedHighlightStyle);}},didSelectionStateChange_:function(){this.setHighlightStyle_('row-highlight-style',this.resolvedRowHighlightStyle);this.setHighlightStyle_('cell-highlight-style',this.resolvedCellHighlightStyle);for(var i=0;i<this.$.body.children.length;i++)
-this.updateTabIndexForTableRowNode_(this.$.body.children[i]);this.maybeUpdateSelectedRow_();},maybeUpdateSelectedRow_:function(){if(this.selectedTableRowInfo_===undefined)
-return;if(this.selectionMode_===SelectionMode.NONE){this.removeSelectedState_();this.selectedTableRowInfo_=undefined;return;}
-function isVisible(rowInfo){if(!rowInfo.htmlNode)
-return false;return!!rowInfo.htmlNode.parentElement;}
+if(wasBodyOrHeaderDirty)this.applySizes_();if(this.footerDirty_){Polymer.dom(this.$.foot).textContent='';this.generateTableRowNodes_(this.$.foot,this.tableFooterRows_,this.tableFooterRowsInfo_,0,undefined,undefined);if(this.tableFooterRowsInfo_.length){Polymer.dom(this.$.body).classList.add('has-footer');}else{Polymer.dom(this.$.body).classList.remove('has-footer');}
+this.footerDirty_=false;}},appendNewElement_(parent,tagName){const element=parent.ownerDocument.createElement(tagName);Polymer.dom(parent).appendChild(element);return element;},getExpandedForTableRow(userRow){this.rebuildIfNeeded_();const rowInfo=this.tableRowsInfo_.get(userRow);if(rowInfo===undefined){throw new Error('Row has not been seen, must expand its parents');}
+return rowInfo.isExpanded;},getExpandedForUserRow_(userRow){if(userRow[this.subRowsPropertyName_]===undefined){return false;}
+if(userRow[this.subRowsPropertyName_].length===0){return false;}
+if(userRow.isExpanded){return true;}
+if((userRow.isExpanded!==undefined)&&(userRow.isExpanded===false)){return false;}
+const rowInfo=this.tableRowsInfo_.get(userRow);if(rowInfo&&rowInfo.isExpanded){return true;}
+if(this.defaultExpansionStateCallback_===undefined){return false;}
+let parentUserRow=undefined;if(rowInfo&&rowInfo.parentRowInfo){parentUserRow=rowInfo.parentRowInfo.userRow;}
+return this.defaultExpansionStateCallback_(userRow,parentUserRow);},setExpandedForTableRow(userRow,expanded){this.rebuildIfNeeded_();const rowInfo=this.tableRowsInfo_.get(userRow);if(rowInfo===undefined){throw new Error('Row has not been seen, must expand its parents');}
+return this.setExpandedForUserRow_(this.$.body,this.tableRowsInfo_,userRow,expanded);},setExpandedForUserRow_(tableSection,rowInfoMap,userRow,expanded){this.rebuildIfNeeded_();const rowInfo=rowInfoMap.get(userRow);if(rowInfo===undefined){throw new Error('Row has not been seen, must expand its parents');}
+const wasExpanded=rowInfo.isExpanded;rowInfo.isExpanded=!!expanded;if(rowInfo.htmlNode===undefined)return;if(rowInfo.htmlNode.parentElement!==tableSection){return;}
+const expandButton=Polymer.dom(rowInfo.htmlNode).querySelector('expand-button');if(rowInfo.isExpanded){Polymer.dom(expandButton).classList.add('button-expanded');const lastAddedRow=rowInfo.htmlNode;if(rowInfo.userRow[this.subRowsPropertyName_]){this.generateTableRowNodes_(tableSection,rowInfo.userRow[this.subRowsPropertyName_],rowInfoMap,rowInfo.indentation+1,lastAddedRow,rowInfo);}}else{Polymer.dom(expandButton).classList.remove('button-expanded');this.removeSubNodes_(tableSection,rowInfo,rowInfoMap);}
+if(wasExpanded!==rowInfo.isExpanded){const e=new tr.b.Event('row-expanded-changed');e.row=rowInfo.userRow;this.dispatchEvent(e);}
+this.maybeUpdateSelectedRow_();},get selectionMode(){return this.selectionMode_;},set selectionMode(selectionMode){if(!SelectionModeValues.has(selectionMode)){throw new Error('Invalid selection mode '+selectionMode);}
+this.rebuildIfNeeded_();this.selectionMode_=selectionMode;this.didSelectionStateChange_();},get rowHighlightStyle(){return this.rowHighlightStyle_;},set rowHighlightStyle(rowHighlightStyle){if(!HighlightStyleValues.has(rowHighlightStyle)){throw new Error('Invalid row highlight style '+rowHighlightStyle);}
+this.rebuildIfNeeded_();this.rowHighlightStyle_=rowHighlightStyle;this.didSelectionStateChange_();},get resolvedRowHighlightStyle(){if(this.rowHighlightStyle_!==HighlightStyle.DEFAULT){return this.rowHighlightStyle_;}
+switch(this.selectionMode_){case SelectionMode.NONE:return HighlightStyle.NONE;case SelectionMode.ROW:return HighlightStyle.DARK;case SelectionMode.CELL:return HighlightStyle.LIGHT;default:throw new Error('Invalid selection mode '+selectionMode);}},get cellHighlightStyle(){return this.cellHighlightStyle_;},set cellHighlightStyle(cellHighlightStyle){if(!HighlightStyleValues.has(cellHighlightStyle)){throw new Error('Invalid cell highlight style '+cellHighlightStyle);}
+this.rebuildIfNeeded_();this.cellHighlightStyle_=cellHighlightStyle;this.didSelectionStateChange_();},get resolvedCellHighlightStyle(){if(this.cellHighlightStyle_!==HighlightStyle.DEFAULT){return this.cellHighlightStyle_;}
+switch(this.selectionMode_){case SelectionMode.NONE:case SelectionMode.ROW:return HighlightStyle.NONE;case SelectionMode.CELL:return HighlightStyle.DARK;default:throw new Error('Invalid selection mode '+selectionMode);}},setHighlightStyle_(highlightAttribute,resolvedHighlightStyle){switch(resolvedHighlightStyle){case HighlightStyle.NONE:Polymer.dom(this.$.body).removeAttribute(highlightAttribute);break;case HighlightStyle.LIGHT:Polymer.dom(this.$.body).setAttribute(highlightAttribute,'light');break;case HighlightStyle.DARK:Polymer.dom(this.$.body).setAttribute(highlightAttribute,'dark');break;default:throw new Error('Invalid resolved highlight style '+
+resolvedHighlightStyle);}},didSelectionStateChange_(){this.setHighlightStyle_('row-highlight-style',this.resolvedRowHighlightStyle);this.setHighlightStyle_('cell-highlight-style',this.resolvedCellHighlightStyle);this.removeSelectedState_();switch(this.selectionMode_){case SelectionMode.ROW:Polymer.dom(this.$.body).setAttribute('selection-mode','row');Polymer.dom(this.$.body).setAttribute('tabindex',0);this.selectedColumnIndex_=undefined;break;case SelectionMode.CELL:Polymer.dom(this.$.body).setAttribute('selection-mode','cell');Polymer.dom(this.$.body).setAttribute('tabindex',0);if(this.selectedTableRowInfo_&&this.selectedColumnIndex_===undefined){const i=this.getFirstSelectableColumnIndex_();if(i===-1){this.selectedTableRowInfo_=undefined;}else{this.selectedColumnIndex_=i;}}
+break;case SelectionMode.NONE:Polymer.dom(this.$.body).removeAttribute('selection-mode');Polymer.dom(this.$.body).removeAttribute('tabindex');this.$.body.blur();this.selectedTableRowInfo_=undefined;this.selectedColumnIndex_=undefined;break;default:throw new Error('Invalid selection mode '+this.selectionMode_);}
+this.maybeUpdateSelectedRow_();},maybeUpdateSelectedRow_(){if(this.selectedTableRowInfo_===undefined)return;function isVisible(rowInfo){if(!rowInfo.htmlNode)return false;return!!rowInfo.htmlNode.parentElement;}
 if(isVisible(this.selectedTableRowInfo_)){this.updateSelectedState_();return;}
-this.removeSelectedState_();var curRowInfo=this.selectedTableRowInfo_;while(curRowInfo&&!isVisible(curRowInfo))
-curRowInfo=curRowInfo.parentRowInfo;this.selectedTableRowInfo_=curRowInfo;if(this.selectedTableRowInfo_)
-this.updateSelectedState_();},didTableRowInfoGetClicked_:function(rowInfo,columnIndex){switch(this.selectionMode_){case SelectionMode.NONE:return;case SelectionMode.CELL:if(!this.doesColumnIndexSupportSelection(columnIndex))
-return;if(this.selectedColumnIndex!==columnIndex)
-this.selectedColumnIndex=columnIndex;case SelectionMode.ROW:if(this.selectedTableRowInfo_!==rowInfo)
-this.selectedTableRow=rowInfo.userRow;}},get selectedTableRow(){if(!this.selectedTableRowInfo_)
-return undefined;return this.selectedTableRowInfo_.userRow;},set selectedTableRow(userRow){this.rebuildIfNeeded_();if(this.selectionMode_===SelectionMode.NONE)
-throw new Error('Selection is off.');var rowInfo;if(userRow===undefined){rowInfo=undefined;}else{rowInfo=this.tableRowsInfo_.get(userRow);if(!rowInfo)
-throw new Error('Row has not been seen, must expand its parents.');}
-var e=this.prepareToChangeSelection_();this.selectedTableRowInfo_=rowInfo;if(this.selectedTableRowInfo_===undefined){this.selectedColumnIndex_=undefined;this.removeSelectedState_();}else{switch(this.selectionMode_){case SelectionMode.ROW:this.selectedColumnIndex_=undefined;break;case SelectionMode.CELL:if(this.selectedColumnIndex_===undefined){var i=this.getFirstSelectableColumnIndex_();if(i==-1)
-throw new Error('Cannot find a selectable column.');this.selectedColumnIndex_=i;}
-break;default:throw new Error('Invalid selection mode '+this.selectionMode_);}
-this.updateSelectedState_();}
-this.dispatchEvent(e);},updateTabIndexForTableRowNode_:function(row){if(this.selectionMode_===SelectionMode.ROW)
-row.tabIndex=0;else
-row.removeAttribute('tabIndex');var enableCellTab=this.selectionMode_===SelectionMode.CELL;for(var i=0;i<this.tableColumns_.length;i++){var cell=row.children[i];if(enableCellTab&&this.doesColumnIndexSupportSelection(i))
-cell.tabIndex=0;else
-cell.removeAttribute('tabIndex');}},prepareToChangeSelection_:function(){var e=new tr.b.Event('selection-changed');var previousSelectedRowInfo=this.selectedTableRowInfo_;if(previousSelectedRowInfo)
-e.previousSelectedTableRow=previousSelectedRowInfo.userRow;else
-e.previousSelectedTableRow=undefined;this.removeSelectedState_();return e;},removeSelectedState_:function(){this.setSelectedState_(false);},updateSelectedState_:function(){this.setSelectedState_(true);},setSelectedState_:function(select){if(this.selectedTableRowInfo_===undefined)
-return;var rowNode=this.selectedTableRowInfo_.htmlNode;if(select)
-rowNode.setAttribute('selected',true);else
-rowNode.removeAttribute('selected');var cellNode=rowNode.children[this.selectedColumnIndex_];if(!cellNode)
-return;if(select)
-cellNode.setAttribute('selected',true);else
-cellNode.removeAttribute('selected');},doesColumnIndexSupportSelection:function(columnIndex){var columnInfo=this.tableColumns_[columnIndex];var scs=columnInfo.supportsCellSelection;if(scs===false)
-return false;return true;},getFirstSelectableColumnIndex_:function(){for(var i=0;i<this.tableColumns_.length;i++){if(this.doesColumnIndexSupportSelection(i))
-return i;}
-return-1;},getSelectableNodeGivenTableRowNode_:function(htmlNode){switch(this.selectionMode_){case SelectionMode.ROW:return htmlNode;case SelectionMode.CELL:return htmlNode.children[this.selectedColumnIndex_];default:throw new Error('Invalid selection mode '+this.selectionMode_);}},get selectedColumnIndex(){if(this.selectionMode_!==SelectionMode.CELL)
-return undefined;return this.selectedColumnIndex_;},set selectedColumnIndex(selectedColumnIndex){this.rebuildIfNeeded_();if(this.selectionMode_===SelectionMode.NONE)
-throw new Error('Selection is off.');if(selectedColumnIndex<0||selectedColumnIndex>=this.tableColumns_.length)
-throw new Error('Invalid index');if(!this.doesColumnIndexSupportSelection(selectedColumnIndex))
-throw new Error('Selection is not supported on this column');var e=this.prepareToChangeSelection_();this.selectedColumnIndex_=selectedColumnIndex;if(this.selectedColumnIndex_===undefined)
-this.selectedTableRowInfo_=undefined;this.updateSelectedState_();this.dispatchEvent(e);},onKeyDown_:function(e){if(this.selectionMode_===SelectionMode.NONE)
-return;if(this.selectedTableRowInfo_===undefined)
-return;var code_to_command_names={13:'ENTER',37:'ARROW_LEFT',38:'ARROW_UP',39:'ARROW_RIGHT',40:'ARROW_DOWN'};var cmdName=code_to_command_names[e.keyCode];if(cmdName===undefined)
-return;e.stopPropagation();e.preventDefault();this.performKeyCommand_(cmdName);},performKeyCommand_:function(cmdName){this.rebuildIfNeeded_();var rowInfo=this.selectedTableRowInfo_;var htmlNode=rowInfo.htmlNode;if(cmdName==='ARROW_UP'){var prev=htmlNode.previousElementSibling;if(prev){tr.ui.b.scrollIntoViewIfNeeded(prev);this.selectedTableRow=prev.rowInfo.userRow;this.focusSelected_();return;}
-return;}
-if(cmdName==='ARROW_DOWN'){var next=htmlNode.nextElementSibling;if(next){tr.ui.b.scrollIntoViewIfNeeded(next);this.selectedTableRow=next.rowInfo.userRow;this.focusSelected_();return;}
-return;}
-if(cmdName==='ARROW_RIGHT'){switch(this.selectionMode_){case SelectionMode.ROW:if(rowInfo.userRow[this.subRowsPropertyName_]===undefined)
-return;if(rowInfo.userRow[this.subRowsPropertyName_].length===0)
-return;if(!rowInfo.isExpanded)
-this.setExpandedForTableRow(rowInfo.userRow,true);this.selectedTableRow=rowInfo.userRow[this.subRowsPropertyName_][0];this.focusSelected_();return;case SelectionMode.CELL:var newIndex=this.selectedColumnIndex_+1;if(newIndex>=this.tableColumns_.length)
-return;if(!this.doesColumnIndexSupportSelection(newIndex))
-return;this.selectedColumnIndex=newIndex;this.focusSelected_();return;default:throw new Error('Invalid selection mode '+this.selectionMode_);}}
-if(cmdName==='ARROW_LEFT'){switch(this.selectionMode_){case SelectionMode.ROW:if(rowInfo.isExpanded){this.setExpandedForTableRow(rowInfo.userRow,false);this.focusSelected_();return;}
-var parentRowInfo=rowInfo.parentRowInfo;if(parentRowInfo){this.selectedTableRow=parentRowInfo.userRow;this.focusSelected_();return;}
-return;case SelectionMode.CELL:var newIndex=this.selectedColumnIndex_-1;if(newIndex<0)
-return;if(!this.doesColumnIndexSupportSelection(newIndex))
-return;this.selectedColumnIndex=newIndex;this.focusSelected_();return;default:throw new Error('Invalid selection mode '+this.selectionMode_);}}
-if(cmdName==='ENTER'){if(rowInfo.userRow[this.subRowsPropertyName_]===undefined)
-return;if(rowInfo.userRow[this.subRowsPropertyName_].length===0)
-return;this.setExpandedForTableRow(rowInfo.userRow,!rowInfo.isExpanded);this.focusSelected_();return;}
-throw new Error('Unrecognized command '+cmdName);},focusSelected_:function(){if(!this.selectedTableRowInfo_)
-return;var node=this.getSelectableNodeGivenTableRowNode_(this.selectedTableRowInfo_.htmlNode);node.focus();},dispatchSortingChangedEvent_:function(){var e=new tr.b.Event('sort-column-changed');e.sortColumnIndex=this.sortColumnIndex_;e.sortDescending=this.sortDescending_;this.dispatchEvent(e);}});})();'use strict';Polymer('tr-ui-b-table-header-cell',{created:function(){this.tapCallback_=undefined;this.cellTitle_='';},set cellTitle(value){this.cellTitle_=value;var titleNode=tr.ui.b.asHTMLOrTextNode(this.cellTitle_,this.ownerDocument);this.$.title.innerText='';this.$.title.appendChild(titleNode);},get cellTitle(){return this.cellTitle_;},clearSideContent:function(){this.$.side.textContent='';},set sideContent(content){this.$.side.textContent=content;},get sideContent(){return this.$.side.textContent;},set tapCallback(callback){this.style.cursor='pointer';this.tapCallback_=callback;},get tapCallback(){return this.tapCallback_;},onTap_:function(){if(this.tapCallback_)
-this.tapCallback_();}});'use strict';tr.exportTo('tr.b',function(){function _iterateElementDeeplyImpl(element,cb,thisArg,includeElement){if(includeElement){if(cb.call(thisArg,element))
+this.removeSelectedState_();let curRowInfo=this.selectedTableRowInfo_;while(curRowInfo&&!isVisible(curRowInfo)){curRowInfo=curRowInfo.parentRowInfo;}
+this.selectedTableRowInfo_=curRowInfo;if(this.selectedTableRowInfo_){this.updateSelectedState_();}else{this.selectedColumnIndex_=undefined;}},didTableRowInfoGetClicked_(rowInfo,columnIndex){switch(this.selectionMode_){case SelectionMode.NONE:return;case SelectionMode.CELL:if(!this.doesColumnIndexSupportSelection(columnIndex)){return;}
+if(this.selectedColumnIndex!==columnIndex){this.selectedColumnIndex=columnIndex;}
+case SelectionMode.ROW:if(this.selectedTableRowInfo_!==rowInfo){this.selectedTableRow=rowInfo.userRow;}}},dispatchStepIntoEvent_(rowInfo,columnIndex){const e=new tr.b.Event('step-into');e.tableRow=rowInfo.userRow;e.tableColumn=this.tableColumns_[columnIndex];e.columnIndex=columnIndex;this.dispatchEvent(e);},get selectedCell(){const row=this.selectedTableRow;const columnIndex=this.selectedColumnIndex;if(row===undefined||columnIndex===undefined||this.tableColumns_.length<=columnIndex){return undefined;}
+const column=this.tableColumns_[columnIndex];return{row,column,value:column.value(row)};},get selectedTableColumnIndex(){const cols=Polymer.dom(this.$.cols).children;for(let i=0;i<cols.length;++i){if(cols[i].getAttribute('selected')){return i;}}
+return undefined;},set selectedTableColumnIndex(selectedIndex){const cols=Polymer.dom(this.$.cols).children;for(let i=0;i<cols.length;++i){if(i===selectedIndex){cols[i].setAttribute('selected',true);}else{cols[i].removeAttribute('selected');}}},get selectedTableRow(){if(!this.selectedTableRowInfo_)return undefined;return this.selectedTableRowInfo_.userRow;},set selectedTableRow(userRow){this.rebuildIfNeeded_();if(this.selectionMode_===SelectionMode.NONE){throw new Error('Selection is off.');}
+let rowInfo;if(userRow===undefined){rowInfo=undefined;}else{rowInfo=this.tableRowsInfo_.get(userRow);if(!rowInfo){throw new Error('Row has not been seen, must expand its parents.');}}
+const e=this.prepareToChangeSelection_();if(!rowInfo){this.selectedColumnIndex_=undefined;}else{switch(this.selectionMode_){case SelectionMode.ROW:this.selectedColumnIndex_=undefined;break;case SelectionMode.CELL:if(this.selectedColumnIndex_===undefined){const i=this.getFirstSelectableColumnIndex_();if(i===-1){throw new Error('Cannot find a selectable column.');}
+this.selectedColumnIndex_=i;}
+break;default:throw new Error('Invalid selection mode '+this.selectionMode_);}}
+this.selectedTableRowInfo_=rowInfo;this.updateSelectedState_();this.dispatchEvent(e);},prepareToChangeSelection_(){const e=new tr.b.Event('selection-changed');const previousSelectedRowInfo=this.selectedTableRowInfo_;if(previousSelectedRowInfo){e.previousSelectedTableRow=previousSelectedRowInfo.userRow;}else{e.previousSelectedTableRow=undefined;}
+this.removeSelectedState_();return e;},removeSelectedState_(){this.setSelectedState_(false);},updateSelectedState_(){this.setSelectedState_(true);},setSelectedState_(select){if(this.selectedTableRowInfo_===undefined)return;const rowNode=this.selectedTableRowInfo_.htmlNode;if(select){Polymer.dom(rowNode).setAttribute('selected',true);}else{Polymer.dom(rowNode).removeAttribute('selected');}
+const cellNode=Polymer.dom(rowNode).children[this.selectedColumnIndex_];if(!cellNode)return;if(select){Polymer.dom(cellNode).setAttribute('selected',true);}else{Polymer.dom(cellNode).removeAttribute('selected');}},doesColumnIndexSupportSelection(columnIndex){const columnInfo=this.tableColumns_[columnIndex];const scs=columnInfo.supportsCellSelection;if(scs===false)return false;return true;},getFirstSelectableColumnIndex_(){for(let i=0;i<this.tableColumns_.length;i++){if(this.doesColumnIndexSupportSelection(i)){return i;}}
+return-1;},getSelectableNodeGivenTableRowNode_(htmlNode){switch(this.selectionMode_){case SelectionMode.ROW:return htmlNode;case SelectionMode.CELL:return Polymer.dom(htmlNode).children[this.selectedColumnIndex_];default:throw new Error('Invalid selection mode '+this.selectionMode_);}},get selectedColumnIndex(){if(this.selectionMode_!==SelectionMode.CELL){return undefined;}
+return this.selectedColumnIndex_;},set selectedColumnIndex(selectedColumnIndex){this.rebuildIfNeeded_();if(this.selectionMode_===SelectionMode.NONE){throw new Error('Selection is off.');}
+if(selectedColumnIndex<0||selectedColumnIndex>=this.tableColumns_.length){throw new Error('Invalid index');}
+if(!this.doesColumnIndexSupportSelection(selectedColumnIndex)){throw new Error('Selection is not supported on this column');}
+const e=this.prepareToChangeSelection_();if(this.selectedColumnIndex_===undefined){this.selectedTableRowInfo_=undefined;}else if(!this.selectedTableRowInfo_){if(this.tableRows_.length===0){throw new Error('No available row to be selected');}
+this.selectedTableRowInfo_=this.tableRowsInfo_.get(this.tableRows_[0]);}
+this.selectedColumnIndex_=selectedColumnIndex;this.updateSelectedState_();this.dispatchEvent(e);},onKeyDown_(e){if(this.selectionMode_===SelectionMode.NONE)return;const CODE_TO_COMMAND_NAMES={13:'ENTER',32:'SPACE',37:'ARROW_LEFT',38:'ARROW_UP',39:'ARROW_RIGHT',40:'ARROW_DOWN'};const cmdName=CODE_TO_COMMAND_NAMES[e.keyCode];if(cmdName===undefined)return;e.stopPropagation();e.preventDefault();this.performKeyCommand_(cmdName);},onFocus_(e){if(this.selectionMode_===SelectionMode.NONE||this.selectedTableRow||this.tableRows_.length===0){return;}
+if(this.selectionMode_===SelectionMode.CELL&&this.getFirstSelectableColumnIndex_()===-1){return;}
+this.selectedTableRow=this.tableRows_[0];},focus(){this.$.body.focus();this.onFocus_();},blur(){this.$.body.blur();},get isFocused(){return this.root.activeElement===this.$.body;},performKeyCommand_(cmdName){this.rebuildIfNeeded_();switch(cmdName){case'ARROW_UP':this.selectPreviousOrFirstRowIfPossible_();return;case'ARROW_DOWN':this.selectNextOrFirstRowIfPossible_();return;case'ARROW_RIGHT':switch(this.selectionMode_){case SelectionMode.NONE:return;case SelectionMode.ROW:this.expandRowAndSelectChildRowIfPossible_();return;case SelectionMode.CELL:this.selectNextSelectableCellToTheRightIfPossible_();return;default:throw new Error('Invalid selection mode '+this.selectionMode_);}
+case'ARROW_LEFT':switch(this.selectionMode_){case SelectionMode.NONE:return;case SelectionMode.ROW:this.collapseRowOrSelectParentRowIfPossible_();return;case SelectionMode.CELL:this.selectNextSelectableCellToTheLeftIfPossible_();return;default:throw new Error('Invalid selection mode '+this.selectionMode_);}
+case'SPACE':this.toggleRowExpansionStateIfPossible_();return;case'ENTER':this.stepIntoSelectionIfPossible_();return;default:throw new Error('Unrecognized command '+cmdName);}},selectPreviousOrFirstRowIfPossible_(){const prev=this.selectedTableRowInfo_?this.selectedTableRowInfo_.htmlNode.previousElementSibling:this.$.body.firstChild;if(!prev)return;if(this.selectionMode_===SelectionMode.CELL&&this.getFirstSelectableColumnIndex_()===-1){return;}
+tr.ui.b.scrollIntoViewIfNeeded(prev);this.selectedTableRow=prev.rowInfo.userRow;},selectNextOrFirstRowIfPossible_(){this.getFirstSelectableColumnIndex_;const next=this.selectedTableRowInfo_?this.selectedTableRowInfo_.htmlNode.nextElementSibling:this.$.body.firstChild;if(!next)return;if(this.selectionMode_===SelectionMode.CELL&&this.getFirstSelectableColumnIndex_()===-1){return;}
+tr.ui.b.scrollIntoViewIfNeeded(next);this.selectedTableRow=next.rowInfo.userRow;},expandRowAndSelectChildRowIfPossible_(){const selectedRowInfo=this.selectedTableRowInfo_;if(!selectedRowInfo||selectedRowInfo.userRow[this.subRowsPropertyName_]===undefined||selectedRowInfo.userRow[this.subRowsPropertyName_].length===0){return;}
+if(!selectedRowInfo.isExpanded){this.setExpandedForTableRow(selectedRowInfo.userRow,true);}
+this.selectedTableRow=selectedRowInfo.htmlNode.nextElementSibling.rowInfo.userRow;},collapseRowOrSelectParentRowIfPossible_(){const selectedRowInfo=this.selectedTableRowInfo_;if(!selectedRowInfo)return;if(selectedRowInfo.isExpanded){this.setExpandedForTableRow(selectedRowInfo.userRow,false);}else{const parentRowInfo=selectedRowInfo.parentRowInfo;if(parentRowInfo){this.selectedTableRow=parentRowInfo.userRow;}}},selectNextSelectableCellToTheRightIfPossible_(){if(!this.selectedTableRowInfo_||this.selectedColumnIndex_===undefined){return;}
+for(let i=this.selectedColumnIndex_+1;i<this.tableColumns_.length;i++){if(this.doesColumnIndexSupportSelection(i)){this.selectedColumnIndex=i;return;}}},selectNextSelectableCellToTheLeftIfPossible_(){if(!this.selectedTableRowInfo_||this.selectedColumnIndex_===undefined){return;}
+for(let i=this.selectedColumnIndex_-1;i>=0;i--){if(this.doesColumnIndexSupportSelection(i)){this.selectedColumnIndex=i;return;}}},toggleRowExpansionStateIfPossible_(){const selectedRowInfo=this.selectedTableRowInfo_;if(!selectedRowInfo||selectedRowInfo.userRow[this.subRowsPropertyName_]===undefined||selectedRowInfo.userRow[this.subRowsPropertyName_].length===0){return;}
+this.setExpandedForTableRow(selectedRowInfo.userRow,!selectedRowInfo.isExpanded);},stepIntoSelectionIfPossible_(){if(!this.selectedTableRowInfo_)return;this.dispatchStepIntoEvent_(this.selectedTableRowInfo_,this.selectedColumnIndex_);},dispatchSortingChangedEvent_(){const e=new tr.b.Event('sort-column-changed');e.sortColumnIndex=this.sortColumnIndex_;e.sortDescending=this.sortDescending_;this.dispatchEvent(e);}});})();'use strict';const ColumnAlignment=tr.ui.b.TableFormat.ColumnAlignment;Polymer({is:'tr-ui-b-table-header-cell',created(){this.tapCallback_=undefined;this.cellTitle_='';this.align_=undefined;this.selectable_=false;this.column_=undefined;},ready(){this.addEventListener('click',this.onTap_.bind(this));},set column(column){this.column_=column;this.align=column.align;this.cellTitle=column.title;},get column(){return this.column_;},set cellTitle(value){this.cellTitle_=value;const titleNode=tr.ui.b.asHTMLOrTextNode(this.cellTitle_,this.ownerDocument);this.$.title.innerText='';Polymer.dom(this.$.title).appendChild(titleNode);},get cellTitle(){return this.cellTitle_;},set align(align){switch(align){case undefined:case ColumnAlignment.LEFT:this.style.justifyContent='';break;case ColumnAlignment.RIGHT:this.style.justifyContent='flex-end';break;default:throw new Error('Invalid alignment of column (title=\''+
+this.cellTitle_+'\'): '+align);}
+this.align_=align;},get align(){return this.align_;},clearSideContent(){Polymer.dom(this.$.side).textContent='';},set sideContent(content){Polymer.dom(this.$.side).textContent=content;this.$.side.style.display=content?'inline':'none';},get sideContent(){return Polymer.dom(this.$.side).textContent;},set sideContentDisabled(sideContentDisabled){this.$.side.classList.toggle('disabled',sideContentDisabled);},get sideContentDisabled(){return this.$.side.classList.contains('disabled');},set tapCallback(callback){this.style.cursor='pointer';this.tapCallback_=callback;},get tapCallback(){return this.tapCallback_;},onTap_(){if(this.tapCallback_){this.tapCallback_();}}});'use strict';tr.exportTo('tr.b.math',function(){class RunningStatistics{constructor(){this.mean_=0;this.count_=0;this.max_=-Infinity;this.min_=Infinity;this.sum_=0;this.variance_=0;this.meanlogs_=0;}
+get count(){return this.count_;}
+get geometricMean(){if(this.meanlogs_===undefined)return 0;return Math.exp(this.meanlogs_);}
+get mean(){if(this.count_===0)return undefined;return this.mean_;}
+get max(){return this.max_;}
+get min(){return this.min_;}
+get sum(){return this.sum_;}
+get variance(){if(this.count_===0)return undefined;if(this.count_===1)return 0;return this.variance_/(this.count_-1);}
+get stddev(){if(this.count_===0)return undefined;return Math.sqrt(this.variance);}
+add(x){this.count_++;this.max_=Math.max(this.max_,x);this.min_=Math.min(this.min_,x);this.sum_+=x;if(x<=0){this.meanlogs_=undefined;}else if(this.meanlogs_!==undefined){this.meanlogs_+=(Math.log(Math.abs(x))-this.meanlogs_)/this.count;}
+if(this.count_===1){this.mean_=x;this.variance_=0;}else{const oldMean=this.mean_;const oldVariance=this.variance_;if(oldMean===Infinity||oldMean===-Infinity){this.mean_=this.sum_/this.count_;}else{this.mean_=oldMean+(x-oldMean)/this.count_;}
+this.variance_=oldVariance+(x-oldMean)*(x-this.mean_);}}
+merge(other){const result=new RunningStatistics();result.count_=this.count_+other.count_;result.sum_=this.sum_+other.sum_;result.min_=Math.min(this.min_,other.min_);result.max_=Math.max(this.max_,other.max_);if(result.count===0){result.mean_=0;result.variance_=0;result.meanlogs_=0;}else{result.mean_=result.sum/result.count;const deltaMean=(this.mean||0)-(other.mean||0);result.variance_=this.variance_+other.variance_+
+(this.count*other.count*deltaMean*deltaMean/result.count);if(this.meanlogs_===undefined||other.meanlogs_===undefined){result.meanlogs_=undefined;}else{result.meanlogs_=(this.count*this.meanlogs_+
+other.count*other.meanlogs_)/result.count;}}
+return result;}
+truncate(unit){this.max_=unit.truncate(this.max_);if(this.meanlogs_!==undefined){const formatted=unit.format(this.geometricMean);let lo=1;let hi=16;while(lo<hi-1){const digits=parseInt((lo+hi)/2);const test=tr.b.math.truncate(this.meanlogs_,digits);if(formatted===unit.format(Math.exp(test))){hi=digits;}else{lo=digits;}}
+const test=tr.b.math.truncate(this.meanlogs_,lo);if(formatted===unit.format(Math.exp(test))){this.meanlogs_=test;}else{this.meanlogs_=tr.b.math.truncate(this.meanlogs_,hi);}}
+this.mean_=unit.truncate(this.mean_);this.min_=unit.truncate(this.min_);this.sum_=unit.truncate(this.sum_);this.variance_=unit.truncate(this.variance_);}
+asDict(){if(!this.count){return[];}
+return[this.count_,this.max_,this.meanlogs_,this.mean_,this.min_,this.sum_,this.variance_,];}
+static fromDict(dict){const result=new RunningStatistics();if(dict.length!==7){return result;}
+[result.count_,result.max_,result.meanlogs_,result.mean_,result.min_,result.sum_,result.variance_,]=dict;return result;}}
+return{RunningStatistics,};});'use strict';tr.exportTo('tr.v.d',function(){class Diagnostic{constructor(){this.guid_=undefined;}
+clone(){return new this.constructor();}
+canAddDiagnostic(otherDiagnostic){return false;}
+addDiagnostic(otherDiagnostic){throw new Error('Abstract virtual method: subclasses must override '+'this method if they override canAddDiagnostic');}
+get guid(){if(this.guid_===undefined){this.guid_=tr.b.GUID.allocateUUID4();}
+return this.guid_;}
+set guid(guid){if(this.guid_!==undefined){throw new Error('Cannot reset guid');}
+this.guid_=guid;}
+get hasGuid(){return this.guid_!==undefined;}
+asDictOrReference(){if(this.guid_!==undefined){return this.guid_;}
+return this.asDict();}
+asDict(){const result={type:this.constructor.name};if(this.guid_!==undefined){result.guid=this.guid_;}
+this.asDictInto_(result);return result;}
+asDictInto_(d){throw new Error('Abstract virtual method: subclasses must override '+'this method if they override canAddDiagnostic');}
+static fromDict(d){const typeInfo=Diagnostic.findTypeInfoWithName(d.type);if(!typeInfo){throw new Error('Unrecognized diagnostic type: '+d.type);}
+const diagnostic=typeInfo.constructor.fromDict(d);if(d.guid!==undefined)diagnostic.guid=d.guid;return diagnostic;}
+static deserialize(type,d,deserializer){const typeInfo=Diagnostic.findTypeInfoWithName(type);if(!typeInfo){throw new Error('Unrecognized diagnostic type: '+type);}
+return typeInfo.constructor.deserialize(d,deserializer);}}
+const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Diagnostic;tr.b.decorateExtensionRegistry(Diagnostic,options);Diagnostic.addEventListener('will-register',function(e){const constructor=e.typeInfo.constructor;if(!(constructor.deserialize instanceof Function)||(constructor.deserialize===Diagnostic.deserialize)||(constructor.deserialize.length!==2)){throw new Error(`Please define ${constructor.name}.deserialize(data, deserializer)`);}
+if(!(constructor.fromDict instanceof Function)||(constructor.fromDict===Diagnostic.fromDict)||(constructor.fromDict.length!==1)){throw new Error(`Please define ${constructor.name}.fromDict(d)`);}
+if(!(constructor.prototype.serialize instanceof Function)||(constructor.prototype.serialize===Diagnostic.prototype.serialize)||(constructor.prototype.serialize.length!==1)){throw new Error(`Please define ${constructor.name}.serialize(serializer)`);}});return{Diagnostic,};});'use strict';tr.exportTo('tr.v.d',function(){class Breakdown extends tr.v.d.Diagnostic{constructor(){super();this.values_=new Map();this.colorScheme='';}
+truncate(unit){for(const[name,value]of this){this.values_.set(name,unit.truncate(value));}}
+clone(){const clone=new Breakdown();clone.colorScheme=this.colorScheme;clone.addDiagnostic(this);return clone;}
+equals(other){if(this.colorScheme!==other.colorScheme)return false;if(this.values_.size!==other.values_.size)return false;for(const[k,v]of this){if(v!==other.get(k))return false;}
 return true;}
-if(element.shadowRoot){if(_iterateElementDeeplyImpl(element.shadowRoot,cb,thisArg,false))
-return true;}
-for(var i=0;i<element.children.length;i++){if(_iterateElementDeeplyImpl(element.children[i],cb,thisArg,true))
-return true;}}
-function iterateElementDeeply(element,cb,thisArg){_iterateElementDeeplyImpl(element,cb,thisArg,false);}
-function findDeepElementMatchingPredicate(element,predicate){var foundElement=undefined;function matches(element){var match=predicate(element);if(!match)
-return false;foundElement=element;return true;}
-iterateElementDeeply(element,matches);return foundElement;}
-function findDeepElementsMatchingPredicate(element,predicate){var foundElements=[];function matches(element){var match=predicate(element);if(match){foundElements.push(element);}
+canAddDiagnostic(otherDiagnostic){return((otherDiagnostic instanceof Breakdown)&&(otherDiagnostic.colorScheme===this.colorScheme));}
+addDiagnostic(otherDiagnostic){for(const[name,value]of otherDiagnostic){this.set(name,this.get(name)+value);}
+return this;}
+set(name,value){if(typeof name!=='string'||typeof value!=='number'){throw new Error('Breakdown maps from strings to numbers');}
+this.values_.set(name,value);}
+get(name){return this.values_.get(name)||0;}*[Symbol.iterator](){for(const pair of this.values_){yield pair;}}
+get size(){return this.values_.size;}
+serialize(serializer){const keys=[...this.values_.keys()];keys.sort();return[serializer.getOrAllocateId(this.colorScheme),serializer.getOrAllocateId(keys.map(k=>serializer.getOrAllocateId(k))),...keys.map(k=>this.get(k)),];}
+asDictInto_(d){d.values={};for(const[name,value]of this){d.values[name]=tr.b.numberToJson(value);}
+if(this.colorScheme){d.colorScheme=this.colorScheme;}}
+static fromEntries(entries){const breakdown=new Breakdown();for(const[name,value]of entries){breakdown.set(name,value);}
+return breakdown;}
+static deserialize(data,deserializer){const breakdown=new Breakdown();breakdown.colorScheme=deserializer.getObject(data[0]);const keys=deserializer.getObject(data[1]);for(let i=0;i<keys.length;++i){breakdown.set(deserializer.getObject(keys[i]),tr.b.numberFromJson(data[i+2]));}
+return breakdown;}
+static fromDict(d){const breakdown=new Breakdown();for(const[name,value]of Object.entries(d.values)){breakdown.set(name,tr.b.numberFromJson(value));}
+if(d.colorScheme){breakdown.colorScheme=d.colorScheme;}
+return breakdown;}}
+tr.v.d.Diagnostic.register(Breakdown,{elementName:'tr-v-ui-breakdown-span'});return{Breakdown,};});'use strict';tr.exportTo('tr.v.d',function(){class CollectedRelatedEventSet extends tr.v.d.Diagnostic{constructor(){super();this.eventSetsByCanonicalUrl_=new Map();}
+asDictInto_(d){d.events={};for(const[canonicalUrl,eventSet]of this){d.events[canonicalUrl]=[];for(const event of eventSet){d.events[canonicalUrl].push({stableId:event.stableId,title:event.title,start:event.start,duration:event.duration});}}}
+static deserialize(events,deserializer){return CollectedRelatedEventSet.fromDict({events});}
+serialize(serializer){const d={};this.asDictInto(d);return d.events;}
+static fromDict(d){const result=new CollectedRelatedEventSet();for(const[canonicalUrl,events]of Object.entries(d.events)){result.eventSetsByCanonicalUrl_.set(canonicalUrl,events.map(e=>new tr.v.d.EventRef(e)));}
+return result;}
+get size(){return this.eventSetsByCanonicalUrl_.size;}
+get(canonicalUrl){return this.eventSetsByCanonicalUrl_.get(canonicalUrl);}*[Symbol.iterator](){for(const[canonicalUrl,eventSet]of this.eventSetsByCanonicalUrl_){yield[canonicalUrl,eventSet];}}
+canAddDiagnostic(otherDiagnostic){return otherDiagnostic instanceof tr.v.d.RelatedEventSet||otherDiagnostic instanceof tr.v.d.CollectedRelatedEventSet;}
+addEventSetForCanonicalUrl(canonicalUrl,events){let myEventSet=this.eventSetsByCanonicalUrl_.get(canonicalUrl);if(myEventSet===undefined){myEventSet=new Set();this.eventSetsByCanonicalUrl_.set(canonicalUrl,myEventSet);}
+for(const event of events){myEventSet.add(event);}}
+addDiagnostic(otherDiagnostic){if(otherDiagnostic instanceof tr.v.d.CollectedRelatedEventSet){for(const[canonicalUrl,otherEventSet]of otherDiagnostic){this.addEventSetForCanonicalUrl(canonicalUrl,otherEventSet);}
+return;}
+if(!otherDiagnostic.canonicalUrl)return;this.addEventSetForCanonicalUrl(otherDiagnostic.canonicalUrl,otherDiagnostic);}}
+tr.v.d.Diagnostic.register(CollectedRelatedEventSet,{elementName:'tr-v-ui-collected-related-event-set-span'});return{CollectedRelatedEventSet,};});'use strict';tr.exportTo('tr.v.d',function(){class DateRange extends tr.v.d.Diagnostic{constructor(ms){super();this.range_=new tr.b.math.Range();this.range_.addValue(ms);}
+get minTimestamp(){return this.range_.min;}
+get maxTimestamp(){return this.range_.max;}
+get minDate(){return new Date(this.range_.min);}
+get maxDate(){return new Date(this.range_.max);}
+get durationMs(){return this.range_.duration;}
+clone(){const clone=new tr.v.d.DateRange(this.range_.min);clone.addDiagnostic(this);return clone;}
+equals(other){if(!(other instanceof DateRange))return false;return this.range_.equals(other.range_);}
+canAddDiagnostic(otherDiagnostic){return otherDiagnostic instanceof DateRange;}
+addDiagnostic(other){this.range_.addRange(other.range_);}
+toString(){const minDate=tr.b.formatDate(this.minDate);if(this.durationMs===0)return minDate;const maxDate=tr.b.formatDate(this.maxDate);return`${minDate} - ${maxDate}`;}
+serialize(serializer){if(this.durationMs===0)return this.range_.min;return[this.range_.min,this.range_.max];}
+asDictInto_(d){d.min=this.range_.min;if(this.durationMs===0)return;d.max=this.range_.max;}
+static deserialize(data,deserializer){if(data instanceof Array){const dr=new DateRange(data[0]);dr.range_.addValue(data[1]);return dr;}
+return new DateRange(data);}
+static fromDict(d){const dateRange=new DateRange(d.min);if(d.max!==undefined)dateRange.range_.addValue(d.max);return dateRange;}}
+tr.v.d.Diagnostic.register(DateRange,{elementName:'tr-v-ui-date-range-span'});return{DateRange,};});'use strict';tr.exportTo('tr.v.d',function(){class DiagnosticRef{constructor(guid){this.guid=guid;}
+asDict(){return this.guid;}
+asDictOrReference(){return this.asDict();}}
+return{DiagnosticRef,};});'use strict';tr.exportTo('tr.v.d',function(){function stableStringify(obj){let replacer;if(!(obj instanceof Array)&&obj!==null){replacer=Object.keys(obj).sort();}
+return JSON.stringify(obj,replacer);}
+class GenericSet extends tr.v.d.Diagnostic{constructor(values){super();if(typeof values[Symbol.iterator]!=='function'){throw new Error('GenericSet must be constructed from an interable.');}
+this.values_=new Set(values);this.has_objects_=false;for(const value of values){if(typeof value==='object'){this.has_objects_=true;}}}
+get size(){return this.values_.size;}
+get length(){return this.values_.size;}*[Symbol.iterator](){for(const value of this.values_){yield value;}}
+has(value){if(typeof value!=='object')return this.values_.has(value);const json=JSON.stringify(value);for(const x of this){if(typeof x!=='object')continue;if(json===JSON.stringify(x))return true;}
 return false;}
-iterateElementDeeply(element,matches);return foundElements;}
-function findDeepElementMatching(element,selector){return findDeepElementMatchingPredicate(element,function(element){return element.matches(selector);});}
-function findDeepElementsMatching(element,selector){return findDeepElementsMatchingPredicate(element,function(element){return element.matches(selector);});}
-function findDeepElementWithTextContent(element,re){return findDeepElementMatchingPredicate(element,function(element){if(element.children.length!==0)
-return false;return re.test(element.textContent);});}
-return{iterateElementDeeply:iterateElementDeeply,findDeepElementMatching:findDeepElementMatching,findDeepElementsMatching:findDeepElementsMatching,findDeepElementMatchingPredicate:findDeepElementMatchingPredicate,findDeepElementsMatchingPredicate:findDeepElementsMatchingPredicate,findDeepElementWithTextContent:findDeepElementWithTextContent};});'use strict';tr.exportTo('tr.ui.b',function(){function getPolymerElementNamed(tagName){for(var i=0;i<Polymer.elements.length;i++){if(Polymer.elements[i].name===tagName)
-return Polymer.elements[i];}}
-function getPolymerElementsThatSubclass(tagName){if(Polymer.waitingFor().length){throw new Error('There are unresolved polymer elements. '+'Wait until Polymer.whenReady');}
-var baseElement;var elementNamesThatExtend={};Polymer.elements.forEach(function(element){if(element.name===tagName)
-baseElement=element;if(element.extends){if(elementNamesThatExtend[element.extends]===undefined)
-elementNamesThatExtend[element.extends]=[];elementNamesThatExtend[element.extends].push(element.name);}});if(!baseElement)
-throw new Error(tagName+' is not a polymer element');var allFoundSubElementNames=[baseElement.name];for(var i=0;i<allFoundSubElementNames.length;i++){var elementName=allFoundSubElementNames[i];allFoundSubElementNames.push.apply(allFoundSubElementNames,elementNamesThatExtend[elementName]);}
-allFoundSubElementNames.shift();return allFoundSubElementNames;}
-return{getPolymerElementNamed:getPolymerElementNamed,getPolymerElementsThatSubclass:getPolymerElementsThatSubclass};});'use strict';tr.exportTo('tr.v.ui',function(){function createScalarSpan(value,opt_config){if(value===undefined)
-return'';var config=opt_config||{};var ownerDocument=config.ownerDocument||document;var span=ownerDocument.createElement('tr-v-ui-scalar-span');var numericValue;if(value instanceof tr.v.ScalarNumeric){span.value=value;numericValue=value.value;}else{var unit=config.unit;if(unit===undefined){throw new Error('Unit must be provided in config when value is a number');}
-span.setValueAndUnit(value,unit);numericValue=value;}
-if(config.total)
-span.percentage=numericValue/config.total;if(config.rightAlign)
-span.rightAlign=true;return span;}
-tr.v.Unit.addEventListener('display-mode-changed',function(e){var scalarSpanTagName='tr-v-ui-scalar-span';var subclassNames=tr.ui.b.getPolymerElementsThatSubclass(scalarSpanTagName);subclassNames.push(scalarSpanTagName);var isSubclass={};subclassNames.forEach(function(n){isSubclass[n.toUpperCase()]=true;});var m=tr.b.findDeepElementsMatchingPredicate(document.body,function(el){return isSubclass[el.tagName];});m.forEach(function(el){el.updateContent_();});});return{createScalarSpan:createScalarSpan};});'use strict';Polymer('tr-v-ui-scalar-span',{ready:function(){this.value_=undefined;this.unit_=undefined;this.warning_=undefined;this.percentage_=undefined;},set contentTextDecoration(deco){this.$.content.style.textDecoration=deco;},get value(){return this.value_;},set value(value){if(value instanceof tr.v.ScalarNumeric){this.value_=value.value;this.unit_=value.unit;}else{this.value_=value;}
-this.updateContent_();},get unit(){return this.unit_;},set unit(unit){this.unit_=unit;this.updateContent_();},setValueAndUnit:function(value,unit){this.value_=value;this.unit_=unit;this.updateContent_();},get percentage(){return this.percentage_;},set percentage(percentage){this.percentage_=percentage;this.updateSparkline_();},get rightAlign(){return this.$.content.classList.contains('right-align');},set rightAlign(rightAlign){if(rightAlign)
-this.$.content.classList.add('right-align');else
-this.$.content.classList.remove('right-align');},updateSparkline_:function(){if(this.percentage_===undefined){this.$.sparkline.style.display='none';this.$.sparkline.style.width='0';}else{this.$.sparkline.style.display='block';this.$.sparkline.style.width=(this.percentage_*100)+'%';}},updateContent_:function(){if(this.unit_===undefined){this.$.content.textContent='';this.$.content.style.color='';return;}
-this.$.content.textContent=this.unit_.format(this.value);var BIGGER_IS_BETTER=tr.v.ImprovementDirection.BIGGER_IS_BETTER;var SMALLER_IS_BETTER=tr.v.ImprovementDirection.SMALLER_IS_BETTER;var color='';if(this.unit_.isDelta){var improvementDirection=this.unit_.improvementDirection;if(this.value>0){switch(improvementDirection){case BIGGER_IS_BETTER:color='green';break;case SMALLER_IS_BETTER:color='red';break;}}else if(this.value<0){switch(improvementDirection){case BIGGER_IS_BETTER:color='red';break;case SMALLER_IS_BETTER:color='green';break;}}}
-this.$.content.style.color=color;},get warning(){return this.warning_;},set warning(warning){this.warning_=warning;var warningEl=this.$.warning;if(this.warning_){warningEl.title=warning;warningEl.style.display='';}else{warningEl.title='';warningEl.style.display='none';}}});'use strict';function isTable(object){if(!(object instanceof Array)||(object.length<2))return false;for(var colName in object[0]){if(typeof colName!=='string')return false;}
-for(var i=0;i<object.length;++i){if(!(object[i]instanceof Object))return false;for(var colName in object[i]){if(i&&(object[0][colName]===undefined))return false;var cellType=typeof object[i][colName];if(cellType!=='string'&&cellType!='number')return false;}
-if(i){for(var colName in object[0]){if(object[i][colName]===undefined)return false;}}}
+equals(other){if(!(other instanceof GenericSet))return false;if(this.size!==other.size)return false;for(const value of this){if(!other.has(value))return false;}
 return true;}
-Polymer('tr-ui-a-generic-object-view',{ready:function(){this.object_=undefined;},get object(){return this.object_;},set object(object){this.object_=object;this.updateContents_();},updateContents_:function(){this.$.content.textContent='';this.appendElementsForType_('',this.object_,0,0,5,'');},appendElementsForType_:function(label,object,indent,depth,maxDepth,suffix){if(depth>maxDepth){this.appendSimpleText_(label,indent,'<recursion limit reached>',suffix);return;}
+get hashKey(){if(this.has_objects_)return undefined;if(this.hash_key_!==undefined){return this.hash_key_;}
+let key='';for(const value of Array.from(this.values_.values()).sort()){key+=value;}
+this.hash_key_=key;return key;}
+serialize(serializer){const i=[...this].map(x=>serializer.getOrAllocateId(x));return(i.length===1)?i[0]:i;}
+asDictInto_(d){d.values=Array.from(this);}
+static deserialize(data,deserializer){if(!(data instanceof Array)){data=[data];}
+return new GenericSet(data.map(datum=>deserializer.getObject(datum)));}
+static fromDict(d){return new GenericSet(d.values);}
+clone(){return new GenericSet(this.values_);}
+canAddDiagnostic(otherDiagnostic){return otherDiagnostic instanceof GenericSet;}
+addDiagnostic(otherDiagnostic){const jsons=new Set();for(const value of this){if(typeof value!=='object')continue;jsons.add(stableStringify(value));}
+for(const value of otherDiagnostic){if(typeof value==='object'){if(jsons.has(stableStringify(value))){continue;}
+this.has_objects_=true;}
+this.values_.add(value);}}}
+tr.v.d.Diagnostic.register(GenericSet,{elementName:'tr-v-ui-generic-set-span'});return{GenericSet,};});'use strict';tr.exportTo('tr.v.d',function(){class EventRef{constructor(event){this.stableId=event.stableId;this.title=event.title;this.start=event.start;this.duration=event.duration;this.end=this.start+this.duration;this.guid=tr.b.GUID.allocateSimple();}}
+return{EventRef,};});'use strict';tr.exportTo('tr.v.d',function(){class RelatedEventSet extends tr.v.d.Diagnostic{constructor(opt_events){super();this.eventsByStableId_=new Map();this.canonicalUrl_=undefined;if(opt_events){if(opt_events instanceof tr.model.EventSet||opt_events instanceof Array){for(const event of opt_events){this.add(event);}}else{this.add(opt_events);}}}
+clone(){const clone=new tr.v.d.CollectedRelatedEventSet();clone.addDiagnostic(this);return clone;}
+equals(other){if(this.length!==other.length)return false;for(const event of this){if(!other.has(event))return false;}
+return true;}
+add(event){this.eventsByStableId_.set(event.stableId,event);}
+has(event){return this.eventsByStableId_.has(event.stableId);}
+get length(){return this.eventsByStableId_.size;}*[Symbol.iterator](){for(const event of this.eventsByStableId_.values()){yield event;}}
+get canonicalUrl(){return this.canonicalUrl_;}
+resolve(model,opt_required){for(const[stableId,value]of this.eventsByStableId_){if(!(value instanceof tr.v.d.EventRef))continue;const event=model.getEventByStableId(stableId);if(event instanceof tr.model.Event){this.eventsByStableId_.set(stableId,event);}else if(opt_required){throw new Error('Unable to find Event '+stableId);}}}
+serialize(serializer){return[...this].map(event=>[event.stableId,serializer.getOrAllocateId(event.title),event.start,event.duration,]);}
+asDictInto_(d){d.events=[];for(const event of this){d.events.push({stableId:event.stableId,title:event.title,start:tr.b.Unit.byName.timeStampInMs.truncate(event.start),duration:tr.b.Unit.byName.timeDurationInMs.truncate(event.duration),});}}
+static deserialize(data,deserializer){return new RelatedEventSet(data.map(event=>new tr.v.d.EventRef({stableId:event[0],title:deserializer.getObject(event[1]),start:event[2],duration:event[3],})));}
+static fromDict(d){return new RelatedEventSet(d.events.map(event=>new tr.v.d.EventRef(event)));}}
+tr.v.d.Diagnostic.register(RelatedEventSet,{elementName:'tr-v-ui-related-event-set-span'});return{RelatedEventSet,};});'use strict';tr.exportTo('tr.v.d',function(){class RelatedNameMap extends tr.v.d.Diagnostic{constructor(opt_info){super();this.map_=new Map();if(opt_info){for(const[key,name]of Object.entries(opt_info)){this.set(key,name);}}}
+clone(){const clone=new RelatedNameMap();clone.addDiagnostic(this);return clone;}
+equals(other){if(!(other instanceof RelatedNameMap))return false;const keys1=new Set(this.map_.keys());const keys2=new Set(other.map_.keys());if(!tr.b.setsEqual(keys1,keys2))return false;for(const[key,name]of this){if(name!==other.get(key))return false;}
+return true;}
+canAddDiagnostic(otherDiagnostic){return otherDiagnostic instanceof RelatedNameMap;}
+addDiagnostic(otherDiagnostic){for(const[key,name]of otherDiagnostic){const existing=this.get(key);if(existing===undefined){this.set(key,name);}else if(existing!==name){throw new Error('Histogram names differ: '+`"${existing}" != "${name}"`);}}}
+serialize(serializer){const keys=[...this.map_.keys()];keys.sort();const names=keys.map(k=>serializer.getOrAllocateId(this.get(k)));const keysId=serializer.getOrAllocateId(keys.map(k=>serializer.getOrAllocateId(k)));return[keysId,...names];}
+asDictInto_(d){d.names={};for(const[key,name]of this)d.names[key]=name;}
+set(key,name){this.map_.set(key,name);}
+get(key){return this.map_.get(key);}*[Symbol.iterator](){for(const pair of this.map_)yield pair;}*values(){for(const value of this.map_.values())yield value;}
+static fromEntries(entries){const names=new RelatedNameMap();for(const[key,name]of entries){names.set(key,name);}
+return names;}
+static deserialize(data,deserializer){const names=new RelatedNameMap();const keys=deserializer.getObject(data[0]);for(let i=0;i<keys.length;++i){names.set(deserializer.getObject(keys[i]),deserializer.getObject(data[i+1]));}
+return names;}
+static fromDict(d){return RelatedNameMap.fromEntries(Object.entries(d.names||{}));}}
+tr.v.d.Diagnostic.register(RelatedNameMap,{elementName:'tr-v-ui-related-name-map-span',});return{RelatedNameMap,};});'use strict';tr.exportTo('tr.v.d',function(){class Scalar extends tr.v.d.Diagnostic{constructor(value){super();if(!(value instanceof tr.b.Scalar)){throw new Error('expected Scalar');}
+this.value=value;}
+clone(){return new Scalar(this.value);}
+serialize(serializer){return this.value.asDict();}
+asDictInto_(d){d.value=this.value.asDict();}
+static deserialize(value,deserializer){return Scalar.fromDict({value});}
+static fromDict(d){return new Scalar(tr.b.Scalar.fromDict(d.value));}}
+tr.v.d.Diagnostic.register(Scalar,{elementName:'tr-v-ui-scalar-diagnostic-span'});return{Scalar,};});'use strict';tr.exportTo('tr.v.d',function(){class UnmergeableDiagnosticSet extends tr.v.d.Diagnostic{constructor(diagnostics){super();this._diagnostics=diagnostics;}
+clone(){const clone=new tr.v.d.UnmergeableDiagnosticSet();clone.addDiagnostic(this);return clone;}
+canAddDiagnostic(otherDiagnostic){return true;}
+addDiagnostic(otherDiagnostic){if(otherDiagnostic instanceof UnmergeableDiagnosticSet){for(const subOtherDiagnostic of otherDiagnostic){const clone=subOtherDiagnostic.clone();this.addDiagnostic(clone);}
+return;}
+for(let i=0;i<this._diagnostics.length;++i){if(this._diagnostics[i].canAddDiagnostic(otherDiagnostic)){this._diagnostics[i].addDiagnostic(otherDiagnostic);return;}}
+const clone=otherDiagnostic.clone();this._diagnostics.push(clone);}
+get length(){return this._diagnostics.length;}*[Symbol.iterator](){for(const diagnostic of this._diagnostics)yield diagnostic;}
+asDictInto_(d){d.diagnostics=this._diagnostics.map(d=>d.asDictOrReference());}
+static deserialize(data,deserializer){return new UnmergeableDiagnosticSet(d.map(i=>deserializer.getDiagnostic(i).diagnostic));}
+serialize(serializer){return this._diagnostics.map(d=>serializer.getOrAllocateDiagnosticId('',d));}
+static fromDict(d){return new UnmergeableDiagnosticSet(d.diagnostics.map(d=>((typeof d==='string')?new tr.v.d.DiagnosticRef(d):tr.v.d.Diagnostic.fromDict(d))));}}
+tr.v.d.Diagnostic.register(UnmergeableDiagnosticSet,{elementName:'tr-v-ui-unmergeable-diagnostic-set-span'});return{UnmergeableDiagnosticSet,};});'use strict';tr.exportTo('tr.v.d',function(){const RESERVED_INFOS={ANGLE_REVISIONS:{name:'angleRevisions',type:tr.v.d.GenericSet},ARCHITECTURES:{name:'architectures',type:tr.v.d.GenericSet},BENCHMARKS:{name:'benchmarks',type:tr.v.d.GenericSet},BENCHMARK_START:{name:'benchmarkStart',type:tr.v.d.DateRange},BENCHMARK_DESCRIPTIONS:{name:'benchmarkDescriptions',type:tr.v.d.GenericSet},BOTS:{name:'bots',type:tr.v.d.GenericSet},BUG_COMPONENTS:{name:'bugComponents',type:tr.v.d.GenericSet},BUILDS:{name:'builds',type:tr.v.d.GenericSet},CATAPULT_REVISIONS:{name:'catapultRevisions',type:tr.v.d.GenericSet},CHROMIUM_COMMIT_POSITIONS:{name:'chromiumCommitPositions',type:tr.v.d.GenericSet},CHROMIUM_REVISIONS:{name:'chromiumRevisions',type:tr.v.d.GenericSet},DESCRIPTION:{name:'description',type:tr.v.d.GenericSet},DEVICE_IDS:{name:'deviceIds',type:tr.v.d.GenericSet},DOCUMENTATION_URLS:{name:'documentationUrls',type:tr.v.d.GenericSet},FUCHSIA_GARNET_REVISIONS:{name:'fuchsiaGarnetRevisions',type:tr.v.d.GenericSet},FUCHSIA_PERIDOT_REVISIONS:{name:'fuchsiaPeridotRevisions',type:tr.v.d.GenericSet},FUCHSIA_TOPAZ_REVISIONS:{name:'fuchsiaTopazRevisions',type:tr.v.d.GenericSet},FUCHSIA_ZIRCON_REVISIONS:{name:'fuchsiaZirconRevisions',type:tr.v.d.GenericSet},GPUS:{name:'gpus',type:tr.v.d.GenericSet},IS_REFERENCE_BUILD:{name:'isReferenceBuild',type:tr.v.d.GenericSet},LABELS:{name:'labels',type:tr.v.d.GenericSet},LOG_URLS:{name:'logUrls',type:tr.v.d.GenericSet},MASTERS:{name:'masters',type:tr.v.d.GenericSet},MEMORY_AMOUNTS:{name:'memoryAmounts',type:tr.v.d.GenericSet},OS_NAMES:{name:'osNames',type:tr.v.d.GenericSet},OS_VERSIONS:{name:'osVersions',type:tr.v.d.GenericSet},OWNERS:{name:'owners',type:tr.v.d.GenericSet},POINT_ID:{name:'pointId',type:tr.v.d.GenericSet},PRODUCT_VERSIONS:{name:'productVersions',type:tr.v.d.GenericSet},REVISION_TIMESTAMPS:{name:'revisionTimestamps',type:tr.v.d.DateRange},SKIA_REVISIONS:{name:'skiaRevisions',type:tr.v.d.GenericSet},STATISTICS_NAMES:{name:'statisticsNames',type:tr.v.d.GenericSet},STORIES:{name:'stories',type:tr.v.d.GenericSet},STORYSET_REPEATS:{name:'storysetRepeats',type:tr.v.d.GenericSet},STORY_TAGS:{name:'storyTags',type:tr.v.d.GenericSet},SUMMARY_KEYS:{name:'summaryKeys',type:tr.v.d.GenericSet},TEST_PATH:{name:'testPath',type:tr.v.d.GenericSet},TRACE_START:{name:'traceStart',type:tr.v.d.DateRange},TRACE_URLS:{name:'traceUrls',type:tr.v.d.GenericSet},V8_COMMIT_POSITIONS:{name:'v8CommitPositions',type:tr.v.d.DateRange},V8_REVISIONS:{name:'v8Revisions',type:tr.v.d.GenericSet},WEBRTC_REVISIONS:{name:'webrtcRevisions',type:tr.v.d.GenericSet},};const RESERVED_NAMES={};const RESERVED_NAMES_TO_TYPES=new Map();for(const[codename,info]of Object.entries(RESERVED_INFOS)){RESERVED_NAMES[codename]=info.name;if(RESERVED_NAMES_TO_TYPES.has(info.name)){throw new Error(`Duplicate reserved name "${info.name}"`);}
+RESERVED_NAMES_TO_TYPES.set(info.name,info.type);}
+const RESERVED_NAMES_SET=new Set(Object.values(RESERVED_NAMES));return{RESERVED_INFOS,RESERVED_NAMES,RESERVED_NAMES_SET,RESERVED_NAMES_TO_TYPES,};});'use strict';tr.exportTo('tr.v.d',function(){class DiagnosticMap extends Map{constructor(opt_allowReservedNames){super();if(opt_allowReservedNames===undefined){opt_allowReservedNames=true;}
+this.allowReservedNames_=opt_allowReservedNames;}
+set(name,diagnostic){if(typeof(name)!=='string'){throw new Error(`name must be string, not ${name}`);}
+if(!(diagnostic instanceof tr.v.d.Diagnostic)&&!(diagnostic instanceof tr.v.d.DiagnosticRef)){throw new Error(`Must be instanceof Diagnostic: ${diagnostic}`);}
+if(!this.allowReservedNames_&&tr.v.d.RESERVED_NAMES_SET.has(name)&&!(diagnostic instanceof tr.v.d.UnmergeableDiagnosticSet)&&!(diagnostic instanceof tr.v.d.DiagnosticRef)){const type=tr.v.d.RESERVED_NAMES_TO_TYPES.get(name);if(type&&!(diagnostic instanceof type)){throw new Error(`Diagnostics named "${name}" must be ${type.name}, `+`not ${diagnostic.constructor.name}`);}}
+Map.prototype.set.call(this,name,diagnostic);}
+delete(name){if(name===undefined)throw new Error('missing name');Map.prototype.delete.call(this,name);}
+deserializeAdd(data,deserializer){for(const id of data){const{name,diagnostic}=deserializer.getDiagnostic(id);this.set(name,diagnostic);}}
+addDicts(dict){for(const[name,diagnosticDict]of Object.entries(dict)){if(name==='tagmap')continue;if(typeof diagnosticDict==='string'){this.set(name,new tr.v.d.DiagnosticRef(diagnosticDict));}else if(diagnosticDict.type!=='RelatedHistogramMap'&&diagnosticDict.type!=='RelatedHistogramBreakdown'&&diagnosticDict.type!=='TagMap'){this.set(name,tr.v.d.Diagnostic.fromDict(diagnosticDict));}}}
+resolveSharedDiagnostics(histograms,opt_required){for(const[name,value]of this){if(!(value instanceof tr.v.d.DiagnosticRef)){continue;}
+const guid=value.guid;const diagnostic=histograms.lookupDiagnostic(guid);if(diagnostic instanceof tr.v.d.Diagnostic){this.set(name,diagnostic);}else if(opt_required){throw new Error('Unable to find shared Diagnostic '+guid);}}}
+serialize(serializer){const data=[];for(const[name,diagnostic]of this){data.push(serializer.getOrAllocateDiagnosticId(name,diagnostic));}
+return data;}
+asDict(){const dict={};for(const[name,diagnostic]of this){dict[name]=diagnostic.asDictOrReference();}
+return dict;}
+static deserialize(data,deserializer){const diagnostics=new DiagnosticMap();diagnostics.deserializeAdd(data,deserializer);return diagnostics;}
+static fromDict(d){const diagnostics=new DiagnosticMap();diagnostics.addDicts(d);return diagnostics;}
+static fromObject(obj){const diagnostics=new DiagnosticMap();if(!(obj instanceof Map))obj=Object.entries(obj);for(const[name,diagnostic]of obj){if(!diagnostic)continue;diagnostics.set(name,diagnostic);}
+return diagnostics;}
+addDiagnostics(other){for(const[name,otherDiagnostic]of other){const myDiagnostic=this.get(name);if(myDiagnostic!==undefined&&myDiagnostic.canAddDiagnostic(otherDiagnostic)){myDiagnostic.addDiagnostic(otherDiagnostic);continue;}
+const clone=otherDiagnostic.clone();if(myDiagnostic===undefined){this.set(name,clone);continue;}
+this.set(name,new tr.v.d.UnmergeableDiagnosticSet([myDiagnostic,clone]));}}}
+return{DiagnosticMap};});'use strict';tr.exportTo('tr.v',function(){const MAX_DIAGNOSTIC_MAPS=16;const DEFAULT_SAMPLE_VALUES_PER_BIN=10;const DEFAULT_REBINNED_COUNT=40;const DEFAULT_BOUNDARIES_FOR_UNIT=new Map();const DEFAULT_ITERATION_FOR_BOOTSTRAP_RESAMPLING=500;const DELTA=String.fromCharCode(916);const Z_SCORE_NAME='z-score';const P_VALUE_NAME='p-value';const U_STATISTIC_NAME='U';function percentToString(percent,opt_force3){if(percent<0||percent>1){throw new Error('percent must be in [0,1]');}
+if(percent===0)return'000';if(percent===1)return'100';let str=percent.toString();if(str[1]!=='.'){throw new Error('Unexpected percent');}
+str=str+'0'.repeat(Math.max(4-str.length,0));if(str.length>4){if(opt_force3){str=str.slice(0,4);}else{str=str.slice(0,4)+'_'+str.slice(4);}}
+return'0'+str.slice(2);}
+function percentFromString(s){return parseFloat(s[0]+'.'+s.substr(1).replace(/_/g,''));}
+class HistogramBin{constructor(range){this.range=range;this.count=0;this.diagnosticMaps=[];}
+addSample(value){this.count+=1;}
+addDiagnosticMap(diagnostics){tr.b.math.Statistics.uniformlySampleStream(this.diagnosticMaps,this.count,diagnostics,MAX_DIAGNOSTIC_MAPS);}
+addBin(other){if(!this.range.equals(other.range)){throw new Error('Merging incompatible Histogram bins.');}
+tr.b.math.Statistics.mergeSampledStreams(this.diagnosticMaps,this.count,other.diagnosticMaps,other.count,MAX_DIAGNOSTIC_MAPS);this.count+=other.count;}
+deserialize(data,deserializer){if(!(data instanceof Array)){this.count=data;return;}
+this.count=data[0];for(const sample of data.slice(1)){if(!(sample instanceof Array))continue;this.diagnosticMaps.push(tr.v.d.DiagnosticMap.deserialize(sample.slice(1),deserializer));}}
+fromDict(dict){this.count=dict[0];if(dict.length>1){for(const map of dict[1]){this.diagnosticMaps.push(tr.v.d.DiagnosticMap.fromDict(map));}}}
+serialize(serializer){if(!this.diagnosticMaps.length){return this.count;}
+return[this.count,...this.diagnosticMaps.map(d=>[undefined,...d.serialize(serializer)])];}
+asDict(){if(!this.diagnosticMaps.length){return[this.count];}
+return[this.count,this.diagnosticMaps.map(d=>d.asDict())];}}
+const DEFAULT_SUMMARY_OPTIONS=new Map([['avg',true],['count',true],['geometricMean',false],['max',true],['min',true],['nans',false],['std',true],['sum',true],]);class Histogram{constructor(name,unit,opt_binBoundaries){if(!(unit instanceof tr.b.Unit)){throw new Error('unit must be a Unit: '+unit);}
+let binBoundaries=opt_binBoundaries;if(!binBoundaries){const baseUnit=unit.baseUnit?unit.baseUnit:unit;binBoundaries=DEFAULT_BOUNDARIES_FOR_UNIT.get(baseUnit.unitName);}
+this.binBoundariesDict_=binBoundaries.asDict();this.allBins=binBoundaries.bins.slice();this.description='';const allowReservedNames=false;this.diagnostics_=new tr.v.d.DiagnosticMap(allowReservedNames);this.maxNumSampleValues_=this.defaultMaxNumSampleValues_;this.name_=name;this.nanDiagnosticMaps=[];this.numNans=0;this.running_=undefined;this.sampleValues_=[];this.sampleMeans_=[];this.summaryOptions=new Map(DEFAULT_SUMMARY_OPTIONS);this.summaryOptions.set('percentile',[]);this.summaryOptions.set('iprs',[]);this.summaryOptions.set('ci',[]);this.unit=unit;}
+static create(name,unit,samples,opt_options){const options=opt_options||{};const hist=new Histogram(name,unit,options.binBoundaries);if(options.description)hist.description=options.description;if(options.summaryOptions){let summaryOptions=options.summaryOptions;if(!(summaryOptions instanceof Map)){summaryOptions=Object.entries(summaryOptions);}
+for(const[name,value]of summaryOptions){hist.summaryOptions.set(name,value);}}
+if(options.diagnostics!==undefined){let diagnostics=options.diagnostics;if(!(diagnostics instanceof Map)){diagnostics=Object.entries(diagnostics);}
+for(const[name,diagnostic]of diagnostics){if(!diagnostic)continue;hist.diagnostics.set(name,diagnostic);}}
+if(!(samples instanceof Array))samples=[samples];for(const sample of samples){if(typeof sample==='object'){hist.addSample(sample.value,sample.diagnostics);}else{hist.addSample(sample);}}
+return hist;}
+get diagnostics(){return this.diagnostics_;}
+get running(){return this.running_;}
+get maxNumSampleValues(){return this.maxNumSampleValues_;}
+set maxNumSampleValues(n){this.maxNumSampleValues_=n;tr.b.math.Statistics.uniformlySampleArray(this.sampleValues_,this.maxNumSampleValues_);}
+get name(){return this.name_;}
+deserializeStatistics_(){const statisticsNames=this.diagnostics.get(tr.v.d.RESERVED_NAMES.STATISTICS_NAMES);if(!statisticsNames)return;for(const statName of statisticsNames){if(statName.startsWith('pct_')){const percent=percentFromString(statName.substr(4));this.summaryOptions.get('percentile').push(percent);}else if(statName.startsWith('ipr_')){const lower=percentFromString(statName.substr(4,3));const upper=percentFromString(statName.substr(8));this.summaryOptions.get('iprs').push(tr.b.math.Range.fromExplicitRange(lower,upper));}else if(statName.startsWith('ci_')){const percent=percentFromString(statName.replace('_lower','').replace('_upper','').substr(3));if(!this.summaryOptions.get('ci').includes(percent)){this.summaryOptions.get('ci').push(percent);}}}
+for(const statName of this.summaryOptions.keys()){if(statName==='percentile'||statName==='iprs'||statName==='ci'){continue;}
+this.summaryOptions.set(statName,statisticsNames.has(statName));}}
+deserializeBin_(i,bin,deserializer){this.allBins[i]=new HistogramBin(this.allBins[i].range);this.allBins[i].deserialize(bin,deserializer);if(!(bin instanceof Array))return;for(let sample of bin.slice(1)){if(sample instanceof Array){sample=sample[0];}
+this.sampleValues_.push(sample);}}
+deserializeBins_(bins,deserializer){if(bins instanceof Array){for(let i=0;i<bins.length;++i){this.deserializeBin_(i,bins[i],deserializer);}}else{for(const[i,binData]of Object.entries(bins)){this.deserializeBin_(i,binData,deserializer);}}}
+static deserialize(data,deserializer){const[name,unit,boundaries,diagnostics,running,bins,nanBin]=data;const hist=new Histogram(deserializer.getObject(name),tr.b.Unit.fromJSON(unit),HistogramBinBoundaries.fromDict(deserializer.getObject(boundaries)));hist.diagnostics.deserializeAdd(diagnostics,deserializer);const description=hist.diagnostics.get(tr.v.d.RESERVED_NAMES.DESCRIPTION);if(description&&description.length){hist.description=[...description][0];}
+hist.deserializeStatistics_();if(running){hist.running_=tr.b.math.RunningStatistics.fromDict(running);}
+if(bins){hist.deserializeBins_(bins,deserializer);}
+if(nanBin){if(!(nanBin instanceof Array)){hist.numNans=nanBin;}else{hist.numNans=nanBin[0];for(const sample of nanBin.slice(1)){if(!(sample instanceof Array))continue;hist.nanDiagnosticMaps.push(tr.v.d.DiagnosticMap.deserialize(sample.slice(1),deserializer));}}}
+return hist;}
+static fromDict(dict){const hist=new Histogram(dict.name,tr.b.Unit.fromJSON(dict.unit),HistogramBinBoundaries.fromDict(dict.binBoundaries));if(dict.description){hist.description=dict.description;}
+if(dict.diagnostics){hist.diagnostics.addDicts(dict.diagnostics);}
+if(dict.allBins){if(dict.allBins.length!==undefined){for(let i=0;i<dict.allBins.length;++i){hist.allBins[i]=new HistogramBin(hist.allBins[i].range);hist.allBins[i].fromDict(dict.allBins[i]);}}else{for(const[i,binDict]of Object.entries(dict.allBins)){if(i>=hist.allBins.length||i<0){throw new Error('Invalid index "'+i+'" out of bounds of [0..'+hist.allBins.length+')');}
+hist.allBins[i]=new HistogramBin(hist.allBins[i].range);hist.allBins[i].fromDict(binDict);}}}
+if(dict.running){hist.running_=tr.b.math.RunningStatistics.fromDict(dict.running);}
+if(dict.summaryOptions){if(dict.summaryOptions.iprs){dict.summaryOptions.iprs=dict.summaryOptions.iprs.map(r=>tr.b.math.Range.fromExplicitRange(r[0],r[1]));}
+hist.customizeSummaryOptions(dict.summaryOptions);}
+if(dict.maxNumSampleValues!==undefined){hist.maxNumSampleValues=dict.maxNumSampleValues;}
+if(dict.sampleValues){hist.sampleValues_=dict.sampleValues;}
+if(dict.numNans){hist.numNans=dict.numNans;}
+if(dict.nanDiagnostics){for(const map of dict.nanDiagnostics){hist.nanDiagnosticMaps.push(tr.v.d.DiagnosticMap.fromDict(map));}}
+return hist;}
+get numValues(){return this.running_?this.running_.count:0;}
+get average(){return this.running_?this.running_.mean:undefined;}
+get standardDeviation(){return this.running_?this.running_.stddev:undefined;}
+get geometricMean(){return this.running_?this.running_.geometricMean:0;}
+get sum(){return this.running_?this.running_.sum:0;}
+get min(){return this.running_?this.running_.min:Infinity;}
+get max(){return this.running_?this.running_.max:-Infinity;}
+getDifferenceSignificance(other,opt_alpha){if(this.unit!==other.unit){throw new Error('Cannot compare Histograms with different units');}
+if(this.unit.improvementDirection===tr.b.ImprovementDirection.DONT_CARE){return tr.b.math.Statistics.Significance.DONT_CARE;}
+if(!(other instanceof Histogram)){throw new Error('Unable to compute a p-value');}
+const testResult=tr.b.math.Statistics.mwu(this.sampleValues,other.sampleValues,opt_alpha);return testResult.significance;}
+getApproximatePercentile(percent){if(percent<0||percent>1){throw new Error('percent must be in [0,1]');}
+if(this.numValues===0)return undefined;if(this.allBins.length===1){const sortedSampleValues=this.sampleValues.slice().sort((x,y)=>x-y);return sortedSampleValues[Math.floor((sortedSampleValues.length-1)*percent)];}
+let valuesToSkip=Math.floor((this.numValues-1)*percent);for(const bin of this.allBins){valuesToSkip-=bin.count;if(valuesToSkip>=0)continue;if(bin.range.min===-Number.MAX_VALUE){return bin.range.max;}
+if(bin.range.max===Number.MAX_VALUE){return bin.range.min;}
+return bin.range.center;}
+return this.allBins[this.allBins.length-1].range.min;}
+getBinIndexForValue(value){const i=tr.b.findFirstTrueIndexInSortedArray(this.allBins,b=>value<b.range.max);if(0<=i&&i<this.allBins.length)return i;return this.allBins.length-1;}
+getBinForValue(value){return this.allBins[this.getBinIndexForValue(value)];}
+addSample(value,opt_diagnostics){if(opt_diagnostics){if(!(opt_diagnostics instanceof tr.v.d.DiagnosticMap)){opt_diagnostics=tr.v.d.DiagnosticMap.fromObject(opt_diagnostics);}
+for(const[name,diag]of opt_diagnostics){if(diag instanceof tr.v.d.Breakdown){diag.truncate(this.unit);}}}
+if(typeof(value)!=='number'||isNaN(value)){this.numNans++;if(opt_diagnostics){tr.b.math.Statistics.uniformlySampleStream(this.nanDiagnosticMaps,this.numNans,opt_diagnostics,MAX_DIAGNOSTIC_MAPS);}}else{if(this.running_===undefined){this.running_=new tr.b.math.RunningStatistics();}
+this.sampleMeans_=[];this.running_.add(value);value=this.unit.truncate(value);const binIndex=this.getBinIndexForValue(value);let bin=this.allBins[binIndex];if(bin.count===0){bin=new HistogramBin(bin.range);this.allBins[binIndex]=bin;}
+bin.addSample(value);if(opt_diagnostics){bin.addDiagnosticMap(opt_diagnostics);}}
+tr.b.math.Statistics.uniformlySampleStream(this.sampleValues_,this.numValues+this.numNans,value,this.maxNumSampleValues);}
+resampleMean_(percent){const filteredSamples=this.sampleValues_.filter(value=>typeof(value)==='number'&&!isNaN(value));const sampleCount=filteredSamples.length;if(sampleCount===0||percent<=0.0||percent>=1.0){return[undefined,undefined];}else if(sampleCount===1){return[filteredSamples[0],filteredSamples[0]];}
+const iterations=DEFAULT_ITERATION_FOR_BOOTSTRAP_RESAMPLING;if(this.sampleMeans_.length!==iterations){this.sampleMeans_=[];for(let i=0;i<iterations;i++){let tempSum=0.0;for(let j=0;j<sampleCount;j++){tempSum+=filteredSamples[Math.floor(Math.random()*sampleCount)];}
+this.sampleMeans_.push(tempSum/sampleCount);}
+this.sampleMeans_.sort((a,b)=>a-b);}
+return[this.sampleMeans_[Math.floor((iterations-1)*(0.5-percent/2))],this.sampleMeans_[Math.ceil((iterations-1)*(0.5+percent/2))],];}
+sampleValuesInto(samples){for(const sampleValue of this.sampleValues){samples.push(sampleValue);}}
+canAddHistogram(other){if(this.unit!==other.unit){return false;}
+if(this.binBoundariesDict_===other.binBoundariesDict_){return true;}
+if(!this.binBoundariesDict_||!other.binBoundariesDict_){return true;}
+if(this.binBoundariesDict_.length!==other.binBoundariesDict_.length){return false;}
+for(let i=0;i<this.binBoundariesDict_.length;++i){const slice=this.binBoundariesDict_[i];const otherSlice=other.binBoundariesDict_[i];if(slice instanceof Array){if(!(otherSlice instanceof Array)){return false;}
+if(slice[0]!==otherSlice[0]||!tr.b.math.approximately(slice[1],otherSlice[1])||slice[2]!==otherSlice[2]){return false;}}else{if(otherSlice instanceof Array){return false;}
+if(!tr.b.math.approximately(slice,otherSlice)){return false;}}}
+return true;}
+addHistogram(other){if(!this.canAddHistogram(other)){throw new Error('Merging incompatible Histograms');}
+if(!!this.binBoundariesDict_===!!other.binBoundariesDict_){for(let i=0;i<this.allBins.length;++i){let bin=this.allBins[i];if(bin.count===0){bin=new HistogramBin(bin.range);this.allBins[i]=bin;}
+bin.addBin(other.allBins[i]);}}else{const[multiBin,singleBin]=this.binBoundariesDict_?[this,other]:[other,this];for(const value of singleBin.sampleValues){if(typeof(value)!=='number'||isNaN(value)){continue;}
+const binIndex=multiBin.getBinIndexForValue(value);let bin=multiBin.allBins[binIndex];if(bin.count===0){bin=new HistogramBin(bin.range);multiBin.allBins[binIndex]=bin;}
+bin.addSample(value);}}
+tr.b.math.Statistics.mergeSampledStreams(this.nanDiagnosticMaps,this.numNans,other.nanDiagnosticMaps,other.numNans,MAX_DIAGNOSTIC_MAPS);tr.b.math.Statistics.mergeSampledStreams(this.sampleValues,this.numValues+this.numNans,other.sampleValues,other.numValues+other.numNans,(this.maxNumSampleValues+other.maxNumSampleValues)/2);this.numNans+=other.numNans;if(other.running_!==undefined){if(this.running_===undefined){this.running_=new tr.b.math.RunningStatistics();}
+this.running_=this.running_.merge(other.running_);}
+this.sampleMeans_=[];this.diagnostics.addDiagnostics(other.diagnostics);for(const[stat,option]of other.summaryOptions){if(stat==='percentile'){const percentiles=this.summaryOptions.get(stat);for(const percent of option){if(!percentiles.includes(percent))percentiles.push(percent);}}else if(stat==='iprs'){const thisIprs=this.summaryOptions.get(stat);for(const ipr of option){let found=false;for(const thisIpr of thisIprs){found=ipr.equals(thisIpr);if(found)break;}
+if(!found)thisIprs.push(ipr);}}else if(stat==='ci'){const CIs=this.summaryOptions.get(stat);for(const CI of option){if(!CIs.includes(CI))CIs.push(CI);}}else if(option&&!this.summaryOptions.get(stat)){this.summaryOptions.set(stat,true);}}}
+customizeSummaryOptions(summaryOptions){for(const[key,value]of Object.entries(summaryOptions)){this.summaryOptions.set(key,value);}}
+getStatisticScalar(statName,opt_referenceHistogram,opt_mwu){if(statName==='avg'){if(typeof(this.average)!=='number')return undefined;return new tr.b.Scalar(this.unit,this.average);}
+if(statName==='std'){if(typeof(this.standardDeviation)!=='number')return undefined;return new tr.b.Scalar(this.unit,this.standardDeviation);}
+if(statName==='geometricMean'){if(typeof(this.geometricMean)!=='number')return undefined;return new tr.b.Scalar(this.unit,this.geometricMean);}
+if(statName==='min'||statName==='max'||statName==='sum'){if(this.running_===undefined){this.running_=new tr.b.math.RunningStatistics();}
+if(typeof(this.running_[statName])!=='number')return undefined;return new tr.b.Scalar(this.unit,this.running_[statName]);}
+if(statName==='nans'){return new tr.b.Scalar(tr.b.Unit.byName.count_smallerIsBetter,this.numNans);}
+if(statName==='count'){return new tr.b.Scalar(tr.b.Unit.byName.count_smallerIsBetter,this.numValues);}
+if(statName.substr(0,4)==='pct_'){if(this.numValues===0)return undefined;const percent=percentFromString(statName.substr(4));const percentile=this.getApproximatePercentile(percent);if(typeof(percentile)!=='number')return undefined;return new tr.b.Scalar(this.unit,percentile);}
+if(statName.substr(0,3)==='ci_'){const percent=percentFromString(statName.substr(3,3));const[lowCI,highCI]=this.resampleMean_(percent);if(statName.substr(7)==='lower'){if(typeof(lowCI)!=='number')return undefined;return new tr.b.Scalar(this.unit,lowCI);}else if(statName.substr(7)==='upper'){if(typeof(highCI)!=='number')return undefined;return new tr.b.Scalar(this.unit,highCI);}
+if(typeof(highCI)!=='number'||typeof(lowCI)!=='number'){return undefined;}
+return new tr.b.Scalar(this.unit,highCI-lowCI);}
+if(statName.substr(0,4)==='ipr_'){let lower=percentFromString(statName.substr(4,3));let upper=percentFromString(statName.substr(8));if(lower>=upper){throw new Error('Invalid inter-percentile range: '+statName);}
+lower=this.getApproximatePercentile(lower);upper=this.getApproximatePercentile(upper);const ipr=upper-lower;if(typeof(ipr)!=='number')return undefined;return new tr.b.Scalar(this.unit,ipr);}
+if(!this.canCompare(opt_referenceHistogram)){throw new Error('Cannot compute '+statName+' when histograms are not comparable');}
+const suffix=tr.b.Unit.nameSuffixForImprovementDirection(this.unit.improvementDirection);const deltaIndex=statName.indexOf(DELTA);if(deltaIndex>=0){const baseStatName=statName.substr(deltaIndex+1);const thisStat=this.getStatisticScalar(baseStatName);const otherStat=opt_referenceHistogram.getStatisticScalar(baseStatName);const deltaValue=thisStat.value-otherStat.value;if(statName[0]==='%'){return new tr.b.Scalar(tr.b.Unit.byName['normalizedPercentageDelta'+suffix],deltaValue/otherStat.value);}
+return new tr.b.Scalar(thisStat.unit.correspondingDeltaUnit,deltaValue);}
+if(statName===Z_SCORE_NAME){return new tr.b.Scalar(tr.b.Unit.byName['sigmaDelta'+suffix],(this.average-opt_referenceHistogram.average)/opt_referenceHistogram.standardDeviation);}
+const mwu=opt_mwu||tr.b.math.Statistics.mwu(this.sampleValues,opt_referenceHistogram.sampleValues);if(statName===P_VALUE_NAME){return new tr.b.Scalar(tr.b.Unit.byName.unitlessNumber,mwu.p);}
+if(statName===U_STATISTIC_NAME){return new tr.b.Scalar(tr.b.Unit.byName.unitlessNumber,mwu.U);}
+throw new Error('Unrecognized statistic name: '+statName);}
+get statisticsNames(){const statisticsNames=new Set();for(const[statName,option]of this.summaryOptions){if(statName==='percentile'){for(const pctile of option){statisticsNames.add('pct_'+tr.v.percentToString(pctile));}}else if(statName==='iprs'){for(const range of option){statisticsNames.add('ipr_'+tr.v.percentToString(range.min,true)+'_'+tr.v.percentToString(range.max,true));}}else if(statName==='ci'){for(const CIpctile of option){const CIpctStr=tr.v.percentToString(CIpctile);statisticsNames.add('ci_'+CIpctStr+'_lower');statisticsNames.add('ci_'+CIpctStr+'_upper');statisticsNames.add('ci_'+CIpctStr);}}else if(option){statisticsNames.add(statName);}}
+return statisticsNames;}
+canCompare(other){return other instanceof Histogram&&this.unit===other.unit&&this.numValues>0&&other.numValues>0;}
+getAvailableStatisticName(statName,opt_referenceHist){if(this.canCompare(opt_referenceHist))return statName;if(statName===Z_SCORE_NAME||statName===P_VALUE_NAME||statName===U_STATISTIC_NAME){return'avg';}
+const deltaIndex=statName.indexOf(DELTA);if(deltaIndex<0)return statName;return statName.substr(deltaIndex+1);}
+static getDeltaStatisticsNames(statNames){const deltaNames=[];for(const statName of statNames){deltaNames.push(`${DELTA}${statName}`);deltaNames.push(`%${DELTA}${statName}`);}
+return deltaNames.concat([Z_SCORE_NAME,P_VALUE_NAME,U_STATISTIC_NAME]);}
+get statisticsScalars(){const results=new Map();for(const statName of this.statisticsNames){const scalar=this.getStatisticScalar(statName);if(scalar===undefined)continue;results.set(statName,scalar);}
+return results;}
+get sampleValues(){return this.sampleValues_;}
+clone(){const binBoundaries=HistogramBinBoundaries.fromDict(this.binBoundariesDict_);const hist=new Histogram(this.name,this.unit,binBoundaries);for(const[stat,option]of this.summaryOptions){if(stat==='percentile'||stat==='iprs'||stat==='ci'){hist.summaryOptions.set(stat,Array.from(option));}else{hist.summaryOptions.set(stat,option);}}
+hist.addHistogram(this);return hist;}
+rebin(newBoundaries){const rebinned=new tr.v.Histogram(this.name,this.unit,newBoundaries);rebinned.description=this.description;for(const sample of this.sampleValues){rebinned.addSample(sample);}
+rebinned.running_=this.running_;for(const[name,diagnostic]of this.diagnostics){rebinned.diagnostics.set(name,diagnostic);}
+for(const[stat,option]of this.summaryOptions){if(stat==='percentile'||stat==='ci'){rebinned.summaryOptions.set(stat,Array.from(option));}else{rebinned.summaryOptions.set(stat,option);}}
+return rebinned;}
+serialize(serializer){let nanBin=this.numNans;if(this.nanDiagnosticMaps.length){nanBin=[nanBin,...this.nanDiagnosticMaps.map(dm=>[undefined,...dm.serialize(serializer)])];}
+this.diagnostics.set(tr.v.d.RESERVED_NAMES.STATISTICS_NAMES,new tr.v.d.GenericSet([...this.statisticsNames].sort()));this.diagnostics.set(tr.v.d.RESERVED_NAMES.DESCRIPTION,new tr.v.d.GenericSet([this.description].sort()));return[serializer.getOrAllocateId(this.name),this.unit.asJSON2(),serializer.getOrAllocateId(this.binBoundariesDict_),this.diagnostics.serialize(serializer),this.running_?this.running_.asDict():0,this.serializeBins_(serializer),nanBin,];}
+asDict(){const dict={};dict.name=this.name;dict.unit=this.unit.asJSON();if(this.binBoundariesDict_!==undefined){dict.binBoundaries=this.binBoundariesDict_;}
+if(this.description){dict.description=this.description;}
+if(this.diagnostics.size){dict.diagnostics=this.diagnostics.asDict();}
+if(this.maxNumSampleValues!==this.defaultMaxNumSampleValues_){dict.maxNumSampleValues=this.maxNumSampleValues;}
+if(this.numNans){dict.numNans=this.numNans;}
+if(this.nanDiagnosticMaps.length){dict.nanDiagnostics=this.nanDiagnosticMaps.map(dm=>dm.asDict());}
+if(this.numValues){dict.sampleValues=this.sampleValues.slice();this.running.truncate(this.unit);dict.running=this.running_.asDict();dict.allBins=this.allBinsAsDict_();}
+const summaryOptions={};let anyOverriddenSummaryOptions=false;for(const[name,value]of this.summaryOptions){let option;if(name==='percentile'){if(value.length===0)continue;option=Array.from(value);}else if(name==='iprs'){if(value.length===0)continue;option=value.map(r=>[r.min,r.max]);}else if(name==='ci'){if(value.length===0)continue;option=Array.from(value);}else if(value===DEFAULT_SUMMARY_OPTIONS.get(name)){continue;}else{option=value;}
+summaryOptions[name]=option;anyOverriddenSummaryOptions=true;}
+if(anyOverriddenSummaryOptions){dict.summaryOptions=summaryOptions;}
+return dict;}
+serializeBins_(serializer){const numBins=this.allBins.length;let emptyBins=0;for(let i=0;i<numBins;++i){if(this.allBins[i].count===0){++emptyBins;}}
+if(emptyBins===numBins){return 0;}
+if(emptyBins>(numBins/2)){const allBinsDict={};for(let i=0;i<numBins;++i){const bin=this.allBins[i];if(bin.count>0){allBinsDict[i]=bin.serialize(serializer);}}
+return allBinsDict;}
+const allBinsArray=[];for(let i=0;i<numBins;++i){allBinsArray.push(this.allBins[i].serialize(serializer));}
+return allBinsArray;}
+allBinsAsDict_(){const numBins=this.allBins.length;let emptyBins=0;for(let i=0;i<numBins;++i){if(this.allBins[i].count===0){++emptyBins;}}
+if(emptyBins===numBins){return undefined;}
+if(emptyBins>(numBins/2)){const allBinsDict={};for(let i=0;i<numBins;++i){const bin=this.allBins[i];if(bin.count>0){allBinsDict[i]=bin.asDict();}}
+return allBinsDict;}
+const allBinsArray=[];for(let i=0;i<numBins;++i){allBinsArray.push(this.allBins[i].asDict());}
+return allBinsArray;}
+get defaultMaxNumSampleValues_(){return DEFAULT_SAMPLE_VALUES_PER_BIN*Math.max(this.allBins.length,DEFAULT_REBINNED_COUNT);}}
+Histogram.AVERAGE_ONLY_SUMMARY_OPTIONS={count:false,max:false,min:false,std:false,sum:false,};const HISTOGRAM_BIN_BOUNDARIES_CACHE=new Map();class HistogramBinBoundaries{static createLinear(min,max,numBins){return new HistogramBinBoundaries(min).addLinearBins(max,numBins);}
+static createExponential(min,max,numBins){return new HistogramBinBoundaries(min).addExponentialBins(max,numBins);}
+static createWithBoundaries(binBoundaries){const builder=new HistogramBinBoundaries(binBoundaries[0]);for(const boundary of binBoundaries.slice(1)){builder.addBinBoundary(boundary);}
+return builder;}
+constructor(minBinBoundary){this.builder_=[minBinBoundary];this.range_=new tr.b.math.Range();this.range_.addValue(minBinBoundary);this.binRanges_=undefined;this.bins_=undefined;}
+get range(){return this.range_;}
+asDict(){if(this.builder_.length===1&&this.builder_[0]===Number.MAX_VALUE){return undefined;}
+return this.builder_;}
+pushBuilderSlice_(slice){this.builder_.push(slice);this.builder_=this.builder_.slice();}
+static fromDict(dict){if(dict===undefined){return HistogramBinBoundaries.SINGULAR;}
+const cacheKey=JSON.stringify(dict);if(HISTOGRAM_BIN_BOUNDARIES_CACHE.has(cacheKey)){return HISTOGRAM_BIN_BOUNDARIES_CACHE.get(cacheKey);}
+const binBoundaries=new HistogramBinBoundaries(dict[0]);for(const slice of dict.slice(1)){if(!(slice instanceof Array)){binBoundaries.addBinBoundary(slice);continue;}
+switch(slice[0]){case HistogramBinBoundaries.SLICE_TYPE.LINEAR:binBoundaries.addLinearBins(slice[1],slice[2]);break;case HistogramBinBoundaries.SLICE_TYPE.EXPONENTIAL:binBoundaries.addExponentialBins(slice[1],slice[2]);break;default:throw new Error('Unrecognized HistogramBinBoundaries slice type');}}
+HISTOGRAM_BIN_BOUNDARIES_CACHE.set(cacheKey,binBoundaries);return binBoundaries;}
+get bins(){if(this.bins_===undefined){this.buildBins_();}
+return this.bins_;}
+buildBins_(){this.bins_=this.binRanges.map(r=>new HistogramBin(r));}
+get binRanges(){if(this.binRanges_===undefined){this.buildBinRanges_();}
+return this.binRanges_;}
+buildBinRanges_(){if(typeof this.builder_[0]!=='number'){throw new Error('Invalid start of builder_');}
+this.binRanges_=[];let prevBoundary=this.builder_[0];if(prevBoundary>-Number.MAX_VALUE){this.binRanges_.push(tr.b.math.Range.fromExplicitRange(-Number.MAX_VALUE,prevBoundary));}
+for(const slice of this.builder_.slice(1)){if(!(slice instanceof Array)){this.binRanges_.push(tr.b.math.Range.fromExplicitRange(prevBoundary,slice));prevBoundary=slice;continue;}
+const nextMaxBinBoundary=slice[1];const binCount=slice[2];const sliceMinBinBoundary=prevBoundary;switch(slice[0]){case HistogramBinBoundaries.SLICE_TYPE.LINEAR:{const binWidth=(nextMaxBinBoundary-prevBoundary)/binCount;for(let i=1;i<binCount;i++){const boundary=sliceMinBinBoundary+i*binWidth;this.binRanges_.push(tr.b.math.Range.fromExplicitRange(prevBoundary,boundary));prevBoundary=boundary;}
+break;}
+case HistogramBinBoundaries.SLICE_TYPE.EXPONENTIAL:{const binExponentWidth=Math.log(nextMaxBinBoundary/prevBoundary)/binCount;for(let i=1;i<binCount;i++){const boundary=sliceMinBinBoundary*Math.exp(i*binExponentWidth);this.binRanges_.push(tr.b.math.Range.fromExplicitRange(prevBoundary,boundary));prevBoundary=boundary;}
+break;}
+default:throw new Error('Unrecognized HistogramBinBoundaries slice type');}
+this.binRanges_.push(tr.b.math.Range.fromExplicitRange(prevBoundary,nextMaxBinBoundary));prevBoundary=nextMaxBinBoundary;}
+if(prevBoundary<Number.MAX_VALUE){this.binRanges_.push(tr.b.math.Range.fromExplicitRange(prevBoundary,Number.MAX_VALUE));}}
+addBinBoundary(nextMaxBinBoundary){if(nextMaxBinBoundary<=this.range.max){throw new Error('The added max bin boundary must be larger than '+'the current max boundary');}
+this.binRanges_=undefined;this.bins_=undefined;this.pushBuilderSlice_(nextMaxBinBoundary);this.range.addValue(nextMaxBinBoundary);return this;}
+addLinearBins(nextMaxBinBoundary,binCount){if(binCount<=0){throw new Error('Bin count must be positive');}
+if(nextMaxBinBoundary<=this.range.max){throw new Error('The new max bin boundary must be greater than '+'the previous max bin boundary');}
+this.binRanges_=undefined;this.bins_=undefined;this.pushBuilderSlice_([HistogramBinBoundaries.SLICE_TYPE.LINEAR,nextMaxBinBoundary,binCount]);this.range.addValue(nextMaxBinBoundary);return this;}
+addExponentialBins(nextMaxBinBoundary,binCount){if(binCount<=0){throw new Error('Bin count must be positive');}
+if(this.range.max<=0){throw new Error('Current max bin boundary must be positive');}
+if(this.range.max>=nextMaxBinBoundary){throw new Error('The last added max boundary must be greater than '+'the current max boundary boundary');}
+this.binRanges_=undefined;this.bins_=undefined;this.pushBuilderSlice_([HistogramBinBoundaries.SLICE_TYPE.EXPONENTIAL,nextMaxBinBoundary,binCount]);this.range.addValue(nextMaxBinBoundary);return this;}}
+HistogramBinBoundaries.SLICE_TYPE={LINEAR:0,EXPONENTIAL:1,};HistogramBinBoundaries.SINGULAR=new HistogramBinBoundaries(Number.MAX_VALUE);DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.timeDurationInMs.unitName,HistogramBinBoundaries.createExponential(1e-3,1e6,1e2));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.timeInMsAutoFormat.unitName,new HistogramBinBoundaries(0).addBinBoundary(1).addExponentialBins(1e3,3).addBinBoundary(tr.b.convertUnit(2,tr.b.UnitScale.TIME.SEC,tr.b.UnitScale.TIME.MILLI_SEC)).addBinBoundary(tr.b.convertUnit(5,tr.b.UnitScale.TIME.SEC,tr.b.UnitScale.TIME.MILLI_SEC)).addBinBoundary(tr.b.convertUnit(10,tr.b.UnitScale.TIME.SEC,tr.b.UnitScale.TIME.MILLI_SEC)).addBinBoundary(tr.b.convertUnit(30,tr.b.UnitScale.TIME.SEC,tr.b.UnitScale.TIME.MILLI_SEC)).addBinBoundary(tr.b.convertUnit(tr.b.UnitScale.TIME.MINUTE.value,tr.b.UnitScale.TIME.SEC,tr.b.UnitScale.TIME.MILLI_SEC)).addBinBoundary(2*tr.b.convertUnit(tr.b.UnitScale.TIME.MINUTE.value,tr.b.UnitScale.TIME.SEC,tr.b.UnitScale.TIME.MILLI_SEC)).addBinBoundary(5*tr.b.convertUnit(tr.b.UnitScale.TIME.MINUTE.value,tr.b.UnitScale.TIME.SEC,tr.b.UnitScale.TIME.MILLI_SEC)).addBinBoundary(10*tr.b.convertUnit(tr.b.UnitScale.TIME.MINUTE.value,tr.b.UnitScale.TIME.SEC,tr.b.UnitScale.TIME.MILLI_SEC)).addBinBoundary(30*tr.b.convertUnit(tr.b.UnitScale.TIME.MINUTE.value,tr.b.UnitScale.TIME.SEC,tr.b.UnitScale.TIME.MILLI_SEC)).addBinBoundary(tr.b.convertUnit(tr.b.UnitScale.TIME.HOUR.value,tr.b.UnitScale.TIME.SEC,tr.b.UnitScale.TIME.MILLI_SEC)).addBinBoundary(2*tr.b.convertUnit(tr.b.UnitScale.TIME.HOUR.value,tr.b.UnitScale.TIME.SEC,tr.b.UnitScale.TIME.MILLI_SEC)).addBinBoundary(6*tr.b.convertUnit(tr.b.UnitScale.TIME.HOUR.value,tr.b.UnitScale.TIME.SEC,tr.b.UnitScale.TIME.MILLI_SEC)).addBinBoundary(12*tr.b.convertUnit(tr.b.UnitScale.TIME.HOUR.value,tr.b.UnitScale.TIME.SEC,tr.b.UnitScale.TIME.MILLI_SEC)).addBinBoundary(tr.b.convertUnit(tr.b.UnitScale.TIME.DAY.value,tr.b.UnitScale.TIME.SEC,tr.b.UnitScale.TIME.MILLI_SEC)).addBinBoundary(tr.b.convertUnit(tr.b.UnitScale.TIME.WEEK.value,tr.b.UnitScale.TIME.SEC,tr.b.UnitScale.TIME.MILLI_SEC)).addBinBoundary(tr.b.convertUnit(tr.b.UnitScale.TIME.MONTH.value,tr.b.UnitScale.TIME.SEC,tr.b.UnitScale.TIME.MILLI_SEC)).addBinBoundary(tr.b.convertUnit(tr.b.UnitScale.TIME.YEAR.value,tr.b.UnitScale.TIME.SEC,tr.b.UnitScale.TIME.MILLI_SEC)));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.timeStampInMs.unitName,HistogramBinBoundaries.createLinear(0,1e10,1e3));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.normalizedPercentage.unitName,HistogramBinBoundaries.createLinear(0,1.0,20));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.sizeInBytes.unitName,HistogramBinBoundaries.createExponential(1,1e12,1e2));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.energyInJoules.unitName,HistogramBinBoundaries.createExponential(1e-3,1e3,50));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.powerInWatts.unitName,HistogramBinBoundaries.createExponential(1e-3,1,50));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.unitlessNumber.unitName,HistogramBinBoundaries.createExponential(1e-3,1e3,50));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.count.unitName,HistogramBinBoundaries.createExponential(1,1e3,20));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.sigma.unitName,HistogramBinBoundaries.createLinear(-5,5,50));return{DEFAULT_REBINNED_COUNT,DELTA,Histogram,HistogramBinBoundaries,P_VALUE_NAME,U_STATISTIC_NAME,Z_SCORE_NAME,percentFromString,percentToString,};});'use strict';tr.exportTo('tr.v.ui',function(){Polymer({is:'tr-v-ui-scalar-context-controller',created(){this.host_=undefined;this.groupToContext_=new Map();this.dirtyGroups_=new Set();},attached(){if(this.host_){throw new Error('Scalar context controller is already attached to a host');}
+const host=findParentOrHost(this);if(host.__scalarContextController){throw new Error('Multiple scalar context controllers attached to this host');}
+host.__scalarContextController=this;this.host_=host;},detached(){if(!this.host_){throw new Error('Scalar context controller is not attached to a host');}
+if(this.host_.__scalarContextController!==this){throw new Error('Scalar context controller is not attached to its host');}
+delete this.host_.__scalarContextController;this.host_=undefined;},getContext(group){return this.groupToContext_.get(group);},onScalarSpanAdded(group,span){let context=this.groupToContext_.get(group);if(context===undefined){context={spans:new Set(),range:new tr.b.math.Range()};this.groupToContext_.set(group,context);}
+if(context.spans.has(span)){throw new Error('Scalar span already registered with group: '+group);}
+context.spans.add(span);this.markGroupDirtyAndScheduleUpdate_(group);},onScalarSpanRemoved(group,span){const context=this.groupToContext_.get(group);if(!context.spans.has(span)){throw new Error('Scalar span not registered with group: '+group);}
+context.spans.delete(span);this.markGroupDirtyAndScheduleUpdate_(group);},onScalarSpanUpdated(group,span){const context=this.groupToContext_.get(group);if(!context.spans.has(span)){throw new Error('Scalar span not registered with group: '+group);}
+this.markGroupDirtyAndScheduleUpdate_(group);},markGroupDirtyAndScheduleUpdate_(group){const alreadyDirty=this.dirtyGroups_.size>0;this.dirtyGroups_.add(group);if(!alreadyDirty){tr.b.requestAnimationFrameInThisFrameIfPossible(this.updateContext,this);}},updateContext(){const groups=this.dirtyGroups_;if(groups.size===0)return;this.dirtyGroups_=new Set();for(const group of groups){this.updateGroup_(group);}
+const event=new tr.b.Event('context-updated');event.groups=groups;this.dispatchEvent(event);},updateGroup_(group){const context=this.groupToContext_.get(group);if(context.spans.size===0){this.groupToContext_.delete(group);return;}
+context.range.reset();for(const span of context.spans){context.range.addValue(span.value);}}});function getScalarContextControllerForElement(element){while(element){if(element.__scalarContextController){return element.__scalarContextController;}
+element=findParentOrHost(element);}
+return undefined;}
+function findParentOrHost(node){if(node.parentElement){return node.parentElement;}
+while(Polymer.dom(node).parentNode){node=Polymer.dom(node).parentNode;}
+return node.host;}
+return{getScalarContextControllerForElement,};});'use strict';tr.exportTo('tr.v.ui',function(){function createScalarSpan(value,opt_config){if(value===undefined)return'';const config=opt_config||{};const ownerDocument=config.ownerDocument||document;const span=ownerDocument.createElement('tr-v-ui-scalar-span');let numericValue;if(value instanceof tr.b.Scalar){span.value=value;numericValue=value.value;}else if(value instanceof tr.v.Histogram){numericValue=value.average;if(numericValue===undefined)return'';span.setValueAndUnit(numericValue,value.unit);}else{const unit=config.unit;if(unit===undefined){throw new Error('Unit must be provided in config when value is a number');}
+span.setValueAndUnit(value,unit);numericValue=value;}
+if(config.context){span.context=config.context;}
+if(config.customContextRange){span.customContextRange=config.customContextRange;}
+if(config.leftAlign){span.leftAlign=true;}
+if(config.inline){span.inline=true;}
+if(config.significance!==undefined){span.significance=config.significance;}
+if(config.contextGroup!==undefined){span.contextGroup=config.contextGroup;}
+return span;}
+return{createScalarSpan,};});'use strict';Polymer({is:'tr-v-ui-scalar-span',properties:{contextGroup:{type:String,reflectToAttribute:true,observer:'contextGroupChanged_'}},created(){this.value_=undefined;this.unit_=undefined;this.context_=undefined;this.warning_=undefined;this.significance_=tr.b.math.Statistics.Significance.DONT_CARE;this.shouldSearchForContextController_=false;this.lazyContextController_=undefined;this.onContextUpdated_=this.onContextUpdated_.bind(this);this.updateContents_=this.updateContents_.bind(this);this.customContextRange_=undefined;},get significance(){return this.significance_;},set significance(s){this.significance_=s;this.updateContents_();},set contentTextDecoration(deco){this.$.content.style.textDecoration=deco;},get value(){return this.value_;},set value(value){if(value instanceof tr.b.Scalar){this.value_=value.value;this.unit_=value.unit;}else{this.value_=value;}
+this.updateContents_();if(this.hasContext_(this.contextGroup)){this.contextController_.onScalarSpanUpdated(this.contextGroup,this);}else{this.updateSparkline_();}},get contextController_(){if(this.shouldSearchForContextController_){this.lazyContextController_=tr.v.ui.getScalarContextControllerForElement(this);this.shouldSearchForContextController_=false;}
+return this.lazyContextController_;},hasContext_(contextGroup){return!!(contextGroup&&this.contextController_);},contextGroupChanged_(newContextGroup,oldContextGroup){this.detachFromContextControllerIfPossible_(oldContextGroup);if(!this.attachToContextControllerIfPossible_(newContextGroup)){this.onContextUpdated_();}},attachToContextControllerIfPossible_(contextGroup){if(!this.hasContext_(contextGroup))return false;this.contextController_.addEventListener('context-updated',this.onContextUpdated_);this.contextController_.onScalarSpanAdded(contextGroup,this);return true;},detachFromContextControllerIfPossible_(contextGroup){if(!this.hasContext_(contextGroup))return;this.contextController_.removeEventListener('context-updated',this.onContextUpdated_);this.contextController_.onScalarSpanRemoved(contextGroup,this);},attached(){tr.b.Unit.addEventListener('display-mode-changed',this.updateContents_);this.shouldSearchForContextController_=true;this.attachToContextControllerIfPossible_(this.contextGroup);},detached(){tr.b.Unit.removeEventListener('display-mode-changed',this.updateContents_);this.detachFromContextControllerIfPossible_(this.contextGroup);this.shouldSearchForContextController_=false;this.lazyContextController_=undefined;},onContextUpdated_(){this.updateSparkline_();},get context(){return this.context_;},set context(context){this.context_=context;this.updateContents_();},get unit(){return this.unit_;},set unit(unit){this.unit_=unit;this.updateContents_();this.updateSparkline_();},setValueAndUnit(value,unit){this.value_=value;this.unit_=unit;this.updateContents_();},get customContextRange(){return this.customContextRange_;},set customContextRange(customContextRange){this.customContextRange_=customContextRange;this.updateSparkline_();},get inline(){return Polymer.dom(this).classList.contains('inline');},set inline(inline){if(inline){Polymer.dom(this).classList.add('inline');}else{Polymer.dom(this).classList.remove('inline');}},get leftAlign(){return Polymer.dom(this).classList.contains('left-align');},set leftAlign(leftAlign){if(leftAlign){Polymer.dom(this).classList.add('left-align');}else{Polymer.dom(this).classList.remove('left-align');}},updateSparkline_(){Polymer.dom(this.$.sparkline).classList.remove('positive');Polymer.dom(this.$.sparkline).classList.remove('better');Polymer.dom(this.$.sparkline).classList.remove('worse');Polymer.dom(this.$.sparkline).classList.remove('same');this.$.sparkline.style.display='none';this.$.sparkline.style.left='0';this.$.sparkline.style.width='0';let range=this.customContextRange_;if(!range&&this.hasContext_(this.contextGroup)){const context=this.contextController_.getContext(this.contextGroup);if(context){range=context.range;}}
+if(!range||range.isEmpty)return;const leftPoint=Math.min(range.min,0);const rightPoint=Math.max(range.max,0);const pointDistance=rightPoint-leftPoint;if(pointDistance===0){return;}
+this.$.sparkline.style.display='block';let left;let width;if(this.value>0){width=Math.min(this.value,rightPoint);left=-leftPoint;Polymer.dom(this.$.sparkline).classList.add('positive');}else if(this.value<=0){width=-Math.max(this.value,leftPoint);left=(-leftPoint)-width;}
+this.$.sparkline.style.left=this.buildSparklineStyle_(left/pointDistance,false);this.$.sparkline.style.width=this.buildSparklineStyle_(width/pointDistance,true);const changeClass=this.changeClassName_;if(changeClass){Polymer.dom(this.$.sparkline).classList.add(changeClass);}},buildSparklineStyle_(ratio,isWidth){let position='calc('+ratio+' * (100% - 1px)';if(isWidth){position+=' + 1px';}
+position+=')';return position;},updateContents_(){Polymer.dom(this.$.content).textContent='';Polymer.dom(this.$.content).classList.remove('better');Polymer.dom(this.$.content).classList.remove('worse');Polymer.dom(this.$.content).classList.remove('same');this.$.insignificant.style.display='';this.$.significantly_better.style.display='';this.$.significantly_worse.style.display='';if(this.unit_===undefined)return;this.$.content.title='';Polymer.dom(this.$.content).textContent=this.unit_.format(this.value,this.context);this.updateDelta_();},updateDelta_(){let changeClass=this.changeClassName_;if(!changeClass){this.$.significance.style.display='none';return;}
+this.$.significance.style.display='inline';let title;switch(changeClass){case'better':title='improvement';break;case'worse':title='regression';break;case'same':title='no change';break;default:throw new Error('Unknown change class: '+changeClass);}
+Polymer.dom(this.$.content).classList.add(changeClass);switch(this.significance){case tr.b.math.Statistics.Significance.DONT_CARE:break;case tr.b.math.Statistics.Significance.INSIGNIFICANT:if(changeClass!=='same')title='insignificant '+title;this.$.insignificant.style.display='inline';changeClass='same';break;case tr.b.math.Statistics.Significance.SIGNIFICANT:if(changeClass==='same'){throw new Error('How can no change be significant?');}
+this.$['significantly_'+changeClass].style.display='inline';title='significant '+title;break;default:throw new Error('Unknown significance '+this.significance);}
+this.$.significance.title=title;this.$.content.title=title;},get changeClassName_(){if(!this.unit_||!this.unit_.isDelta)return undefined;switch(this.unit_.improvementDirection){case tr.b.ImprovementDirection.DONT_CARE:return undefined;case tr.b.ImprovementDirection.BIGGER_IS_BETTER:if(this.value===0)return'same';return this.value>0?'better':'worse';case tr.b.ImprovementDirection.SMALLER_IS_BETTER:if(this.value===0)return'same';return this.value<0?'better':'worse';default:throw new Error('Unknown improvement direction: '+
+this.unit_.improvementDirection);}},get warning(){return this.warning_;},set warning(warning){this.warning_=warning;const warningEl=this.$.warning;if(this.warning_){warningEl.title=warning;warningEl.style.display='inline';}else{warningEl.title='';warningEl.style.display='';}},get timestamp(){return this.value;},set timestamp(timestamp){if(timestamp instanceof tr.b.u.TimeStamp){this.value=timestamp;return;}
+this.setValueAndUnit(timestamp,tr.b.u.Units.timeStampInMs);},get duration(){return this.value;},set duration(duration){if(duration instanceof tr.b.u.TimeDuration){this.value=duration;return;}
+this.setValueAndUnit(duration,tr.b.u.Units.timeDurationInMs);}});'use strict';function isTable(object){if(!(object instanceof Array)||(object.length<2))return false;for(const colName in object[0]){if(typeof colName!=='string')return false;}
+for(let i=0;i<object.length;++i){if(!(object[i]instanceof Object))return false;for(const colName in object[i]){if(i&&(object[0][colName]===undefined))return false;const cellType=typeof object[i][colName];if(cellType!=='string'&&cellType!=='number')return false;}
+if(i){for(const colName in object[0]){if(object[i][colName]===undefined)return false;}}}
+return true;}
+Polymer({is:'tr-ui-a-generic-object-view',ready(){this.object_=undefined;},get object(){return this.object_;},set object(object){this.object_=object;this.updateContents_();},updateContents_(){Polymer.dom(this.$.content).textContent='';this.appendElementsForType_('',this.object_,0,0,5,'');},appendElementsForType_(label,object,indent,depth,maxDepth,suffix){if(depth>maxDepth){this.appendSimpleText_(label,indent,'<recursion limit reached>',suffix);return;}
 if(object===undefined){this.appendSimpleText_(label,indent,'undefined',suffix);return;}
 if(object===null){this.appendSimpleText_(label,indent,'null',suffix);return;}
-if(!(object instanceof Object)){var type=typeof object;if(type=='string'){var objectReplaced=false;if((object[0]=='{'&&object[object.length-1]=='}')||(object[0]=='['&&object[object.length-1]==']')){try{object=JSON.parse(object);objectReplaced=true;}catch(e){}}
-if(!objectReplaced){if(object.indexOf('\n')!==-1){var lines=object.split('\n');lines.forEach(function(line,i){var text,ioff,ll,ss;if(i==0){text='"'+line;ioff=0;ll=label;ss='';}else if(i<lines.length-1){text=line;ioff=1;ll='';ss='';}else{text=line+'"';ioff=1;ll='';ss=suffix;}
-var el=this.appendSimpleText_(ll,indent+ioff*label.length+ioff,text,ss);el.style.whiteSpace='pre';return el;},this);return;}else{this.appendSimpleText_(label,indent,'"'+object+'"',suffix);return;}}
-else{}}else{return this.appendSimpleText_(label,indent,object,suffix);}}
-if(object instanceof tr.model.ObjectSnapshot){var link=document.createElement('tr-ui-a-analysis-link');link.selection=new tr.model.EventSet(object);this.appendElementWithLabel_(label,indent,link,suffix);return;}
-if(object instanceof tr.model.ObjectInstance){var link=document.createElement('tr-ui-a-analysis-link');link.selection=new tr.model.EventSet(object);this.appendElementWithLabel_(label,indent,link,suffix);return;}
-if(object instanceof tr.b.Rect){this.appendSimpleText_(label,indent,object.toString(),suffix);return;}
-if(object instanceof tr.v.ScalarNumeric){var el=this.ownerDocument.createElement('tr-v-ui-scalar-span');el.value=object;this.appendElementWithLabel_(label,indent,el,suffix);return;}
+if(!(object instanceof Object)){const type=typeof object;if(type!=='string'){return this.appendSimpleText_(label,indent,object,suffix);}
+let objectReplaced=false;if((object[0]==='{'&&object[object.length-1]==='}')||(object[0]==='['&&object[object.length-1]===']')){try{object=JSON.parse(object);objectReplaced=true;}catch(e){}}
+if(!objectReplaced){if(object.includes('\n')){const lines=object.split('\n');lines.forEach(function(line,i){let text;let ioff;let ll;let ss;if(i===0){text='"'+line;ioff=0;ll=label;ss='';}else if(i<lines.length-1){text=line;ioff=1;ll='';ss='';}else{text=line+'"';ioff=1;ll='';ss=suffix;}
+const el=this.appendSimpleText_(ll,indent+ioff*label.length+ioff,text,ss);el.style.whiteSpace='pre';return el;},this);return;}
+if(tr.b.isUrl(object)){const link=document.createElement('a');link.href=object;link.textContent=object;this.appendElementWithLabel_(label,indent,link,suffix);return;}
+this.appendSimpleText_(label,indent,'"'+object+'"',suffix);return;}}
+if(object instanceof tr.model.ObjectSnapshot){const link=document.createElement('tr-ui-a-analysis-link');link.selection=new tr.model.EventSet(object);this.appendElementWithLabel_(label,indent,link,suffix);return;}
+if(object instanceof tr.model.ObjectInstance){const link=document.createElement('tr-ui-a-analysis-link');link.selection=new tr.model.EventSet(object);this.appendElementWithLabel_(label,indent,link,suffix);return;}
+if(object instanceof tr.b.math.Rect){this.appendSimpleText_(label,indent,object.toString(),suffix);return;}
+if(object instanceof tr.b.Scalar){const el=this.ownerDocument.createElement('tr-v-ui-scalar-span');el.value=object;el.inline=true;this.appendElementWithLabel_(label,indent,el,suffix);return;}
 if(object instanceof Array){this.appendElementsForArray_(label,object,indent,depth,maxDepth,suffix);return;}
-this.appendElementsForObject_(label,object,indent,depth,maxDepth,suffix);},appendElementsForArray_:function(label,object,indent,depth,maxDepth,suffix){if(object.length==0){this.appendSimpleText_(label,indent,'[]',suffix);return;}
-if(isTable(object)){var table=document.createElement('tr-ui-b-table');var columns=[];tr.b.iterItems(object[0],function(colName){columns.push({title:colName,value:function(row){return row[colName];}});});table.tableColumns=columns;table.tableRows=object;this.appendElementWithLabel_(label,indent,table,suffix);table.rebuild();return;}
-this.appendElementsForType_(label+'[',object[0],indent,depth+1,maxDepth,object.length>1?',':']'+suffix);for(var i=1;i<object.length;i++){this.appendElementsForType_('',object[i],indent+label.length+1,depth+1,maxDepth,i<object.length-1?',':']'+suffix);}
-return;},appendElementsForObject_:function(label,object,indent,depth,maxDepth,suffix){var keys=tr.b.dictionaryKeys(object);if(keys.length==0){this.appendSimpleText_(label,indent,'{}',suffix);return;}
-this.appendElementsForType_(label+'{'+keys[0]+': ',object[keys[0]],indent,depth,maxDepth,keys.length>1?',':'}'+suffix);for(var i=1;i<keys.length;i++){this.appendElementsForType_(keys[i]+': ',object[keys[i]],indent+label.length+1,depth+1,maxDepth,i<keys.length-1?',':'}'+suffix);}},appendElementWithLabel_:function(label,indent,dataElement,suffix){var row=document.createElement('div');var indentSpan=document.createElement('span');indentSpan.style.whiteSpace='pre';for(var i=0;i<indent;i++)
-indentSpan.textContent+=' ';row.appendChild(indentSpan);var labelSpan=document.createElement('span');labelSpan.textContent=label;row.appendChild(labelSpan);row.appendChild(dataElement);var suffixSpan=document.createElement('span');suffixSpan.textContent=suffix;row.appendChild(suffixSpan);row.dataElement=dataElement;this.$.content.appendChild(row);},appendSimpleText_:function(label,indent,text,suffix){var el=this.ownerDocument.createElement('span');el.textContent=text;this.appendElementWithLabel_(label,indent,el,suffix);return el;}});'use strict';Polymer('tr-ui-a-generic-object-view-with-label',{ready:function(){this.labelEl_=document.createElement('div');this.genericObjectView_=document.createElement('tr-ui-a-generic-object-view');this.shadowRoot.appendChild(this.labelEl_);this.shadowRoot.appendChild(this.genericObjectView_);},get label(){return this.labelEl_.textContent;},set label(label){this.labelEl_.textContent=label;},get object(){return this.genericObjectView_.object;},set object(object){this.genericObjectView_.object=object;}});'use strict';tr.exportTo('tr.ui.analysis',function(){var ObjectSnapshotView=tr.ui.b.define('object-snapshot-view');ObjectSnapshotView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.objectSnapshot_=undefined;},get requiresTallView(){return true;},set modelEvent(obj){this.objectSnapshot=obj;},get modelEvent(){return this.objectSnapshot;},get objectSnapshot(){return this.objectSnapshot_;},set objectSnapshot(i){this.objectSnapshot_=i;this.updateContents();},updateContents:function(){throw new Error('Not implemented');}};var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectSnapshotView;options.defaultMetadata={showInstances:true,showInTrackView:true};tr.b.decorateExtensionRegistry(ObjectSnapshotView,options);return{ObjectSnapshotView:ObjectSnapshotView};});'use strict';Polymer('tr-ui-b-drag-handle',{__proto__:HTMLDivElement.prototype,created:function(){this.lastMousePos_=0;this.onMouseMove_=this.onMouseMove_.bind(this);this.onMouseUp_=this.onMouseUp_.bind(this);this.addEventListener('mousedown',this.onMouseDown_);this.target_=undefined;this.horizontal=true;this.observer_=new WebKitMutationObserver(this.didTargetMutate_.bind(this));this.targetSizesByModeKey_={};},get modeKey_(){return this.target_.className==''?'.':this.target_.className;},get target(){return this.target_;},set target(target){this.observer_.disconnect();this.target_=target;if(!this.target_)
-return;this.observer_.observe(this.target_,{attributes:true,attributeFilter:['class']});},get horizontal(){return this.horizontal_;},set horizontal(h){this.horizontal_=h;if(this.horizontal_)
-this.className='horizontal-drag-handle';else
-this.className='vertical-drag-handle';},get vertical(){return!this.horizontal_;},set vertical(v){this.horizontal=!v;},forceMutationObserverFlush_:function(){var records=this.observer_.takeRecords();if(records.length)
-this.didTargetMutate_(records);},didTargetMutate_:function(e){var modeSize=this.targetSizesByModeKey_[this.modeKey_];if(modeSize!==undefined){this.setTargetSize_(modeSize);return;}
-this.target_.style[this.targetStyleKey_]='';},get targetStyleKey_(){return this.horizontal_?'height':'width';},getTargetSize_:function(){var targetStyleKey=this.targetStyleKey_;if(!this.target_.style[targetStyleKey]){this.target_.style[targetStyleKey]=window.getComputedStyle(this.target_)[targetStyleKey];}
-var size=parseInt(this.target_.style[targetStyleKey]);this.targetSizesByModeKey_[this.modeKey_]=size;return size;},setTargetSize_:function(s){this.target_.style[this.targetStyleKey_]=s+'px';this.targetSizesByModeKey_[this.modeKey_]=s;},applyDelta_:function(delta){var curSize=this.getTargetSize_();var newSize;if(this.target_===this.nextElementSibling){newSize=curSize+delta;}else{newSize=curSize-delta;}
-this.setTargetSize_(newSize);},onMouseMove_:function(e){var curMousePos=this.horizontal_?e.clientY:e.clientX;var delta=this.lastMousePos_-curMousePos;this.applyDelta_(delta);this.lastMousePos_=curMousePos;e.preventDefault();return true;},onMouseDown_:function(e){if(!this.target_)
-return;this.forceMutationObserverFlush_();this.lastMousePos_=this.horizontal_?e.clientY:e.clientX;document.addEventListener('mousemove',this.onMouseMove_);document.addEventListener('mouseup',this.onMouseUp_);e.preventDefault();return true;},onMouseUp_:function(e){document.removeEventListener('mousemove',this.onMouseMove_);document.removeEventListener('mouseup',this.onMouseUp_);e.preventDefault();}});'use strict';tr.exportTo('tr.ui.b',function(){function HotKey(dict){if(dict.eventType===undefined)
-throw new Error('eventType must be given');if(dict.keyCode===undefined&&dict.keyCodes===undefined)
-throw new Error('keyCode or keyCodes must be given');if(dict.keyCode!==undefined&&dict.keyCodes!==undefined)
-throw new Error('Only keyCode or keyCodes can be given');if(dict.callback===undefined)
-throw new Error('callback must be given');this.eventType_=dict.eventType;this.keyCodes_=[];if(dict.keyCode)
-this.pushKeyCode_(dict.keyCode);else if(dict.keyCodes){dict.keyCodes.forEach(this.pushKeyCode_,this);}
+this.appendElementsForObject_(label,object,indent,depth,maxDepth,suffix);},appendElementsForArray_(label,object,indent,depth,maxDepth,suffix){if(object.length===0){this.appendSimpleText_(label,indent,'[]',suffix);return;}
+if(isTable(object)){const table=document.createElement('tr-ui-b-table');const columns=[];for(const colName of Object.keys(object[0])){let allStrings=true;let allNumbers=true;for(let i=0;i<object.length;++i){if(typeof(object[i][colName])!=='string'){allStrings=false;}
+if(typeof(object[i][colName])!=='number'){allNumbers=false;}
+if(!allStrings&&!allNumbers)break;}
+const column={title:colName};column.value=function(row){return row[colName];};if(allStrings){column.cmp=function(x,y){return x[colName].localeCompare(y[colName]);};}else if(allNumbers){column.cmp=function(x,y){return x[colName]-y[colName];};}
+columns.push(column);}
+table.tableColumns=columns;table.tableRows=object;this.appendElementWithLabel_(label,indent,table,suffix);table.rebuild();return;}
+this.appendElementsForType_(label+'[',object[0],indent,depth+1,maxDepth,object.length>1?',':']'+suffix);for(let i=1;i<object.length;i++){this.appendElementsForType_('',object[i],indent+label.length+1,depth+1,maxDepth,i<object.length-1?',':']'+suffix);}
+return;},appendElementsForObject_(label,object,indent,depth,maxDepth,suffix){const keys=Object.keys(object);if(keys.length===0){this.appendSimpleText_(label,indent,'{}',suffix);return;}
+this.appendElementsForType_(label+'{'+keys[0]+': ',object[keys[0]],indent,depth,maxDepth,keys.length>1?',':'}'+suffix);for(let i=1;i<keys.length;i++){this.appendElementsForType_(keys[i]+': ',object[keys[i]],indent+label.length+1,depth+1,maxDepth,i<keys.length-1?',':'}'+suffix);}},appendElementWithLabel_(label,indent,dataElement,suffix){const row=document.createElement('div');const indentSpan=document.createElement('span');indentSpan.style.whiteSpace='pre';for(let i=0;i<indent;i++){Polymer.dom(indentSpan).textContent+=' ';}
+Polymer.dom(row).appendChild(indentSpan);const labelSpan=document.createElement('span');Polymer.dom(labelSpan).textContent=label;Polymer.dom(row).appendChild(labelSpan);Polymer.dom(row).appendChild(dataElement);const suffixSpan=document.createElement('span');Polymer.dom(suffixSpan).textContent=suffix;Polymer.dom(row).appendChild(suffixSpan);row.dataElement=dataElement;Polymer.dom(this.$.content).appendChild(row);},appendSimpleText_(label,indent,text,suffix){const el=this.ownerDocument.createElement('span');Polymer.dom(el).textContent=text;this.appendElementWithLabel_(label,indent,el,suffix);return el;}});'use strict';Polymer({is:'tr-ui-a-generic-object-view-with-label',ready(){this.labelEl_=document.createElement('div');this.genericObjectView_=document.createElement('tr-ui-a-generic-object-view');Polymer.dom(this.root).appendChild(this.labelEl_);Polymer.dom(this.root).appendChild(this.genericObjectView_);},get label(){return Polymer.dom(this.labelEl_).textContent;},set label(label){Polymer.dom(this.labelEl_).textContent=label;},get object(){return this.genericObjectView_.object;},set object(object){this.genericObjectView_.object=object;}});'use strict';tr.exportTo('tr.ui.analysis',function(){const ObjectSnapshotView=tr.ui.b.define('object-snapshot-view');ObjectSnapshotView.prototype={__proto__:HTMLDivElement.prototype,decorate(){this.objectSnapshot_=undefined;},get requiresTallView(){return true;},set modelEvent(obj){this.objectSnapshot=obj;},get modelEvent(){return this.objectSnapshot;},get objectSnapshot(){return this.objectSnapshot_;},set objectSnapshot(i){this.objectSnapshot_=i;this.updateContents();},updateContents(){throw new Error('Not implemented');}};const options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectSnapshotView;options.defaultMetadata={showInstances:true,showInTrackView:true};tr.b.decorateExtensionRegistry(ObjectSnapshotView,options);return{ObjectSnapshotView,};});'use strict';Polymer({is:'tr-ui-b-drag-handle',created(){this.lastMousePos_=0;this.onMouseMove_=this.onMouseMove_.bind(this);this.onMouseUp_=this.onMouseUp_.bind(this);this.addEventListener('mousedown',this.onMouseDown_);this.target_=undefined;this.horizontal=true;this.observer_=new WebKitMutationObserver(this.didTargetMutate_.bind(this));this.targetSizesByModeKey_={};this.currentDraggingSize_=undefined;},get modeKey_(){return this.target_.className===''?'.':this.target_.className;},get target(){return this.target_;},set target(target){this.observer_.disconnect();this.target_=target;if(!this.target_)return;this.observer_.observe(this.target_,{attributes:true,attributeFilter:['class']});},get horizontal(){return this.horizontal_;},set horizontal(h){this.horizontal_=h;if(this.horizontal_){this.className='horizontal-drag-handle';}else{this.className='vertical-drag-handle';}},get vertical(){return!this.horizontal_;},set vertical(v){this.horizontal=!v;},forceMutationObserverFlush_(){const records=this.observer_.takeRecords();if(records.length){this.didTargetMutate_(records);}},didTargetMutate_(e){const modeSize=this.targetSizesByModeKey_[this.modeKey_];if(modeSize!==undefined){this.setTargetSize_(modeSize);return;}
+this.target_.style[this.targetStyleKey_]='';},get targetStyleKey_(){return this.horizontal_?'height':'width';},getTargetSize_(){const size=parseInt(window.getComputedStyle(this.target_)[this.targetStyleKey_]);this.targetSizesByModeKey_[this.modeKey_]=size;return size;},setTargetSize_(s){this.target_.style[this.targetStyleKey_]=s+'px';this.targetSizesByModeKey_[this.modeKey_]=this.getTargetSize_();tr.b.dispatchSimpleEvent(this,'drag-handle-resize',true,false);},applyDelta_(delta){if(this.target_===this.nextElementSibling){this.currentDraggingSize_+=delta;}else{this.currentDraggingSize_-=delta;}
+this.setTargetSize_(this.currentDraggingSize_);},onMouseMove_(e){const curMousePos=this.horizontal_?e.clientY:e.clientX;const delta=this.lastMousePos_-curMousePos;this.applyDelta_(delta);this.lastMousePos_=curMousePos;e.preventDefault();return true;},onMouseDown_(e){if(!this.target_)return;this.forceMutationObserverFlush_();this.currentDraggingSize_=this.getTargetSize_();this.lastMousePos_=this.horizontal_?e.clientY:e.clientX;document.addEventListener('mousemove',this.onMouseMove_);document.addEventListener('mouseup',this.onMouseUp_);e.preventDefault();return true;},onMouseUp_(e){document.removeEventListener('mousemove',this.onMouseMove_);document.removeEventListener('mouseup',this.onMouseUp_);e.preventDefault();this.currentDraggingSize_=undefined;}});'use strict';tr.exportTo('tr.ui.b',function(){function HotKey(dict){if(dict.eventType===undefined){throw new Error('eventType must be given');}
+if(dict.keyCode===undefined&&dict.keyCodes===undefined){throw new Error('keyCode or keyCodes must be given');}
+if(dict.keyCode!==undefined&&dict.keyCodes!==undefined){throw new Error('Only keyCode or keyCodes can be given');}
+if(dict.callback===undefined){throw new Error('callback must be given');}
+this.eventType_=dict.eventType;this.keyCodes_=[];if(dict.keyCode){this.pushKeyCode_(dict.keyCode);}else if(dict.keyCodes){dict.keyCodes.forEach(this.pushKeyCode_,this);}
 this.useCapture_=!!dict.useCapture;this.callback_=dict.callback;this.thisArg_=dict.thisArg!==undefined?dict.thisArg:undefined;this.helpText_=dict.helpText!==undefined?dict.helpText:undefined;}
-HotKey.prototype={get eventType(){return this.eventType_;},get keyCodes(){return this.keyCodes_;},get helpText(){return this.helpText_;},call:function(e){this.callback_.call(this.thisArg_,e);},pushKeyCode_:function(keyCode){this.keyCodes_.push(keyCode);}};return{HotKey:HotKey};});'use strict';Polymer('tv-ui-b-hotkey-controller',{created:function(){this.isAttached_=false;this.globalMode_=false;this.slavedToParentController_=undefined;this.curHost_=undefined;this.childControllers_=[];this.bubblingKeyDownHotKeys_={};this.capturingKeyDownHotKeys_={};this.bubblingKeyPressHotKeys_={};this.capturingKeyPressHotKeys_={};this.onBubblingKeyDown_=this.onKey_.bind(this,false);this.onCapturingKeyDown_=this.onKey_.bind(this,true);this.onBubblingKeyPress_=this.onKey_.bind(this,false);this.onCapturingKeyPress_=this.onKey_.bind(this,true);},attached:function(){this.isAttached_=true;var host=this.findHost_();if(host.__hotkeyController)
-throw new Error('Multiple hotkey controllers attached to this host');host.__hotkeyController=this;this.curHost_=host;var parentElement;if(host.parentElement)
-parentElement=host.parentElement;else
-parentElement=host.parentNode.host;var parentController=tr.b.getHotkeyControllerForElement(parentElement);if(parentController){this.slavedToParentController_=parentController;parentController.addChildController_(this);return;}
-host.addEventListener('keydown',this.onBubblingKeyDown_,false);host.addEventListener('keydown',this.onCapturingKeyDown_,true);host.addEventListener('keypress',this.onBubblingKeyPress_,false);host.addEventListener('keypress',this.onCapturingKeyPress_,true);},detached:function(){this.isAttached_=false;var host=this.curHost_;if(!host)
-return;delete host.__hotkeyController;this.curHost_=undefined;if(this.slavedToParentController_){this.slavedToParentController_.removeChildController_(this);this.slavedToParentController_=undefined;return;}
-host.removeEventListener('keydown',this.onBubblingKeyDown_,false);host.removeEventListener('keydown',this.onCapturingKeyDown_,true);host.removeEventListener('keypress',this.onBubblingKeyPress_,false);host.removeEventListener('keypress',this.onCapturingKeyPress_,true);},addChildController_:function(controller){var i=this.childControllers_.indexOf(controller);if(i!==-1)
-throw new Error('Controller already registered');this.childControllers_.push(controller);},removeChildController_:function(controller){var i=this.childControllers_.indexOf(controller);if(i===-1)
-throw new Error('Controller not registered');this.childControllers_.splice(i,1);return controller;},getKeyMapForEventType_:function(eventType,useCapture){if(eventType==='keydown'){if(!useCapture)
-return this.bubblingKeyDownHotKeys_;else
-return this.capturingKeyDownHotKeys_;}else if(eventType==='keypress'){if(!useCapture)
-return this.bubblingKeyPressHotKeys_;else
-return this.capturingKeyPressHotKeys_;}else{throw new Error('Unsupported key event');}},addHotKey:function(hotKey){if(!(hotKey instanceof tr.ui.b.HotKey))
-throw new Error('hotKey must be a tr.ui.b.HotKey');var keyMap=this.getKeyMapForEventType_(hotKey.eventType,hotKey.useCapture);for(var i=0;i<hotKey.keyCodes.length;i++){var keyCode=hotKey.keyCodes[i];if(keyMap[keyCode])
-throw new Error('Key is already bound for keyCode='+keyCode);}
-for(var i=0;i<hotKey.keyCodes.length;i++){var keyCode=hotKey.keyCodes[i];keyMap[keyCode]=hotKey;}
-return hotKey;},removeHotKey:function(hotKey){if(!(hotKey instanceof tr.ui.b.HotKey))
-throw new Error('hotKey must be a tr.ui.b.HotKey');var keyMap=this.getKeyMapForEventType_(hotKey.eventType,hotKey.useCapture);for(var i=0;i<hotKey.keyCodes.length;i++){var keyCode=hotKey.keyCodes[i];if(!keyMap[keyCode])
-throw new Error('Key is not bound for keyCode='+keyCode);keyMap[keyCode]=hotKey;}
-for(var i=0;i<hotKey.keyCodes.length;i++){var keyCode=hotKey.keyCodes[i];delete keyMap[keyCode];}
-return hotKey;},get globalMode(){return this.globalMode_;},set globalMode(globalMode){var wasAttached=this.isAttached_;if(wasAttached)
-this.detached();this.globalMode_=!!globalMode;if(wasAttached)
-this.attached();},get topmostConroller_(){if(this.slavedToParentController_)
-return this.slavedToParentController_.topmostConroller_;return this;},childRequestsGeneralFocus:function(child){var topmost=this.topmostConroller_;if(topmost.curHost_){if(topmost.curHost_.hasAttribute('tabIndex')){topmost.curHost_.focus();}else{if(document.activeElement)
-document.activeElement.blur();}}else{if(document.activeElement)
-document.activeElement.blur();}},childRequestsBlur:function(child){child.blur();var topmost=this.topmostConroller_;if(topmost.curHost_){topmost.curHost_.focus();}},findHost_:function(){if(this.globalMode_){return document.body;}else{if(this.parentElement)
-return this.parentElement;var node=this;while(node.parentNode){node=node.parentNode;}
-return node.host;}},appendMatchingHotKeysTo_:function(matchedHotKeys,useCapture,e){var localKeyMap=this.getKeyMapForEventType_(e.type,useCapture);var localHotKey=localKeyMap[e.keyCode];if(localHotKey)
-matchedHotKeys.push(localHotKey);for(var i=0;i<this.childControllers_.length;i++){var controller=this.childControllers_[i];controller.appendMatchingHotKeysTo_(matchedHotKeys,useCapture,e);}},onKey_:function(useCapture,e){if(useCapture==false&&e.path[0].tagName=='INPUT')
-return;var sortedControllers;var matchedHotKeys=[];this.appendMatchingHotKeysTo_(matchedHotKeys,useCapture,e);if(matchedHotKeys.length===0)
-return false;if(matchedHotKeys.length>1){throw new Error('More than one hotKey is currently unsupported');}
-var hotKey=matchedHotKeys[0];var prevented=0;prevented|=hotKey.call(e);return!prevented&&e.defaultPrevented;}});'use strict';tr.exportTo('tr.b',function(){function getHotkeyControllerForElement(refElement){var curElement=refElement;while(curElement){if(curElement.tagName==='tv-ui-b-hotkey-controller')
-return curElement;if(curElement.__hotkeyController)
-return curElement.__hotkeyController;if(curElement.parentElement){curElement=curElement.parentElement;continue;}
+HotKey.prototype={get eventType(){return this.eventType_;},get keyCodes(){return this.keyCodes_;},get helpText(){return this.helpText_;},call(e){this.callback_.call(this.thisArg_,e);},pushKeyCode_(keyCode){this.keyCodes_.push(keyCode);}};return{HotKey,};});'use strict';Polymer({is:'tv-ui-b-hotkey-controller',created(){this.isAttached_=false;this.globalMode_=false;this.slavedToParentController_=undefined;this.curHost_=undefined;this.childControllers_=[];this.bubblingKeyDownHotKeys_={};this.capturingKeyDownHotKeys_={};this.bubblingKeyPressHotKeys_={};this.capturingKeyPressHotKeys_={};this.onBubblingKeyDown_=this.onKey_.bind(this,false);this.onCapturingKeyDown_=this.onKey_.bind(this,true);this.onBubblingKeyPress_=this.onKey_.bind(this,false);this.onCapturingKeyPress_=this.onKey_.bind(this,true);},attached(){this.isAttached_=true;const host=this.findHost_();if(host.__hotkeyController){throw new Error('Multiple hotkey controllers attached to this host');}
+host.__hotkeyController=this;this.curHost_=host;let parentElement;if(host.parentElement){parentElement=host.parentElement;}else{parentElement=Polymer.dom(host).parentNode.host;}
+const parentController=tr.b.getHotkeyControllerForElement(parentElement);if(parentController){this.slavedToParentController_=parentController;parentController.addChildController_(this);return;}
+host.addEventListener('keydown',this.onBubblingKeyDown_,false);host.addEventListener('keydown',this.onCapturingKeyDown_,true);host.addEventListener('keypress',this.onBubblingKeyPress_,false);host.addEventListener('keypress',this.onCapturingKeyPress_,true);},detached(){this.isAttached_=false;const host=this.curHost_;if(!host)return;delete host.__hotkeyController;this.curHost_=undefined;if(this.slavedToParentController_){this.slavedToParentController_.removeChildController_(this);this.slavedToParentController_=undefined;return;}
+host.removeEventListener('keydown',this.onBubblingKeyDown_,false);host.removeEventListener('keydown',this.onCapturingKeyDown_,true);host.removeEventListener('keypress',this.onBubblingKeyPress_,false);host.removeEventListener('keypress',this.onCapturingKeyPress_,true);},addChildController_(controller){const i=this.childControllers_.indexOf(controller);if(i!==-1){throw new Error('Controller already registered');}
+this.childControllers_.push(controller);},removeChildController_(controller){const i=this.childControllers_.indexOf(controller);if(i===-1){throw new Error('Controller not registered');}
+this.childControllers_.splice(i,1);return controller;},getKeyMapForEventType_(eventType,useCapture){if(eventType==='keydown'){if(!useCapture){return this.bubblingKeyDownHotKeys_;}
+return this.capturingKeyDownHotKeys_;}
+if(eventType==='keypress'){if(!useCapture){return this.bubblingKeyPressHotKeys_;}
+return this.capturingKeyPressHotKeys_;}
+throw new Error('Unsupported key event');},addHotKey(hotKey){if(!(hotKey instanceof tr.ui.b.HotKey)){throw new Error('hotKey must be a tr.ui.b.HotKey');}
+const keyMap=this.getKeyMapForEventType_(hotKey.eventType,hotKey.useCapture);for(let i=0;i<hotKey.keyCodes.length;i++){const keyCode=hotKey.keyCodes[i];if(keyMap[keyCode]){throw new Error('Key is already bound for keyCode='+keyCode);}}
+for(let i=0;i<hotKey.keyCodes.length;i++){const keyCode=hotKey.keyCodes[i];keyMap[keyCode]=hotKey;}
+return hotKey;},removeHotKey(hotKey){if(!(hotKey instanceof tr.ui.b.HotKey)){throw new Error('hotKey must be a tr.ui.b.HotKey');}
+const keyMap=this.getKeyMapForEventType_(hotKey.eventType,hotKey.useCapture);for(let i=0;i<hotKey.keyCodes.length;i++){const keyCode=hotKey.keyCodes[i];if(!keyMap[keyCode]){throw new Error('Key is not bound for keyCode='+keyCode);}
+keyMap[keyCode]=hotKey;}
+for(let i=0;i<hotKey.keyCodes.length;i++){const keyCode=hotKey.keyCodes[i];delete keyMap[keyCode];}
+return hotKey;},get globalMode(){return this.globalMode_;},set globalMode(globalMode){const wasAttached=this.isAttached_;if(wasAttached){this.detached();}
+this.globalMode_=!!globalMode;if(wasAttached){this.attached();}},get topmostConroller_(){if(this.slavedToParentController_){return this.slavedToParentController_.topmostConroller_;}
+return this;},childRequestsGeneralFocus(child){const topmost=this.topmostConroller_;if(topmost.curHost_){if(topmost.curHost_.hasAttribute('tabIndex')){topmost.curHost_.focus();}else{if(document.activeElement){document.activeElement.blur();}}}else{if(document.activeElement){document.activeElement.blur();}}},childRequestsBlur(child){child.blur();const topmost=this.topmostConroller_;if(topmost.curHost_){topmost.curHost_.focus();}},findHost_(){if(this.globalMode_)return document.body;if(this.parentElement)return this.parentElement;if(!Polymer.dom(this).parentNode)return this.host;let node=this.parentNode;while(Polymer.dom(node).parentNode)node=Polymer.dom(node).parentNode;return node.host;},appendMatchingHotKeysTo_(matchedHotKeys,useCapture,e){const localKeyMap=this.getKeyMapForEventType_(e.type,useCapture);const localHotKey=localKeyMap[e.keyCode];if(localHotKey){matchedHotKeys.push(localHotKey);}
+for(let i=0;i<this.childControllers_.length;i++){const controller=this.childControllers_[i];controller.appendMatchingHotKeysTo_(matchedHotKeys,useCapture,e);}},onKey_(useCapture,e){if(!useCapture&&e.path[0].tagName==='INPUT')return;let sortedControllers;const matchedHotKeys=[];this.appendMatchingHotKeysTo_(matchedHotKeys,useCapture,e);if(matchedHotKeys.length===0)return false;if(matchedHotKeys.length>1){throw new Error('More than one hotKey is currently unsupported');}
+const hotKey=matchedHotKeys[0];let prevented=0;prevented|=hotKey.call(e);return!prevented&&e.defaultPrevented;}});'use strict';tr.exportTo('tr.b',function(){function getHotkeyControllerForElement(refElement){let curElement=refElement;while(curElement){if(curElement.tagName==='tv-ui-b-hotkey-controller'){return curElement;}
+if(curElement.__hotkeyController){return curElement.__hotkeyController;}
+if(curElement.parentElement){curElement=curElement.parentElement;continue;}
 curElement=findHost(curElement);}
 return undefined;}
-function findHost(initialNode){var node=initialNode;while(node.parentNode){node=node.parentNode;}
+function findHost(initialNode){let node=initialNode;while(Polymer.dom(node).parentNode){node=Polymer.dom(node).parentNode;}
 return node.host;}
-return{getHotkeyControllerForElement:getHotkeyControllerForElement};});'use strict';Polymer('tr-ui-b-info-bar',{ready:function(){this.messageEl_=this.$.message;this.buttonsEl_=this.$.buttons;this.message='';this.visible=false;},get message(){return this.messageEl_.textContent;},set message(message){this.messageEl_.textContent=message;},get visible(){return!this.classList.contains('info-bar-hidden');},set visible(visible){if(visible)
-this.classList.remove('info-bar-hidden');else
-this.classList.add('info-bar-hidden');},removeAllButtons:function(){this.buttonsEl_.textContent='';},addButton:function(text,clickCallback){var button=document.createElement('button');button.textContent=text;button.addEventListener('click',clickCallback);this.buttonsEl_.appendChild(button);return button;}});'use strict';tr.exportTo('tr.ui.b',function(){var ContainerThatDecoratesItsChildren=tr.ui.b.define('div');ContainerThatDecoratesItsChildren.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.observer_=new WebKitMutationObserver(this.didMutate_.bind(this));this.observer_.observe(this,{childList:true});Object.defineProperty(this,'textContent',{get:undefined,set:this.onSetTextContent_});},appendChild:function(x){HTMLUnknownElement.prototype.appendChild.call(this,x);this.didMutate_(this.observer_.takeRecords());},insertBefore:function(x,y){HTMLUnknownElement.prototype.insertBefore.call(this,x,y);this.didMutate_(this.observer_.takeRecords());},removeChild:function(x){HTMLUnknownElement.prototype.removeChild.call(this,x);this.didMutate_(this.observer_.takeRecords());},replaceChild:function(x,y){HTMLUnknownElement.prototype.replaceChild.call(this,x,y);this.didMutate_(this.observer_.takeRecords());},onSetTextContent_:function(textContent){if(textContent!='')
-throw new Error('textContent can only be set to \'\'.');this.clear();},clear:function(){while(this.lastChild)
-HTMLUnknownElement.prototype.removeChild.call(this,this.lastChild);this.didMutate_(this.observer_.takeRecords());},didMutate_:function(records){this.beginDecorating_();for(var i=0;i<records.length;i++){var addedNodes=records[i].addedNodes;if(addedNodes){for(var j=0;j<addedNodes.length;j++)
-this.decorateChild_(addedNodes[j]);}
-var removedNodes=records[i].removedNodes;if(removedNodes){for(var j=0;j<removedNodes.length;j++){this.undecorateChild_(removedNodes[j]);}}}
-this.doneDecoratingForNow_();},decorateChild_:function(child){throw new Error('Not implemented');},undecorateChild_:function(child){throw new Error('Not implemented');},beginDecorating_:function(){},doneDecoratingForNow_:function(){}};return{ContainerThatDecoratesItsChildren:ContainerThatDecoratesItsChildren};});'use strict';tr.exportTo('tr.ui.b',function(){var ListView=tr.ui.b.define('x-list-view',tr.ui.b.ContainerThatDecoratesItsChildren);ListView.prototype={__proto__:tr.ui.b.ContainerThatDecoratesItsChildren.prototype,decorate:function(){tr.ui.b.ContainerThatDecoratesItsChildren.prototype.decorate.call(this);this.classList.add('x-list-view');this.onItemClicked_=this.onItemClicked_.bind(this);this.onKeyDown_=this.onKeyDown_.bind(this);this.tabIndex=0;this.addEventListener('keydown',this.onKeyDown_);this.selectionChanged_=false;},decorateChild_:function(item){item.classList.add('list-item');item.addEventListener('click',this.onItemClicked_,true);var listView=this;Object.defineProperty(item,'selected',{configurable:true,set:function(value){var oldSelection=listView.selectedElement;if(oldSelection&&oldSelection!=this&&value)
-listView.selectedElement.removeAttribute('selected');if(value)
-this.setAttribute('selected','selected');else
-this.removeAttribute('selected');var newSelection=listView.selectedElement;if(newSelection!=oldSelection)
-tr.b.dispatchSimpleEvent(listView,'selection-changed',false);},get:function(){return this.hasAttribute('selected');}});},undecorateChild_:function(item){this.selectionChanged_|=item.selected;item.classList.remove('list-item');item.removeEventListener('click',this.onItemClicked_);delete item.selected;},beginDecorating_:function(){this.selectionChanged_=false;},doneDecoratingForNow_:function(){if(this.selectionChanged_)
-tr.b.dispatchSimpleEvent(this,'selection-changed',false);},get selectedElement(){var el=this.querySelector('.list-item[selected]');if(!el)
-return undefined;return el;},set selectedElement(el){if(!el){if(this.selectedElement)
-this.selectedElement.selected=false;return;}
-if(el.parentElement!=this)
-throw new Error('Can only select elements that are children of this list view');el.selected=true;},getElementByIndex:function(index){return this.querySelector('.list-item:nth-child('+index+')');},clear:function(){var changed=this.selectedElement!==undefined;tr.ui.b.ContainerThatDecoratesItsChildren.prototype.clear.call(this);if(changed)
-tr.b.dispatchSimpleEvent(this,'selection-changed',false);},onItemClicked_:function(e){var currentSelectedElement=this.selectedElement;if(currentSelectedElement)
-currentSelectedElement.removeAttribute('selected');var element=e.target;while(element.parentElement!=this)
-element=element.parentElement;if(element!==currentSelectedElement)
-element.setAttribute('selected','selected');tr.b.dispatchSimpleEvent(this,'selection-changed',false);},onKeyDown_:function(e){if(this.selectedElement===undefined)
-return;if(e.keyCode==38){var prev=this.selectedElement.previousSibling;if(prev){prev.selected=true;tr.ui.b.scrollIntoViewIfNeeded(prev);e.preventDefault();return true;}}else if(e.keyCode==40){var next=this.selectedElement.nextSibling;if(next){next.selected=true;tr.ui.b.scrollIntoViewIfNeeded(next);e.preventDefault();return true;}}},addItem:function(textContent){var item=document.createElement('div');item.textContent=textContent;this.appendChild(item);return item;}};return{ListView:ListView};});'use strict';tr.exportTo('tr.ui.b',function(){function MouseTracker(opt_targetElement){this.onMouseDown_=this.onMouseDown_.bind(this);this.onMouseMove_=this.onMouseMove_.bind(this);this.onMouseUp_=this.onMouseUp_.bind(this);this.targetElement=opt_targetElement;}
-MouseTracker.prototype={get targetElement(){return this.targetElement_;},set targetElement(targetElement){if(this.targetElement_)
-this.targetElement_.removeEventListener('mousedown',this.onMouseDown_);this.targetElement_=targetElement;if(this.targetElement_)
-this.targetElement_.addEventListener('mousedown',this.onMouseDown_);},onMouseDown_:function(e){if(e.button!==0)
-return true;e=this.remakeEvent_(e,'mouse-tracker-start');this.targetElement_.dispatchEvent(e);document.addEventListener('mousemove',this.onMouseMove_);document.addEventListener('mouseup',this.onMouseUp_);this.targetElement_.addEventListener('blur',this.onMouseUp_);this.savePreviousUserSelect_=document.body.style['-webkit-user-select'];document.body.style['-webkit-user-select']='none';e.preventDefault();return true;},onMouseMove_:function(e){e=this.remakeEvent_(e,'mouse-tracker-move');this.targetElement_.dispatchEvent(e);},onMouseUp_:function(e){document.removeEventListener('mousemove',this.onMouseMove_);document.removeEventListener('mouseup',this.onMouseUp_);this.targetElement_.removeEventListener('blur',this.onMouseUp_);document.body.style['-webkit-user-select']=this.savePreviousUserSelect_;e=this.remakeEvent_(e,'mouse-tracker-end');this.targetElement_.dispatchEvent(e);},remakeEvent_:function(e,newType){var remade=new tr.b.Event(newType,true,true);remade.x=e.x;remade.y=e.y;remade.offsetX=e.offsetX;remade.offsetY=e.offsetY;remade.clientX=e.clientX;remade.clientY=e.clientY;return remade;}};function trackMouseMovesUntilMouseUp(mouseMoveHandler,opt_mouseUpHandler,opt_keyUpHandler){function cleanupAndDispatchToMouseUp(e){document.removeEventListener('mousemove',mouseMoveHandler);if(opt_keyUpHandler)
-document.removeEventListener('keyup',opt_keyUpHandler);document.removeEventListener('mouseup',cleanupAndDispatchToMouseUp);if(opt_mouseUpHandler)
-opt_mouseUpHandler(e);}
-document.addEventListener('mousemove',mouseMoveHandler);if(opt_keyUpHandler)
-document.addEventListener('keyup',opt_keyUpHandler);document.addEventListener('mouseup',cleanupAndDispatchToMouseUp);}
-return{MouseTracker:MouseTracker,trackMouseMovesUntilMouseUp:trackMouseMovesUntilMouseUp};});'use strict';tr.exportTo('tr.ui.b',function(){var MOUSE_SELECTOR_MODE={};MOUSE_SELECTOR_MODE.SELECTION=0x1;MOUSE_SELECTOR_MODE.PANSCAN=0x2;MOUSE_SELECTOR_MODE.ZOOM=0x4;MOUSE_SELECTOR_MODE.TIMING=0x8;MOUSE_SELECTOR_MODE.ROTATE=0x10;MOUSE_SELECTOR_MODE.ALL_MODES=0x1F;var MOUSE_SELECTOR_MODE_INFOS={};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.PANSCAN]={mode:MOUSE_SELECTOR_MODE.PANSCAN,title:'pan',eventNames:{enter:'enterpan',begin:'beginpan',update:'updatepan',end:'endpan',exit:'exitpan'},activeBackgroundPosition:'-30px -10px',defaultBackgroundPosition:'0 -10px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.SELECTION]={mode:MOUSE_SELECTOR_MODE.SELECTION,title:'selection',eventNames:{enter:'enterselection',begin:'beginselection',update:'updateselection',end:'endselection',exit:'exitselection'},activeBackgroundPosition:'-30px -40px',defaultBackgroundPosition:'0 -40px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.ZOOM]={mode:MOUSE_SELECTOR_MODE.ZOOM,title:'zoom',eventNames:{enter:'enterzoom',begin:'beginzoom',update:'updatezoom',end:'endzoom',exit:'exitzoom'},activeBackgroundPosition:'-30px -70px',defaultBackgroundPosition:'0 -70px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.TIMING]={mode:MOUSE_SELECTOR_MODE.TIMING,title:'timing',eventNames:{enter:'entertiming',begin:'begintiming',update:'updatetiming',end:'endtiming',exit:'exittiming'},activeBackgroundPosition:'-30px -100px',defaultBackgroundPosition:'0 -100px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.ROTATE]={mode:MOUSE_SELECTOR_MODE.ROTATE,title:'rotate',eventNames:{enter:'enterrotate',begin:'beginrotate',update:'updaterotate',end:'endrotate',exit:'exitrotate'},activeBackgroundPosition:'-30px -130px',defaultBackgroundPosition:'0 -130px'};return{MOUSE_SELECTOR_MODE_INFOS:MOUSE_SELECTOR_MODE_INFOS,MOUSE_SELECTOR_MODE:MOUSE_SELECTOR_MODE};});'use strict';Polymer('tr-ui-b-mouse-mode-icon',{publish:{modeName:{value:undefined,reflect:true}},created:function(){this.active_=false;this.acceleratorKey_=undefined;},ready:function(){this.updateContents_();},get mode(){return tr.ui.b.MOUSE_SELECTOR_MODE[this.modeName];},set mode(mode){var modeInfo=tr.ui.b.MOUSE_SELECTOR_MODE_INFOS[mode];var modeName=tr.b.findFirstKeyInDictMatching(tr.ui.b.MOUSE_SELECTOR_MODE,function(modeName,candidateMode){return candidateMode===mode;});if(modeName===undefined)
-throw new Error('Unknown mode');this.modeName=modeName;},modeNameChanged:function(){this.updateContents_();},get active(){return this.active_;},set active(active){this.active_=!!active;if(this.active_)
-this.classList.add('active');else
-this.classList.remove('active');this.updateContents_();},get acceleratorKey(){return this.acceleratorKey_;},set acceleratorKey(acceleratorKey){this.acceleratorKey_=acceleratorKey;this.updateContents_();},updateContents_:function(){if(this.modeName===undefined)
-return;var mode=this.mode;if(mode===undefined)
-throw new Error('Invalid mode');var modeInfo=tr.ui.b.MOUSE_SELECTOR_MODE_INFOS[mode];if(!modeInfo)
-throw new Error('Invalid mode');var title=modeInfo.title;if(this.acceleratorKey_)
-title=title+' ('+this.acceleratorKey_+')';this.title=title;var bp;if(this.active_)
-bp=modeInfo.activeBackgroundPosition;else
-bp=modeInfo.defaultBackgroundPosition;this.style.backgroundPosition=bp;}});'use strict';tr.exportTo('tr.ui.b',function(){var MOUSE_SELECTOR_MODE=tr.ui.b.MOUSE_SELECTOR_MODE;var MOUSE_SELECTOR_MODE_INFOS=tr.ui.b.MOUSE_SELECTOR_MODE_INFOS;var MIN_MOUSE_SELECTION_DISTANCE=4;var MODIFIER={SHIFT:0x1,SPACE:0x2,CMD_OR_CTRL:0x4};function isCmdOrCtrlPressed(event){if(tr.isMac)
-return event.metaKey;else
-return event.ctrlKey;}
-Polymer('tr-ui-b-mouse-mode-selector',{__proto__:HTMLDivElement.prototype,created:function(){this.supportedModeMask_=MOUSE_SELECTOR_MODE.ALL_MODES;this.initialRelativeMouseDownPos_={x:0,y:0};this.defaultMode_=MOUSE_SELECTOR_MODE.PANSCAN;this.settingsKey_=undefined;this.mousePos_={x:0,y:0};this.mouseDownPos_={x:0,y:0};this.onMouseDown_=this.onMouseDown_.bind(this);this.onMouseMove_=this.onMouseMove_.bind(this);this.onMouseUp_=this.onMouseUp_.bind(this);this.onKeyDown_=this.onKeyDown_.bind(this);this.onKeyUp_=this.onKeyUp_.bind(this);this.mode_=undefined;this.modeToKeyCodeMap_={};this.modifierToModeMap_={};this.targetElement_=undefined;this.modeBeforeAlternativeModeActivated_=null;this.isInteracting_=false;this.isClick_=false;},ready:function(){this.buttonsEl_=this.shadowRoot.querySelector('.buttons');this.dragHandleEl_=this.shadowRoot.querySelector('.drag-handle');this.supportedModeMask=MOUSE_SELECTOR_MODE.ALL_MODES;this.dragHandleEl_.addEventListener('mousedown',this.onDragHandleMouseDown_.bind(this));this.buttonsEl_.addEventListener('mouseup',this.onButtonMouseUp_);this.buttonsEl_.addEventListener('mousedown',this.onButtonMouseDown_);this.buttonsEl_.addEventListener('click',this.onButtonPress_.bind(this));},attached:function(){document.addEventListener('keydown',this.onKeyDown_);document.addEventListener('keyup',this.onKeyUp_);},detached:function(){document.removeEventListener('keydown',this.onKeyDown_);document.removeEventListener('keyup',this.onKeyUp_);},get targetElement(){return this.targetElement_;},set targetElement(target){if(this.targetElement_)
-this.targetElement_.removeEventListener('mousedown',this.onMouseDown_);this.targetElement_=target;if(this.targetElement_)
-this.targetElement_.addEventListener('mousedown',this.onMouseDown_);},get defaultMode(){return this.defaultMode_;},set defaultMode(defaultMode){this.defaultMode_=defaultMode;},get settingsKey(){return this.settingsKey_;},set settingsKey(settingsKey){this.settingsKey_=settingsKey;if(!this.settingsKey_)
-return;var mode=tr.b.Settings.get(this.settingsKey_+'.mode',undefined);if(MOUSE_SELECTOR_MODE_INFOS[mode]===undefined)
-mode=undefined;if((mode&this.supportedModeMask_)===0)
-mode=undefined;if(!mode)
-mode=this.defaultMode_;this.mode=mode;var pos=tr.b.Settings.get(this.settingsKey_+'.pos',undefined);if(pos)
-this.pos=pos;},get supportedModeMask(){return this.supportedModeMask_;},set supportedModeMask(supportedModeMask){if(this.mode&&(supportedModeMask&this.mode)===0)
-throw new Error('supportedModeMask must include current mode.');function createButtonForMode(mode){return button;}
-this.supportedModeMask_=supportedModeMask;this.buttonsEl_.textContent='';for(var modeName in MOUSE_SELECTOR_MODE){if(modeName=='ALL_MODES')
-continue;var mode=MOUSE_SELECTOR_MODE[modeName];if((this.supportedModeMask_&mode)===0)
-continue;var button=document.createElement('tr-ui-b-mouse-mode-icon');button.mode=mode;button.classList.add('tool-button');this.buttonsEl_.appendChild(button);}},getButtonForMode_:function(mode){for(var i=0;i<this.buttonsEl_.children.length;i++){var buttonEl=this.buttonsEl_.children[i];if(buttonEl.mode===mode)
-return buttonEl;}
-return undefined;},get mode(){return this.currentMode_;},set mode(newMode){if(newMode!==undefined){if(typeof newMode!=='number')
-throw new Error('Mode must be a number');if((newMode&this.supportedModeMask_)===0)
-throw new Error('Cannot switch to this mode, it is not supported');if(MOUSE_SELECTOR_MODE_INFOS[newMode]===undefined)
-throw new Error('Unrecognized mode');}
-var modeInfo;if(this.currentMode_===newMode)
-return;if(this.currentMode_){var buttonEl=this.getButtonForMode_(this.currentMode_);if(buttonEl)
-buttonEl.active=false;if(this.isInteracting_){var mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.end);this.dispatchEvent(mouseEvent);}
+return{getHotkeyControllerForElement,};});'use strict';Polymer({is:'tr-ui-b-info-bar',ready(){this.messageEl_=this.$.message;this.buttonsEl_=this.$.buttons;this.message='';},get message(){return Polymer.dom(this.messageEl_).textContent;},set message(message){Polymer.dom(this.messageEl_).textContent=message;},get visible(){return!this.hidden;},set visible(visible){this.hidden=!visible;},removeAllButtons(){Polymer.dom(this.buttonsEl_).textContent='';},addButton(text,clickCallback){const button=document.createElement('button');Polymer.dom(button).textContent=text;button.addEventListener('click',event=>clickCallback(event,this));Polymer.dom(this.buttonsEl_).appendChild(button);return button;}});'use strict';tr.exportTo('tr.ui.b',function(){const ContainerThatDecoratesItsChildren=tr.ui.b.define('div');ContainerThatDecoratesItsChildren.prototype={__proto__:HTMLDivElement.prototype,decorate(){this.observer_=new WebKitMutationObserver(this.didMutate_.bind(this));this.observer_.observe(this,{childList:true});Object.defineProperty(this,'textContent',{get:undefined,set:this.onSetTextContent_});},appendChild(x){HTMLDivElement.prototype.appendChild.call(this,x);this.didMutate_(this.observer_.takeRecords());},insertBefore(x,y){HTMLDivElement.prototype.insertBefore.call(this,x,y);this.didMutate_(this.observer_.takeRecords());},removeChild(x){HTMLDivElement.prototype.removeChild.call(this,x);this.didMutate_(this.observer_.takeRecords());},replaceChild(x,y){HTMLDivElement.prototype.replaceChild.call(this,x,y);this.didMutate_(this.observer_.takeRecords());},onSetTextContent_(textContent){if(textContent!==''){throw new Error('textContent can only be set to \'\'.');}
+this.clear();},clear(){while(Polymer.dom(this).lastChild){HTMLDivElement.prototype.removeChild.call(this,Polymer.dom(this).lastChild);}
+this.didMutate_(this.observer_.takeRecords());},didMutate_(records){this.beginDecorating_();for(let i=0;i<records.length;i++){const addedNodes=records[i].addedNodes;if(addedNodes){for(let j=0;j<addedNodes.length;j++){this.decorateChild_(addedNodes[j]);}}
+const removedNodes=records[i].removedNodes;if(removedNodes){for(let j=0;j<removedNodes.length;j++){this.undecorateChild_(removedNodes[j]);}}}
+this.doneDecoratingForNow_();},decorateChild_(child){throw new Error('Not implemented');},undecorateChild_(child){throw new Error('Not implemented');},beginDecorating_(){},doneDecoratingForNow_(){}};return{ContainerThatDecoratesItsChildren,};});'use strict';tr.exportTo('tr.ui.b',function(){const ListView=tr.ui.b.define('x-list-view',tr.ui.b.ContainerThatDecoratesItsChildren);ListView.prototype={__proto__:tr.ui.b.ContainerThatDecoratesItsChildren.prototype,decorate(){tr.ui.b.ContainerThatDecoratesItsChildren.prototype.decorate.call(this);Polymer.dom(this).classList.add('x-list-view');this.style.display='block';this.style.userSelect='none';this.style.outline='none';this.onItemClicked_=this.onItemClicked_.bind(this);this.onKeyDown_=this.onKeyDown_.bind(this);this.tabIndex=0;this.addEventListener('keydown',this.onKeyDown_);this.selectionChanged_=false;},decorateChild_(item){Polymer.dom(item).classList.add('list-item');item.style.paddingTop='2px';item.style.paddingRight='4px';item.style.paddingBottom='2px';item.style.paddingLeft='4px';item.addEventListener('click',this.onItemClicked_,true);Object.defineProperty(item,'selected',{configurable:true,get:()=>item.hasAttribute('selected'),set:value=>{const oldSelection=this.selectedElement;if(oldSelection&&oldSelection!==item&&value){Polymer.dom(this.selectedElement).removeAttribute('selected');}
+if(value){Polymer.dom(item).setAttribute('selected','selected');item.style.backgroundColor='rgb(171, 217, 202)';item.style.outline='1px dotted rgba(0,0,0,0.1)';item.style.outlineOffset=0;}else{Polymer.dom(item).removeAttribute('selected');item.style.backgroundColor='';}
+const newSelection=this.selectedElement;if(newSelection!==oldSelection){tr.b.dispatchSimpleEvent(this,'selection-changed',false);}},});},undecorateChild_(item){this.selectionChanged_|=item.selected;Polymer.dom(item).classList.remove('list-item');item.removeEventListener('click',this.onItemClicked_);delete item.selected;},beginDecorating_(){this.selectionChanged_=false;},doneDecoratingForNow_(){if(this.selectionChanged_){tr.b.dispatchSimpleEvent(this,'selection-changed',false);}},get selectedElement(){const el=Polymer.dom(this).querySelector('.list-item[selected]');if(!el)return undefined;return el;},set selectedElement(el){if(!el){if(this.selectedElement){this.selectedElement.selected=false;}
+return;}
+if(el.parentElement!==this){throw new Error('Can only select elements that are children of this list view');}
+el.selected=true;},getElementByIndex(index){return Polymer.dom(this).querySelector('.list-item:nth-child('+index+')');},clear(){const changed=this.selectedElement!==undefined;tr.ui.b.ContainerThatDecoratesItsChildren.prototype.clear.call(this);if(changed){tr.b.dispatchSimpleEvent(this,'selection-changed',false);}},onItemClicked_(e){const currentSelectedElement=this.selectedElement;if(currentSelectedElement){Polymer.dom(currentSelectedElement).removeAttribute('selected');}
+let element=e.target;while(element.parentElement!==this){element=element.parentElement;}
+if(element!==currentSelectedElement){Polymer.dom(element).setAttribute('selected','selected');}
+tr.b.dispatchSimpleEvent(this,'selection-changed',false);},onKeyDown_(e){if(this.selectedElement===undefined)return;if(e.keyCode===38){const prev=Polymer.dom(this.selectedElement).previousSibling;if(prev){prev.selected=true;tr.ui.b.scrollIntoViewIfNeeded(prev);e.preventDefault();return true;}}else if(e.keyCode===40){const next=Polymer.dom(this.selectedElement).nextSibling;if(next){next.selected=true;tr.ui.b.scrollIntoViewIfNeeded(next);e.preventDefault();return true;}}},addItem(textContent){const item=document.createElement('div');Polymer.dom(item).textContent=textContent;Polymer.dom(this).appendChild(item);item.style.userSelect='none';return item;}};return{ListView,};});'use strict';tr.exportTo('tr.ui.b',function(){const MOUSE_SELECTOR_MODE={};MOUSE_SELECTOR_MODE.SELECTION=0x1;MOUSE_SELECTOR_MODE.PANSCAN=0x2;MOUSE_SELECTOR_MODE.ZOOM=0x4;MOUSE_SELECTOR_MODE.TIMING=0x8;MOUSE_SELECTOR_MODE.ROTATE=0x10;MOUSE_SELECTOR_MODE.ALL_MODES=0x1F;const MOUSE_SELECTOR_MODE_INFOS={};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.PANSCAN]={name:'PANSCAN',mode:MOUSE_SELECTOR_MODE.PANSCAN,title:'pan',eventNames:{enter:'enterpan',begin:'beginpan',update:'updatepan',end:'endpan',exit:'exitpan'},activeBackgroundPosition:'-30px -10px',defaultBackgroundPosition:'0 -10px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.SELECTION]={name:'SELECTION',mode:MOUSE_SELECTOR_MODE.SELECTION,title:'selection',eventNames:{enter:'enterselection',begin:'beginselection',update:'updateselection',end:'endselection',exit:'exitselection'},activeBackgroundPosition:'-30px -40px',defaultBackgroundPosition:'0 -40px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.ZOOM]={name:'ZOOM',mode:MOUSE_SELECTOR_MODE.ZOOM,title:'zoom',eventNames:{enter:'enterzoom',begin:'beginzoom',update:'updatezoom',end:'endzoom',exit:'exitzoom'},activeBackgroundPosition:'-30px -70px',defaultBackgroundPosition:'0 -70px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.TIMING]={name:'TIMING',mode:MOUSE_SELECTOR_MODE.TIMING,title:'timing',eventNames:{enter:'entertiming',begin:'begintiming',update:'updatetiming',end:'endtiming',exit:'exittiming'},activeBackgroundPosition:'-30px -100px',defaultBackgroundPosition:'0 -100px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.ROTATE]={name:'ROTATE',mode:MOUSE_SELECTOR_MODE.ROTATE,title:'rotate',eventNames:{enter:'enterrotate',begin:'beginrotate',update:'updaterotate',end:'endrotate',exit:'exitrotate'},activeBackgroundPosition:'-30px -130px',defaultBackgroundPosition:'0 -130px'};return{MOUSE_SELECTOR_MODE_INFOS,MOUSE_SELECTOR_MODE,};});'use strict';Polymer({is:'tr-ui-b-mouse-mode-icon',properties:{modeName:{type:String,reflectToAttribute:true,observer:'modeNameChanged'},},created(){this.active_=false;this.acceleratorKey_=undefined;},ready(){this.updateContents_();},get mode(){return tr.ui.b.MOUSE_SELECTOR_MODE[this.modeName];},set mode(mode){const modeInfo=tr.ui.b.MOUSE_SELECTOR_MODE_INFOS[mode];if(modeInfo===undefined){throw new Error('Unknown mode');}
+this.modeName=modeInfo.name;},modeNameChanged(){this.updateContents_();},get active(){return this.active_;},set active(active){this.active_=!!active;if(this.active_){Polymer.dom(this).classList.add('active');}else{Polymer.dom(this).classList.remove('active');}
+this.updateContents_();},get acceleratorKey(){return this.acceleratorKey_;},set acceleratorKey(acceleratorKey){this.acceleratorKey_=acceleratorKey;this.updateContents_();},updateContents_(){if(this.modeName===undefined)return;const mode=this.mode;if(mode===undefined){throw new Error('Invalid mode');}
+const modeInfo=tr.ui.b.MOUSE_SELECTOR_MODE_INFOS[mode];if(!modeInfo){throw new Error('Invalid mode');}
+let title=modeInfo.title;if(this.acceleratorKey_){title=title+' ('+this.acceleratorKey_+')';}
+this.title=title;let bp;if(this.active_){bp=modeInfo.activeBackgroundPosition;}else{bp=modeInfo.defaultBackgroundPosition;}
+this.style.backgroundPosition=bp;}});'use strict';tr.exportTo('tr.ui.b',function(){function MouseTracker(opt_targetElement){this.onMouseDown_=this.onMouseDown_.bind(this);this.onMouseMove_=this.onMouseMove_.bind(this);this.onMouseUp_=this.onMouseUp_.bind(this);this.targetElement=opt_targetElement;}
+MouseTracker.prototype={get targetElement(){return this.targetElement_;},set targetElement(targetElement){if(this.targetElement_){this.targetElement_.removeEventListener('mousedown',this.onMouseDown_);}
+this.targetElement_=targetElement;if(this.targetElement_){this.targetElement_.addEventListener('mousedown',this.onMouseDown_);}},onMouseDown_(e){if(e.button!==0)return true;e=this.remakeEvent_(e,'mouse-tracker-start');this.targetElement_.dispatchEvent(e);document.addEventListener('mousemove',this.onMouseMove_);document.addEventListener('mouseup',this.onMouseUp_);this.targetElement_.addEventListener('blur',this.onMouseUp_);this.savePreviousUserSelect_=document.body.style['-webkit-user-select'];document.body.style['-webkit-user-select']='none';e.preventDefault();return true;},onMouseMove_(e){e=this.remakeEvent_(e,'mouse-tracker-move');this.targetElement_.dispatchEvent(e);},onMouseUp_(e){document.removeEventListener('mousemove',this.onMouseMove_);document.removeEventListener('mouseup',this.onMouseUp_);this.targetElement_.removeEventListener('blur',this.onMouseUp_);document.body.style['-webkit-user-select']=this.savePreviousUserSelect_;e=this.remakeEvent_(e,'mouse-tracker-end');this.targetElement_.dispatchEvent(e);},remakeEvent_(e,newType){const remade=new tr.b.Event(newType,true,true);remade.x=e.x;remade.y=e.y;remade.offsetX=e.offsetX;remade.offsetY=e.offsetY;remade.clientX=e.clientX;remade.clientY=e.clientY;return remade;}};function trackMouseMovesUntilMouseUp(mouseMoveHandler,opt_mouseUpHandler,opt_keyUpHandler){function cleanupAndDispatchToMouseUp(e){document.removeEventListener('mousemove',mouseMoveHandler);if(opt_keyUpHandler){document.removeEventListener('keyup',opt_keyUpHandler);}
+document.removeEventListener('mouseup',cleanupAndDispatchToMouseUp);if(opt_mouseUpHandler){opt_mouseUpHandler(e);}}
+document.addEventListener('mousemove',mouseMoveHandler);if(opt_keyUpHandler){document.addEventListener('keyup',opt_keyUpHandler);}
+document.addEventListener('mouseup',cleanupAndDispatchToMouseUp);}
+return{MouseTracker,trackMouseMovesUntilMouseUp,};});'use strict';tr.exportTo('tr.ui.b',function(){const MOUSE_SELECTOR_MODE=tr.ui.b.MOUSE_SELECTOR_MODE;const MOUSE_SELECTOR_MODE_INFOS=tr.ui.b.MOUSE_SELECTOR_MODE_INFOS;const MIN_MOUSE_SELECTION_DISTANCE=4;const MODIFIER={SHIFT:0x1,SPACE:0x2,CMD_OR_CTRL:0x4};function isCmdOrCtrlPressed(event){if(tr.isMac)return event.metaKey;return event.ctrlKey;}
+Polymer({is:'tr-ui-b-mouse-mode-selector',created(){this.supportedModeMask_=MOUSE_SELECTOR_MODE.ALL_MODES;this.initialRelativeMouseDownPos_={x:0,y:0};this.defaultMode_=MOUSE_SELECTOR_MODE.PANSCAN;this.settingsKey_=undefined;this.mousePos_={x:0,y:0};this.mouseDownPos_={x:0,y:0};this.onMouseDown_=this.onMouseDown_.bind(this);this.onMouseMove_=this.onMouseMove_.bind(this);this.onMouseUp_=this.onMouseUp_.bind(this);this.onKeyDown_=this.onKeyDown_.bind(this);this.onKeyUp_=this.onKeyUp_.bind(this);this.mode_=undefined;this.modeToKeyCodeMap_={};this.modifierToModeMap_={};this.targetElement_=undefined;this.modeBeforeAlternativeModeActivated_=null;this.isInteracting_=false;this.isClick_=false;},ready(){this.buttonsEl_=Polymer.dom(this.root).querySelector('.buttons');this.dragHandleEl_=Polymer.dom(this.root).querySelector('.drag-handle');this.supportedModeMask=MOUSE_SELECTOR_MODE.ALL_MODES;this.dragHandleEl_.addEventListener('mousedown',this.onDragHandleMouseDown_.bind(this));this.buttonsEl_.addEventListener('mouseup',this.onButtonMouseUp_);this.buttonsEl_.addEventListener('mousedown',this.onButtonMouseDown_);this.buttonsEl_.addEventListener('click',this.onButtonPress_.bind(this));},attached(){document.addEventListener('keydown',this.onKeyDown_);document.addEventListener('keyup',this.onKeyUp_);},detached(){document.removeEventListener('keydown',this.onKeyDown_);document.removeEventListener('keyup',this.onKeyUp_);},get targetElement(){return this.targetElement_;},set targetElement(target){if(this.targetElement_){this.targetElement_.removeEventListener('mousedown',this.onMouseDown_);}
+this.targetElement_=target;if(this.targetElement_){this.targetElement_.addEventListener('mousedown',this.onMouseDown_);}},get defaultMode(){return this.defaultMode_;},set defaultMode(defaultMode){this.defaultMode_=defaultMode;},get settingsKey(){return this.settingsKey_;},set settingsKey(settingsKey){this.settingsKey_=settingsKey;if(!this.settingsKey_)return;let mode=tr.b.Settings.get(this.settingsKey_+'.mode',undefined);if(MOUSE_SELECTOR_MODE_INFOS[mode]===undefined){mode=undefined;}
+if((mode&this.supportedModeMask_)===0){mode=undefined;}
+if(!mode)mode=this.defaultMode_;this.mode=mode;const pos=tr.b.Settings.get(this.settingsKey_+'.pos',undefined);if(pos)this.pos=pos;},get supportedModeMask(){return this.supportedModeMask_;},set supportedModeMask(supportedModeMask){if(this.mode&&(supportedModeMask&this.mode)===0){throw new Error('supportedModeMask must include current mode.');}
+function createButtonForMode(mode){return button;}
+this.supportedModeMask_=supportedModeMask;Polymer.dom(this.buttonsEl_).textContent='';for(const modeName in MOUSE_SELECTOR_MODE){if(modeName==='ALL_MODES')continue;const mode=MOUSE_SELECTOR_MODE[modeName];if((this.supportedModeMask_&mode)===0)continue;const button=document.createElement('tr-ui-b-mouse-mode-icon');button.mode=mode;Polymer.dom(button).classList.add('tool-button');Polymer.dom(this.buttonsEl_).appendChild(button);}},getButtonForMode_(mode){for(let i=0;i<this.buttonsEl_.children.length;i++){const buttonEl=this.buttonsEl_.children[i];if(buttonEl.mode===mode){return buttonEl;}}
+return undefined;},get mode(){return this.currentMode_;},set mode(newMode){if(newMode!==undefined){if(typeof newMode!=='number'){throw new Error('Mode must be a number');}
+if((newMode&this.supportedModeMask_)===0){throw new Error('Cannot switch to this mode, it is not supported');}
+if(MOUSE_SELECTOR_MODE_INFOS[newMode]===undefined){throw new Error('Unrecognized mode');}}
+let modeInfo;if(this.currentMode_===newMode)return;if(this.currentMode_){const buttonEl=this.getButtonForMode_(this.currentMode_);if(buttonEl)buttonEl.active=false;if(this.isInteracting_){const mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.end);this.dispatchEvent(mouseEvent);}
 modeInfo=MOUSE_SELECTOR_MODE_INFOS[this.currentMode_];tr.b.dispatchSimpleEvent(this,modeInfo.eventNames.exit,true);}
-this.currentMode_=newMode;if(this.currentMode_){var buttonEl=this.getButtonForMode_(this.currentMode_);if(buttonEl)
-buttonEl.active=true;this.mouseDownPos_.x=this.mousePos_.x;this.mouseDownPos_.y=this.mousePos_.y;modeInfo=MOUSE_SELECTOR_MODE_INFOS[this.currentMode_];if(!this.isInAlternativeMode_)
-tr.b.dispatchSimpleEvent(this,modeInfo.eventNames.enter,true);if(this.isInteracting_){var mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.begin);this.dispatchEvent(mouseEvent);}}
-if(this.settingsKey_&&!this.isInAlternativeMode_)
-tr.b.Settings.set(this.settingsKey_+'.mode',this.mode);},setKeyCodeForMode:function(mode,keyCode){if((mode&this.supportedModeMask_)===0)
-throw new Error('Mode not supported');this.modeToKeyCodeMap_[mode]=keyCode;if(!this.buttonsEl_)
-return;var buttonEl=this.getButtonForMode_(mode);if(buttonEl)
-buttonEl.acceleratorKey=String.fromCharCode(keyCode);},setCurrentMousePosFromEvent_:function(e){this.mousePos_.x=e.clientX;this.mousePos_.y=e.clientY;},createEvent_:function(eventName,sourceEvent){var event=new tr.b.Event(eventName,true);event.clientX=this.mousePos_.x;event.clientY=this.mousePos_.y;event.deltaX=this.mousePos_.x-this.mouseDownPos_.x;event.deltaY=this.mousePos_.y-this.mouseDownPos_.y;event.mouseDownX=this.mouseDownPos_.x;event.mouseDownY=this.mouseDownPos_.y;event.didPreventDefault=false;event.preventDefault=function(){event.didPreventDefault=true;if(sourceEvent)
-sourceEvent.preventDefault();};event.stopPropagation=function(){sourceEvent.stopPropagation();};event.stopImmediatePropagation=function(){throw new Error('Not implemented');};return event;},onMouseDown_:function(e){if(e.button!==0)
-return;this.setCurrentMousePosFromEvent_(e);var mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.begin,e);if(this.mode===MOUSE_SELECTOR_MODE.SELECTION)
-mouseEvent.appendSelection=isCmdOrCtrlPressed(e);this.dispatchEvent(mouseEvent);this.isInteracting_=true;this.isClick_=true;tr.ui.b.trackMouseMovesUntilMouseUp(this.onMouseMove_,this.onMouseUp_);},onMouseMove_:function(e){this.setCurrentMousePosFromEvent_(e);var mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.update,e);this.dispatchEvent(mouseEvent);if(this.isInteracting_)
-this.checkIsClick_(e);},onMouseUp_:function(e){if(e.button!==0)
-return;var mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.end,e);mouseEvent.isClick=this.isClick_;this.dispatchEvent(mouseEvent);if(this.isClick_&&!mouseEvent.didPreventDefault)
-this.dispatchClickEvents_(e);this.isInteracting_=false;this.updateAlternativeModeState_(e);},onButtonMouseDown_:function(e){e.preventDefault();e.stopImmediatePropagation();},onButtonMouseUp_:function(e){e.preventDefault();e.stopImmediatePropagation();},onButtonPress_:function(e){this.modeBeforeAlternativeModeActivated_=undefined;this.mode=e.target.mode;e.preventDefault();},onKeyDown_:function(e){if(e.path[0].tagName=='INPUT')
-return;if(e.keyCode===' '.charCodeAt(0))
-this.spacePressed_=true;this.updateAlternativeModeState_(e);},onKeyUp_:function(e){if(e.path[0].tagName=='INPUT')
-return;if(e.keyCode===' '.charCodeAt(0))
-this.spacePressed_=false;var didHandleKey=false;tr.b.iterItems(this.modeToKeyCodeMap_,function(modeStr,keyCode){if(e.keyCode===keyCode){this.modeBeforeAlternativeModeActivated_=undefined;var mode=parseInt(modeStr);this.mode=mode;didHandleKey=true;}},this);if(didHandleKey){e.preventDefault();e.stopPropagation();return;}
-this.updateAlternativeModeState_(e);},updateAlternativeModeState_:function(e){var shiftPressed=e.shiftKey;var spacePressed=this.spacePressed_;var cmdOrCtrlPressed=isCmdOrCtrlPressed(e);var smm=this.supportedModeMask_;var newMode;var isNewModeAnAlternativeMode=false;if(shiftPressed&&(this.modifierToModeMap_[MODIFIER.SHIFT]&smm)!==0){newMode=this.modifierToModeMap_[MODIFIER.SHIFT];isNewModeAnAlternativeMode=true;}else if(spacePressed&&(this.modifierToModeMap_[MODIFIER.SPACE]&smm)!==0){newMode=this.modifierToModeMap_[MODIFIER.SPACE];isNewModeAnAlternativeMode=true;}else if(cmdOrCtrlPressed&&(this.modifierToModeMap_[MODIFIER.CMD_OR_CTRL]&smm)!==0){newMode=this.modifierToModeMap_[MODIFIER.CMD_OR_CTRL];isNewModeAnAlternativeMode=true;}else{if(this.isInAlternativeMode_){newMode=this.modeBeforeAlternativeModeActivated_;isNewModeAnAlternativeMode=false;}else{newMode=undefined;}}
-if(this.mode===newMode||newMode===undefined)
-return;if(isNewModeAnAlternativeMode)
-this.modeBeforeAlternativeModeActivated_=this.mode;this.mode=newMode;},get isInAlternativeMode_(){return!!this.modeBeforeAlternativeModeActivated_;},setModifierForAlternateMode:function(mode,modifier){this.modifierToModeMap_[modifier]=mode;},get pos(){return{x:parseInt(this.style.left),y:parseInt(this.style.top)};},set pos(pos){pos=this.constrainPositionToBounds_(pos);this.style.left=pos.x+'px';this.style.top=pos.y+'px';if(this.settingsKey_)
-tr.b.Settings.set(this.settingsKey_+'.pos',this.pos);},constrainPositionToBounds_:function(pos){var parent=this.offsetParent||document.body;var parentRect=tr.ui.b.windowRectForElement(parent);var top=0;var bottom=parentRect.height-this.offsetHeight;var left=0;var right=parentRect.width-this.offsetWidth;var res={};res.x=Math.max(pos.x,left);res.x=Math.min(res.x,right);res.y=Math.max(pos.y,top);res.y=Math.min(res.y,bottom);return res;},onDragHandleMouseDown_:function(e){e.preventDefault();e.stopImmediatePropagation();var mouseDownPos={x:e.clientX-this.offsetLeft,y:e.clientY-this.offsetTop};tr.ui.b.trackMouseMovesUntilMouseUp(function(e){var pos={};pos.x=e.clientX-mouseDownPos.x;pos.y=e.clientY-mouseDownPos.y;this.pos=pos;}.bind(this));},checkIsClick_:function(e){if(!this.isInteracting_||!this.isClick_)
-return;var deltaX=this.mousePos_.x-this.mouseDownPos_.x;var deltaY=this.mousePos_.y-this.mouseDownPos_.y;var minDist=MIN_MOUSE_SELECTION_DISTANCE;if(deltaX*deltaX+deltaY*deltaY>minDist*minDist)
-this.isClick_=false;},dispatchClickEvents_:function(e){if(!this.isClick_)
-return;var modeInfo=MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.SELECTION];var eventNames=modeInfo.eventNames;var mouseEvent=this.createEvent_(eventNames.begin);mouseEvent.appendSelection=isCmdOrCtrlPressed(e);this.dispatchEvent(mouseEvent);mouseEvent=this.createEvent_(eventNames.end);this.dispatchEvent(mouseEvent);}});return{MIN_MOUSE_SELECTION_DISTANCE:MIN_MOUSE_SELECTION_DISTANCE,MODIFIER:MODIFIER};});'use strict';(function(){var DETAILS_SPLIT_REGEX=/^(\S*)\s*([\S\s]*)$/;Polymer('tr-ui-e-chrome-cc-display-item-list-item',{created:function(){this.name='';this.rawDetails='';this.richDetails=undefined;this.data_=undefined;},get data(){return this.data_;},set data(data){this.data_=data;if(!data){this.name='DATA MISSING';this.rawDetails='';this.richDetails=undefined;}else if(typeof data==='string'){var match=data.match(DETAILS_SPLIT_REGEX);this.name=match[1];this.rawDetails=match[2];this.richDetails=undefined;}else{this.name=data.name;this.rawDetails='';this.richDetails=data;}},stopPropagation:function(e){e.stopPropagation();}});})();'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){function Selection(){this.selectionToSetIfClicked=undefined;};Selection.prototype={get specicifity(){throw new Error('Not implemented');},get associatedLayerId(){throw new Error('Not implemented');},get associatedRenderPassId(){throw new Error('Not implemented');},get highlightsByLayerId(){return{};},createAnalysis:function(){throw new Error('Not implemented');},findEquivalent:function(lthi){throw new Error('Not implemented');}};function RenderPassSelection(renderPass,renderPassId){if(!renderPass||(renderPassId===undefined))
-throw new Error('Render pass (with id) is required');this.renderPass_=renderPass;this.renderPassId_=renderPassId;}
-RenderPassSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 1;},get associatedLayerId(){return undefined;},get associatedRenderPassId(){return this.renderPassId_;},get renderPass(){return this.renderPass_;},createAnalysis:function(){var dataView=document.createElement('tr-ui-a-generic-object-view-with-label');dataView.label='RenderPass '+this.renderPassId_;dataView.object=this.renderPass_.args;return dataView;},get title(){return this.renderPass_.objectInstance.typeName;}};function LayerSelection(layer){if(!layer)
-throw new Error('Layer is required');this.layer_=layer;}
-LayerSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 1;},get associatedLayerId(){return this.layer_.layerId;},get associatedRenderPassId(){return undefined;},get layer(){return this.layer_;},createAnalysis:function(){var dataView=document.createElement('tr-ui-a-generic-object-view-with-label');dataView.label='Layer '+this.layer_.layerId;if(this.layer_.usingGpuRasterization)
-dataView.label+=' (GPU-rasterized)';dataView.object=this.layer_.args;return dataView;},get title(){return this.layer_.objectInstance.typeName;},findEquivalent:function(lthi){var layer=lthi.activeTree.findLayerWithId(this.layer_.layerId)||lthi.pendingTree.findLayerWithId(this.layer_.layerId);if(!layer)
-return undefined;return new LayerSelection(layer);}};function TileSelection(tile,opt_data){this.tile_=tile;this.data_=opt_data||{};}
-TileSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 2;},get associatedLayerId(){return this.tile_.layerId;},get highlightsByLayerId(){var highlights={};highlights[this.tile_.layerId]=[{colorKey:this.tile_.objectInstance.typeName,rect:this.tile_.layerRect}];return highlights;},createAnalysis:function(){var analysis=document.createElement('tr-ui-a-generic-object-view-with-label');analysis.label='Tile '+this.tile_.objectInstance.id+' on layer '+
+this.currentMode_=newMode;if(this.currentMode_){const buttonEl=this.getButtonForMode_(this.currentMode_);if(buttonEl)buttonEl.active=true;this.mouseDownPos_.x=this.mousePos_.x;this.mouseDownPos_.y=this.mousePos_.y;modeInfo=MOUSE_SELECTOR_MODE_INFOS[this.currentMode_];if(!this.isInAlternativeMode_){tr.b.dispatchSimpleEvent(this,modeInfo.eventNames.enter,true);}
+if(this.isInteracting_){const mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.begin);this.dispatchEvent(mouseEvent);}}
+if(this.settingsKey_&&!this.isInAlternativeMode_){tr.b.Settings.set(this.settingsKey_+'.mode',this.mode);}},setKeyCodeForMode(mode,keyCode){if((mode&this.supportedModeMask_)===0){throw new Error('Mode not supported');}
+this.modeToKeyCodeMap_[mode]=keyCode;if(!this.buttonsEl_)return;const buttonEl=this.getButtonForMode_(mode);if(buttonEl){buttonEl.acceleratorKey=String.fromCharCode(keyCode);}},setCurrentMousePosFromEvent_(e){this.mousePos_.x=e.clientX;this.mousePos_.y=e.clientY;},createEvent_(eventName,sourceEvent){const event=new tr.b.Event(eventName,true);event.clientX=this.mousePos_.x;event.clientY=this.mousePos_.y;event.deltaX=this.mousePos_.x-this.mouseDownPos_.x;event.deltaY=this.mousePos_.y-this.mouseDownPos_.y;event.mouseDownX=this.mouseDownPos_.x;event.mouseDownY=this.mouseDownPos_.y;event.didPreventDefault=false;event.preventDefault=function(){event.didPreventDefault=true;if(sourceEvent){sourceEvent.preventDefault();}};event.stopPropagation=function(){sourceEvent.stopPropagation();};event.stopImmediatePropagation=function(){throw new Error('Not implemented');};return event;},onMouseDown_(e){if(e.button!==0)return;this.setCurrentMousePosFromEvent_(e);const mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.begin,e);if(this.mode===MOUSE_SELECTOR_MODE.SELECTION){mouseEvent.appendSelection=isCmdOrCtrlPressed(e);}
+this.dispatchEvent(mouseEvent);this.isInteracting_=true;this.isClick_=true;tr.ui.b.trackMouseMovesUntilMouseUp(this.onMouseMove_,this.onMouseUp_);},onMouseMove_(e){this.setCurrentMousePosFromEvent_(e);const mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.update,e);this.dispatchEvent(mouseEvent);if(this.isInteracting_){this.checkIsClick_(e);}},onMouseUp_(e){if(e.button!==0)return;const mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.end,e);mouseEvent.isClick=this.isClick_;this.dispatchEvent(mouseEvent);if(this.isClick_&&!mouseEvent.didPreventDefault){this.dispatchClickEvents_(e);}
+this.isInteracting_=false;this.updateAlternativeModeState_(e);},onButtonMouseDown_(e){e.preventDefault();e.stopImmediatePropagation();},onButtonMouseUp_(e){e.preventDefault();e.stopImmediatePropagation();},onButtonPress_(e){this.modeBeforeAlternativeModeActivated_=undefined;this.mode=e.target.mode;e.preventDefault();},onKeyDown_(e){if(e.path[0].tagName==='INPUT')return;if(e.keyCode===' '.charCodeAt(0)){this.spacePressed_=true;}
+this.updateAlternativeModeState_(e);},onKeyUp_(e){if(e.path[0].tagName==='INPUT')return;if(e.keyCode===' '.charCodeAt(0)){this.spacePressed_=false;}
+let didHandleKey=false;for(const[modeStr,keyCode]of Object.entries(this.modeToKeyCodeMap_)){if(e.keyCode===keyCode){this.modeBeforeAlternativeModeActivated_=undefined;const mode=parseInt(modeStr);this.mode=mode;didHandleKey=true;}}
+if(didHandleKey){e.preventDefault();e.stopPropagation();return;}
+this.updateAlternativeModeState_(e);},updateAlternativeModeState_(e){const shiftPressed=e.shiftKey;const spacePressed=this.spacePressed_;const cmdOrCtrlPressed=isCmdOrCtrlPressed(e);const smm=this.supportedModeMask_;let newMode;let isNewModeAnAlternativeMode=false;if(shiftPressed&&(this.modifierToModeMap_[MODIFIER.SHIFT]&smm)!==0){newMode=this.modifierToModeMap_[MODIFIER.SHIFT];isNewModeAnAlternativeMode=true;}else if(spacePressed&&(this.modifierToModeMap_[MODIFIER.SPACE]&smm)!==0){newMode=this.modifierToModeMap_[MODIFIER.SPACE];isNewModeAnAlternativeMode=true;}else if(cmdOrCtrlPressed&&(this.modifierToModeMap_[MODIFIER.CMD_OR_CTRL]&smm)!==0){newMode=this.modifierToModeMap_[MODIFIER.CMD_OR_CTRL];isNewModeAnAlternativeMode=true;}else{if(this.isInAlternativeMode_){newMode=this.modeBeforeAlternativeModeActivated_;isNewModeAnAlternativeMode=false;}else{newMode=undefined;}}
+if(this.mode===newMode||newMode===undefined)return;if(isNewModeAnAlternativeMode){this.modeBeforeAlternativeModeActivated_=this.mode;}
+this.mode=newMode;},get isInAlternativeMode_(){return!!this.modeBeforeAlternativeModeActivated_;},setModifierForAlternateMode(mode,modifier){this.modifierToModeMap_[modifier]=mode;},get pos(){return{x:parseInt(this.style.left),y:parseInt(this.style.top)};},set pos(pos){pos=this.constrainPositionToBounds_(pos);this.style.left=pos.x+'px';this.style.top=pos.y+'px';if(this.settingsKey_){tr.b.Settings.set(this.settingsKey_+'.pos',this.pos);}},constrainPositionToBounds_(pos){const parent=this.offsetParent||document.body;const parentRect=tr.ui.b.windowRectForElement(parent);const top=0;const bottom=parentRect.height-this.offsetHeight;const left=0;const right=parentRect.width-this.offsetWidth;const res={};res.x=Math.max(pos.x,left);res.x=Math.min(res.x,right);res.y=Math.max(pos.y,top);res.y=Math.min(res.y,bottom);return res;},onDragHandleMouseDown_(e){e.preventDefault();e.stopImmediatePropagation();const mouseDownPos={x:e.clientX-this.offsetLeft,y:e.clientY-this.offsetTop};tr.ui.b.trackMouseMovesUntilMouseUp(function(e){const pos={};pos.x=e.clientX-mouseDownPos.x;pos.y=e.clientY-mouseDownPos.y;this.pos=pos;}.bind(this));},checkIsClick_(e){if(!this.isInteracting_||!this.isClick_)return;const deltaX=this.mousePos_.x-this.mouseDownPos_.x;const deltaY=this.mousePos_.y-this.mouseDownPos_.y;const minDist=MIN_MOUSE_SELECTION_DISTANCE;if(deltaX*deltaX+deltaY*deltaY>minDist*minDist){this.isClick_=false;}},dispatchClickEvents_(e){if(!this.isClick_)return;const modeInfo=MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.SELECTION];const eventNames=modeInfo.eventNames;let mouseEvent=this.createEvent_(eventNames.begin);mouseEvent.appendSelection=isCmdOrCtrlPressed(e);this.dispatchEvent(mouseEvent);mouseEvent=this.createEvent_(eventNames.end);this.dispatchEvent(mouseEvent);}});return{MIN_MOUSE_SELECTION_DISTANCE,MODIFIER,};});'use strict';(function(){const DETAILS_SPLIT_REGEX=/^(\S*)\s*([\S\s]*)$/;Polymer({is:'tr-ui-e-chrome-cc-display-item-list-item',created(){Polymer.dom(this).setAttribute('name','');Polymer.dom(this).setAttribute('rawDetails','');Polymer.dom(this).setAttribute('richDetails',undefined);Polymer.dom(this).setAttribute('data_',undefined);},get data(){return this.data_;},set data(data){this.data_=data;if(!data){this.name='DATA MISSING';this.rawDetails='';this.richDetails=undefined;}else if(typeof data==='string'){const match=data.match(DETAILS_SPLIT_REGEX);this.name=match[1];this.rawDetails=match[2];this.richDetails=undefined;}else{this.name=data.name;this.rawDetails='';this.richDetails=data;}},stopPropagation(e){e.stopPropagation();},_computeIfSKP(richDetails){return richDetails&&richDetails.skp64;},_computeHref(richDetails){return'data:application/octet-stream;base64,'+richDetails.skp64;}});})();'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){function Selection(){this.selectionToSetIfClicked=undefined;}
+Selection.prototype={get specicifity(){throw new Error('Not implemented');},get associatedLayerId(){throw new Error('Not implemented');},get associatedRenderPassId(){throw new Error('Not implemented');},get highlightsByLayerId(){return{};},createAnalysis(){throw new Error('Not implemented');},findEquivalent(lthi){throw new Error('Not implemented');}};function RenderPassSelection(renderPass,renderPassId){if(!renderPass||(renderPassId===undefined)){throw new Error('Render pass (with id) is required');}
+this.renderPass_=renderPass;this.renderPassId_=renderPassId;}
+RenderPassSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 1;},get associatedLayerId(){return undefined;},get associatedRenderPassId(){return this.renderPassId_;},get renderPass(){return this.renderPass_;},createAnalysis(){const dataView=document.createElement('tr-ui-a-generic-object-view-with-label');dataView.label='RenderPass '+this.renderPassId_;dataView.object=this.renderPass_.args;return dataView;},get title(){return this.renderPass_.objectInstance.typeName;}};function LayerSelection(layer){if(!layer){throw new Error('Layer is required');}
+this.layer_=layer;}
+LayerSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 1;},get associatedLayerId(){return this.layer_.layerId;},get associatedRenderPassId(){return undefined;},get layer(){return this.layer_;},createAnalysis(){const dataView=document.createElement('tr-ui-a-generic-object-view-with-label');dataView.label='Layer '+this.layer_.layerId;if(this.layer_.usingGpuRasterization){dataView.label+=' (GPU-rasterized)';}
+dataView.object=this.layer_.args;return dataView;},get title(){return this.layer_.objectInstance.typeName;},findEquivalent(lthi){const layer=lthi.activeTree.findLayerWithId(this.layer_.layerId)||lthi.pendingTree.findLayerWithId(this.layer_.layerId);if(!layer)return undefined;return new LayerSelection(layer);}};function TileSelection(tile,opt_data){this.tile_=tile;this.data_=opt_data||{};}
+TileSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 2;},get associatedLayerId(){return this.tile_.layerId;},get highlightsByLayerId(){const highlights={};highlights[this.tile_.layerId]=[{colorKey:this.tile_.objectInstance.typeName,rect:this.tile_.layerRect}];return highlights;},createAnalysis(){const analysis=document.createElement('tr-ui-a-generic-object-view-with-label');analysis.label='Tile '+this.tile_.objectInstance.id+' on layer '+
 this.tile_.layerId;if(this.data_){analysis.object={moreInfo:this.data_,tileArgs:this.tile_.args};}else{analysis.object=this.tile_.args;}
-return analysis;},findEquivalent:function(lthi){var tileInstance=this.tile_.tileInstance;if(lthi.ts<tileInstance.creationTs||lthi.ts>=tileInstance.deletionTs)
-return undefined;var tileSnapshot=tileInstance.getSnapshotAt(lthi.ts);if(!tileSnapshot)
-return undefined;return new TileSelection(tileSnapshot);}};function LayerRectSelection(layer,rectType,rect,opt_data){this.layer_=layer;this.rectType_=rectType;this.rect_=rect;this.data_=opt_data!==undefined?opt_data:rect;}
-LayerRectSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 2;},get associatedLayerId(){return this.layer_.layerId;},get highlightsByLayerId(){var highlights={};highlights[this.layer_.layerId]=[{colorKey:this.rectType_,rect:this.rect_}];return highlights;},createAnalysis:function(){var analysis=document.createElement('tr-ui-a-generic-object-view-with-label');analysis.label=this.rectType_+' on layer '+this.layer_.layerId;analysis.object=this.data_;return analysis;},findEquivalent:function(lthi){return undefined;}};function AnimationRectSelection(layer,rect){this.layer_=layer;this.rect_=rect;}
-AnimationRectSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 0;},get associatedLayerId(){return this.layer_.layerId;},createAnalysis:function(){var analysis=document.createElement('tr-ui-a-generic-object-view-with-label');analysis.label='Animation Bounds of layer '+this.layer_.layerId;analysis.object=this.rect_;return analysis;}};return{Selection:Selection,RenderPassSelection:RenderPassSelection,LayerSelection:LayerSelection,TileSelection:TileSelection,LayerRectSelection:LayerRectSelection,AnimationRectSelection:AnimationRectSelection};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var OPS_TIMING_ITERATIONS=3;var ANNOTATION='Comment';var BEGIN_ANNOTATION='BeginCommentGroup';var END_ANNOTATION='EndCommentGroup';var ANNOTATION_ID='ID: ';var ANNOTATION_CLASS='CLASS: ';var ANNOTATION_TAG='TAG: ';var constants=tr.e.cc.constants;var PictureOpsListView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-ops-list-view');PictureOpsListView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.opsList_=new tr.ui.b.ListView();this.appendChild(this.opsList_);this.selectedOp_=undefined;this.selectedOpIndex_=undefined;this.opsList_.addEventListener('selection-changed',this.onSelectionChanged_.bind(this));this.picture_=undefined;},get picture(){return this.picture_;},set picture(picture){this.picture_=picture;this.updateContents_();},updateContents_:function(){this.opsList_.clear();if(!this.picture_)
-return;var ops=this.picture_.getOps();if(!ops)
-return;ops=this.picture_.tagOpsWithTimings(ops);ops=this.opsTaggedWithAnnotations_(ops);for(var i=0;i<ops.length;i++){var op=ops[i];var item=document.createElement('div');item.opIndex=op.opIndex;item.textContent=i+') '+op.cmd_string;if(op.elementInfo.tag||op.elementInfo.id||op.elementInfo.class){var elementInfo=document.createElement('span');elementInfo.classList.add('elementInfo');var tag=op.elementInfo.tag?op.elementInfo.tag:'unknown';var id=op.elementInfo.id?'id='+op.elementInfo.id:undefined;var className=op.elementInfo.class?'class='+
-op.elementInfo.class:undefined;elementInfo.textContent='<'+tag+(id?' ':'')+
+return analysis;},findEquivalent(lthi){const tileInstance=this.tile_.tileInstance;if(lthi.ts<tileInstance.creationTs||lthi.ts>=tileInstance.deletionTs){return undefined;}
+const tileSnapshot=tileInstance.getSnapshotAt(lthi.ts);if(!tileSnapshot)return undefined;return new TileSelection(tileSnapshot);}};function LayerRectSelection(layer,rectType,rect,opt_data){this.layer_=layer;this.rectType_=rectType;this.rect_=rect;this.data_=opt_data!==undefined?opt_data:rect;}
+LayerRectSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 2;},get associatedLayerId(){return this.layer_.layerId;},get highlightsByLayerId(){const highlights={};highlights[this.layer_.layerId]=[{colorKey:this.rectType_,rect:this.rect_}];return highlights;},createAnalysis(){const analysis=document.createElement('tr-ui-a-generic-object-view-with-label');analysis.label=this.rectType_+' on layer '+this.layer_.layerId;analysis.object=this.data_;return analysis;},findEquivalent(lthi){return undefined;}};function AnimationRectSelection(layer,rect){this.layer_=layer;this.rect_=rect;}
+AnimationRectSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 0;},get associatedLayerId(){return this.layer_.layerId;},createAnalysis(){const analysis=document.createElement('tr-ui-a-generic-object-view-with-label');analysis.label='Animation Bounds of layer '+this.layer_.layerId;analysis.object=this.rect_;return analysis;}};return{Selection,RenderPassSelection,LayerSelection,TileSelection,LayerRectSelection,AnimationRectSelection,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const OPS_TIMING_ITERATIONS=3;const ANNOTATION='Comment';const BEGIN_ANNOTATION='BeginCommentGroup';const END_ANNOTATION='EndCommentGroup';const ANNOTATION_ID='ID: ';const ANNOTATION_CLASS='CLASS: ';const ANNOTATION_TAG='TAG: ';const constants=tr.e.cc.constants;const PictureOpsListView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-ops-list-view');PictureOpsListView.prototype={__proto__:HTMLDivElement.prototype,decorate(){this.style.borderTop='1px solid grey';this.style.overflow='auto';this.opsList_=new tr.ui.b.ListView();Polymer.dom(this).appendChild(this.opsList_);this.selectedOp_=undefined;this.selectedOpIndex_=undefined;this.opsList_.addEventListener('selection-changed',this.onSelectionChanged_.bind(this));this.picture_=undefined;},get picture(){return this.picture_;},set picture(picture){this.picture_=picture;this.updateContents_();},updateContents_(){this.opsList_.clear();if(!this.picture_)return;let ops=this.picture_.getOps();if(!ops)return;ops=this.picture_.tagOpsWithTimings(ops);ops=this.opsTaggedWithAnnotations_(ops);for(let i=0;i<ops.length;i++){const op=ops[i];const item=document.createElement('div');item.opIndex=op.opIndex;Polymer.dom(item).textContent=i+') '+op.cmd_string;if(op.elementInfo.tag||op.elementInfo.id||op.elementInfo.class){const elementInfo=document.createElement('span');Polymer.dom(elementInfo).classList.add('elementInfo');elementInfo.style.color='purple';elementInfo.style.fontSize='small';elementInfo.style.fontWeight='bold';elementInfo.style.color='#777';const tag=op.elementInfo.tag?op.elementInfo.tag:'unknown';const id=op.elementInfo.id?'id='+op.elementInfo.id:undefined;const className=op.elementInfo.class?'class='+
+op.elementInfo.class:undefined;Polymer.dom(elementInfo).textContent='<'+tag+(id?' ':'')+
 (id?id:'')+(className?' ':'')+
-(className?className:'')+'>';item.appendChild(elementInfo);}
-if(op.info.length>0){var infoItem=document.createElement('div');infoItem.textContent=JSON.stringify(op.info);item.appendChild(infoItem);}
-if(op.cmd_time&&op.cmd_time>=0.0001){var time=document.createElement('span');time.classList.add('time');var rounded=op.cmd_time.toFixed(4);time.textContent='('+rounded+'ms)';item.appendChild(time);}
-this.opsList_.appendChild(item);}},onSelectionChanged_:function(e){var beforeSelectedOp=true;if(this.opsList_.selectedElement===this.selectedOp_){this.opsList_.selectedElement=undefined;beforeSelectedOp=false;this.selectedOpIndex_=undefined;}
-this.selectedOp_=this.opsList_.selectedElement;var ops=this.opsList_.children;for(var i=0;i<ops.length;i++){var op=ops[i];if(op===this.selectedOp_){beforeSelectedOp=false;this.selectedOpIndex_=op.opIndex;}else if(beforeSelectedOp){op.setAttribute('beforeSelection','beforeSelection');}else{op.removeAttribute('beforeSelection');}}
-tr.b.dispatchSimpleEvent(this,'selection-changed',false);},get numOps(){return this.opsList_.children.length;},get selectedOpIndex(){return this.selectedOpIndex_;},set selectedOpIndex(s){this.selectedOpIndex_=s;if(s===undefined){this.opsList_.selectedElement=this.selectedOp_;this.onSelectionChanged_();}else{if(s<0)throw new Error('Invalid index');if(s>=this.numOps)throw new Error('Invalid index');this.opsList_.selectedElement=this.opsList_.getElementByIndex(s+1);tr.ui.b.scrollIntoViewIfNeeded(this.opsList_.selectedElement);}},opsTaggedWithAnnotations_:function(ops){var annotationGroups=new Array();var opsWithoutAnnotations=new Array();for(var opIndex=0;opIndex<ops.length;opIndex++){var op=ops[opIndex];op.opIndex=opIndex;switch(op.cmd_string){case BEGIN_ANNOTATION:annotationGroups.push(new Array());break;case END_ANNOTATION:annotationGroups.pop();break;case ANNOTATION:annotationGroups[annotationGroups.length-1].push(op);break;default:var annotations=new Array();var elementInfo={};annotationGroups.forEach(function(annotationGroup){elementInfo={};annotationGroup.forEach(function(annotation){annotation.info.forEach(function(info){if(info.indexOf(ANNOTATION_TAG)!=-1)
-elementInfo.tag=info.substring(info.indexOf(ANNOTATION_TAG)+
-ANNOTATION_TAG.length).toLowerCase();else if(info.indexOf(ANNOTATION_ID)!=-1)
-elementInfo.id=info.substring(info.indexOf(ANNOTATION_ID)+
-ANNOTATION_ID.length);else if(info.indexOf(ANNOTATION_CLASS)!=-1)
-elementInfo.class=info.substring(info.indexOf(ANNOTATION_CLASS)+
-ANNOTATION_CLASS.length);annotations.push(info);});});});op.annotations=annotations;op.elementInfo=elementInfo;opsWithoutAnnotations.push(op);}}
-return opsWithoutAnnotations;}};return{PictureOpsListView:PictureOpsListView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var THIS_DOC=document.currentScript.ownerDocument;var DisplayItemDebugger=tr.ui.b.define('tr-ui-e-chrome-cc-display-item-debugger');DisplayItemDebugger.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){var node=tr.ui.b.instantiateTemplate('#tr-ui-e-chrome-cc-display-item-debugger-template',THIS_DOC);this.appendChild(node);this.pictureAsImageData_=undefined;this.zoomScaleValue_=1;this.sizeInfo_=this.querySelector('.size');this.rasterArea_=this.querySelector('raster-area');this.rasterCanvas_=this.rasterArea_.querySelector('canvas');this.rasterCtx_=this.rasterCanvas_.getContext('2d');this.trackMouse_();this.displayItemInfo_=this.querySelector('display-item-info');this.displayItemInfo_.addEventListener('click',this.onDisplayItemInfoClick_.bind(this),false);this.displayItemListView_=new tr.ui.b.ListView();this.displayItemListView_.addEventListener('selection-changed',this.onDisplayItemListSelection_.bind(this));this.displayItemInfo_.appendChild(this.displayItemListView_);this.displayListFilename_=this.querySelector('.dlfilename');this.displayListExportButton_=this.querySelector('.dlexport');this.displayListExportButton_.addEventListener('click',this.onExportDisplayListClicked_.bind(this));this.skpFilename_=this.querySelector('.skpfilename');this.skpExportButton_=this.querySelector('.skpexport');this.skpExportButton_.addEventListener('click',this.onExportSkPictureClicked_.bind(this));var leftPanel=this.querySelector('left-panel');var middleDragHandle=document.createElement('tr-ui-b-drag-handle');middleDragHandle.horizontal=false;middleDragHandle.target=leftPanel;var rightPanel=this.querySelector('right-panel');this.infoBar_=document.createElement('tr-ui-b-info-bar');this.rasterArea_.insertBefore(this.infoBar_,this.rasterCanvas_);this.insertBefore(middleDragHandle,rightPanel);this.picture_=undefined;this.pictureOpsListView_=new tr.ui.e.chrome.cc.PictureOpsListView();rightPanel.insertBefore(this.pictureOpsListView_,this.rasterArea_);this.pictureOpsListDragHandle_=document.createElement('tr-ui-b-drag-handle');this.pictureOpsListDragHandle_.horizontal=false;this.pictureOpsListDragHandle_.target=this.pictureOpsListView_;rightPanel.insertBefore(this.pictureOpsListDragHandle_,this.rasterArea_);},get picture(){return this.picture_;},set displayItemList(displayItemList){this.displayItemList_=displayItemList;this.picture=this.displayItemList_;this.displayItemListView_.clear();this.displayItemList_.items.forEach(function(item){var listItem=document.createElement('tr-ui-e-chrome-cc-display-item-list-item');listItem.data=item;this.displayItemListView_.appendChild(listItem);}.bind(this));},set picture(picture){this.picture_=picture;var showOpsList=picture&&picture!==this.displayItemList_;this.updateDrawOpsList_(showOpsList);if(picture){var size=this.getRasterCanvasSize_();this.rasterCanvas_.width=size.width;this.rasterCanvas_.height=size.height;}
-var bounds=this.rasterArea_.getBoundingClientRect();var selectorBounds=this.mouseModeSelector_.getBoundingClientRect();this.mouseModeSelector_.pos={x:(bounds.right-selectorBounds.width-10),y:bounds.top};this.rasterize_();this.scheduleUpdateContents_();},getRasterCanvasSize_:function(){var style=window.getComputedStyle(this.rasterArea_);var width=parseInt(style.width);var height=parseInt(style.height);if(this.picture_){width=Math.max(width,this.picture_.layerRect.width);height=Math.max(height,this.picture_.layerRect.height);}
-return{width:width,height:height};},scheduleUpdateContents_:function(){if(this.updateContentsPending_)
-return;this.updateContentsPending_=true;tr.b.requestAnimationFrameInThisFrameIfPossible(this.updateContents_.bind(this));},updateContents_:function(){this.updateContentsPending_=false;if(this.picture_){this.sizeInfo_.textContent='('+
+(className?className:'')+'>';Polymer.dom(item).appendChild(elementInfo);}
+if(op.info.length>0){const infoItem=document.createElement('div');Polymer.dom(infoItem).textContent=JSON.stringify(op.info);infoItem.style.fontSize='x-small';infoItem.style.color='#777';Polymer.dom(item).appendChild(infoItem);}
+if(op.cmd_time&&op.cmd_time>=0.0001){const time=document.createElement('span');Polymer.dom(time).classList.add('time');const rounded=op.cmd_time.toFixed(4);Polymer.dom(time).textContent='('+rounded+'ms)';time.style.fontSize='x-small';time.style.color='rgb(136, 0, 0)';Polymer.dom(item).appendChild(time);}
+item.style.borderBottom='1px solid #555';item.style.fontSize='small';item.style.fontWeight='bold';item.style.paddingBottom='5px';item.style.paddingLeft='5px';item.style.cursor='pointer';for(const child of item.children){child.style.fontWeight='normal';child.style.marginLeft='1em';child.style.maxWidth='300px';}
+Polymer.dom(this.opsList_).appendChild(item);}},onSelectionChanged_(e){let beforeSelectedOp=true;if(this.opsList_.selectedElement===this.selectedOp_){this.opsList_.selectedElement=undefined;beforeSelectedOp=false;this.selectedOpIndex_=undefined;}
+this.selectedOp_=this.opsList_.selectedElement;const ops=this.opsList_.children;for(let i=0;i<ops.length;i++){const op=ops[i];if(op===this.selectedOp_){beforeSelectedOp=false;this.selectedOpIndex_=op.opIndex;}else if(beforeSelectedOp){Polymer.dom(op).setAttribute('beforeSelection','beforeSelection');op.style.backgroundColor='rgb(103, 199, 165)';}else{Polymer.dom(op).removeAttribute('beforeSelection');op.style.backgroundColor='';}}
+tr.b.dispatchSimpleEvent(this,'selection-changed',false);},get numOps(){return this.opsList_.children.length;},get selectedOpIndex(){return this.selectedOpIndex_;},set selectedOpIndex(s){this.selectedOpIndex_=s;if(s===undefined){this.opsList_.selectedElement=this.selectedOp_;this.onSelectionChanged_();}else{if(s<0)throw new Error('Invalid index');if(s>=this.numOps)throw new Error('Invalid index');this.opsList_.selectedElement=this.opsList_.getElementByIndex(s+1);tr.ui.b.scrollIntoViewIfNeeded(this.opsList_.selectedElement);}},opsTaggedWithAnnotations_(ops){const annotationGroups=[];const opsWithoutAnnotations=[];for(let opIndex=0;opIndex<ops.length;opIndex++){const op=ops[opIndex];op.opIndex=opIndex;switch(op.cmd_string){case BEGIN_ANNOTATION:annotationGroups.push([]);break;case END_ANNOTATION:annotationGroups.pop();break;case ANNOTATION:annotationGroups[annotationGroups.length-1].push(op);break;default:{const annotations=[];let elementInfo={};annotationGroups.forEach(function(annotationGroup){elementInfo={};annotationGroup.forEach(function(annotation){annotation.info.forEach(function(info){if(info.includes(ANNOTATION_TAG)){elementInfo.tag=info.substring(info.indexOf(ANNOTATION_TAG)+
+ANNOTATION_TAG.length).toLowerCase();}else if(info.includes(ANNOTATION_ID)){elementInfo.id=info.substring(info.indexOf(ANNOTATION_ID)+
+ANNOTATION_ID.length);}else if(info.includes(ANNOTATION_CLASS)){elementInfo.class=info.substring(info.indexOf(ANNOTATION_CLASS)+
+ANNOTATION_CLASS.length);}
+annotations.push(info);});});});op.annotations=annotations;op.elementInfo=elementInfo;opsWithoutAnnotations.push(op);}}}
+return opsWithoutAnnotations;}};return{PictureOpsListView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const THIS_DOC=document.currentScript.ownerDocument;const DisplayItemDebugger=tr.ui.b.define('tr-ui-e-chrome-cc-display-item-debugger');DisplayItemDebugger.prototype={__proto__:HTMLDivElement.prototype,decorate(){const node=tr.ui.b.instantiateTemplate('#tr-ui-e-chrome-cc-display-item-debugger-template',THIS_DOC);Polymer.dom(this).appendChild(node);this.style.flexGrow=1;this.style.flexShrink=1;this.style.flexBasis='auto';this.style.display='flex';this.style.minWidth=0;this.pictureAsImageData_=undefined;this.zoomScaleValue_=1;this.sizeInfo_=Polymer.dom(this).querySelector('.size');this.rasterArea_=Polymer.dom(this).querySelector('raster-area');this.rasterArea_.style.flexGrow=1;this.rasterArea_.style.flexShrink=1;this.rasterArea_.style.flexBasis='auto';this.rasterArea_.style.backgroundColor='#ddd';this.rasterArea_.style.minHeight='200px';this.rasterArea_.style.minWidth='200px';this.rasterArea_.style.paddingLeft='5px';this.rasterArea_.style.display='flex';this.rasterArea_.style.flexDirection='column';this.rasterCanvas_=Polymer.dom(this.rasterArea_).querySelector('canvas');this.rasterCtx_=this.rasterCanvas_.getContext('2d');const canvasScroller=Polymer.dom(this).querySelector('canvas-scroller');canvasScroller.style.flexGrow=1;canvasScroller.style.flexShrink=1;canvasScroller.style.flexBasis='auto';canvasScroller.style.minWidth=0;canvasScroller.style.minHeight=0;canvasScroller.style.overflow='auto';this.trackMouse_();this.displayItemInfo_=Polymer.dom(this).querySelector('display-item-info');this.displayItemInfo_.addEventListener('click',this.onDisplayItemInfoClick_.bind(this),false);this.displayItemListView_=new tr.ui.b.ListView();this.displayItemListView_.addEventListener('selection-changed',this.onDisplayItemListSelection_.bind(this));Polymer.dom(this.displayItemInfo_).appendChild(this.displayItemListView_);this.displayListFilename_=Polymer.dom(this).querySelector('.dlfilename');this.displayListExportButton_=Polymer.dom(this).querySelector('.dlexport');this.displayListExportButton_.addEventListener('click',this.onExportDisplayListClicked_.bind(this));this.skpFilename_=Polymer.dom(this).querySelector('.skpfilename');this.skpExportButton_=Polymer.dom(this).querySelector('.skpexport');this.skpExportButton_.addEventListener('click',this.onExportSkPictureClicked_.bind(this));const leftPanel=Polymer.dom(this).querySelector('left-panel');leftPanel.style.flexGrow=0;leftPanel.style.flexShrink=0;leftPanel.style.flexBasis='auto';leftPanel.style.minWidth='200px';leftPanel.style.overflow='auto';leftPanel.children[0].paddingTop='2px';leftPanel.children[0].children[0].style.borderBottom='1px solid #555';const leftPanelTitle=leftPanel.querySelector('.title');leftPanelTitle.style.fontWeight='bold';leftPanelTitle.style.marginLeft='5px';leftPanelTitle.style.marginright='5px';for(const div of leftPanel.querySelectorAll('.export')){div.style.margin='5px';}
+const middleDragHandle=document.createElement('tr-ui-b-drag-handle');middleDragHandle.style.flexGrow=0;middleDragHandle.style.flexShrink=0;middleDragHandle.style.flexBasis='auto';middleDragHandle.horizontal=false;middleDragHandle.target=leftPanel;const rightPanel=Polymer.dom(this).querySelector('right-panel');rightPanel.style.display='flex';rightPanel.style.flexGrow=1;rightPanel.style.flexShrink=1;rightPanel.style.flexBasis='auto';rightPanel.style.minWidth=0;this.infoBar_=document.createElement('tr-ui-b-info-bar');Polymer.dom(this.rasterArea_).insertBefore(this.infoBar_,canvasScroller);Polymer.dom(this).insertBefore(middleDragHandle,rightPanel);this.picture_=undefined;this.pictureOpsListView_=new tr.ui.e.chrome.cc.PictureOpsListView();this.pictureOpsListView_.style.flexGrow=0;this.pictureOpsListView_.style.flexShrink=0;this.pictureOpsListView_.style.flexBasis='auto';this.pictureOpsListView_.style.overflow='auto';this.pictureOpsListView_.style.minWidth='100px';Polymer.dom(rightPanel).insertBefore(this.pictureOpsListView_,this.rasterArea_);this.pictureOpsListDragHandle_=document.createElement('tr-ui-b-drag-handle');this.pictureOpsListDragHandle_.horizontal=false;this.pictureOpsListDragHandle_.target=this.pictureOpsListView_;Polymer.dom(rightPanel).insertBefore(this.pictureOpsListDragHandle_,this.rasterArea_);},get picture(){return this.picture_;},set displayItemList(displayItemList){this.displayItemList_=displayItemList;this.picture=this.displayItemList_;this.displayItemListView_.clear();this.displayItemList_.items.forEach(function(item){const listItem=document.createElement('tr-ui-e-chrome-cc-display-item-list-item');listItem.data=item;Polymer.dom(this.displayItemListView_).appendChild(listItem);}.bind(this));},set picture(picture){this.picture_=picture;const showOpsList=picture&&picture!==this.displayItemList_;this.updateDrawOpsList_(showOpsList);if(picture){const size=this.getRasterCanvasSize_();this.rasterCanvas_.width=size.width;this.rasterCanvas_.height=size.height;}
+const bounds=this.rasterArea_.getBoundingClientRect();const selectorBounds=this.mouseModeSelector_.getBoundingClientRect();this.mouseModeSelector_.pos={x:(bounds.right-selectorBounds.width-10),y:bounds.top};this.rasterize_();this.scheduleUpdateContents_();},getRasterCanvasSize_(){const style=window.getComputedStyle(this.rasterArea_);let width=parseInt(style.width);let height=parseInt(style.height);if(this.picture_){width=Math.max(width,this.picture_.layerRect.width);height=Math.max(height,this.picture_.layerRect.height);}
+return{width,height};},scheduleUpdateContents_(){if(this.updateContentsPending_)return;this.updateContentsPending_=true;tr.b.requestAnimationFrameInThisFrameIfPossible(this.updateContents_.bind(this));},updateContents_(){this.updateContentsPending_=false;if(this.picture_){Polymer.dom(this.sizeInfo_).textContent='('+
 this.picture_.layerRect.width+' x '+
 this.picture_.layerRect.height+')';}
-if(!this.pictureAsImageData_)
-return;this.infoBar_.visible=false;this.infoBar_.removeAllButtons();if(this.pictureAsImageData_.error){this.infoBar_.message='Cannot rasterize...';this.infoBar_.addButton('More info...',function(e){var overlay=new tr.ui.b.Overlay();overlay.textContent=this.pictureAsImageData_.error;overlay.visible=true;e.stopPropagation();return false;}.bind(this));this.infoBar_.visible=true;}
-this.drawPicture_();},drawPicture_:function(){var size=this.getRasterCanvasSize_();if(size.width!==this.rasterCanvas_.width)
-this.rasterCanvas_.width=size.width;if(size.height!==this.rasterCanvas_.height)
-this.rasterCanvas_.height=size.height;this.rasterCtx_.clearRect(0,0,size.width,size.height);if(!this.picture_||!this.pictureAsImageData_.imageData)
-return;var imgCanvas=this.pictureAsImageData_.asCanvas();var w=imgCanvas.width;var h=imgCanvas.height;this.rasterCtx_.drawImage(imgCanvas,0,0,w,h,0,0,w*this.zoomScaleValue_,h*this.zoomScaleValue_);},rasterize_:function(){if(this.picture_){this.picture_.rasterize({showOverdraw:false},this.onRasterComplete_.bind(this));}},onRasterComplete_:function(pictureAsImageData){this.pictureAsImageData_=pictureAsImageData;this.scheduleUpdateContents_();},onDisplayItemListSelection_:function(e){var selected=this.displayItemListView_.selectedElement;if(!selected){this.picture=this.displayItemList_;return;}
-var index=Array.prototype.indexOf.call(this.displayItemListView_.children,selected);var displayItem=this.displayItemList_.items[index];if(displayItem&&displayItem.skp64)
-this.picture=new tr.e.cc.Picture(displayItem.skp64,this.displayItemList_.layerRect);else
-this.picture=undefined;},onDisplayItemInfoClick_:function(e){if(e&&e.target==this.displayItemInfo_){this.displayItemListView_.selectedElement=undefined;}},updateDrawOpsList_:function(showOpsList){if(showOpsList){this.pictureOpsListView_.picture=this.picture_;if(this.pictureOpsListView_.numOps>0){this.pictureOpsListView_.classList.add('hasPictureOps');this.pictureOpsListDragHandle_.classList.add('hasPictureOps');}}else{this.pictureOpsListView_.classList.remove('hasPictureOps');this.pictureOpsListDragHandle_.classList.remove('hasPictureOps');}},trackMouse_:function(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this.rasterArea_;this.rasterArea_.appendChild(this.mouseModeSelector_);this.mouseModeSelector_.supportedModeMask=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.mode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.defaultMode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.settingsKey='pictureDebugger.mouseModeSelector';this.mouseModeSelector_.addEventListener('beginzoom',this.onBeginZoom_.bind(this));this.mouseModeSelector_.addEventListener('updatezoom',this.onUpdateZoom_.bind(this));this.mouseModeSelector_.addEventListener('endzoom',this.onEndZoom_.bind(this));},onBeginZoom_:function(e){this.isZooming_=true;this.lastMouseViewPos_=this.extractRelativeMousePosition_(e);e.preventDefault();},onUpdateZoom_:function(e){if(!this.isZooming_)
-return;var currentMouseViewPos=this.extractRelativeMousePosition_(e);this.zoomScaleValue_+=((this.lastMouseViewPos_.y-currentMouseViewPos.y)*0.001);this.zoomScaleValue_=Math.max(this.zoomScaleValue_,0.1);this.drawPicture_();this.lastMouseViewPos_=currentMouseViewPos;},onEndZoom_:function(e){this.lastMouseViewPos_=undefined;this.isZooming_=false;e.preventDefault();},extractRelativeMousePosition_:function(e){return{x:e.clientX-this.rasterArea_.offsetLeft,y:e.clientY-this.rasterArea_.offsetTop};},saveFile_:function(filename,rawData){if(!rawData)
-return;var length=rawData.length;var arrayBuffer=new ArrayBuffer(length);var uint8Array=new Uint8Array(arrayBuffer);for(var c=0;c<length;c++)
-uint8Array[c]=rawData.charCodeAt(c);var blob=new Blob([uint8Array],{type:'application/octet-binary'});var blobUrl=window.URL.createObjectURL(blob);var link=document.createElementNS('http://www.w3.org/1999/xhtml','a');link.href=blobUrl;link.download=filename;var event=document.createEvent('MouseEvents');event.initMouseEvent('click',true,false,window,0,0,0,0,0,false,false,false,false,0,null);link.dispatchEvent(event);},onExportDisplayListClicked_:function(){var rawData=JSON.stringify(this.displayItemList_.items);this.saveFile_(this.displayListFilename_.value,rawData);},onExportSkPictureClicked_:function(){var rawData=tr.b.Base64.atob(this.picture_.getBase64SkpData());this.saveFile_(this.skpFilename_.value,rawData);}};return{DisplayItemDebugger:DisplayItemDebugger};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var DisplayItemSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-display-item-list-view',tr.ui.analysis.ObjectSnapshotView);DisplayItemSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-chrome-cc-display-item-list-view');this.displayItemDebugger_=new tr.ui.e.chrome.cc.DisplayItemDebugger();this.appendChild(this.displayItemDebugger_);},updateContents:function(){if(this.objectSnapshot_&&this.displayItemDebugger_)
-this.displayItemDebugger_.displayItemList=this.objectSnapshot_;}};tr.ui.analysis.ObjectSnapshotView.register(DisplayItemSnapshotView,{typeNames:['cc::DisplayItemList'],showInstances:false});return{DisplayItemSnapshotView:DisplayItemSnapshotView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var constants=tr.e.cc.constants;var bytesToRoundedMegabytes=tr.e.cc.bytesToRoundedMegabytes;var RENDER_PASS_QUADS=Math.max(constants.ACTIVE_TREE,constants.PENDING_TREE)+1;var LayerPicker=tr.ui.b.define('tr-ui-e-chrome-cc-layer-picker');LayerPicker.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.lthi_=undefined;this.controls_=document.createElement('top-controls');this.renderPassQuads_=false;this.itemList_=new tr.ui.b.ListView();this.appendChild(this.controls_);this.appendChild(this.itemList_);this.itemList_.addEventListener('selection-changed',this.onItemSelectionChanged_.bind(this));this.controls_.appendChild(tr.ui.b.createSelector(this,'whichTree','layerPicker.whichTree',constants.ACTIVE_TREE,[{label:'Active tree',value:constants.ACTIVE_TREE},{label:'Pending tree',value:constants.PENDING_TREE},{label:'Render pass quads',value:RENDER_PASS_QUADS}]));this.showPureTransformLayers_=false;var showPureTransformLayers=tr.ui.b.createCheckBox(this,'showPureTransformLayers','layerPicker.showPureTransformLayers',false,'Transform layers');showPureTransformLayers.classList.add('show-transform-layers');showPureTransformLayers.title='When checked, pure transform layers are shown';this.controls_.appendChild(showPureTransformLayers);},get lthiSnapshot(){return this.lthiSnapshot_;},set lthiSnapshot(lthiSnapshot){this.lthiSnapshot_=lthiSnapshot;this.updateContents_();},get whichTree(){return this.renderPassQuads_?constants.ACTIVE_TREE:this.whichTree_;},set whichTree(whichTree){this.whichTree_=whichTree;this.renderPassQuads_=(whichTree==RENDER_PASS_QUADS);this.updateContents_();tr.b.dispatchSimpleEvent(this,'selection-change',false);},get layerTreeImpl(){if(this.lthiSnapshot===undefined)
-return undefined;return this.lthiSnapshot.getTree(this.whichTree);},get isRenderPassQuads(){return this.renderPassQuads_;},get showPureTransformLayers(){return this.showPureTransformLayers_;},set showPureTransformLayers(show){if(this.showPureTransformLayers_===show)
-return;this.showPureTransformLayers_=show;this.updateContents_();},getRenderPassInfos_:function(){if(!this.lthiSnapshot_)
-return[];var renderPassInfo=[];if(!this.lthiSnapshot_.args.frame||!this.lthiSnapshot_.args.frame.renderPasses)
-return renderPassInfo;var renderPasses=this.lthiSnapshot_.args.frame.renderPasses;for(var i=0;i<renderPasses.length;++i){var info={renderPass:renderPasses[i],depth:0,id:i,name:'cc::RenderPass'};renderPassInfo.push(info);}
-return renderPassInfo;},getLayerInfos_:function(){if(!this.lthiSnapshot_)
-return[];var tree=this.lthiSnapshot_.getTree(this.whichTree_);if(!tree)
-return[];var layerInfos=[];var showPureTransformLayers=this.showPureTransformLayers_;function isPureTransformLayer(layer){if(layer.args.compositingReasons&&layer.args.compositingReasons.length!=1&&layer.args.compositingReasons[0]!='No reasons given')
-return false;if(layer.args.drawsContent)
-return false;return true;}
-var visitedLayers={};function visitLayer(layer,depth,isMask,isReplica){if(visitedLayers[layer.layerId])
-return;visitedLayers[layer.layerId]=true;var info={layer:layer,depth:depth};if(layer.args.drawsContent)
-info.name=layer.objectInstance.name;else
-info.name='cc::LayerImpl';if(layer.usingGpuRasterization)
-info.name+=' (G)';info.isMaskLayer=isMask;info.replicaLayer=isReplica;if(showPureTransformLayers||!isPureTransformLayer(layer))
-layerInfos.push(info);};tree.iterLayers(visitLayer);return layerInfos;},updateContents_:function(){if(this.renderPassQuads_)
-this.updateRenderPassContents_();else
-this.updateLayerContents_();},updateRenderPassContents_:function(){this.itemList_.clear();var selectedRenderPassId;if(this.selection_&&this.selection_.associatedRenderPassId)
-selectedRenderPassId=this.selection_.associatedRenderPassId;var renderPassInfos=this.getRenderPassInfos_();renderPassInfos.forEach(function(renderPassInfo){var renderPass=renderPassInfo.renderPass;var id=renderPassInfo.id;var item=this.createElementWithDepth_(renderPassInfo.depth);var labelEl=item.appendChild(tr.ui.b.createSpan());labelEl.textContent=renderPassInfo.name+' '+id;item.renderPass=renderPass;item.renderPassId=id;this.itemList_.appendChild(item);if(id==selectedRenderPassId){renderPass.selectionState=tr.model.SelectionState.SELECTED;}},this);},updateLayerContents_:function(){this.changingItemSelection_=true;try{this.itemList_.clear();var selectedLayerId;if(this.selection_&&this.selection_.associatedLayerId)
-selectedLayerId=this.selection_.associatedLayerId;var layerInfos=this.getLayerInfos_();layerInfos.forEach(function(layerInfo){var layer=layerInfo.layer;var id=layer.layerId;var item=this.createElementWithDepth_(layerInfo.depth);var labelEl=item.appendChild(tr.ui.b.createSpan());labelEl.textContent=layerInfo.name+' '+id;var notesEl=item.appendChild(tr.ui.b.createSpan());if(layerInfo.isMaskLayer)
-notesEl.textContent+='(mask)';if(layerInfo.isReplicaLayer)
-notesEl.textContent+='(replica)';if(layer.gpuMemoryUsageInBytes!==undefined){var rounded=bytesToRoundedMegabytes(layer.gpuMemoryUsageInBytes);if(rounded!==0)
-notesEl.textContent+=' ('+rounded+' MB)';}
-item.layer=layer;this.itemList_.appendChild(item);if(layer.layerId==selectedLayerId){layer.selectionState=tr.model.SelectionState.SELECTED;item.selected=true;}},this);}finally{this.changingItemSelection_=false;}},createElementWithDepth_:function(depth){var item=document.createElement('div');var indentEl=item.appendChild(tr.ui.b.createSpan());indentEl.style.whiteSpace='pre';for(var i=0;i<depth;i++)
-indentEl.textContent=indentEl.textContent+' ';return item;},onItemSelectionChanged_:function(e){if(this.changingItemSelection_)
-return;if(this.renderPassQuads_)
-this.onRenderPassSelected_(e);else
-this.onLayerSelected_(e);tr.b.dispatchSimpleEvent(this,'selection-change',false);},onRenderPassSelected_:function(e){var selectedRenderPass;var selectedRenderPassId;if(this.itemList_.selectedElement){selectedRenderPass=this.itemList_.selectedElement.renderPass;selectedRenderPassId=this.itemList_.selectedElement.renderPassId;}
-if(selectedRenderPass){this.selection_=new tr.ui.e.chrome.cc.RenderPassSelection(selectedRenderPass,selectedRenderPassId);}else{this.selection_=undefined;}},onLayerSelected_:function(e){var selectedLayer;if(this.itemList_.selectedElement)
-selectedLayer=this.itemList_.selectedElement.layer;if(selectedLayer)
-this.selection_=new tr.ui.e.chrome.cc.LayerSelection(selectedLayer);else
-this.selection_=undefined;},get selection(){return this.selection_;},set selection(selection){if(this.selection_==selection)
-return;this.selection_=selection;this.updateContents_();}};return{LayerPicker:LayerPicker};});'use strict';tr.exportTo('tr.e.cc',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function RenderPassSnapshot(){ObjectSnapshot.apply(this,arguments);}
-RenderPassSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);},initialize:function(){tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['quadList']);}};ObjectSnapshot.register(RenderPassSnapshot,{typeName:'cc::RenderPass'});return{RenderPassSnapshot:RenderPassSnapshot};});'use strict';tr.exportTo('tr.ui.b',function(){var constants={DEFAULT_SCALE:0.5,DEFAULT_EYE_DISTANCE:10000,MINIMUM_DISTANCE:1000,MAXIMUM_DISTANCE:100000,FOV:15,RESCALE_TIMEOUT_MS:200,MAXIMUM_TILT:80,SETTINGS_NAMESPACE:'tr.ui_camera'};var Camera=tr.ui.b.define('camera');Camera.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(eventSource){this.eventSource_=eventSource;this.eventSource_.addEventListener('beginpan',this.onPanBegin_.bind(this));this.eventSource_.addEventListener('updatepan',this.onPanUpdate_.bind(this));this.eventSource_.addEventListener('endpan',this.onPanEnd_.bind(this));this.eventSource_.addEventListener('beginzoom',this.onZoomBegin_.bind(this));this.eventSource_.addEventListener('updatezoom',this.onZoomUpdate_.bind(this));this.eventSource_.addEventListener('endzoom',this.onZoomEnd_.bind(this));this.eventSource_.addEventListener('beginrotate',this.onRotateBegin_.bind(this));this.eventSource_.addEventListener('updaterotate',this.onRotateUpdate_.bind(this));this.eventSource_.addEventListener('endrotate',this.onRotateEnd_.bind(this));this.eye_=[0,0,constants.DEFAULT_EYE_DISTANCE];this.gazeTarget_=[0,0,0];this.rotation_=[0,0];this.pixelRatio_=window.devicePixelRatio||1;},get modelViewMatrix(){var mvMatrix=mat4.create();mat4.lookAt(mvMatrix,this.eye_,this.gazeTarget_,[0,1,0]);return mvMatrix;},get projectionMatrix(){var rect=tr.ui.b.windowRectForElement(this.canvas_).scaleSize(this.pixelRatio_);var aspectRatio=rect.width/rect.height;var matrix=mat4.create();mat4.perspective(matrix,tr.b.deg2rad(constants.FOV),aspectRatio,1,100000);return matrix;},set canvas(c){this.canvas_=c;},set deviceRect(rect){this.deviceRect_=rect;},get stackingDistanceDampening(){var gazeVector=[this.gazeTarget_[0]-this.eye_[0],this.gazeTarget_[1]-this.eye_[1],this.gazeTarget_[2]-this.eye_[2]];vec3.normalize(gazeVector,gazeVector);return 1+gazeVector[2];},loadCameraFromSettings:function(settings){this.eye_=settings.get('eye',this.eye_,constants.SETTINGS_NAMESPACE);this.gazeTarget_=settings.get('gaze_target',this.gazeTarget_,constants.SETTINGS_NAMESPACE);this.rotation_=settings.get('rotation',this.rotation_,constants.SETTINGS_NAMESPACE);this.dispatchRenderEvent_();},saveCameraToSettings:function(settings){settings.set('eye',this.eye_,constants.SETTINGS_NAMESPACE);settings.set('gaze_target',this.gazeTarget_,constants.SETTINGS_NAMESPACE);settings.set('rotation',this.rotation_,constants.SETTINGS_NAMESPACE);},resetCamera:function(){this.eye_=[0,0,constants.DEFAULT_EYE_DISTANCE];this.gazeTarget_=[0,0,0];this.rotation_=[0,0];var settings=tr.b.SessionSettings();var keys=settings.keys(constants.SETTINGS_NAMESPACE);if(keys.length!==0){this.loadCameraFromSettings(settings);return;}
-if(this.deviceRect_){var rect=tr.ui.b.windowRectForElement(this.canvas_).scaleSize(this.pixelRatio_);this.eye_[0]=this.deviceRect_.width/2;this.eye_[1]=this.deviceRect_.height/2;this.gazeTarget_[0]=this.deviceRect_.width/2;this.gazeTarget_[1]=this.deviceRect_.height/2;}
-this.saveCameraToSettings(settings);this.dispatchRenderEvent_();},updatePanByDelta:function(delta){var rect=tr.ui.b.windowRectForElement(this.canvas_).scaleSize(this.pixelRatio_);var eyeVector=[this.eye_[0]-this.gazeTarget_[0],this.eye_[1]-this.gazeTarget_[1],this.eye_[2]-this.gazeTarget_[2]];var length=vec3.length(eyeVector);vec3.normalize(eyeVector,eyeVector);var halfFov=constants.FOV/2;var multiplier=2.0*length*Math.tan(tr.b.deg2rad(halfFov))/rect.height;var up=[0,1,0];var rotMatrix=mat4.create();mat4.rotate(rotMatrix,rotMatrix,tr.b.deg2rad(this.rotation_[1]),[0,1,0]);mat4.rotate(rotMatrix,rotMatrix,tr.b.deg2rad(this.rotation_[0]),[1,0,0]);vec3.transformMat4(up,up,rotMatrix);var right=[0,0,0];vec3.cross(right,eyeVector,up);vec3.normalize(right,right);for(var i=0;i<3;++i){this.gazeTarget_[i]+=delta[0]*multiplier*right[i]-delta[1]*multiplier*up[i];this.eye_[i]=this.gazeTarget_[i]+length*eyeVector[i];}
-if(Math.abs(this.gazeTarget_[2])>1e-6){var gazeVector=[-eyeVector[0],-eyeVector[1],-eyeVector[2]];var newLength=tr.b.clamp(-this.eye_[2]/gazeVector[2],constants.MINIMUM_DISTANCE,constants.MAXIMUM_DISTANCE);for(var i=0;i<3;++i)
-this.gazeTarget_[i]=this.eye_[i]+newLength*gazeVector[i];}
-this.saveCameraToSettings(tr.b.SessionSettings());this.dispatchRenderEvent_();},updateZoomByDelta:function(delta){var deltaY=delta[1];deltaY=tr.b.clamp(deltaY,-50,50);var scale=1.0-deltaY/100.0;var eyeVector=[0,0,0];vec3.subtract(eyeVector,this.eye_,this.gazeTarget_);var length=vec3.length(eyeVector);if(length*scale<constants.MINIMUM_DISTANCE)
-scale=constants.MINIMUM_DISTANCE/length;else if(length*scale>constants.MAXIMUM_DISTANCE)
-scale=constants.MAXIMUM_DISTANCE/length;vec3.scale(eyeVector,eyeVector,scale);vec3.add(this.eye_,this.gazeTarget_,eyeVector);this.saveCameraToSettings(tr.b.SessionSettings());this.dispatchRenderEvent_();},updateRotateByDelta:function(delta){delta[0]*=0.5;delta[1]*=0.5;if(Math.abs(this.rotation_[0]+delta[1])>constants.MAXIMUM_TILT)
-return;if(Math.abs(this.rotation_[1]-delta[0])>constants.MAXIMUM_TILT)
-return;var eyeVector=[0,0,0,0];vec3.subtract(eyeVector,this.eye_,this.gazeTarget_);var rotMatrix=mat4.create();mat4.rotate(rotMatrix,rotMatrix,-tr.b.deg2rad(this.rotation_[0]),[1,0,0]);mat4.rotate(rotMatrix,rotMatrix,-tr.b.deg2rad(this.rotation_[1]),[0,1,0]);vec4.transformMat4(eyeVector,eyeVector,rotMatrix);this.rotation_[0]+=delta[1];this.rotation_[1]-=delta[0];mat4.identity(rotMatrix);mat4.rotate(rotMatrix,rotMatrix,tr.b.deg2rad(this.rotation_[1]),[0,1,0]);mat4.rotate(rotMatrix,rotMatrix,tr.b.deg2rad(this.rotation_[0]),[1,0,0]);vec4.transformMat4(eyeVector,eyeVector,rotMatrix);vec3.add(this.eye_,this.gazeTarget_,eyeVector);this.saveCameraToSettings(tr.b.SessionSettings());this.dispatchRenderEvent_();},onPanBegin_:function(e){this.panning_=true;this.lastMousePosition_=this.getMousePosition_(e);},onPanUpdate_:function(e){if(!this.panning_)
-return;var delta=this.getMouseDelta_(e,this.lastMousePosition_);this.lastMousePosition_=this.getMousePosition_(e);this.updatePanByDelta(delta);},onPanEnd_:function(e){this.panning_=false;},onZoomBegin_:function(e){this.zooming_=true;var p=this.getMousePosition_(e);this.lastMousePosition_=p;this.zoomPoint_=p;},onZoomUpdate_:function(e){if(!this.zooming_)
-return;var delta=this.getMouseDelta_(e,this.lastMousePosition_);this.lastMousePosition_=this.getMousePosition_(e);this.updateZoomByDelta(delta);},onZoomEnd_:function(e){this.zooming_=false;this.zoomPoint_=undefined;},onRotateBegin_:function(e){this.rotating_=true;this.lastMousePosition_=this.getMousePosition_(e);},onRotateUpdate_:function(e){if(!this.rotating_)
-return;var delta=this.getMouseDelta_(e,this.lastMousePosition_);this.lastMousePosition_=this.getMousePosition_(e);this.updateRotateByDelta(delta);},onRotateEnd_:function(e){this.rotating_=false;},getMousePosition_:function(e){var rect=tr.ui.b.windowRectForElement(this.canvas_);return[(e.clientX-rect.x)*this.pixelRatio_,(e.clientY-rect.y)*this.pixelRatio_];},getMouseDelta_:function(e,p){var newP=this.getMousePosition_(e);return[newP[0]-p[0],newP[1]-p[1]];},dispatchRenderEvent_:function(){tr.b.dispatchSimpleEvent(this,'renderrequired',false,false);}};return{Camera:Camera};});'use strict';tr.exportTo('tr.ui.b',function(){var THIS_DOC=document.currentScript.ownerDocument;var constants={};constants.IMAGE_LOAD_RETRY_TIME_MS=500;constants.SUBDIVISION_MINIMUM=1;constants.SUBDIVISION_RECURSION_DEPTH=3;constants.SUBDIVISION_DEPTH_THRESHOLD=100;constants.FAR_PLANE_DISTANCE=10000;function drawTexturedTriangle(ctx,img,p0,p1,p2,t0,t1,t2){var tmp_p0=[p0[0],p0[1]];var tmp_p1=[p1[0],p1[1]];var tmp_p2=[p2[0],p2[1]];var tmp_t0=[t0[0],t0[1]];var tmp_t1=[t1[0],t1[1]];var tmp_t2=[t2[0],t2[1]];ctx.beginPath();ctx.moveTo(tmp_p0[0],tmp_p0[1]);ctx.lineTo(tmp_p1[0],tmp_p1[1]);ctx.lineTo(tmp_p2[0],tmp_p2[1]);ctx.closePath();tmp_p1[0]-=tmp_p0[0];tmp_p1[1]-=tmp_p0[1];tmp_p2[0]-=tmp_p0[0];tmp_p2[1]-=tmp_p0[1];tmp_t1[0]-=tmp_t0[0];tmp_t1[1]-=tmp_t0[1];tmp_t2[0]-=tmp_t0[0];tmp_t2[1]-=tmp_t0[1];var det=1/(tmp_t1[0]*tmp_t2[1]-tmp_t2[0]*tmp_t1[1]),a=(tmp_t2[1]*tmp_p1[0]-tmp_t1[1]*tmp_p2[0])*det,b=(tmp_t2[1]*tmp_p1[1]-tmp_t1[1]*tmp_p2[1])*det,c=(tmp_t1[0]*tmp_p2[0]-tmp_t2[0]*tmp_p1[0])*det,d=(tmp_t1[0]*tmp_p2[1]-tmp_t2[0]*tmp_p1[1])*det,e=tmp_p0[0]-a*tmp_t0[0]-c*tmp_t0[1],f=tmp_p0[1]-b*tmp_t0[0]-d*tmp_t0[1];ctx.save();ctx.transform(a,b,c,d,e,f);ctx.clip();ctx.drawImage(img,0,0);ctx.restore();}
-function drawTriangleSub(ctx,img,p0,p1,p2,t0,t1,t2,opt_recursion_depth){var depth=opt_recursion_depth||0;var subdivisionIndex=0;if(depth<constants.SUBDIVISION_MINIMUM){subdivisionIndex=7;}else if(depth<constants.SUBDIVISION_RECURSION_DEPTH){if(Math.abs(p0[2]-p1[2])>constants.SUBDIVISION_DEPTH_THRESHOLD)
-subdivisionIndex+=1;if(Math.abs(p0[2]-p2[2])>constants.SUBDIVISION_DEPTH_THRESHOLD)
-subdivisionIndex+=2;if(Math.abs(p1[2]-p2[2])>constants.SUBDIVISION_DEPTH_THRESHOLD)
-subdivisionIndex+=4;}
-var p01=vec4.create();var p02=vec4.create();var p12=vec4.create();var t01=vec2.create();var t02=vec2.create();var t12=vec2.create();for(var i=0;i<2;++i){p0[i]*=p0[2];p1[i]*=p1[2];p2[i]*=p2[2];}
-for(var i=0;i<4;++i){p01[i]=(p0[i]+p1[i])/2;p02[i]=(p0[i]+p2[i])/2;p12[i]=(p1[i]+p2[i])/2;}
-for(var i=0;i<2;++i){p0[i]/=p0[2];p1[i]/=p1[2];p2[i]/=p2[2];p01[i]/=p01[2];p02[i]/=p02[2];p12[i]/=p12[2];}
-for(var i=0;i<2;++i){t01[i]=(t0[i]+t1[i])/2;t02[i]=(t0[i]+t2[i])/2;t12[i]=(t1[i]+t2[i])/2;}
+if(!this.pictureAsImageData_)return;this.infoBar_.visible=false;this.infoBar_.removeAllButtons();if(this.pictureAsImageData_.error){this.infoBar_.message='Cannot rasterize...';this.infoBar_.addButton('More info...',function(e){const overlay=new tr.ui.b.Overlay();Polymer.dom(overlay).textContent=this.pictureAsImageData_.error;overlay.visible=true;e.stopPropagation();return false;}.bind(this));this.infoBar_.visible=true;}
+this.drawPicture_();},drawPicture_(){const size=this.getRasterCanvasSize_();if(size.width!==this.rasterCanvas_.width){this.rasterCanvas_.width=size.width;}
+if(size.height!==this.rasterCanvas_.height){this.rasterCanvas_.height=size.height;}
+this.rasterCtx_.clearRect(0,0,size.width,size.height);if(!this.picture_||!this.pictureAsImageData_.imageData)return;const imgCanvas=this.pictureAsImageData_.asCanvas();const w=imgCanvas.width;const h=imgCanvas.height;this.rasterCtx_.drawImage(imgCanvas,0,0,w,h,0,0,w*this.zoomScaleValue_,h*this.zoomScaleValue_);},rasterize_(){if(this.picture_){this.picture_.rasterize({showOverdraw:false},this.onRasterComplete_.bind(this));}},onRasterComplete_(pictureAsImageData){this.pictureAsImageData_=pictureAsImageData;this.scheduleUpdateContents_();},onDisplayItemListSelection_(e){const selected=this.displayItemListView_.selectedElement;if(!selected){this.picture=this.displayItemList_;return;}
+const index=Array.prototype.indexOf.call(this.displayItemListView_.children,selected);const displayItem=this.displayItemList_.items[index];if(displayItem&&displayItem.skp64){this.picture=new tr.e.cc.Picture(displayItem.skp64,this.displayItemList_.layerRect);}else{this.picture=undefined;}},onDisplayItemInfoClick_(e){if(e&&e.target===this.displayItemInfo_){this.displayItemListView_.selectedElement=undefined;}},updateDrawOpsList_(showOpsList){if(showOpsList){this.pictureOpsListView_.picture=this.picture_;if(this.pictureOpsListView_.numOps>0){this.pictureOpsListView_.style.display='block';this.pictureOpsListDragHandle_.style.display='block';}}else{this.pictureOpsListView_.style.display='none';this.pictureOpsListDragHandle_.style.display='none';}},trackMouse_(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this.rasterArea_;Polymer.dom(this.rasterArea_).appendChild(this.mouseModeSelector_);this.mouseModeSelector_.supportedModeMask=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.mode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.defaultMode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.settingsKey='pictureDebugger.mouseModeSelector';this.mouseModeSelector_.addEventListener('beginzoom',this.onBeginZoom_.bind(this));this.mouseModeSelector_.addEventListener('updatezoom',this.onUpdateZoom_.bind(this));this.mouseModeSelector_.addEventListener('endzoom',this.onEndZoom_.bind(this));},onBeginZoom_(e){this.isZooming_=true;this.lastMouseViewPos_=this.extractRelativeMousePosition_(e);e.preventDefault();},onUpdateZoom_(e){if(!this.isZooming_)return;const currentMouseViewPos=this.extractRelativeMousePosition_(e);this.zoomScaleValue_+=((this.lastMouseViewPos_.y-currentMouseViewPos.y)*0.001);this.zoomScaleValue_=Math.max(this.zoomScaleValue_,0.1);this.drawPicture_();this.lastMouseViewPos_=currentMouseViewPos;},onEndZoom_(e){this.lastMouseViewPos_=undefined;this.isZooming_=false;e.preventDefault();},extractRelativeMousePosition_(e){return{x:e.clientX-this.rasterArea_.offsetLeft,y:e.clientY-this.rasterArea_.offsetTop};},saveFile_(filename,rawData){if(!rawData)return;const length=rawData.length;const arrayBuffer=new ArrayBuffer(length);const uint8Array=new Uint8Array(arrayBuffer);for(let c=0;c<length;c++){uint8Array[c]=rawData.charCodeAt(c);}
+const blob=new Blob([uint8Array],{type:'application/octet-binary'});const blobUrl=window.URL.createObjectURL(blob);const link=document.createElementNS('http://www.w3.org/1999/xhtml','a');link.href=blobUrl;link.download=filename;const event=document.createEvent('MouseEvents');event.initMouseEvent('click',true,false,window,0,0,0,0,0,false,false,false,false,0,null);link.dispatchEvent(event);},onExportDisplayListClicked_(){const rawData=JSON.stringify(this.displayItemList_.items);this.saveFile_(this.displayListFilename_.value,rawData);},onExportSkPictureClicked_(){const rawData=tr.b.Base64.atob(this.picture_.getBase64SkpData());this.saveFile_(this.skpFilename_.value,rawData);}};return{DisplayItemDebugger,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const DisplayItemSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-display-item-list-view',tr.ui.analysis.ObjectSnapshotView);DisplayItemSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate(){this.style.display='flex';this.style.flexGrow=1;this.style.flexShrink=1;this.style.flexBasis='auto';this.style.minWidth=0;this.displayItemDebugger_=new tr.ui.e.chrome.cc.DisplayItemDebugger();this.displayItemDebugger_.style.flexGrow=1;this.displayItemDebugger_.style.flexShrink=1;this.displayItemDebugger_.style.flexBasis='auto';this.displayItemDebugger_.style.minWidth=0;Polymer.dom(this).appendChild(this.displayItemDebugger_);},updateContents(){if(this.objectSnapshot_&&this.displayItemDebugger_){this.displayItemDebugger_.displayItemList=this.objectSnapshot_;}}};tr.ui.analysis.ObjectSnapshotView.register(DisplayItemSnapshotView,{typeNames:['cc::DisplayItemList'],showInstances:false});return{DisplayItemSnapshotView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const constants=tr.e.cc.constants;const RENDER_PASS_QUADS=Math.max(constants.ACTIVE_TREE,constants.PENDING_TREE)+1;const LayerPicker=tr.ui.b.define('tr-ui-e-chrome-cc-layer-picker');LayerPicker.prototype={__proto__:HTMLUnknownElement.prototype,decorate(){this.lthi_=undefined;this.controls_=document.createElement('top-controls');this.renderPassQuads_=false;this.style.display='flex';this.style.flexDirection='column';this.controls_.style.flexGrow=0;this.controls_.style.flexShrink=0;this.controls_.style.flexBasis='auto';this.controls_.style.backgroundImage='-webkit-gradient(linear, 0 0, 100% 0, from(#E5E5E5), to(#D1D1D1))';this.controls_.style.borderBottom='1px solid #8e8e8e';this.controls_.style.borderTop='1px solid white';this.controls_.style.display='inline';this.controls_.style.fontSize='14px';this.controls_.style.paddingLeft='2px';this.itemList_=new tr.ui.b.ListView();this.itemList_.style.flexGrow=1;this.itemList_.style.flexShrink=1;this.itemList_.style.flexBasis='auto';this.itemList_.style.fontFamily='monospace';this.itemList_.style.overflow='auto';Polymer.dom(this).appendChild(this.controls_);Polymer.dom(this).appendChild(this.itemList_);this.itemList_.addEventListener('selection-changed',this.onItemSelectionChanged_.bind(this));Polymer.dom(this.controls_).appendChild(tr.ui.b.createSelector(this,'whichTree','layerPicker.whichTree',constants.ACTIVE_TREE,[{label:'Active tree',value:constants.ACTIVE_TREE},{label:'Pending tree',value:constants.PENDING_TREE},{label:'Render pass quads',value:RENDER_PASS_QUADS}]));this.showPureTransformLayers_=false;const showPureTransformLayers=tr.ui.b.createCheckBox(this,'showPureTransformLayers','layerPicker.showPureTransformLayers',false,'Transform layers');Polymer.dom(showPureTransformLayers).classList.add('show-transform-layers');showPureTransformLayers.title='When checked, pure transform layers are shown';Polymer.dom(this.controls_).appendChild(showPureTransformLayers);},get lthiSnapshot(){return this.lthiSnapshot_;},set lthiSnapshot(lthiSnapshot){this.lthiSnapshot_=lthiSnapshot;this.updateContents_();},get whichTree(){return this.renderPassQuads_?constants.ACTIVE_TREE:this.whichTree_;},set whichTree(whichTree){this.whichTree_=whichTree;this.renderPassQuads_=(whichTree===RENDER_PASS_QUADS);this.updateContents_();tr.b.dispatchSimpleEvent(this,'selection-change',false);},get layerTreeImpl(){if(this.lthiSnapshot===undefined)return undefined;return this.lthiSnapshot.getTree(this.whichTree);},get isRenderPassQuads(){return this.renderPassQuads_;},get showPureTransformLayers(){return this.showPureTransformLayers_;},set showPureTransformLayers(show){if(this.showPureTransformLayers_===show)return;this.showPureTransformLayers_=show;this.updateContents_();},getRenderPassInfos_(){if(!this.lthiSnapshot_)return[];const renderPassInfo=[];if(!this.lthiSnapshot_.args.frame||!this.lthiSnapshot_.args.frame.renderPasses){return renderPassInfo;}
+const renderPasses=this.lthiSnapshot_.args.frame.renderPasses;for(let i=0;i<renderPasses.length;++i){const info={renderPass:renderPasses[i],depth:0,id:i,name:'cc::RenderPass'};renderPassInfo.push(info);}
+return renderPassInfo;},getLayerInfos_(){if(!this.lthiSnapshot_)return[];const tree=this.lthiSnapshot_.getTree(this.whichTree_);if(!tree)return[];const layerInfos=[];const showPureTransformLayers=this.showPureTransformLayers_;const visitedLayers={};function visitLayer(layer,depth,isMask,isReplica){if(visitedLayers[layer.layerId])return;visitedLayers[layer.layerId]=true;const info={layer,depth};if(layer.args.drawsContent){info.name=layer.objectInstance.name;}else{info.name='cc::LayerImpl';}
+if(layer.usingGpuRasterization){info.name+=' (G)';}
+info.isMaskLayer=isMask;info.replicaLayer=isReplica;if(showPureTransformLayers||layer.args.drawsContent){layerInfos.push(info);}}
+tree.iterLayers(visitLayer);return layerInfos;},updateContents_(){if(this.renderPassQuads_){this.updateRenderPassContents_();}else{this.updateLayerContents_();}},updateRenderPassContents_(){this.itemList_.clear();let selectedRenderPassId;if(this.selection_&&this.selection_.associatedRenderPassId){selectedRenderPassId=this.selection_.associatedRenderPassId;}
+const renderPassInfos=this.getRenderPassInfos_();renderPassInfos.forEach(function(renderPassInfo){const renderPass=renderPassInfo.renderPass;const id=renderPassInfo.id;const item=this.createElementWithDepth_(renderPassInfo.depth);const labelEl=Polymer.dom(item).appendChild(tr.ui.b.createSpan());Polymer.dom(labelEl).textContent=renderPassInfo.name+' '+id;item.renderPass=renderPass;item.renderPassId=id;Polymer.dom(this.itemList_).appendChild(item);if(id===selectedRenderPassId){renderPass.selectionState=tr.model.SelectionState.SELECTED;}},this);},updateLayerContents_(){this.changingItemSelection_=true;try{this.itemList_.clear();let selectedLayerId;if(this.selection_&&this.selection_.associatedLayerId){selectedLayerId=this.selection_.associatedLayerId;}
+const layerInfos=this.getLayerInfos_();layerInfos.forEach(function(layerInfo){const layer=layerInfo.layer;const id=layer.layerId;const item=this.createElementWithDepth_(layerInfo.depth);const labelEl=Polymer.dom(item).appendChild(tr.ui.b.createSpan());Polymer.dom(labelEl).textContent=layerInfo.name+' '+id;const notesEl=Polymer.dom(item).appendChild(tr.ui.b.createSpan());if(layerInfo.isMaskLayer){Polymer.dom(notesEl).textContent+='(mask)';}
+if(layerInfo.isReplicaLayer){Polymer.dom(notesEl).textContent+='(replica)';}
+if((layer.gpuMemoryUsageInBytes!==undefined)&&(layer.gpuMemoryUsageInBytes>0)){const gpuUsageStr=tr.b.Unit.byName.sizeInBytes.format(layer.gpuMemoryUsageInBytes);Polymer.dom(notesEl).textContent+=' ('+gpuUsageStr+' MiB)';}
+item.layer=layer;Polymer.dom(this.itemList_).appendChild(item);if(layer.layerId===selectedLayerId){layer.selectionState=tr.model.SelectionState.SELECTED;item.selected=true;}},this);}finally{this.changingItemSelection_=false;}},createElementWithDepth_(depth){const item=document.createElement('div');const indentEl=Polymer.dom(item).appendChild(tr.ui.b.createSpan());indentEl.style.whiteSpace='pre';for(let i=0;i<depth;i++){Polymer.dom(indentEl).textContent=Polymer.dom(indentEl).textContent+' ';}
+return item;},onItemSelectionChanged_(e){if(this.changingItemSelection_)return;if(this.renderPassQuads_){this.onRenderPassSelected_(e);}else{this.onLayerSelected_(e);}
+tr.b.dispatchSimpleEvent(this,'selection-change',false);},onRenderPassSelected_(e){let selectedRenderPass;let selectedRenderPassId;if(this.itemList_.selectedElement){selectedRenderPass=this.itemList_.selectedElement.renderPass;selectedRenderPassId=this.itemList_.selectedElement.renderPassId;}
+if(selectedRenderPass){this.selection_=new tr.ui.e.chrome.cc.RenderPassSelection(selectedRenderPass,selectedRenderPassId);}else{this.selection_=undefined;}},onLayerSelected_(e){let selectedLayer;if(this.itemList_.selectedElement){selectedLayer=this.itemList_.selectedElement.layer;}
+if(selectedLayer){this.selection_=new tr.ui.e.chrome.cc.LayerSelection(selectedLayer);}else{this.selection_=undefined;}},get selection(){return this.selection_;},set selection(selection){if(this.selection_===selection)return;this.selection_=selection;this.updateContents_();}};return{LayerPicker,};});'use strict';tr.exportTo('tr.e.cc',function(){const ObjectSnapshot=tr.model.ObjectSnapshot;function RenderPassSnapshot(){ObjectSnapshot.apply(this,arguments);}
+RenderPassSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize(){tr.e.cc.preInitializeObject(this);},initialize(){tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['quadList']);}};ObjectSnapshot.subTypes.register(RenderPassSnapshot,{typeName:'cc::RenderPass'});return{RenderPassSnapshot,};});'use strict';tr.exportTo('tr.ui.b',function(){const deg2rad=tr.b.math.deg2rad;const constants={DEFAULT_SCALE:0.5,DEFAULT_EYE_DISTANCE:10000,MINIMUM_DISTANCE:1000,MAXIMUM_DISTANCE:100000,FOV:15,RESCALE_TIMEOUT_MS:200,MAXIMUM_TILT:80,SETTINGS_NAMESPACE:'tr.ui_camera'};const Camera=tr.ui.b.define('camera');Camera.prototype={__proto__:HTMLUnknownElement.prototype,decorate(eventSource){this.eventSource_=eventSource;this.eventSource_.addEventListener('beginpan',this.onPanBegin_.bind(this));this.eventSource_.addEventListener('updatepan',this.onPanUpdate_.bind(this));this.eventSource_.addEventListener('endpan',this.onPanEnd_.bind(this));this.eventSource_.addEventListener('beginzoom',this.onZoomBegin_.bind(this));this.eventSource_.addEventListener('updatezoom',this.onZoomUpdate_.bind(this));this.eventSource_.addEventListener('endzoom',this.onZoomEnd_.bind(this));this.eventSource_.addEventListener('beginrotate',this.onRotateBegin_.bind(this));this.eventSource_.addEventListener('updaterotate',this.onRotateUpdate_.bind(this));this.eventSource_.addEventListener('endrotate',this.onRotateEnd_.bind(this));this.eye_=[0,0,constants.DEFAULT_EYE_DISTANCE];this.gazeTarget_=[0,0,0];this.rotation_=[0,0];this.pixelRatio_=window.devicePixelRatio||1;},get modelViewMatrix(){const mvMatrix=mat4.create();mat4.lookAt(mvMatrix,this.eye_,this.gazeTarget_,[0,1,0]);return mvMatrix;},get projectionMatrix(){const rect=tr.ui.b.windowRectForElement(this.canvas_).scaleSize(this.pixelRatio_);const aspectRatio=rect.width/rect.height;const matrix=mat4.create();mat4.perspective(matrix,deg2rad(constants.FOV),aspectRatio,1,100000);return matrix;},set canvas(c){this.canvas_=c;},set deviceRect(rect){this.deviceRect_=rect;},get stackingDistanceDampening(){const gazeVector=[this.gazeTarget_[0]-this.eye_[0],this.gazeTarget_[1]-this.eye_[1],this.gazeTarget_[2]-this.eye_[2]];vec3.normalize(gazeVector,gazeVector);return 1+gazeVector[2];},loadCameraFromSettings(settings){this.eye_=settings.get('eye',this.eye_,constants.SETTINGS_NAMESPACE);this.gazeTarget_=settings.get('gaze_target',this.gazeTarget_,constants.SETTINGS_NAMESPACE);this.rotation_=settings.get('rotation',this.rotation_,constants.SETTINGS_NAMESPACE);this.dispatchRenderEvent_();},saveCameraToSettings(settings){settings.set('eye',this.eye_,constants.SETTINGS_NAMESPACE);settings.set('gaze_target',this.gazeTarget_,constants.SETTINGS_NAMESPACE);settings.set('rotation',this.rotation_,constants.SETTINGS_NAMESPACE);},resetCamera(){this.eye_=[0,0,constants.DEFAULT_EYE_DISTANCE];this.gazeTarget_=[0,0,0];this.rotation_=[0,0];const settings=tr.b.SessionSettings();const keys=settings.keys(constants.SETTINGS_NAMESPACE);if(keys.length!==0){this.loadCameraFromSettings(settings);return;}
+if(this.deviceRect_){const rect=tr.ui.b.windowRectForElement(this.canvas_).scaleSize(this.pixelRatio_);this.eye_[0]=this.deviceRect_.width/2;this.eye_[1]=this.deviceRect_.height/2;this.gazeTarget_[0]=this.deviceRect_.width/2;this.gazeTarget_[1]=this.deviceRect_.height/2;}
+this.saveCameraToSettings(settings);this.dispatchRenderEvent_();},updatePanByDelta(delta){const rect=tr.ui.b.windowRectForElement(this.canvas_).scaleSize(this.pixelRatio_);const eyeVector=[this.eye_[0]-this.gazeTarget_[0],this.eye_[1]-this.gazeTarget_[1],this.eye_[2]-this.gazeTarget_[2]];const length=vec3.length(eyeVector);vec3.normalize(eyeVector,eyeVector);const halfFov=constants.FOV/2;const multiplier=2.0*length*Math.tan(deg2rad(halfFov))/rect.height;const up=[0,1,0];const rotMatrix=mat4.create();mat4.rotate(rotMatrix,rotMatrix,deg2rad(this.rotation_[1]),[0,1,0]);mat4.rotate(rotMatrix,rotMatrix,deg2rad(this.rotation_[0]),[1,0,0]);vec3.transformMat4(up,up,rotMatrix);const right=[0,0,0];vec3.cross(right,eyeVector,up);vec3.normalize(right,right);for(let i=0;i<3;++i){this.gazeTarget_[i]+=delta[0]*multiplier*right[i]-delta[1]*multiplier*up[i];this.eye_[i]=this.gazeTarget_[i]+length*eyeVector[i];}
+if(Math.abs(this.gazeTarget_[2])>1e-6){const gazeVector=[-eyeVector[0],-eyeVector[1],-eyeVector[2]];const newLength=tr.b.math.clamp(-this.eye_[2]/gazeVector[2],constants.MINIMUM_DISTANCE,constants.MAXIMUM_DISTANCE);for(let i=0;i<3;++i){this.gazeTarget_[i]=this.eye_[i]+newLength*gazeVector[i];}}
+this.saveCameraToSettings(tr.b.SessionSettings());this.dispatchRenderEvent_();},updateZoomByDelta(delta){let deltaY=delta[1];deltaY=tr.b.math.clamp(deltaY,-50,50);let scale=1.0-deltaY/100.0;const eyeVector=[0,0,0];vec3.subtract(eyeVector,this.eye_,this.gazeTarget_);const length=vec3.length(eyeVector);if(length*scale<constants.MINIMUM_DISTANCE){scale=constants.MINIMUM_DISTANCE/length;}else if(length*scale>constants.MAXIMUM_DISTANCE){scale=constants.MAXIMUM_DISTANCE/length;}
+vec3.scale(eyeVector,eyeVector,scale);vec3.add(this.eye_,this.gazeTarget_,eyeVector);this.saveCameraToSettings(tr.b.SessionSettings());this.dispatchRenderEvent_();},updateRotateByDelta(delta){delta[0]*=0.5;delta[1]*=0.5;if(Math.abs(this.rotation_[0]+delta[1])>constants.MAXIMUM_TILT){return;}
+if(Math.abs(this.rotation_[1]-delta[0])>constants.MAXIMUM_TILT){return;}
+const eyeVector=[0,0,0,0];vec3.subtract(eyeVector,this.eye_,this.gazeTarget_);const rotMatrix=mat4.create();mat4.rotate(rotMatrix,rotMatrix,-deg2rad(this.rotation_[0]),[1,0,0]);mat4.rotate(rotMatrix,rotMatrix,-deg2rad(this.rotation_[1]),[0,1,0]);vec4.transformMat4(eyeVector,eyeVector,rotMatrix);this.rotation_[0]+=delta[1];this.rotation_[1]-=delta[0];mat4.identity(rotMatrix);mat4.rotate(rotMatrix,rotMatrix,deg2rad(this.rotation_[1]),[0,1,0]);mat4.rotate(rotMatrix,rotMatrix,deg2rad(this.rotation_[0]),[1,0,0]);vec4.transformMat4(eyeVector,eyeVector,rotMatrix);vec3.add(this.eye_,this.gazeTarget_,eyeVector);this.saveCameraToSettings(tr.b.SessionSettings());this.dispatchRenderEvent_();},onPanBegin_(e){this.panning_=true;this.lastMousePosition_=this.getMousePosition_(e);},onPanUpdate_(e){if(!this.panning_)return;const delta=this.getMouseDelta_(e,this.lastMousePosition_);this.lastMousePosition_=this.getMousePosition_(e);this.updatePanByDelta(delta);},onPanEnd_(e){this.panning_=false;},onZoomBegin_(e){this.zooming_=true;const p=this.getMousePosition_(e);this.lastMousePosition_=p;this.zoomPoint_=p;},onZoomUpdate_(e){if(!this.zooming_)return;const delta=this.getMouseDelta_(e,this.lastMousePosition_);this.lastMousePosition_=this.getMousePosition_(e);this.updateZoomByDelta(delta);},onZoomEnd_(e){this.zooming_=false;this.zoomPoint_=undefined;},onRotateBegin_(e){this.rotating_=true;this.lastMousePosition_=this.getMousePosition_(e);},onRotateUpdate_(e){if(!this.rotating_)return;const delta=this.getMouseDelta_(e,this.lastMousePosition_);this.lastMousePosition_=this.getMousePosition_(e);this.updateRotateByDelta(delta);},onRotateEnd_(e){this.rotating_=false;},getMousePosition_(e){const rect=tr.ui.b.windowRectForElement(this.canvas_);return[(e.clientX-rect.x)*this.pixelRatio_,(e.clientY-rect.y)*this.pixelRatio_];},getMouseDelta_(e,p){const newP=this.getMousePosition_(e);return[newP[0]-p[0],newP[1]-p[1]];},dispatchRenderEvent_(){tr.b.dispatchSimpleEvent(this,'renderrequired',false,false);}};return{Camera,};});'use strict';tr.exportTo('tr.ui.b',function(){const THIS_DOC=document.currentScript.ownerDocument;const constants={};constants.IMAGE_LOAD_RETRY_TIME_MS=500;constants.SUBDIVISION_MINIMUM=1;constants.SUBDIVISION_RECURSION_DEPTH=3;constants.SUBDIVISION_DEPTH_THRESHOLD=100;constants.FAR_PLANE_DISTANCE=10000;function drawTexturedTriangle(ctx,img,p0,p1,p2,t0,t1,t2){const tmpP0=[p0[0],p0[1]];const tmpP1=[p1[0],p1[1]];const tmpP2=[p2[0],p2[1]];const tmpT0=[t0[0],t0[1]];const tmpT1=[t1[0],t1[1]];const tmpT2=[t2[0],t2[1]];ctx.beginPath();ctx.moveTo(tmpP0[0],tmpP0[1]);ctx.lineTo(tmpP1[0],tmpP1[1]);ctx.lineTo(tmpP2[0],tmpP2[1]);ctx.closePath();tmpP1[0]-=tmpP0[0];tmpP1[1]-=tmpP0[1];tmpP2[0]-=tmpP0[0];tmpP2[1]-=tmpP0[1];tmpT1[0]-=tmpT0[0];tmpT1[1]-=tmpT0[1];tmpT2[0]-=tmpT0[0];tmpT2[1]-=tmpT0[1];const det=1/(tmpT1[0]*tmpT2[1]-tmpT2[0]*tmpT1[1]);const a=(tmpT2[1]*tmpP1[0]-tmpT1[1]*tmpP2[0])*det;const b=(tmpT2[1]*tmpP1[1]-tmpT1[1]*tmpP2[1])*det;const c=(tmpT1[0]*tmpP2[0]-tmpT2[0]*tmpP1[0])*det;const d=(tmpT1[0]*tmpP2[1]-tmpT2[0]*tmpP1[1])*det;const e=tmpP0[0]-a*tmpT0[0]-c*tmpT0[1];const f=tmpP0[1]-b*tmpT0[0]-d*tmpT0[1];ctx.save();ctx.transform(a,b,c,d,e,f);ctx.clip();ctx.drawImage(img,0,0);ctx.restore();}
+function drawTriangleSub(ctx,img,p0,p1,p2,t0,t1,t2,opt_recursionDepth){const depth=opt_recursionDepth||0;let subdivisionIndex=0;if(depth<constants.SUBDIVISION_MINIMUM){subdivisionIndex=7;}else if(depth<constants.SUBDIVISION_RECURSION_DEPTH){if(Math.abs(p0[2]-p1[2])>constants.SUBDIVISION_DEPTH_THRESHOLD){subdivisionIndex+=1;}
+if(Math.abs(p0[2]-p2[2])>constants.SUBDIVISION_DEPTH_THRESHOLD){subdivisionIndex+=2;}
+if(Math.abs(p1[2]-p2[2])>constants.SUBDIVISION_DEPTH_THRESHOLD){subdivisionIndex+=4;}}
+const p01=vec4.create();const p02=vec4.create();const p12=vec4.create();const t01=vec2.create();const t02=vec2.create();const t12=vec2.create();for(let i=0;i<2;++i){p0[i]*=p0[2];p1[i]*=p1[2];p2[i]*=p2[2];}
+for(let i=0;i<4;++i){p01[i]=(p0[i]+p1[i])/2;p02[i]=(p0[i]+p2[i])/2;p12[i]=(p1[i]+p2[i])/2;}
+for(let i=0;i<2;++i){p0[i]/=p0[2];p1[i]/=p1[2];p2[i]/=p2[2];p01[i]/=p01[2];p02[i]/=p02[2];p12[i]/=p12[2];}
+for(let i=0;i<2;++i){t01[i]=(t0[i]+t1[i])/2;t02[i]=(t0[i]+t2[i])/2;t12[i]=(t1[i]+t2[i])/2;}
 switch(subdivisionIndex){case 1:drawTriangleSub(ctx,img,p0,p01,p2,t0,t01,t2,depth+1);drawTriangleSub(ctx,img,p01,p1,p2,t01,t1,t2,depth+1);break;case 2:drawTriangleSub(ctx,img,p0,p1,p02,t0,t1,t02,depth+1);drawTriangleSub(ctx,img,p1,p02,p2,t1,t02,t2,depth+1);break;case 3:drawTriangleSub(ctx,img,p0,p01,p02,t0,t01,t02,depth+1);drawTriangleSub(ctx,img,p02,p01,p2,t02,t01,t2,depth+1);drawTriangleSub(ctx,img,p01,p1,p2,t01,t1,t2,depth+1);break;case 4:drawTriangleSub(ctx,img,p0,p12,p2,t0,t12,t2,depth+1);drawTriangleSub(ctx,img,p0,p1,p12,t0,t1,t12,depth+1);break;case 5:drawTriangleSub(ctx,img,p0,p01,p2,t0,t01,t2,depth+1);drawTriangleSub(ctx,img,p2,p01,p12,t2,t01,t12,depth+1);drawTriangleSub(ctx,img,p01,p1,p12,t01,t1,t12,depth+1);break;case 6:drawTriangleSub(ctx,img,p0,p12,p02,t0,t12,t02,depth+1);drawTriangleSub(ctx,img,p0,p1,p12,t0,t1,t12,depth+1);drawTriangleSub(ctx,img,p02,p12,p2,t02,t12,t2,depth+1);break;case 7:drawTriangleSub(ctx,img,p0,p01,p02,t0,t01,t02,depth+1);drawTriangleSub(ctx,img,p01,p12,p02,t01,t12,t02,depth+1);drawTriangleSub(ctx,img,p01,p1,p12,t01,t1,t12,depth+1);drawTriangleSub(ctx,img,p02,p12,p2,t02,t12,t2,depth+1);break;default:drawTexturedTriangle(ctx,img,p0,p1,p2,t0,t1,t2);break;}}
-var tmp_vec4=vec4.create();function transform(transformed,point,matrix,viewport){vec4.set(tmp_vec4,point[0],point[1],0,1);vec4.transformMat4(tmp_vec4,tmp_vec4,matrix);var w=tmp_vec4[3];if(w<1e-6)w=1e-6;transformed[0]=((tmp_vec4[0]/w)+1)*viewport.width/2;transformed[1]=((tmp_vec4[1]/w)+1)*viewport.height/2;transformed[2]=w;}
-function drawProjectedQuadBackgroundToContext(quad,p1,p2,p3,p4,ctx,quadCanvas){if(quad.imageData){quadCanvas.width=quad.imageData.width;quadCanvas.height=quad.imageData.height;quadCanvas.getContext('2d').putImageData(quad.imageData,0,0);var quadBBox=new tr.b.BBox2();quadBBox.addQuad(quad);var iw=quadCanvas.width;var ih=quadCanvas.height;drawTriangleSub(ctx,quadCanvas,p1,p2,p4,[0,0],[iw,0],[0,ih]);drawTriangleSub(ctx,quadCanvas,p2,p3,p4,[iw,0],[iw,ih],[0,ih]);}
+const tmpVec4=vec4.create();function transform(transformed,point,matrix,viewport){vec4.set(tmpVec4,point[0],point[1],0,1);vec4.transformMat4(tmpVec4,tmpVec4,matrix);let w=tmpVec4[3];if(w<1e-6)w=1e-6;transformed[0]=((tmpVec4[0]/w)+1)*viewport.width/2;transformed[1]=((tmpVec4[1]/w)+1)*viewport.height/2;transformed[2]=w;}
+function drawProjectedQuadBackgroundToContext(quad,p1,p2,p3,p4,ctx,quadCanvas){if(quad.imageData){quadCanvas.width=quad.imageData.width;quadCanvas.height=quad.imageData.height;quadCanvas.getContext('2d').putImageData(quad.imageData,0,0);const quadBBox=new tr.b.math.BBox2();quadBBox.addQuad(quad);const iw=quadCanvas.width;const ih=quadCanvas.height;drawTriangleSub(ctx,quadCanvas,p1,p2,p4,[0,0],[iw,0],[0,ih]);drawTriangleSub(ctx,quadCanvas,p2,p3,p4,[iw,0],[iw,ih],[0,ih]);}
 if(quad.backgroundColor){ctx.fillStyle=quad.backgroundColor;ctx.beginPath();ctx.moveTo(p1[0],p1[1]);ctx.lineTo(p2[0],p2[1]);ctx.lineTo(p3[0],p3[1]);ctx.lineTo(p4[0],p4[1]);ctx.closePath();ctx.fill();}}
-function drawProjectedQuadOutlineToContext(quad,p1,p2,p3,p4,ctx,quadCanvas){ctx.beginPath();ctx.moveTo(p1[0],p1[1]);ctx.lineTo(p2[0],p2[1]);ctx.lineTo(p3[0],p3[1]);ctx.lineTo(p4[0],p4[1]);ctx.closePath();ctx.save();if(quad.borderColor)
-ctx.strokeStyle=quad.borderColor;else
-ctx.strokeStyle='rgb(128,128,128)';if(quad.shadowOffset){ctx.shadowColor='rgb(0, 0, 0)';ctx.shadowOffsetX=quad.shadowOffset[0];ctx.shadowOffsetY=quad.shadowOffset[1];if(quad.shadowBlur)
-ctx.shadowBlur=quad.shadowBlur;}
-if(quad.borderWidth)
-ctx.lineWidth=quad.borderWidth;else
-ctx.lineWidth=1;ctx.stroke();ctx.restore();}
-function drawProjectedQuadSelectionOutlineToContext(quad,p1,p2,p3,p4,ctx,quadCanvas){if(!quad.upperBorderColor)
-return;ctx.lineWidth=8;ctx.strokeStyle=quad.upperBorderColor;ctx.beginPath();ctx.moveTo(p1[0],p1[1]);ctx.lineTo(p2[0],p2[1]);ctx.lineTo(p3[0],p3[1]);ctx.lineTo(p4[0],p4[1]);ctx.closePath();ctx.stroke();}
+function drawProjectedQuadOutlineToContext(quad,p1,p2,p3,p4,ctx,quadCanvas){ctx.beginPath();ctx.moveTo(p1[0],p1[1]);ctx.lineTo(p2[0],p2[1]);ctx.lineTo(p3[0],p3[1]);ctx.lineTo(p4[0],p4[1]);ctx.closePath();ctx.save();if(quad.borderColor){ctx.strokeStyle=quad.borderColor;}else{ctx.strokeStyle='rgb(128,128,128)';}
+if(quad.shadowOffset){ctx.shadowColor='rgb(0, 0, 0)';ctx.shadowOffsetX=quad.shadowOffset[0];ctx.shadowOffsetY=quad.shadowOffset[1];if(quad.shadowBlur){ctx.shadowBlur=quad.shadowBlur;}}
+if(quad.borderWidth){ctx.lineWidth=quad.borderWidth;}else{ctx.lineWidth=1;}
+ctx.stroke();ctx.restore();}
+function drawProjectedQuadSelectionOutlineToContext(quad,p1,p2,p3,p4,ctx,quadCanvas){if(!quad.upperBorderColor)return;ctx.lineWidth=8;ctx.strokeStyle=quad.upperBorderColor;ctx.beginPath();ctx.moveTo(p1[0],p1[1]);ctx.lineTo(p2[0],p2[1]);ctx.lineTo(p3[0],p3[1]);ctx.lineTo(p4[0],p4[1]);ctx.closePath();ctx.stroke();}
 function drawProjectedQuadToContext(passNumber,quad,p1,p2,p3,p4,ctx,quadCanvas){if(passNumber===0){drawProjectedQuadBackgroundToContext(quad,p1,p2,p3,p4,ctx,quadCanvas);}else if(passNumber===1){drawProjectedQuadOutlineToContext(quad,p1,p2,p3,p4,ctx,quadCanvas);}else if(passNumber===2){drawProjectedQuadSelectionOutlineToContext(quad,p1,p2,p3,p4,ctx,quadCanvas);}else{throw new Error('Invalid pass number');}}
-var tmp_p1=vec3.create();var tmp_p2=vec3.create();var tmp_p3=vec3.create();var tmp_p4=vec3.create();function transformAndProcessQuads(matrix,viewport,quads,numPasses,handleQuadFunc,opt_arg1,opt_arg2){for(var passNumber=0;passNumber<numPasses;passNumber++){for(var i=0;i<quads.length;i++){var quad=quads[i];transform(tmp_p1,quad.p1,matrix,viewport);transform(tmp_p2,quad.p2,matrix,viewport);transform(tmp_p3,quad.p3,matrix,viewport);transform(tmp_p4,quad.p4,matrix,viewport);handleQuadFunc(passNumber,quad,tmp_p1,tmp_p2,tmp_p3,tmp_p4,opt_arg1,opt_arg2);}}}
-var QuadStackView=tr.ui.b.define('quad-stack-view');QuadStackView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.className='quad-stack-view';var node=tr.ui.b.instantiateTemplate('#quad-stack-view-template',THIS_DOC);this.appendChild(node);this.updateHeaderVisibility_();this.canvas_=this.querySelector('#canvas');this.chromeImages_={left:this.querySelector('#chrome-left'),mid:this.querySelector('#chrome-mid'),right:this.querySelector('#chrome-right')};var stackingDistanceSlider=this.querySelector('#stacking-distance-slider');stackingDistanceSlider.value=tr.b.Settings.get('quadStackView.stackingDistance',45);stackingDistanceSlider.addEventListener('change',this.onStackingDistanceChange_.bind(this));stackingDistanceSlider.addEventListener('input',this.onStackingDistanceChange_.bind(this));this.trackMouse_();this.camera_=new tr.ui.b.Camera(this.mouseModeSelector_);this.camera_.addEventListener('renderrequired',this.onRenderRequired_.bind(this));this.cameraWasReset_=false;this.camera_.canvas=this.canvas_;this.viewportRect_=tr.b.Rect.fromXYWH(0,0,0,0);this.pixelRatio_=window.devicePixelRatio||1;},updateHeaderVisibility_:function(){if(this.headerText)
-this.querySelector('#header').style.display='';else
-this.querySelector('#header').style.display='none';},get headerText(){return this.querySelector('#header').textContent;},set headerText(headerText){this.querySelector('#header').textContent=headerText;this.updateHeaderVisibility_();},onStackingDistanceChange_:function(e){tr.b.Settings.set('quadStackView.stackingDistance',this.stackingDistance);this.scheduleRender();e.stopPropagation();},get stackingDistance(){return this.querySelector('#stacking-distance-slider').value;},get mouseModeSelector(){return this.mouseModeSelector_;},get camera(){return this.camera_;},set quads(q){this.quads_=q;this.scheduleRender();},set deviceRect(rect){if(!rect||rect.equalTo(this.deviceRect_))
-return;this.deviceRect_=rect;this.camera_.deviceRect=rect;this.chromeQuad_=undefined;},resize:function(){if(!this.offsetParent)
-return true;var width=parseInt(window.getComputedStyle(this.offsetParent).width);var height=parseInt(window.getComputedStyle(this.offsetParent).height);var rect=tr.b.Rect.fromXYWH(0,0,width,height);if(rect.equalTo(this.viewportRect_))
-return false;this.viewportRect_=rect;this.style.width=width+'px';this.style.height=height+'px';this.canvas_.style.width=width+'px';this.canvas_.style.height=height+'px';this.canvas_.width=this.pixelRatio_*width;this.canvas_.height=this.pixelRatio_*height;if(!this.cameraWasReset_){this.camera_.resetCamera();this.cameraWasReset_=true;}
-return true;},readyToDraw:function(){if(!this.chromeImages_.left.src){var leftContent=window.getComputedStyle(this.chromeImages_.left).content;leftContent=tr.ui.b.extractUrlString(leftContent);var midContent=window.getComputedStyle(this.chromeImages_.mid).content;midContent=tr.ui.b.extractUrlString(midContent);var rightContent=window.getComputedStyle(this.chromeImages_.right).content;rightContent=tr.ui.b.extractUrlString(rightContent);this.chromeImages_.left.src=leftContent;this.chromeImages_.mid.src=midContent;this.chromeImages_.right.src=rightContent;}
-return(this.chromeImages_.left.height>0)&&(this.chromeImages_.mid.height>0)&&(this.chromeImages_.right.height>0);},get chromeQuad(){if(this.chromeQuad_)
-return this.chromeQuad_;var chromeCanvas=document.createElement('canvas');var offsetY=this.chromeImages_.left.height;chromeCanvas.width=this.deviceRect_.width;chromeCanvas.height=this.deviceRect_.height+offsetY;var leftWidth=this.chromeImages_.left.width;var midWidth=this.chromeImages_.mid.width;var rightWidth=this.chromeImages_.right.width;var chromeCtx=chromeCanvas.getContext('2d');chromeCtx.drawImage(this.chromeImages_.left,0,0);chromeCtx.save();chromeCtx.translate(leftWidth,0);var s=(this.deviceRect_.width-leftWidth-rightWidth)/midWidth;chromeCtx.scale(s,1);chromeCtx.drawImage(this.chromeImages_.mid,0,0);chromeCtx.restore();chromeCtx.drawImage(this.chromeImages_.right,leftWidth+s*midWidth,0);var chromeRect=tr.b.Rect.fromXYWH(this.deviceRect_.x,this.deviceRect_.y-offsetY,this.deviceRect_.width,this.deviceRect_.height+offsetY);var chromeQuad=tr.b.Quad.fromRect(chromeRect);chromeQuad.stackingGroupId=this.maxStackingGroupId_+1;chromeQuad.imageData=chromeCtx.getImageData(0,0,chromeCanvas.width,chromeCanvas.height);chromeQuad.shadowOffset=[0,0];chromeQuad.shadowBlur=5;chromeQuad.borderWidth=3;this.chromeQuad_=chromeQuad;return this.chromeQuad_;},scheduleRender:function(){if(this.redrawScheduled_)
-return false;this.redrawScheduled_=true;tr.b.requestAnimationFrame(this.render,this);},onRenderRequired_:function(e){this.scheduleRender();},stackTransformAndProcessQuads_:function(numPasses,handleQuadFunc,includeChromeQuad,opt_arg1,opt_arg2){var mv=this.camera_.modelViewMatrix;var p=this.camera_.projectionMatrix;var viewport=tr.b.Rect.fromXYWH(0,0,this.canvas_.width,this.canvas_.height);var quadStacks=[];for(var i=0;i<this.quads_.length;++i){var quad=this.quads_[i];var stackingId=quad.stackingGroupId||0;while(stackingId>=quadStacks.length)
-quadStacks.push([]);quadStacks[stackingId].push(quad);}
-var mvp=mat4.create();this.maxStackingGroupId_=quadStacks.length;var effectiveStackingDistance=this.stackingDistance*this.camera_.stackingDistanceDampening;mat4.multiply(mvp,p,mv);for(var i=0;i<quadStacks.length;++i){transformAndProcessQuads(mvp,viewport,quadStacks[i],numPasses,handleQuadFunc,opt_arg1,opt_arg2);mat4.translate(mv,mv,[0,0,effectiveStackingDistance]);mat4.multiply(mvp,p,mv);}
-if(includeChromeQuad&&this.deviceRect_){transformAndProcessQuads(mvp,viewport,[this.chromeQuad],numPasses,drawProjectedQuadToContext,opt_arg1,opt_arg2);}},render:function(){this.redrawScheduled_=false;if(!this.readyToDraw()){setTimeout(this.scheduleRender.bind(this),constants.IMAGE_LOAD_RETRY_TIME_MS);return;}
-if(!this.quads_)
-return;var canvasCtx=this.canvas_.getContext('2d');if(!this.resize())
-canvasCtx.clearRect(0,0,this.canvas_.width,this.canvas_.height);var quadCanvas=document.createElement('canvas');this.stackTransformAndProcessQuads_(3,drawProjectedQuadToContext,true,canvasCtx,quadCanvas);quadCanvas.width=0;},trackMouse_:function(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this.canvas_;this.mouseModeSelector_.supportedModeMask=tr.ui.b.MOUSE_SELECTOR_MODE.SELECTION|tr.ui.b.MOUSE_SELECTOR_MODE.PANSCAN|tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM|tr.ui.b.MOUSE_SELECTOR_MODE.ROTATE;this.mouseModeSelector_.mode=tr.ui.b.MOUSE_SELECTOR_MODE.PANSCAN;this.mouseModeSelector_.pos={x:0,y:100};this.appendChild(this.mouseModeSelector_);this.mouseModeSelector_.settingsKey='quadStackView.mouseModeSelector';this.mouseModeSelector_.setModifierForAlternateMode(tr.ui.b.MOUSE_SELECTOR_MODE.ROTATE,tr.ui.b.MODIFIER.SHIFT);this.mouseModeSelector_.setModifierForAlternateMode(tr.ui.b.MOUSE_SELECTOR_MODE.PANSCAN,tr.ui.b.MODIFIER.SPACE);this.mouseModeSelector_.setModifierForAlternateMode(tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM,tr.ui.b.MODIFIER.CMD_OR_CTRL);this.mouseModeSelector_.addEventListener('updateselection',this.onSelectionUpdate_.bind(this));this.mouseModeSelector_.addEventListener('endselection',this.onSelectionUpdate_.bind(this));},extractRelativeMousePosition_:function(e){var br=this.canvas_.getBoundingClientRect();return[this.pixelRatio_*(e.clientX-this.canvas_.offsetLeft-br.left),this.pixelRatio_*(e.clientY-this.canvas_.offsetTop-br.top)];},onSelectionUpdate_:function(e){var mousePos=this.extractRelativeMousePosition_(e);var res=[];function handleQuad(passNumber,quad,p1,p2,p3,p4){if(tr.b.pointInImplicitQuad(mousePos,p1,p2,p3,p4))
-res.push(quad);}
-this.stackTransformAndProcessQuads_(1,handleQuad,false);var e=new tr.b.Event('selectionchange');e.quads=res;this.dispatchEvent(e);}};return{QuadStackView:QuadStackView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var ColorScheme=tr.b.ColorScheme;var THIS_DOC=document.currentScript.ownerDocument;var TILE_HEATMAP_TYPE={};TILE_HEATMAP_TYPE.NONE='none';TILE_HEATMAP_TYPE.SCHEDULED_PRIORITY='scheduledPriority';TILE_HEATMAP_TYPE.USING_GPU_MEMORY='usingGpuMemory';var cc=tr.ui.e.chrome.cc;function createTileRectsSelectorBaseOptions(){return[{label:'None',value:'none'},{label:'Coverage Rects',value:'coverage'}];}
-var bytesToRoundedMegabytes=tr.e.cc.bytesToRoundedMegabytes;var LayerTreeQuadStackView=tr.ui.b.define('tr-ui-e-chrome-cc-layer-tree-quad-stack-view');LayerTreeQuadStackView.prototype={__proto__:HTMLDivElement.prototype,decorate:function(){this.isRenderPassQuads_=false;this.pictureAsImageData_={};this.messages_=[];this.controls_=document.createElement('top-controls');this.infoBar_=document.createElement('tr-ui-b-info-bar');this.quadStackView_=new tr.ui.b.QuadStackView();this.quadStackView_.addEventListener('selectionchange',this.onQuadStackViewSelectionChange_.bind(this));this.extraHighlightsByLayerId_=undefined;this.inputEventImageData_=undefined;var m=tr.ui.b.MOUSE_SELECTOR_MODE;var mms=this.quadStackView_.mouseModeSelector;mms.settingsKey='tr.e.cc.layerTreeQuadStackView.mouseModeSelector';mms.setKeyCodeForMode(m.SELECTION,'Z'.charCodeAt(0));mms.setKeyCodeForMode(m.PANSCAN,'X'.charCodeAt(0));mms.setKeyCodeForMode(m.ZOOM,'C'.charCodeAt(0));mms.setKeyCodeForMode(m.ROTATE,'V'.charCodeAt(0));var node=tr.ui.b.instantiateTemplate('#tr-ui-e-chrome-cc-layer-tree-quad-stack-view-template',THIS_DOC);this.appendChild(node);this.appendChild(this.controls_);this.appendChild(this.infoBar_);this.appendChild(this.quadStackView_);this.tileRectsSelector_=tr.ui.b.createSelector(this,'howToShowTiles','layerView.howToShowTiles','none',createTileRectsSelectorBaseOptions());this.controls_.appendChild(this.tileRectsSelector_);var tileHeatmapText=tr.ui.b.createSpan({textContent:'Tile heatmap:'});this.controls_.appendChild(tileHeatmapText);var tileHeatmapSelector=tr.ui.b.createSelector(this,'tileHeatmapType','layerView.tileHeatmapType',TILE_HEATMAP_TYPE.NONE,[{label:'None',value:TILE_HEATMAP_TYPE.NONE},{label:'Scheduled Priority',value:TILE_HEATMAP_TYPE.SCHEDULED_PRIORITY},{label:'Is using GPU memory',value:TILE_HEATMAP_TYPE.USING_GPU_MEMORY}]);this.controls_.appendChild(tileHeatmapSelector);var showOtherLayersCheckbox=tr.ui.b.createCheckBox(this,'showOtherLayers','layerView.showOtherLayers',true,'Other layers/passes');showOtherLayersCheckbox.title='When checked, show all layers, selected or not.';this.controls_.appendChild(showOtherLayersCheckbox);var showInvalidationsCheckbox=tr.ui.b.createCheckBox(this,'showInvalidations','layerView.showInvalidations',true,'Invalidations');showInvalidationsCheckbox.title='When checked, compositing invalidations are highlighted in red';this.controls_.appendChild(showInvalidationsCheckbox);var showUnrecordedRegionCheckbox=tr.ui.b.createCheckBox(this,'showUnrecordedRegion','layerView.showUnrecordedRegion',true,'Unrecorded area');showUnrecordedRegionCheckbox.title='When checked, unrecorded areas are highlighted in yellow';this.controls_.appendChild(showUnrecordedRegionCheckbox);var showBottlenecksCheckbox=tr.ui.b.createCheckBox(this,'showBottlenecks','layerView.showBottlenecks',true,'Bottlenecks');showBottlenecksCheckbox.title='When checked, scroll bottlenecks are highlighted';this.controls_.appendChild(showBottlenecksCheckbox);var showLayoutRectsCheckbox=tr.ui.b.createCheckBox(this,'showLayoutRects','layerView.showLayoutRects',false,'Layout rects');showLayoutRectsCheckbox.title='When checked, shows rects for regions where layout happened';this.controls_.appendChild(showLayoutRectsCheckbox);var showContentsCheckbox=tr.ui.b.createCheckBox(this,'showContents','layerView.showContents',true,'Contents');showContentsCheckbox.title='When checked, show the rendered contents inside the layer outlines';this.controls_.appendChild(showContentsCheckbox);var showAnimationBoundsCheckbox=tr.ui.b.createCheckBox(this,'showAnimationBounds','layerView.showAnimationBounds',false,'Animation Bounds');showAnimationBoundsCheckbox.title='When checked, show a border around'+' a layer showing the extent of its animation.';this.controls_.appendChild(showAnimationBoundsCheckbox);var showInputEventsCheckbox=tr.ui.b.createCheckBox(this,'showInputEvents','layerView.showInputEvents',true,'Input events');showInputEventsCheckbox.title='When checked, input events are '+'displayed as circles.';this.controls_.appendChild(showInputEventsCheckbox);this.whatRasterizedLink_=document.createElement('a');this.whatRasterizedLink_.classList.add('what-rasterized');this.whatRasterizedLink_.textContent='What rasterized?';this.whatRasterizedLink_.addEventListener('click',this.onWhatRasterizedLinkClicked_.bind(this));this.appendChild(this.whatRasterizedLink_);},get layerTreeImpl(){return this.layerTreeImpl_;},set isRenderPassQuads(newValue){this.isRenderPassQuads_=newValue;},set layerTreeImpl(layerTreeImpl){if(this.layerTreeImpl_===layerTreeImpl)
-return;this.layerTreeImpl_=layerTreeImpl;this.selection=undefined;},get extraHighlightsByLayerId(){return this.extraHighlightsByLayerId_;},set extraHighlightsByLayerId(extraHighlightsByLayerId){this.extraHighlightsByLayerId_=extraHighlightsByLayerId;this.scheduleUpdateContents_();},get showOtherLayers(){return this.showOtherLayers_;},set showOtherLayers(show){this.showOtherLayers_=show;this.updateContents_();},get showAnimationBounds(){return this.showAnimationBounds_;},set showAnimationBounds(show){this.showAnimationBounds_=show;this.updateContents_();},get showInputEvents(){return this.showInputEvents_;},set showInputEvents(show){this.showInputEvents_=show;this.updateContents_();},get showContents(){return this.showContents_;},set showContents(show){this.showContents_=show;this.updateContents_();},get showInvalidations(){return this.showInvalidations_;},set showInvalidations(show){this.showInvalidations_=show;this.updateContents_();},get showUnrecordedRegion(){return this.showUnrecordedRegion_;},set showUnrecordedRegion(show){this.showUnrecordedRegion_=show;this.updateContents_();},get showBottlenecks(){return this.showBottlenecks_;},set showBottlenecks(show){this.showBottlenecks_=show;this.updateContents_();},get showLayoutRects(){return this.showLayoutRects_;},set showLayoutRects(show){this.showLayoutRects_=show;this.updateContents_();},get howToShowTiles(){return this.howToShowTiles_;},set howToShowTiles(val){console.assert((val==='none')||(val==='coverage')||!isNaN(parseFloat(val)));this.howToShowTiles_=val;this.updateContents_();},get tileHeatmapType(){return this.tileHeatmapType_;},set tileHeatmapType(val){this.tileHeatmapType_=val;this.updateContents_();},get selection(){return this.selection_;},set selection(selection){if(this.selection===selection)
-return;this.selection_=selection;tr.b.dispatchSimpleEvent(this,'selection-change');this.updateContents_();},regenerateContent:function(){this.updateTilesSelector_();this.updateContents_();},loadDataForImageElement_:function(image,callback){var imageContent=window.getComputedStyle(image).content;image.src=tr.ui.b.extractUrlString(imageContent);image.onload=function(){var canvas=document.createElement('canvas');var ctx=canvas.getContext('2d');canvas.width=image.width;canvas.height=image.height;ctx.drawImage(image,0,0);var imageData=ctx.getImageData(0,0,canvas.width,canvas.height);callback(imageData);}},onQuadStackViewSelectionChange_:function(e){var selectableQuads=e.quads.filter(function(q){return q.selectionToSetIfClicked!==undefined;});if(selectableQuads.length==0){this.selection=undefined;return;}
-selectableQuads.sort(function(x,y){var z=x.stackingGroupId-y.stackingGroupId;if(z!=0)
-return z;return x.selectionToSetIfClicked.specicifity-
-y.selectionToSetIfClicked.specicifity;});var quadToSelect=selectableQuads[selectableQuads.length-1];this.selection=quadToSelect.selectionToSetIfClicked;},scheduleUpdateContents_:function(){if(this.updateContentsPending_)
-return;this.updateContentsPending_=true;tr.b.requestAnimationFrameInThisFrameIfPossible(this.updateContents_,this);},updateContents_:function(){if(!this.layerTreeImpl_){this.quadStackView_.headerText='No tree';this.quadStackView_.quads=[];return;}
-var status=this.computePictureLoadingStatus_();if(!status.picturesComplete)
-return;var lthi=this.layerTreeImpl_.layerTreeHostImpl;var lthiInstance=lthi.objectInstance;var worldViewportRect=tr.b.Rect.fromXYWH(0,0,lthi.deviceViewportSize.width,lthi.deviceViewportSize.height);this.quadStackView_.deviceRect=worldViewportRect;if(this.isRenderPassQuads_)
-this.quadStackView_.quads=this.generateRenderPassQuads();else
-this.quadStackView_.quads=this.generateLayerQuads();this.updateWhatRasterizedLinkState_();var message='';if(lthi.tilesHaveGpuMemoryUsageInfo){var thisTreeUsageInBytes=this.layerTreeImpl_.gpuMemoryUsageInBytes;var otherTreeUsageInBytes=lthi.gpuMemoryUsageInBytes-
-thisTreeUsageInBytes;message+=bytesToRoundedMegabytes(thisTreeUsageInBytes)+'MB on this tree';if(otherTreeUsageInBytes){message+=', '+
-bytesToRoundedMegabytes(otherTreeUsageInBytes)+'MB on the other tree';}}else{if(this.layerTreeImpl_){var thisTreeUsageInBytes=this.layerTreeImpl_.gpuMemoryUsageInBytes;message+=bytesToRoundedMegabytes(thisTreeUsageInBytes)+'MB on this tree';if(this.layerTreeImpl_.otherTree){message+=', ???MB on other tree. ';}}}
-if(lthi.args.tileManagerBasicState){var tmgs=lthi.args.tileManagerBasicState.globalState;message+=' (softMax='+
-bytesToRoundedMegabytes(tmgs.softMemoryLimitInBytes)+'MB, hardMax='+
-bytesToRoundedMegabytes(tmgs.hardMemoryLimitInBytes)+'MB, '+
-tmgs.memoryLimitPolicy+')';}else{var thread=lthi.snapshottedOnThread;var didManageTilesSlices=thread.sliceGroup.slices.filter(function(s){if(s.category!=='tr.e.cc')
-return false;if(s.title!=='DidManage')
-return false;if(s.end>lthi.ts)
-return false;return true;});didManageTilesSlices.sort(function(x,y){return x.end-y.end;});if(didManageTilesSlices.length>0){var newest=didManageTilesSlices[didManageTilesSlices.length-1];var tmgs=newest.args.state.global_state;message+=' (softMax='+
-bytesToRoundedMegabytes(tmgs.soft_memory_limit_in_bytes)+'MB, hardMax='+
-bytesToRoundedMegabytes(tmgs.hard_memory_limit_in_bytes)+'MB, '+
-tmgs.memory_limit_policy+')';}}
-if(this.layerTreeImpl_.otherTree)
-message+=' (Another tree exists)';if(message.length)
-this.quadStackView_.headerText=message;else
-this.quadStackView_.headerText=undefined;this.updateInfoBar_(status.messages);},updateTilesSelector_:function(){var data=createTileRectsSelectorBaseOptions();if(this.layerTreeImpl_){var lthi=this.layerTreeImpl_.layerTreeHostImpl;var scaleNames=lthi.getContentsScaleNames();for(var scale in scaleNames){data.push({label:'Scale '+scale+' ('+scaleNames[scale]+')',value:scale});}}
-var new_selector=tr.ui.b.createSelector(this,'howToShowTiles','layerView.howToShowTiles','none',data);this.controls_.replaceChild(new_selector,this.tileRectsSelector_);this.tileRectsSelector_=new_selector;},computePictureLoadingStatus_:function(){var layers=this.layers;var status={messages:[],picturesComplete:true};if(this.showContents){var hasPendingRasterizeImage=false;var firstPictureError=undefined;var hasMissingLayerRect=false;var hasUnresolvedPictureRef=false;for(var i=0;i<layers.length;i++){var layer=layers[i];for(var ir=0;ir<layer.pictures.length;++ir){var picture=layer.pictures[ir];if(picture.idRef){hasUnresolvedPictureRef=true;continue;}
+const tmpP1=vec3.create();const tmpP2=vec3.create();const tmpP3=vec3.create();const tmpP4=vec3.create();function transformAndProcessQuads(matrix,viewport,quads,numPasses,handleQuadFunc,opt_arg1,opt_arg2){for(let passNumber=0;passNumber<numPasses;passNumber++){for(let i=0;i<quads.length;i++){const quad=quads[i];transform(tmpP1,quad.p1,matrix,viewport);transform(tmpP2,quad.p2,matrix,viewport);transform(tmpP3,quad.p3,matrix,viewport);transform(tmpP4,quad.p4,matrix,viewport);handleQuadFunc(passNumber,quad,tmpP1,tmpP2,tmpP3,tmpP4,opt_arg1,opt_arg2);}}}
+const QuadStackView=tr.ui.b.define('quad-stack-view');QuadStackView.prototype={__proto__:HTMLDivElement.prototype,decorate(){this.className='quad-stack-view';this.style.display='flex';this.style.position='relative';const node=tr.ui.b.instantiateTemplate('#quad-stack-view-template',THIS_DOC);Polymer.dom(this).appendChild(node);this.updateHeaderVisibility_();const header=Polymer.dom(this).querySelector('#header');header.style.position='absolute';header.style.fontSize='70%';header.style.top='10px';header.style.left='10px';header.style.right='150px';const scroller=Polymer.dom(this).querySelector('#canvas-scroller');scroller.style.flexGrow=1;scroller.style.flexShrink=1;scroller.style.flexBasis='auto';scroller.style.minWidth=0;scroller.style.minHeight=0;scroller.style.overflow='auto';this.canvas_=Polymer.dom(this).querySelector('#canvas');this.chromeImages_={left:Polymer.dom(this).querySelector('#chrome-left'),mid:Polymer.dom(this).querySelector('#chrome-mid'),right:Polymer.dom(this).querySelector('#chrome-right')};const stackingDistanceSlider=Polymer.dom(this).querySelector('#stacking-distance-slider');stackingDistanceSlider.style.position='absolute';stackingDistanceSlider.style.fontSize='70%';stackingDistanceSlider.style.top='10px';stackingDistanceSlider.style.right='10px';stackingDistanceSlider.value=tr.b.Settings.get('quadStackView.stackingDistance',45);stackingDistanceSlider.addEventListener('change',this.onStackingDistanceChange_.bind(this));stackingDistanceSlider.addEventListener('input',this.onStackingDistanceChange_.bind(this));this.trackMouse_();this.camera_=new tr.ui.b.Camera(this.mouseModeSelector_);this.camera_.addEventListener('renderrequired',this.onRenderRequired_.bind(this));this.cameraWasReset_=false;this.camera_.canvas=this.canvas_;this.viewportRect_=tr.b.math.Rect.fromXYWH(0,0,0,0);this.pixelRatio_=window.devicePixelRatio||1;},updateHeaderVisibility_(){if(this.headerText){Polymer.dom(this).querySelector('#header').style.display='';}else{Polymer.dom(this).querySelector('#header').style.display='none';}},get headerText(){return Polymer.dom(this).querySelector('#header').textContent;},set headerText(headerText){Polymer.dom(this).querySelector('#header').textContent=headerText;this.updateHeaderVisibility_();},onStackingDistanceChange_(e){tr.b.Settings.set('quadStackView.stackingDistance',this.stackingDistance);this.scheduleRender();e.stopPropagation();},get stackingDistance(){return Polymer.dom(this).querySelector('#stacking-distance-slider').value;},get mouseModeSelector(){return this.mouseModeSelector_;},get camera(){return this.camera_;},set quads(q){this.quads_=q;this.scheduleRender();},set deviceRect(rect){if(!rect||rect.equalTo(this.deviceRect_))return;this.deviceRect_=rect;this.camera_.deviceRect=rect;this.chromeQuad_=undefined;},resize(){if(!this.offsetParent)return true;const width=parseInt(window.getComputedStyle(this.offsetParent).width);const height=parseInt(window.getComputedStyle(this.offsetParent).height);const rect=tr.b.math.Rect.fromXYWH(0,0,width,height);if(rect.equalTo(this.viewportRect_))return false;this.viewportRect_=rect;this.canvas_.style.width=width+'px';this.canvas_.style.height=height+'px';this.canvas_.width=this.pixelRatio_*width;this.canvas_.height=this.pixelRatio_*height;if(!this.cameraWasReset_){this.camera_.resetCamera();this.cameraWasReset_=true;}
+return true;},readyToDraw(){if(!this.chromeImages_.left.src){let leftContent=window.getComputedStyle(this.chromeImages_.left).backgroundImage;leftContent=tr.ui.b.extractUrlString(leftContent);let midContent=window.getComputedStyle(this.chromeImages_.mid).backgroundImage;midContent=tr.ui.b.extractUrlString(midContent);let rightContent=window.getComputedStyle(this.chromeImages_.right).backgroundImage;rightContent=tr.ui.b.extractUrlString(rightContent);this.chromeImages_.left.src=leftContent;this.chromeImages_.mid.src=midContent;this.chromeImages_.right.src=rightContent;}
+return(this.chromeImages_.left.height>0)&&(this.chromeImages_.mid.height>0)&&(this.chromeImages_.right.height>0);},get chromeQuad(){if(this.chromeQuad_)return this.chromeQuad_;const chromeCanvas=document.createElement('canvas');const offsetY=this.chromeImages_.left.height;chromeCanvas.width=this.deviceRect_.width;chromeCanvas.height=this.deviceRect_.height+offsetY;const leftWidth=this.chromeImages_.left.width;const midWidth=this.chromeImages_.mid.width;const rightWidth=this.chromeImages_.right.width;const chromeCtx=chromeCanvas.getContext('2d');chromeCtx.drawImage(this.chromeImages_.left,0,0);chromeCtx.save();chromeCtx.translate(leftWidth,0);const s=(this.deviceRect_.width-leftWidth-rightWidth)/midWidth;chromeCtx.scale(s,1);chromeCtx.drawImage(this.chromeImages_.mid,0,0);chromeCtx.restore();chromeCtx.drawImage(this.chromeImages_.right,leftWidth+s*midWidth,0);const chromeRect=tr.b.math.Rect.fromXYWH(this.deviceRect_.x,this.deviceRect_.y-offsetY,this.deviceRect_.width,this.deviceRect_.height+offsetY);const chromeQuad=tr.b.math.Quad.fromRect(chromeRect);chromeQuad.stackingGroupId=this.maxStackingGroupId_+1;chromeQuad.imageData=chromeCtx.getImageData(0,0,chromeCanvas.width,chromeCanvas.height);chromeQuad.shadowOffset=[0,0];chromeQuad.shadowBlur=5;chromeQuad.borderWidth=3;this.chromeQuad_=chromeQuad;return this.chromeQuad_;},scheduleRender(){if(this.redrawScheduled_)return false;this.redrawScheduled_=true;tr.b.requestAnimationFrame(this.render,this);},onRenderRequired_(e){this.scheduleRender();},stackTransformAndProcessQuads_(numPasses,handleQuadFunc,includeChromeQuad,opt_arg1,opt_arg2){const mv=this.camera_.modelViewMatrix;const p=this.camera_.projectionMatrix;const viewport=tr.b.math.Rect.fromXYWH(0,0,this.canvas_.width,this.canvas_.height);const quadStacks=[];for(let i=0;i<this.quads_.length;++i){const quad=this.quads_[i];const stackingId=quad.stackingGroupId||0;while(stackingId>=quadStacks.length){quadStacks.push([]);}
+quadStacks[stackingId].push(quad);}
+const mvp=mat4.create();this.maxStackingGroupId_=quadStacks.length;const effectiveStackingDistance=this.stackingDistance*this.camera_.stackingDistanceDampening;mat4.multiply(mvp,p,mv);for(let i=0;i<quadStacks.length;++i){transformAndProcessQuads(mvp,viewport,quadStacks[i],numPasses,handleQuadFunc,opt_arg1,opt_arg2);mat4.translate(mv,mv,[0,0,effectiveStackingDistance]);mat4.multiply(mvp,p,mv);}
+if(includeChromeQuad&&this.deviceRect_){transformAndProcessQuads(mvp,viewport,[this.chromeQuad],numPasses,drawProjectedQuadToContext,opt_arg1,opt_arg2);}},render(){this.redrawScheduled_=false;if(!this.readyToDraw()){setTimeout(this.scheduleRender.bind(this),constants.IMAGE_LOAD_RETRY_TIME_MS);return;}
+if(!this.quads_)return;const canvasCtx=this.canvas_.getContext('2d');if(!this.resize()){canvasCtx.clearRect(0,0,this.canvas_.width,this.canvas_.height);}
+const quadCanvas=document.createElement('canvas');this.stackTransformAndProcessQuads_(3,drawProjectedQuadToContext,true,canvasCtx,quadCanvas);quadCanvas.width=0;},trackMouse_(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this.canvas_;this.mouseModeSelector_.supportedModeMask=tr.ui.b.MOUSE_SELECTOR_MODE.SELECTION|tr.ui.b.MOUSE_SELECTOR_MODE.PANSCAN|tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM|tr.ui.b.MOUSE_SELECTOR_MODE.ROTATE;this.mouseModeSelector_.mode=tr.ui.b.MOUSE_SELECTOR_MODE.PANSCAN;this.mouseModeSelector_.pos={x:0,y:100};Polymer.dom(this).appendChild(this.mouseModeSelector_);this.mouseModeSelector_.settingsKey='quadStackView.mouseModeSelector';this.mouseModeSelector_.setModifierForAlternateMode(tr.ui.b.MOUSE_SELECTOR_MODE.ROTATE,tr.ui.b.MODIFIER.SHIFT);this.mouseModeSelector_.setModifierForAlternateMode(tr.ui.b.MOUSE_SELECTOR_MODE.PANSCAN,tr.ui.b.MODIFIER.SPACE);this.mouseModeSelector_.setModifierForAlternateMode(tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM,tr.ui.b.MODIFIER.CMD_OR_CTRL);this.mouseModeSelector_.addEventListener('updateselection',this.onSelectionUpdate_.bind(this));this.mouseModeSelector_.addEventListener('endselection',this.onSelectionUpdate_.bind(this));},extractRelativeMousePosition_(e){const br=this.canvas_.getBoundingClientRect();return[this.pixelRatio_*(e.clientX-this.canvas_.offsetLeft-br.left),this.pixelRatio_*(e.clientY-this.canvas_.offsetTop-br.top)];},onSelectionUpdate_(e){const mousePos=this.extractRelativeMousePosition_(e);const res=[];function handleQuad(passNumber,quad,p1,p2,p3,p4){if(tr.b.math.pointInImplicitQuad(mousePos,p1,p2,p3,p4)){res.push(quad);}}
+this.stackTransformAndProcessQuads_(1,handleQuad,false);e=new tr.b.Event('selectionchange');e.quads=res;this.dispatchEvent(e);}};return{QuadStackView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const ColorScheme=tr.b.ColorScheme;const THIS_DOC=document.currentScript.ownerDocument;const TILE_HEATMAP_TYPE={};TILE_HEATMAP_TYPE.NONE='none';TILE_HEATMAP_TYPE.SCHEDULED_PRIORITY='scheduledPriority';TILE_HEATMAP_TYPE.USING_GPU_MEMORY='usingGpuMemory';const cc=tr.ui.e.chrome.cc;function createTileRectsSelectorBaseOptions(){return[{label:'None',value:'none'},{label:'Coverage Rects',value:'coverage'}];}
+const LayerTreeQuadStackView=tr.ui.b.define('tr-ui-e-chrome-cc-layer-tree-quad-stack-view');LayerTreeQuadStackView.prototype={__proto__:HTMLDivElement.prototype,decorate(){this.style.flexGrow=1;this.style.flexShrink=1;this.style.flexBasis='auto';this.style.flexDirection='column';this.style.minHeight=0;this.style.display='flex';this.isRenderPassQuads_=false;this.pictureAsImageData_={};this.messages_=[];this.controls_=document.createElement('top-controls');this.controls_.style.flexGrow=0;this.controls_.style.flexShrink=0;this.controls_.style.flexBasis='auto';this.controls_.style.backgroundImage='-webkit-gradient(linear, 0 0, 100% 0, from(#E5E5E5), to(#D1D1D1))';this.controls_.style.borderBottom='1px solid #8e8e8e';this.controls_.style.borderTop='1px solid white';this.controls_.style.display='flex';this.controls_.style.flexDirection='row';this.controls_.style.flexWrap='wrap';this.controls_.style.fontSize='14px';this.controls_.style.paddingLeft='2px';this.controls_.style.overflow='hidden';this.infoBar_=document.createElement('tr-ui-b-info-bar');this.quadStackView_=new tr.ui.b.QuadStackView();this.quadStackView_.addEventListener('selectionchange',this.onQuadStackViewSelectionChange_.bind(this));this.quadStackView_.style.flexGrow=1;this.quadStackView_.style.flexShrink=1;this.quadStackView_.style.flexBasis='auto';this.quadStackView_.style.minWidth='200px';this.extraHighlightsByLayerId_=undefined;this.inputEventImageData_=undefined;const m=tr.ui.b.MOUSE_SELECTOR_MODE;const mms=this.quadStackView_.mouseModeSelector;mms.settingsKey='tr.e.cc.layerTreeQuadStackView.mouseModeSelector';mms.setKeyCodeForMode(m.SELECTION,'Z'.charCodeAt(0));mms.setKeyCodeForMode(m.PANSCAN,'X'.charCodeAt(0));mms.setKeyCodeForMode(m.ZOOM,'C'.charCodeAt(0));mms.setKeyCodeForMode(m.ROTATE,'V'.charCodeAt(0));const node=tr.ui.b.instantiateTemplate('#tr-ui-e-chrome-cc-layer-tree-quad-stack-view-template',THIS_DOC);Polymer.dom(this).appendChild(node);Polymer.dom(this).appendChild(this.controls_);Polymer.dom(this).appendChild(this.infoBar_);Polymer.dom(this).appendChild(this.quadStackView_);this.tileRectsSelector_=tr.ui.b.createSelector(this,'howToShowTiles','layerView.howToShowTiles','none',createTileRectsSelectorBaseOptions());Polymer.dom(this.controls_).appendChild(this.tileRectsSelector_);const tileHeatmapText=tr.ui.b.createSpan({textContent:'Tile heatmap:'});Polymer.dom(this.controls_).appendChild(tileHeatmapText);const tileHeatmapSelector=tr.ui.b.createSelector(this,'tileHeatmapType','layerView.tileHeatmapType',TILE_HEATMAP_TYPE.NONE,[{label:'None',value:TILE_HEATMAP_TYPE.NONE},{label:'Scheduled Priority',value:TILE_HEATMAP_TYPE.SCHEDULED_PRIORITY},{label:'Is using GPU memory',value:TILE_HEATMAP_TYPE.USING_GPU_MEMORY}]);Polymer.dom(this.controls_).appendChild(tileHeatmapSelector);const showOtherLayersCheckbox=tr.ui.b.createCheckBox(this,'showOtherLayers','layerView.showOtherLayers',true,'Other layers/passes');showOtherLayersCheckbox.title='When checked, show all layers, selected or not.';Polymer.dom(this.controls_).appendChild(showOtherLayersCheckbox);const showInvalidationsCheckbox=tr.ui.b.createCheckBox(this,'showInvalidations','layerView.showInvalidations',true,'Invalidations');showInvalidationsCheckbox.title='When checked, compositing invalidations are highlighted in red';Polymer.dom(this.controls_).appendChild(showInvalidationsCheckbox);const showUnrecordedRegionCheckbox=tr.ui.b.createCheckBox(this,'showUnrecordedRegion','layerView.showUnrecordedRegion',true,'Unrecorded area');showUnrecordedRegionCheckbox.title='When checked, unrecorded areas are highlighted in yellow';Polymer.dom(this.controls_).appendChild(showUnrecordedRegionCheckbox);const showBottlenecksCheckbox=tr.ui.b.createCheckBox(this,'showBottlenecks','layerView.showBottlenecks',true,'Bottlenecks');showBottlenecksCheckbox.title='When checked, scroll bottlenecks are highlighted';Polymer.dom(this.controls_).appendChild(showBottlenecksCheckbox);const showLayoutRectsCheckbox=tr.ui.b.createCheckBox(this,'showLayoutRects','layerView.showLayoutRects',false,'Layout rects');showLayoutRectsCheckbox.title='When checked, shows rects for regions where layout happened';Polymer.dom(this.controls_).appendChild(showLayoutRectsCheckbox);const showContentsCheckbox=tr.ui.b.createCheckBox(this,'showContents','layerView.showContents',true,'Contents');showContentsCheckbox.title='When checked, show the rendered contents inside the layer outlines';Polymer.dom(this.controls_).appendChild(showContentsCheckbox);const showAnimationBoundsCheckbox=tr.ui.b.createCheckBox(this,'showAnimationBounds','layerView.showAnimationBounds',false,'Animation Bounds');showAnimationBoundsCheckbox.title='When checked, show a border around'+' a layer showing the extent of its animation.';Polymer.dom(this.controls_).appendChild(showAnimationBoundsCheckbox);const showInputEventsCheckbox=tr.ui.b.createCheckBox(this,'showInputEvents','layerView.showInputEvents',true,'Input events');showInputEventsCheckbox.title='When checked, input events are '+'displayed as circles.';Polymer.dom(this.controls_).appendChild(showInputEventsCheckbox);this.whatRasterizedLink_=document.createElement('tr-ui-a-analysis-link');this.whatRasterizedLink_.style.position='absolute';this.whatRasterizedLink_.style.bottom='15px';this.whatRasterizedLink_.style.left='10px';this.whatRasterizedLink_.selection=this.getWhatRasterizedEventSet_.bind(this);Polymer.dom(this.quadStackView_).appendChild(this.whatRasterizedLink_);},get layerTreeImpl(){return this.layerTreeImpl_;},set isRenderPassQuads(newValue){this.isRenderPassQuads_=newValue;},set layerTreeImpl(layerTreeImpl){if(this.layerTreeImpl_===layerTreeImpl)return;this.layerTreeImpl_=layerTreeImpl;this.selection=undefined;},get extraHighlightsByLayerId(){return this.extraHighlightsByLayerId_;},set extraHighlightsByLayerId(extraHighlightsByLayerId){this.extraHighlightsByLayerId_=extraHighlightsByLayerId;this.scheduleUpdateContents_();},get showOtherLayers(){return this.showOtherLayers_;},set showOtherLayers(show){this.showOtherLayers_=show;this.updateContents_();},get showAnimationBounds(){return this.showAnimationBounds_;},set showAnimationBounds(show){this.showAnimationBounds_=show;this.updateContents_();},get showInputEvents(){return this.showInputEvents_;},set showInputEvents(show){this.showInputEvents_=show;this.updateContents_();},get showContents(){return this.showContents_;},set showContents(show){this.showContents_=show;this.updateContents_();},get showInvalidations(){return this.showInvalidations_;},set showInvalidations(show){this.showInvalidations_=show;this.updateContents_();},get showUnrecordedRegion(){return this.showUnrecordedRegion_;},set showUnrecordedRegion(show){this.showUnrecordedRegion_=show;this.updateContents_();},get showBottlenecks(){return this.showBottlenecks_;},set showBottlenecks(show){this.showBottlenecks_=show;this.updateContents_();},get showLayoutRects(){return this.showLayoutRects_;},set showLayoutRects(show){this.showLayoutRects_=show;this.updateContents_();},get howToShowTiles(){return this.howToShowTiles_;},set howToShowTiles(val){if(val!=='none'&&val!=='coverage'&&isNaN(parseFloat(val))){throw new Error('howToShowTiles requires "none" or "coverage" or a number');}
+this.howToShowTiles_=val;this.updateContents_();},get tileHeatmapType(){return this.tileHeatmapType_;},set tileHeatmapType(val){this.tileHeatmapType_=val;this.updateContents_();},get selection(){return this.selection_;},set selection(selection){if(this.selection===selection)return;this.selection_=selection;tr.b.dispatchSimpleEvent(this,'selection-change');this.updateContents_();},regenerateContent(){this.updateTilesSelector_();this.updateContents_();},loadDataForImageElement_(image,callback){const imageContent=window.getComputedStyle(image).backgroundImage;if(!imageContent){this.scheduleUpdateContents_();return;}
+image.src=tr.ui.b.extractUrlString(imageContent);image.onload=function(){const canvas=document.createElement('canvas');const ctx=canvas.getContext('2d');canvas.width=image.width;canvas.height=image.height;ctx.drawImage(image,0,0);const imageData=ctx.getImageData(0,0,canvas.width,canvas.height);callback(imageData);};},onQuadStackViewSelectionChange_(e){const selectableQuads=e.quads.filter(function(q){return q.selectionToSetIfClicked!==undefined;});if(selectableQuads.length===0){this.selection=undefined;return;}
+selectableQuads.sort(function(x,y){const z=x.stackingGroupId-y.stackingGroupId;if(z!==0)return z;return x.selectionToSetIfClicked.specicifity-
+y.selectionToSetIfClicked.specicifity;});const quadToSelect=selectableQuads[selectableQuads.length-1];this.selection=quadToSelect.selectionToSetIfClicked;},scheduleUpdateContents_(){if(this.updateContentsPending_)return;this.updateContentsPending_=true;tr.b.requestAnimationFrameInThisFrameIfPossible(this.updateContents_,this);},updateContents_(){if(!this.layerTreeImpl_){this.quadStackView_.headerText='No tree';this.quadStackView_.quads=[];return;}
+const status=this.computePictureLoadingStatus_();if(!status.picturesComplete)return;const lthi=this.layerTreeImpl_.layerTreeHostImpl;const lthiInstance=lthi.objectInstance;const worldViewportRect=tr.b.math.Rect.fromXYWH(0,0,lthi.deviceViewportSize.width,lthi.deviceViewportSize.height);this.quadStackView_.deviceRect=worldViewportRect;if(this.isRenderPassQuads_){this.quadStackView_.quads=this.generateRenderPassQuads();}else{this.quadStackView_.quads=this.generateLayerQuads();}
+this.updateWhatRasterizedLinkState_();let message='';if(lthi.tilesHaveGpuMemoryUsageInfo){const thisTreeUsageInBytes=this.layerTreeImpl_.gpuMemoryUsageInBytes;const otherTreeUsageInBytes=lthi.gpuMemoryUsageInBytes-
+thisTreeUsageInBytes;message+=tr.b.convertUnit(thisTreeUsageInBytes,tr.b.UnitPrefixScale.BINARY.NONE,tr.b.UnitPrefixScale.BINARY.MEBI).toFixed(1)+' MiB on this tree';if(otherTreeUsageInBytes){message+=', '+
+tr.b.convertUnit(otherTreeUsageInBytes,tr.b.UnitPrefixScale.BINARY.NONE,tr.b.UnitPrefixScale.BINARY.MEBI).toFixed(1)+' MiB on the other tree';}}else{if(this.layerTreeImpl_){const thisTreeUsageInBytes=this.layerTreeImpl_.gpuMemoryUsageInBytes;message+=tr.b.convertUnit(thisTreeUsageInBytes,tr.b.UnitPrefixScale.BINARY.NONE,tr.b.UnitPrefixScale.BINARY.MEBI).toFixed(1)+' MiB on this tree';if(this.layerTreeImpl_.otherTree){message+=', ??? MiB on other tree. ';}}}
+if(lthi.args.tileManagerBasicState){const tmgs=lthi.args.tileManagerBasicState.globalState;message+=' (softMax='+
+tr.b.convertUnit(tmgs.softMemoryLimitInBytes,tr.b.UnitPrefixScale.BINARY.NONE,tr.b.UnitPrefixScale.BINARY.MEBI).toFixed(1)+' MiB, hardMax='+
+tr.b.convertUnit(tmgs.hardMemoryLimitInBytes,tr.b.UnitPrefixScale.BINARY.NONE,tr.b.UnitPrefixScale.BINARY.MEBI).toFixed(1)+' MiB, '+
+tmgs.memoryLimitPolicy+')';}else{const thread=lthi.snapshottedOnThread;const didManageTilesSlices=thread.sliceGroup.slices.filter(s=>{if(s.category!=='tr.e.cc')return false;if(s.title!=='DidManage')return false;if(s.end>lthi.ts)return false;return true;});didManageTilesSlices.sort(function(x,y){return x.end-y.end;});if(didManageTilesSlices.length>0){const newest=didManageTilesSlices[didManageTilesSlices.length-1];const tmgs=newest.args.state.global_state;message+=' (softMax='+
+tr.b.convertUnit(tmgs.softMemoryLimitInBytes,tr.b.UnitPrefixScale.BINARY.NONE,tr.b.UnitPrefixScale.BINARY.MEBI).toFixed(1)+' MiB, hardMax='+
+tr.b.convertUnit(tmgs.hardMemoryLimitInBytes,tr.b.UnitPrefixScale.BINARY.NONE,tr.b.UnitPrefixScale.BINARY.MEBI).toFixed(1)+' MiB, '+
+tmgs.memoryLimitPolicy+')';}}
+if(this.layerTreeImpl_.otherTree){message+=' (Another tree exists)';}
+if(message.length){this.quadStackView_.headerText=message;}else{this.quadStackView_.headerText=undefined;}
+this.updateInfoBar_(status.messages);},updateTilesSelector_(){const data=createTileRectsSelectorBaseOptions();if(this.layerTreeImpl_){const lthi=this.layerTreeImpl_.layerTreeHostImpl;const scaleNames=lthi.getContentsScaleNames();for(const scale in scaleNames){data.push({label:'Scale '+scale+' ('+scaleNames[scale]+')',value:scale});}}
+const newSelector=tr.ui.b.createSelector(this,'howToShowTiles','layerView.howToShowTiles','none',data);this.controls_.replaceChild(newSelector,this.tileRectsSelector_);this.tileRectsSelector_=newSelector;},computePictureLoadingStatus_(){const layers=this.layers;const status={messages:[],picturesComplete:true};if(this.showContents){let hasPendingRasterizeImage=false;let firstPictureError=undefined;let hasMissingLayerRect=false;let hasUnresolvedPictureRef=false;for(let i=0;i<layers.length;i++){const layer=layers[i];for(let ir=0;ir<layer.pictures.length;++ir){const picture=layer.pictures[ir];if(picture.idRef){hasUnresolvedPictureRef=true;continue;}
 if(!picture.layerRect){hasMissingLayerRect=true;continue;}
-var pictureAsImageData=this.pictureAsImageData_[picture.guid];if(!pictureAsImageData){hasPendingRasterizeImage=true;this.pictureAsImageData_[picture.guid]=tr.e.cc.PictureAsImageData.Pending(this);picture.rasterize({stopIndex:undefined},function(pictureImageData){var picture_=pictureImageData.picture;this.pictureAsImageData_[picture_.guid]=pictureImageData;this.scheduleUpdateContents_();}.bind(this));continue;}
+const pictureAsImageData=this.pictureAsImageData_[picture.guid];if(!pictureAsImageData){hasPendingRasterizeImage=true;this.pictureAsImageData_[picture.guid]=tr.e.cc.PictureAsImageData.Pending(this);picture.rasterize({stopIndex:undefined},function(pictureImageData){const picture_=pictureImageData.picture;this.pictureAsImageData_[picture_.guid]=pictureImageData;this.scheduleUpdateContents_();}.bind(this));continue;}
 if(pictureAsImageData.isPending()){hasPendingRasterizeImage=true;continue;}
-if(pictureAsImageData.error){if(!firstPictureError)
-firstPictureError=pictureAsImageData.error;break;}}}
-if(hasPendingRasterizeImage){status.picturesComplete=false;}else{if(hasUnresolvedPictureRef){status.messages.push({header:'Missing picture',details:'Your trace didnt have pictures for every layer. '+'Old chrome versions had this problem'});}
+if(pictureAsImageData.error){if(!firstPictureError){firstPictureError=pictureAsImageData.error;}
+break;}}}
+if(hasPendingRasterizeImage){status.picturesComplete=false;}else{if(hasUnresolvedPictureRef){status.messages.push({header:'Missing picture',details:'Your trace didn\'t have pictures for every layer. '+'Old chrome versions had this problem'});}
 if(hasMissingLayerRect){status.messages.push({header:'Missing layer rect',details:'Your trace may be corrupt or from a very old '+'Chrome revision.'});}
 if(firstPictureError){status.messages.push({header:'Cannot rasterize',details:firstPictureError});}}}
-if(this.showInputEvents&&this.layerTreeImpl.tracedInputLatencies&&this.inputEventImageData_===undefined){var image=this.querySelector('#input-event');if(!image.src){this.loadDataForImageElement_(image,function(imageData){this.inputEventImageData_=imageData;this.updateContentsPending_=false;this.scheduleUpdateContents_();}.bind(this));}
+if(this.showInputEvents&&this.layerTreeImpl.tracedInputLatencies&&this.inputEventImageData_===undefined){const image=Polymer.dom(this).querySelector('#input-event');if(!image.src){this.loadDataForImageElement_(image,function(imageData){this.inputEventImageData_=imageData;this.updateContentsPending_=false;this.scheduleUpdateContents_();}.bind(this));}
 status.picturesComplete=false;}
-return status;},get selectedRenderPass(){if(this.selection)
-return this.selection.renderPass_;},get selectedLayer(){if(this.selection){var selectedLayerId=this.selection.associatedLayerId;return this.layerTreeImpl_.findLayerWithId(selectedLayerId);}},get renderPasses(){var renderPasses=this.layerTreeImpl.layerTreeHostImpl.args.frame.renderPasses;if(!this.showOtherLayers){var selectedRenderPass=this.selectedRenderPass;if(selectedRenderPass)
-renderPasses=[selectedRenderPass];}
-return renderPasses;},get layers(){var layers=this.layerTreeImpl.renderSurfaceLayerList;if(!this.showOtherLayers){var selectedLayer=this.selectedLayer;if(selectedLayer)
-layers=[selectedLayer];}
-return layers;},appendImageQuads_:function(quads,layer,layerQuad){for(var ir=0;ir<layer.pictures.length;++ir){var picture=layer.pictures[ir];if(!picture.layerRect)
-continue;var unitRect=picture.layerRect.asUVRectInside(layer.bounds);var iq=layerQuad.projectUnitRect(unitRect);var pictureData=this.pictureAsImageData_[picture.guid];if(this.showContents&&pictureData&&pictureData.imageData){iq.imageData=pictureData.imageData;iq.borderColor='rgba(0,0,0,0)';}else{iq.imageData=undefined;}
-iq.stackingGroupId=layerQuad.stackingGroupId;quads.push(iq);}},appendAnimationQuads_:function(quads,layer,layerQuad){if(!layer.animationBoundsRect)
-return;var rect=layer.animationBoundsRect;var abq=tr.b.Quad.fromRect(rect);abq.backgroundColor='rgba(164,191,48,0.5)';abq.borderColor='rgba(205,255,0,0.75)';abq.borderWidth=3.0;abq.stackingGroupId=layerQuad.stackingGroupId;abq.selectionToSetIfClicked=new cc.AnimationRectSelection(layer,rect);quads.push(abq);},appendInvalidationQuads_:function(quads,layer,layerQuad){if(layer.layerTreeImpl.hasSourceFrameBeenDrawnBefore)
-return;for(var ir=0;ir<layer.annotatedInvalidation.rects.length;ir++){var rect=layer.annotatedInvalidation.rects[ir];var unitRect=rect.asUVRectInside(layer.bounds);var iq=layerQuad.projectUnitRect(unitRect);iq.backgroundColor='rgba(0, 255, 0, 0.1)';if(rect.reason==='renderer insertion')
-iq.backgroundColor='rgba(0, 255, 128, 0.1)';iq.borderColor='rgba(0, 255, 0, 1)';iq.stackingGroupId=layerQuad.stackingGroupId;iq.selectionToSetIfClicked=new cc.LayerRectSelection(layer,'Invalidation rect ('+rect.reason+')',rect,rect);quads.push(iq);}
-if(layer.annotatedInvalidation.rects.length===0){for(var ir=0;ir<layer.invalidation.rects.length;ir++){var rect=layer.invalidation.rects[ir];var unitRect=rect.asUVRectInside(layer.bounds);var iq=layerQuad.projectUnitRect(unitRect);iq.backgroundColor='rgba(0, 255, 0, 0.1)';iq.borderColor='rgba(0, 255, 0, 1)';iq.stackingGroupId=layerQuad.stackingGroupId;iq.selectionToSetIfClicked=new cc.LayerRectSelection(layer,'Invalidation rect',rect,rect);quads.push(iq);}}},appendUnrecordedRegionQuads_:function(quads,layer,layerQuad){for(var ir=0;ir<layer.unrecordedRegion.rects.length;ir++){var rect=layer.unrecordedRegion.rects[ir];var unitRect=rect.asUVRectInside(layer.bounds);var iq=layerQuad.projectUnitRect(unitRect);iq.backgroundColor='rgba(240, 230, 140, 0.3)';iq.borderColor='rgba(240, 230, 140, 1)';iq.stackingGroupId=layerQuad.stackingGroupId;iq.selectionToSetIfClicked=new cc.LayerRectSelection(layer,'Unrecorded area',rect,rect);quads.push(iq);}},appendBottleneckQuads_:function(quads,layer,layerQuad,stackingGroupId){function processRegion(region,label,borderColor){var backgroundColor=borderColor.clone();backgroundColor.a=0.4*(borderColor.a||1.0);if(!region||!region.rects)
-return;for(var ir=0;ir<region.rects.length;ir++){var rect=region.rects[ir];var unitRect=rect.asUVRectInside(layer.bounds);var iq=layerQuad.projectUnitRect(unitRect);iq.backgroundColor=backgroundColor.toString();iq.borderColor=borderColor.toString();iq.borderWidth=4.0;iq.stackingGroupId=stackingGroupId;iq.selectionToSetIfClicked=new cc.LayerRectSelection(layer,label,rect,rect);quads.push(iq);}}
-processRegion(layer.touchEventHandlerRegion,'Touch listener',tr.b.Color.fromString('rgb(228, 226, 27)'));processRegion(layer.wheelEventHandlerRegion,'Wheel listener',tr.b.Color.fromString('rgb(176, 205, 29)'));processRegion(layer.nonFastScrollableRegion,'Repaints on scroll',tr.b.Color.fromString('rgb(213, 134, 32)'));},appendTileCoverageRectQuads_:function(quads,layer,layerQuad,heatmapType){if(!layer.tileCoverageRects)
-return;var tiles=[];for(var ct=0;ct<layer.tileCoverageRects.length;++ct){var tile=layer.tileCoverageRects[ct].tile;if(tile!==undefined)
-tiles.push(tile);}
-var lthi=this.layerTreeImpl_.layerTreeHostImpl;var minMax=this.getMinMaxForHeatmap_(lthi.activeTiles,heatmapType);var heatmapResult=this.computeHeatmapColors_(tiles,minMax,heatmapType);var heatIndex=0;for(var ct=0;ct<layer.tileCoverageRects.length;++ct){var rect=layer.tileCoverageRects[ct].geometryRect;rect=rect.scale(1.0/layer.geometryContentsScale);var tile=layer.tileCoverageRects[ct].tile;var unitRect=rect.asUVRectInside(layer.bounds);var quad=layerQuad.projectUnitRect(unitRect);quad.backgroundColor='rgba(0, 0, 0, 0)';quad.stackingGroupId=layerQuad.stackingGroupId;var type=tr.e.cc.tileTypes.missing;if(tile){type=tile.getTypeForLayer(layer);quad.backgroundColor=heatmapResult[heatIndex].color;++heatIndex;}
-quad.borderColor=tr.e.cc.tileBorder[type].color;quad.borderWidth=tr.e.cc.tileBorder[type].width;var label;if(tile)
-label='coverageRect';else
-label='checkerboard coverageRect';quad.selectionToSetIfClicked=new cc.LayerRectSelection(layer,label,rect,layer.tileCoverageRects[ct]);quads.push(quad);}},appendLayoutRectQuads_:function(quads,layer,layerQuad){if(!layer.layoutRects){return;}
-for(var ct=0;ct<layer.layoutRects.length;++ct){var rect=layer.layoutRects[ct].geometryRect;rect=rect.scale(1.0/layer.geometryContentsScale);var unitRect=rect.asUVRectInside(layer.bounds);var quad=layerQuad.projectUnitRect(unitRect);quad.backgroundColor='rgba(0, 0, 0, 0)';quad.stackingGroupId=layerQuad.stackingGroupId;quad.borderColor='rgba(0, 0, 200, 0.7)';quad.borderWidth=2;var label;label='Layout rect';quad.selectionToSetIfClicked=new cc.LayerRectSelection(layer,label,rect);quads.push(quad);}},getValueForHeatmap_:function(tile,heatmapType){if(heatmapType==TILE_HEATMAP_TYPE.SCHEDULED_PRIORITY){return tile.scheduledPriority==0?undefined:tile.scheduledPriority;}else if(heatmapType==TILE_HEATMAP_TYPE.USING_GPU_MEMORY){if(tile.isSolidColor)
-return 0.5;return tile.isUsingGpuMemory?0:1;}},getMinMaxForHeatmap_:function(tiles,heatmapType){var range=new tr.b.Range();if(heatmapType==TILE_HEATMAP_TYPE.USING_GPU_MEMORY){range.addValue(0);range.addValue(1);return range;}
-for(var i=0;i<tiles.length;++i){var value=this.getValueForHeatmap_(tiles[i],heatmapType);if(value===undefined)
-continue;range.addValue(value);}
-if(range.range===0)
-range.addValue(1);return range;},computeHeatmapColors_:function(tiles,minMax,heatmapType){var min=minMax.min;var max=minMax.max;var color=function(value){var hue=120*(1-(value-min)/(max-min));if(hue<0)
-hue=0;return'hsla('+hue+', 100%, 50%, 0.5)';};var values=[];for(var i=0;i<tiles.length;++i){var tile=tiles[i];var value=this.getValueForHeatmap_(tile,heatmapType);var res={value:value,color:value!==undefined?color(value):undefined};values.push(res);}
-return values;},appendTilesWithScaleQuads_:function(quads,layer,layerQuad,scale,heatmapType){var lthi=this.layerTreeImpl_.layerTreeHostImpl;var tiles=[];for(var i=0;i<lthi.activeTiles.length;++i){var tile=lthi.activeTiles[i];if(Math.abs(tile.contentsScale-scale)>1e-6)
-continue;if(layer.layerId!=tile.layerId)
-continue;tiles.push(tile);}
-var minMax=this.getMinMaxForHeatmap_(lthi.activeTiles,heatmapType);var heatmapResult=this.computeHeatmapColors_(tiles,minMax,heatmapType);for(var i=0;i<tiles.length;++i){var tile=tiles[i];var rect=tile.layerRect;if(!tile.layerRect)
-continue;var unitRect=rect.asUVRectInside(layer.bounds);var quad=layerQuad.projectUnitRect(unitRect);quad.backgroundColor='rgba(0, 0, 0, 0)';quad.stackingGroupId=layerQuad.stackingGroupId;var type=tile.getTypeForLayer(layer);quad.borderColor=tr.e.cc.tileBorder[type].color;quad.borderWidth=tr.e.cc.tileBorder[type].width;quad.backgroundColor=heatmapResult[i].color;var data={tileType:type};if(heatmapType!==TILE_HEATMAP_TYPE.NONE)
-data[heatmapType]=heatmapResult[i].value;quad.selectionToSetIfClicked=new cc.TileSelection(tile,data);quads.push(quad);}},appendHighlightQuadsForLayer_:function(quads,layer,layerQuad,highlights){highlights.forEach(function(highlight){var rect=highlight.rect;var unitRect=rect.asUVRectInside(layer.bounds);var quad=layerQuad.projectUnitRect(unitRect);var colorId=ColorScheme.getColorIdForGeneralPurposeString(highlight.colorKey);colorId+=ColorScheme.properties.brightenedOffsets[0];var color=ColorScheme.colors[colorId];var quadForDrawing=quad.clone();quadForDrawing.backgroundColor=color.withAlpha(0.5).toString();quadForDrawing.borderColor=color.withAlpha(1.0).darken().toString();quadForDrawing.stackingGroupId=layerQuad.stackingGroupId;quads.push(quadForDrawing);},this);},generateRenderPassQuads:function(){if(!this.layerTreeImpl.layerTreeHostImpl.args.frame)
-return[];var renderPasses=this.renderPasses;if(!renderPasses)
-return[];var quads=[];for(var i=0;i<renderPasses.length;++i){var quadList=renderPasses[i].quadList;for(var j=0;j<quadList.length;++j){var drawQuad=quadList[j];var quad=drawQuad.rectAsTargetSpaceQuad.clone();quad.borderColor='rgb(170, 204, 238)';quad.borderWidth=2;quad.stackingGroupId=i;quads.push(quad);}}
-return quads;},generateLayerQuads:function(){this.updateContentsPending_=false;var layers=this.layers;var quads=[];var nextStackingGroupId=0;var alreadyVisitedLayerIds={};var selectionHighlightsByLayerId;if(this.selection)
-selectionHighlightsByLayerId=this.selection.highlightsByLayerId;else
-selectionHighlightsByLayerId={};var extraHighlightsByLayerId=this.extraHighlightsByLayerId||{};for(var i=1;i<=layers.length;i++){var layer=layers[layers.length-i];alreadyVisitedLayerIds[layer.layerId]=true;if(layer.objectInstance.name=='cc::NinePatchLayerImpl')
-continue;var layerQuad=layer.layerQuad.clone();if(layer.usingGpuRasterization){var pixelRatio=window.devicePixelRatio||1;layerQuad.borderWidth=2.0*pixelRatio;layerQuad.borderColor='rgba(154,205,50,0.75)';}else{layerQuad.borderColor='rgba(0,0,0,0.75)';}
-layerQuad.stackingGroupId=nextStackingGroupId++;layerQuad.selectionToSetIfClicked=new cc.LayerSelection(layer);layerQuad.layer=layer;if(this.showOtherLayers&&this.selectedLayer==layer)
-layerQuad.upperBorderColor='rgb(156,189,45)';if(this.showAnimationBounds)
-this.appendAnimationQuads_(quads,layer,layerQuad);this.appendImageQuads_(quads,layer,layerQuad);quads.push(layerQuad);if(this.showInvalidations)
-this.appendInvalidationQuads_(quads,layer,layerQuad);if(this.showUnrecordedRegion)
-this.appendUnrecordedRegionQuads_(quads,layer,layerQuad);if(this.showBottlenecks)
-this.appendBottleneckQuads_(quads,layer,layerQuad,layerQuad.stackingGroupId);if(this.showLayoutRects)
-this.appendLayoutRectQuads_(quads,layer,layerQuad);if(this.howToShowTiles==='coverage'){this.appendTileCoverageRectQuads_(quads,layer,layerQuad,this.tileHeatmapType);}else if(this.howToShowTiles!=='none'){this.appendTilesWithScaleQuads_(quads,layer,layerQuad,this.howToShowTiles,this.tileHeatmapType);}
-var highlights;highlights=extraHighlightsByLayerId[layer.layerId];if(highlights){this.appendHighlightQuadsForLayer_(quads,layer,layerQuad,highlights);}
+return status;},get selectedRenderPass(){if(this.selection){return this.selection.renderPass_;}},get selectedLayer(){if(this.selection){const selectedLayerId=this.selection.associatedLayerId;return this.layerTreeImpl_.findLayerWithId(selectedLayerId);}},get renderPasses(){let renderPasses=this.layerTreeImpl.layerTreeHostImpl.args.frame.renderPasses;if(!this.showOtherLayers){const selectedRenderPass=this.selectedRenderPass;if(selectedRenderPass){renderPasses=[selectedRenderPass];}}
+return renderPasses;},get layers(){let layers=this.layerTreeImpl.renderSurfaceLayerList;if(!this.showOtherLayers){const selectedLayer=this.selectedLayer;if(selectedLayer){layers=[selectedLayer];}}
+return layers;},appendImageQuads_(quads,layer,layerQuad){for(let ir=0;ir<layer.pictures.length;++ir){const picture=layer.pictures[ir];if(!picture.layerRect)continue;const unitRect=picture.layerRect.asUVRectInside(layer.bounds);const iq=layerQuad.projectUnitRect(unitRect);const pictureData=this.pictureAsImageData_[picture.guid];if(this.showContents&&pictureData&&pictureData.imageData){iq.imageData=pictureData.imageData;iq.borderColor='rgba(0,0,0,0)';}else{iq.imageData=undefined;}
+iq.stackingGroupId=layerQuad.stackingGroupId;quads.push(iq);}},appendAnimationQuads_(quads,layer,layerQuad){if(!layer.animationBoundsRect)return;const rect=layer.animationBoundsRect;const abq=tr.b.math.Quad.fromRect(rect);abq.backgroundColor='rgba(164,191,48,0.5)';abq.borderColor='rgba(205,255,0,0.75)';abq.borderWidth=3.0;abq.stackingGroupId=layerQuad.stackingGroupId;abq.selectionToSetIfClicked=new cc.AnimationRectSelection(layer,rect);quads.push(abq);},appendInvalidationQuads_(quads,layer,layerQuad){if(layer.layerTreeImpl.hasSourceFrameBeenDrawnBefore)return;for(const rect of layer.invalidation.rects){const unitRect=rect.asUVRectInside(layer.bounds);const iq=layerQuad.projectUnitRect(unitRect);iq.backgroundColor='rgba(0, 255, 0, 0.1)';if(rect.reason==='appeared'){iq.backgroundColor='rgba(0, 255, 128, 0.1)';}
+iq.borderColor='rgba(0, 255, 0, 1)';iq.stackingGroupId=layerQuad.stackingGroupId;let message='Invalidation rect';if(rect.reason){message+=' ('+rect.reason+')';}
+if(rect.client){message+=' for '+rect.client;}
+iq.selectionToSetIfClicked=new cc.LayerRectSelection(layer,message,rect,rect);quads.push(iq);}},appendUnrecordedRegionQuads_(quads,layer,layerQuad){for(let ir=0;ir<layer.unrecordedRegion.rects.length;ir++){const rect=layer.unrecordedRegion.rects[ir];const unitRect=rect.asUVRectInside(layer.bounds);const iq=layerQuad.projectUnitRect(unitRect);iq.backgroundColor='rgba(240, 230, 140, 0.3)';iq.borderColor='rgba(240, 230, 140, 1)';iq.stackingGroupId=layerQuad.stackingGroupId;iq.selectionToSetIfClicked=new cc.LayerRectSelection(layer,'Unrecorded area',rect,rect);quads.push(iq);}},appendBottleneckQuads_(quads,layer,layerQuad,stackingGroupId){function processRegion(region,label,borderColor){const backgroundColor=borderColor.clone();backgroundColor.a=0.4*(borderColor.a||1.0);if(!region||!region.rects)return;for(let ir=0;ir<region.rects.length;ir++){const rect=region.rects[ir];const unitRect=rect.asUVRectInside(layer.bounds);const iq=layerQuad.projectUnitRect(unitRect);iq.backgroundColor=backgroundColor.toString();iq.borderColor=borderColor.toString();iq.borderWidth=4.0;iq.stackingGroupId=stackingGroupId;iq.selectionToSetIfClicked=new cc.LayerRectSelection(layer,label,rect,rect);quads.push(iq);}}
+processRegion(layer.touchEventHandlerRegion,'Touch listener',tr.b.Color.fromString('rgb(228, 226, 27)'));processRegion(layer.wheelEventHandlerRegion,'Wheel listener',tr.b.Color.fromString('rgb(176, 205, 29)'));processRegion(layer.nonFastScrollableRegion,'Repaints on scroll',tr.b.Color.fromString('rgb(213, 134, 32)'));},appendTileCoverageRectQuads_(quads,layer,layerQuad,heatmapType){if(!layer.tileCoverageRects)return;const tiles=[];for(let ct=0;ct<layer.tileCoverageRects.length;++ct){const tile=layer.tileCoverageRects[ct].tile;if(tile!==undefined)tiles.push(tile);}
+const lthi=this.layerTreeImpl_.layerTreeHostImpl;const minMax=this.getMinMaxForHeatmap_(lthi.activeTiles,heatmapType);const heatmapResult=this.computeHeatmapColors_(tiles,minMax,heatmapType);let heatIndex=0;for(let ct=0;ct<layer.tileCoverageRects.length;++ct){let rect=layer.tileCoverageRects[ct].geometryRect;rect=rect.scale(1.0/layer.geometryContentsScale);const tile=layer.tileCoverageRects[ct].tile;const unitRect=rect.asUVRectInside(layer.bounds);const quad=layerQuad.projectUnitRect(unitRect);quad.backgroundColor='rgba(0, 0, 0, 0)';quad.stackingGroupId=layerQuad.stackingGroupId;let type=tr.e.cc.tileTypes.missing;if(tile){type=tile.getTypeForLayer(layer);quad.backgroundColor=heatmapResult[heatIndex].color;++heatIndex;}
+quad.borderColor=tr.e.cc.tileBorder[type].color;quad.borderWidth=tr.e.cc.tileBorder[type].width;let label;if(tile){label='coverageRect';}else{label='checkerboard coverageRect';}
+quad.selectionToSetIfClicked=new cc.LayerRectSelection(layer,label,rect,layer.tileCoverageRects[ct]);quads.push(quad);}},appendLayoutRectQuads_(quads,layer,layerQuad){if(!layer.layoutRects){return;}
+for(let ct=0;ct<layer.layoutRects.length;++ct){let rect=layer.layoutRects[ct].geometryRect;rect=rect.scale(1.0/layer.geometryContentsScale);const unitRect=rect.asUVRectInside(layer.bounds);const quad=layerQuad.projectUnitRect(unitRect);quad.backgroundColor='rgba(0, 0, 0, 0)';quad.stackingGroupId=layerQuad.stackingGroupId;quad.borderColor='rgba(0, 0, 200, 0.7)';quad.borderWidth=2;const label='Layout rect';quad.selectionToSetIfClicked=new cc.LayerRectSelection(layer,label,rect);quads.push(quad);}},getValueForHeatmap_(tile,heatmapType){if(heatmapType===TILE_HEATMAP_TYPE.SCHEDULED_PRIORITY){return tile.scheduledPriority===0?undefined:tile.scheduledPriority;}else if(heatmapType===TILE_HEATMAP_TYPE.USING_GPU_MEMORY){if(tile.isSolidColor)return 0.5;return tile.isUsingGpuMemory?0:1;}},getMinMaxForHeatmap_(tiles,heatmapType){const range=new tr.b.math.Range();if(heatmapType===TILE_HEATMAP_TYPE.USING_GPU_MEMORY){range.addValue(0);range.addValue(1);return range;}
+for(let i=0;i<tiles.length;++i){const value=this.getValueForHeatmap_(tiles[i],heatmapType);if(value===undefined)continue;range.addValue(value);}
+if(range.range===0){range.addValue(1);}
+return range;},computeHeatmapColors_(tiles,minMax,heatmapType){const min=minMax.min;const max=minMax.max;const color=function(value){let hue=120*(1-(value-min)/(max-min));if(hue<0)hue=0;return'hsla('+hue+', 100%, 50%, 0.5)';};const values=[];for(let i=0;i<tiles.length;++i){const tile=tiles[i];const value=this.getValueForHeatmap_(tile,heatmapType);const res={value,color:value!==undefined?color(value):undefined};values.push(res);}
+return values;},appendTilesWithScaleQuads_(quads,layer,layerQuad,scale,heatmapType){const lthi=this.layerTreeImpl_.layerTreeHostImpl;const tiles=[];for(let i=0;i<lthi.activeTiles.length;++i){const tile=lthi.activeTiles[i];if(Math.abs(tile.contentsScale-scale)>1e-6){continue;}
+if(layer.layerId!==tile.layerId)continue;tiles.push(tile);}
+const minMax=this.getMinMaxForHeatmap_(lthi.activeTiles,heatmapType);const heatmapResult=this.computeHeatmapColors_(tiles,minMax,heatmapType);for(let i=0;i<tiles.length;++i){const tile=tiles[i];const rect=tile.layerRect;if(!tile.layerRect)continue;const unitRect=rect.asUVRectInside(layer.bounds);const quad=layerQuad.projectUnitRect(unitRect);quad.backgroundColor='rgba(0, 0, 0, 0)';quad.stackingGroupId=layerQuad.stackingGroupId;const type=tile.getTypeForLayer(layer);quad.borderColor=tr.e.cc.tileBorder[type].color;quad.borderWidth=tr.e.cc.tileBorder[type].width;quad.backgroundColor=heatmapResult[i].color;const data={tileType:type};if(heatmapType!==TILE_HEATMAP_TYPE.NONE){data[heatmapType]=heatmapResult[i].value;}
+quad.selectionToSetIfClicked=new cc.TileSelection(tile,data);quads.push(quad);}},appendHighlightQuadsForLayer_(quads,layer,layerQuad,highlights){highlights.forEach(function(highlight){const rect=highlight.rect;const unitRect=rect.asUVRectInside(layer.bounds);const quad=layerQuad.projectUnitRect(unitRect);let colorId=ColorScheme.getColorIdForGeneralPurposeString(highlight.colorKey);const offset=ColorScheme.properties.brightenedOffsets[0];colorId=ColorScheme.getVariantColorId(colorId,offset);const color=ColorScheme.colors[colorId];const quadForDrawing=quad.clone();quadForDrawing.backgroundColor=color.withAlpha(0.5).toString();quadForDrawing.borderColor=color.withAlpha(1.0).darken().toString();quadForDrawing.stackingGroupId=layerQuad.stackingGroupId;quads.push(quadForDrawing);},this);},generateRenderPassQuads(){if(!this.layerTreeImpl.layerTreeHostImpl.args.frame)return[];const renderPasses=this.renderPasses;if(!renderPasses)return[];const quads=[];for(let i=0;i<renderPasses.length;++i){const quadList=renderPasses[i].quadList;for(let j=0;j<quadList.length;++j){const drawQuad=quadList[j];const quad=drawQuad.rectAsTargetSpaceQuad.clone();quad.borderColor='rgb(170, 204, 238)';quad.borderWidth=2;quad.stackingGroupId=i;quads.push(quad);}}
+return quads;},generateLayerQuads(){this.updateContentsPending_=false;const layers=this.layers;const quads=[];let nextStackingGroupId=0;const alreadyVisitedLayerIds={};let selectionHighlightsByLayerId;if(this.selection){selectionHighlightsByLayerId=this.selection.highlightsByLayerId;}else{selectionHighlightsByLayerId={};}
+const extraHighlightsByLayerId=this.extraHighlightsByLayerId||{};for(let i=1;i<=layers.length;i++){const layer=layers[layers.length-i];alreadyVisitedLayerIds[layer.layerId]=true;if(layer.objectInstance.name==='cc::NinePatchLayerImpl'){continue;}
+const layerQuad=layer.layerQuad.clone();if(layer.usingGpuRasterization){const pixelRatio=window.devicePixelRatio||1;layerQuad.borderWidth=2.0*pixelRatio;layerQuad.borderColor='rgba(154,205,50,0.75)';}else{layerQuad.borderColor='rgba(0,0,0,0.75)';}
+layerQuad.stackingGroupId=nextStackingGroupId++;layerQuad.selectionToSetIfClicked=new cc.LayerSelection(layer);layerQuad.layer=layer;if(this.showOtherLayers&&this.selectedLayer===layer){layerQuad.upperBorderColor='rgb(156,189,45)';}
+if(this.showAnimationBounds){this.appendAnimationQuads_(quads,layer,layerQuad);}
+this.appendImageQuads_(quads,layer,layerQuad);quads.push(layerQuad);if(this.showInvalidations){this.appendInvalidationQuads_(quads,layer,layerQuad);}
+if(this.showUnrecordedRegion){this.appendUnrecordedRegionQuads_(quads,layer,layerQuad);}
+if(this.showBottlenecks){this.appendBottleneckQuads_(quads,layer,layerQuad,layerQuad.stackingGroupId);}
+if(this.showLayoutRects){this.appendLayoutRectQuads_(quads,layer,layerQuad);}
+if(this.howToShowTiles==='coverage'){this.appendTileCoverageRectQuads_(quads,layer,layerQuad,this.tileHeatmapType);}else if(this.howToShowTiles!=='none'){this.appendTilesWithScaleQuads_(quads,layer,layerQuad,this.howToShowTiles,this.tileHeatmapType);}
+let highlights;highlights=extraHighlightsByLayerId[layer.layerId];if(highlights){this.appendHighlightQuadsForLayer_(quads,layer,layerQuad,highlights);}
 highlights=selectionHighlightsByLayerId[layer.layerId];if(highlights){this.appendHighlightQuadsForLayer_(quads,layer,layerQuad,highlights);}}
-this.layerTreeImpl.iterLayers(function(layer,depth,isMask,isReplica){if(!this.showOtherLayers&&this.selectedLayer!=layer)
-return;if(alreadyVisitedLayerIds[layer.layerId])
-return;var layerQuad=layer.layerQuad;var stackingGroupId=nextStackingGroupId++;if(this.showBottlenecks)
-this.appendBottleneckQuads_(quads,layer,layerQuad,stackingGroupId);},this);var tracedInputLatencies=this.layerTreeImpl.tracedInputLatencies;if(this.showInputEvents&&tracedInputLatencies){for(var i=0;i<tracedInputLatencies.length;i++){var coordinatesArray=tracedInputLatencies[i].args.data.coordinates;for(var j=0;j<coordinatesArray.length;j++){var inputQuad=tr.b.Quad.fromXYWH(coordinatesArray[j].x-25,coordinatesArray[j].y-25,50,50);inputQuad.borderColor='rgba(0, 0, 0, 0)';inputQuad.imageData=this.inputEventImageData_;quads.push(inputQuad);}}}
-return quads;},updateInfoBar_:function(infoBarMessages){if(infoBarMessages.length){this.infoBar_.removeAllButtons();this.infoBar_.message='Some problems were encountered...';this.infoBar_.addButton('More info...',function(e){var overlay=new tr.ui.b.Overlay();overlay.textContent='';infoBarMessages.forEach(function(message){var title=document.createElement('h3');title.textContent=message.header;var details=document.createElement('div');details.textContent=message.details;overlay.appendChild(title);overlay.appendChild(details);});overlay.visible=true;e.stopPropagation();return false;});this.infoBar_.visible=true;}else{this.infoBar_.removeAllButtons();this.infoBar_.message='';this.infoBar_.visible=false;}},getWhatRasterized_:function(){var lthi=this.layerTreeImpl_.layerTreeHostImpl;var renderProcess=lthi.objectInstance.parent;var tasks=[];renderProcess.iterateAllEvents(function(event){if(!(event instanceof tr.model.Slice))
-return;var tile=tr.e.cc.getTileFromRasterTaskSlice(event);if(tile===undefined)
-return false;if(tile.containingSnapshot==lthi)
-tasks.push(event);},this);return tasks;},updateWhatRasterizedLinkState_:function(){var tasks=this.getWhatRasterized_();if(tasks.length){this.whatRasterizedLink_.textContent=tasks.length+' raster tasks';this.whatRasterizedLink_.style.display='';}else{this.whatRasterizedLink_.textContent='';this.whatRasterizedLink_.style.display='none';}},onWhatRasterizedLinkClicked_:function(){var tasks=this.getWhatRasterized_();var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(tasks);this.dispatchEvent(event);}};return{LayerTreeQuadStackView:LayerTreeQuadStackView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var constants=tr.e.cc.constants;var LayerView=tr.ui.b.define('tr-ui-e-chrome-cc-layer-view');LayerView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.layerTreeQuadStackView_=new tr.ui.e.chrome.cc.LayerTreeQuadStackView();this.dragBar_=document.createElement('tr-ui-b-drag-handle');this.analysisEl_=document.createElement('tr-ui-e-chrome-cc-layer-view-analysis');this.analysisEl_.addEventListener('requestSelectionChange',this.onRequestSelectionChangeFromAnalysisEl_.bind(this));this.dragBar_.target=this.analysisEl_;this.appendChild(this.layerTreeQuadStackView_);this.appendChild(this.dragBar_);this.appendChild(this.analysisEl_);this.layerTreeQuadStackView_.addEventListener('selection-change',function(){this.layerTreeQuadStackViewSelectionChanged_();}.bind(this));this.layerTreeQuadStackViewSelectionChanged_();},get layerTreeImpl(){return this.layerTreeQuadStackView_.layerTreeImpl;},set layerTreeImpl(newValue){return this.layerTreeQuadStackView_.layerTreeImpl=newValue;},set isRenderPassQuads(newValue){return this.layerTreeQuadStackView_.isRenderPassQuads=newValue;},get selection(){return this.layerTreeQuadStackView_.selection;},set selection(newValue){this.layerTreeQuadStackView_.selection=newValue;},regenerateContent:function(){this.layerTreeQuadStackView_.regenerateContent();},layerTreeQuadStackViewSelectionChanged_:function(){var selection=this.layerTreeQuadStackView_.selection;if(selection){this.dragBar_.style.display='';this.analysisEl_.style.display='';this.analysisEl_.textContent='';var layer=selection.layer;if(layer&&layer.args&&layer.args.pictures){this.analysisEl_.appendChild(this.createPictureBtn_(layer.args.pictures));}
-var analysis=selection.createAnalysis();this.analysisEl_.appendChild(analysis);}else{this.dragBar_.style.display='none';this.analysisEl_.style.display='none';var analysis=this.analysisEl_.firstChild;if(analysis)
-this.analysisEl_.removeChild(analysis);this.layerTreeQuadStackView_.style.height=window.getComputedStyle(this).height;}
-tr.b.dispatchSimpleEvent(this,'selection-change');},createPictureBtn_:function(pictures){if(!(pictures instanceof Array))
-pictures=[pictures];var link=document.createElement('tr-ui-a-analysis-link');link.selection=function(){var layeredPicture=new tr.e.cc.LayeredPicture(pictures);var snapshot=new tr.e.cc.PictureSnapshot(layeredPicture);snapshot.picture=layeredPicture;var selection=new tr.model.EventSet();selection.push(snapshot);return selection;};link.textContent='View in Picture Debugger';return link;},onRequestSelectionChangeFromAnalysisEl_:function(e){if(!(e.selection instanceof tr.ui.e.chrome.cc.Selection))
-return;e.stopPropagation();this.selection=e.selection;},get extraHighlightsByLayerId(){return this.layerTreeQuadStackView_.extraHighlightsByLayerId;},set extraHighlightsByLayerId(extraHighlightsByLayerId){this.layerTreeQuadStackView_.extraHighlightsByLayerId=extraHighlightsByLayerId;}};return{LayerView:LayerView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var LayerTreeHostImplSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-layer-tree-host-impl-snapshot-view',tr.ui.analysis.ObjectSnapshotView);LayerTreeHostImplSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-chrome-cc-lthi-s-view');this.selection_=undefined;this.layerPicker_=new tr.ui.e.chrome.cc.LayerPicker();this.layerPicker_.addEventListener('selection-change',this.onLayerPickerSelectionChanged_.bind(this));this.layerView_=new tr.ui.e.chrome.cc.LayerView();this.layerView_.addEventListener('selection-change',this.onLayerViewSelectionChanged_.bind(this));this.dragHandle_=document.createElement('tr-ui-b-drag-handle');this.dragHandle_.horizontal=false;this.dragHandle_.target=this.layerView_;this.appendChild(this.layerPicker_);this.appendChild(this.dragHandle_);this.appendChild(this.layerView_);this.onLayerViewSelectionChanged_();this.onLayerPickerSelectionChanged_();},get objectSnapshot(){return this.objectSnapshot_;},set objectSnapshot(objectSnapshot){this.objectSnapshot_=objectSnapshot;var lthi=this.objectSnapshot;var layerTreeImpl;if(lthi)
-layerTreeImpl=lthi.getTree(this.layerPicker_.whichTree);this.layerPicker_.lthiSnapshot=lthi;this.layerView_.layerTreeImpl=layerTreeImpl;this.layerView_.regenerateContent();if(!this.selection_)
-return;this.selection=this.selection_.findEquivalent(lthi);},get selection(){return this.selection_;},set selection(selection){if(this.selection_==selection)
-return;this.selection_=selection;this.layerPicker_.selection=selection;this.layerView_.selection=selection;tr.b.dispatchSimpleEvent(this,'cc-selection-change');},onLayerPickerSelectionChanged_:function(){this.selection_=this.layerPicker_.selection;this.layerView_.selection=this.selection;this.layerView_.layerTreeImpl=this.layerPicker_.layerTreeImpl;this.layerView_.isRenderPassQuads=this.layerPicker_.isRenderPassQuads;this.layerView_.regenerateContent();tr.b.dispatchSimpleEvent(this,'cc-selection-change');},onLayerViewSelectionChanged_:function(){this.selection_=this.layerView_.selection;this.layerPicker_.selection=this.selection;tr.b.dispatchSimpleEvent(this,'cc-selection-change');},get extraHighlightsByLayerId(){return this.layerView_.extraHighlightsByLayerId;},set extraHighlightsByLayerId(extraHighlightsByLayerId){this.layerView_.extraHighlightsByLayerId=extraHighlightsByLayerId;}};tr.ui.analysis.ObjectSnapshotView.register(LayerTreeHostImplSnapshotView,{typeName:'cc::LayerTreeHostImpl'});return{LayerTreeHostImplSnapshotView:LayerTreeHostImplSnapshotView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var OPS_TIMING_ITERATIONS=3;var CHART_PADDING_LEFT=65;var CHART_PADDING_RIGHT=40;var AXIS_PADDING_LEFT=60;var AXIS_PADDING_RIGHT=35;var AXIS_PADDING_TOP=25;var AXIS_PADDING_BOTTOM=45;var AXIS_LABEL_PADDING=5;var AXIS_TICK_SIZE=10;var LABEL_PADDING=5;var LABEL_INTERLEAVE_OFFSET=15;var BAR_PADDING=5;var VERTICAL_TICKS=5;var HUE_CHAR_CODE_ADJUSTMENT=5.7;var PictureOpsChartSummaryView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-ops-chart-summary-view');PictureOpsChartSummaryView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.picture_=undefined;this.pictureDataProcessed_=false;this.chartScale_=window.devicePixelRatio;this.chart_=document.createElement('canvas');this.chartCtx_=this.chart_.getContext('2d');this.appendChild(this.chart_);this.opsTimingData_=[];this.chartWidth_=0;this.chartHeight_=0;this.requiresRedraw_=true;this.currentBarMouseOverTarget_=null;this.chart_.addEventListener('mousemove',this.onMouseMove_.bind(this));},get requiresRedraw(){return this.requiresRedraw_;},set requiresRedraw(requiresRedraw){this.requiresRedraw_=requiresRedraw;},get picture(){return this.picture_;},set picture(picture){this.picture_=picture;this.pictureDataProcessed_=false;if(this.classList.contains('hidden'))
-return;this.processPictureData_();this.requiresRedraw=true;this.updateChartContents();},hide:function(){this.classList.add('hidden');},show:function(){this.classList.remove('hidden');if(this.pictureDataProcessed_)
-return;this.processPictureData_();this.requiresRedraw=true;this.updateChartContents();},onMouseMove_:function(e){var lastBarMouseOverTarget=this.currentBarMouseOverTarget_;this.currentBarMouseOverTarget_=null;var x=e.offsetX;var y=e.offsetY;var chartLeft=CHART_PADDING_LEFT;var chartRight=this.chartWidth_-CHART_PADDING_RIGHT;var chartTop=AXIS_PADDING_TOP;var chartBottom=this.chartHeight_-AXIS_PADDING_BOTTOM;var chartInnerWidth=chartRight-chartLeft;if(x>chartLeft&&x<chartRight&&y>chartTop&&y<chartBottom){this.currentBarMouseOverTarget_=Math.floor((x-chartLeft)/chartInnerWidth*this.opsTimingData_.length);this.currentBarMouseOverTarget_=tr.b.clamp(this.currentBarMouseOverTarget_,0,this.opsTimingData_.length-1);}
-if(this.currentBarMouseOverTarget_===lastBarMouseOverTarget)
-return;this.drawChartContents_();},updateChartContents:function(){if(this.requiresRedraw)
-this.updateChartDimensions_();this.drawChartContents_();},updateChartDimensions_:function(){this.chartWidth_=this.offsetWidth;this.chartHeight_=this.offsetHeight;this.chart_.width=this.chartWidth_*this.chartScale_;this.chart_.height=this.chartHeight_*this.chartScale_;this.chart_.style.width=this.chartWidth_+'px';this.chart_.style.height=this.chartHeight_+'px';this.chartCtx_.scale(this.chartScale_,this.chartScale_);},processPictureData_:function(){this.resetOpsTimingData_();this.pictureDataProcessed_=true;if(!this.picture_)
-return;var ops=this.picture_.getOps();if(!ops)
-return;ops=this.picture_.tagOpsWithTimings(ops);if(ops[0].cmd_time===undefined)
-return;this.collapseOpsToTimingBuckets_(ops);},drawChartContents_:function(){this.clearChartContents_();if(this.opsTimingData_.length===0){this.showNoTimingDataMessage_();return;}
-this.drawChartAxes_();this.drawBars_();this.drawLineAtBottomOfChart_();if(this.currentBarMouseOverTarget_===null)
-return;this.drawTooltip_();},drawLineAtBottomOfChart_:function(){this.chartCtx_.strokeStyle='#AAA';this.chartCtx_.moveTo(0,this.chartHeight_-0.5);this.chartCtx_.lineTo(this.chartWidth_,this.chartHeight_-0.5);this.chartCtx_.stroke();},drawTooltip_:function(){var tooltipData=this.opsTimingData_[this.currentBarMouseOverTarget_];var tooltipTitle=tooltipData.cmd_string;var tooltipTime=tooltipData.cmd_time.toFixed(4);var tooltipWidth=110;var tooltipHeight=40;var chartInnerWidth=this.chartWidth_-CHART_PADDING_RIGHT-
-CHART_PADDING_LEFT;var barWidth=chartInnerWidth/this.opsTimingData_.length;var tooltipOffset=Math.round((tooltipWidth-barWidth)*0.5);var left=CHART_PADDING_LEFT+this.currentBarMouseOverTarget_*barWidth-tooltipOffset;var top=Math.round((this.chartHeight_-tooltipHeight)*0.5);this.chartCtx_.save();this.chartCtx_.shadowOffsetX=0;this.chartCtx_.shadowOffsetY=5;this.chartCtx_.shadowBlur=4;this.chartCtx_.shadowColor='rgba(0,0,0,0.4)';this.chartCtx_.strokeStyle='#888';this.chartCtx_.fillStyle='#EEE';this.chartCtx_.fillRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.shadowColor='transparent';this.chartCtx_.translate(0.5,0.5);this.chartCtx_.strokeRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.restore();this.chartCtx_.fillStyle='#222';this.chartCtx_.textBaseline='top';this.chartCtx_.font='800 12px Arial';this.chartCtx_.fillText(tooltipTitle,left+8,top+8);this.chartCtx_.fillStyle='#555';this.chartCtx_.textBaseline='top';this.chartCtx_.font='400 italic 10px Arial';this.chartCtx_.fillText('Total: '+tooltipTime+'ms',left+8,top+22);},drawBars_:function(){var len=this.opsTimingData_.length;var max=this.opsTimingData_[0].cmd_time;var min=this.opsTimingData_[len-1].cmd_time;var width=this.chartWidth_-CHART_PADDING_LEFT-CHART_PADDING_RIGHT;var height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;var barWidth=Math.floor(width/len);var opData;var opTiming;var opHeight;var opLabel;var barLeft;for(var b=0;b<len;b++){opData=this.opsTimingData_[b];opTiming=opData.cmd_time/max;opHeight=Math.round(Math.max(1,opTiming*height));opLabel=opData.cmd_string;barLeft=CHART_PADDING_LEFT+b*barWidth;this.chartCtx_.fillStyle=this.getOpColor_(opLabel);this.chartCtx_.fillRect(barLeft+BAR_PADDING,AXIS_PADDING_TOP+
-height-opHeight,barWidth-2*BAR_PADDING,opHeight);}},getOpColor_:function(opName){var characters=opName.split('');var hue=characters.reduce(this.reduceNameToHue,0)%360;return'hsl('+hue+', 30%, 50%)';},reduceNameToHue:function(previousValue,currentValue,index,array){return Math.round(previousValue+currentValue.charCodeAt(0)*HUE_CHAR_CODE_ADJUSTMENT);},drawChartAxes_:function(){var len=this.opsTimingData_.length;var max=this.opsTimingData_[0].cmd_time;var min=this.opsTimingData_[len-1].cmd_time;var width=this.chartWidth_-AXIS_PADDING_LEFT-AXIS_PADDING_RIGHT;var height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;var totalBarWidth=this.chartWidth_-CHART_PADDING_LEFT-
-CHART_PADDING_RIGHT;var barWidth=Math.floor(totalBarWidth/len);var tickYInterval=height/(VERTICAL_TICKS-1);var tickYPosition=0;var tickValInterval=(max-min)/(VERTICAL_TICKS-1);var tickVal=0;this.chartCtx_.fillStyle='#333';this.chartCtx_.strokeStyle='#777';this.chartCtx_.save();this.chartCtx_.translate(0.5,0.5);this.chartCtx_.save();this.chartCtx_.translate(AXIS_PADDING_LEFT,AXIS_PADDING_TOP);this.chartCtx_.moveTo(0,0);this.chartCtx_.lineTo(0,height);this.chartCtx_.lineTo(width,height);this.chartCtx_.font='10px Arial';this.chartCtx_.textAlign='right';this.chartCtx_.textBaseline='middle';for(var t=0;t<VERTICAL_TICKS;t++){tickYPosition=Math.round(t*tickYInterval);tickVal=(max-t*tickValInterval).toFixed(4);this.chartCtx_.moveTo(0,tickYPosition);this.chartCtx_.lineTo(-AXIS_TICK_SIZE,tickYPosition);this.chartCtx_.fillText(tickVal,-AXIS_TICK_SIZE-AXIS_LABEL_PADDING,tickYPosition);}
-this.chartCtx_.stroke();this.chartCtx_.restore();this.chartCtx_.save();this.chartCtx_.translate(CHART_PADDING_LEFT+Math.round(barWidth*0.5),AXIS_PADDING_TOP+height+LABEL_PADDING);this.chartCtx_.font='10px Arial';this.chartCtx_.textAlign='center';this.chartCtx_.textBaseline='top';var labelTickLeft;var labelTickBottom;for(var l=0;l<len;l++){labelTickLeft=Math.round(l*barWidth);labelTickBottom=l%2*LABEL_INTERLEAVE_OFFSET;this.chartCtx_.save();this.chartCtx_.moveTo(labelTickLeft,-LABEL_PADDING);this.chartCtx_.lineTo(labelTickLeft,labelTickBottom);this.chartCtx_.stroke();this.chartCtx_.restore();this.chartCtx_.fillText(this.opsTimingData_[l].cmd_string,labelTickLeft,labelTickBottom);}
-this.chartCtx_.restore();this.chartCtx_.restore();},clearChartContents_:function(){this.chartCtx_.clearRect(0,0,this.chartWidth_,this.chartHeight_);},showNoTimingDataMessage_:function(){this.chartCtx_.font='800 italic 14px Arial';this.chartCtx_.fillStyle='#333';this.chartCtx_.textAlign='center';this.chartCtx_.textBaseline='middle';this.chartCtx_.fillText('No timing data available.',this.chartWidth_*0.5,this.chartHeight_*0.5);},collapseOpsToTimingBuckets_:function(ops){var opsTimingDataIndexHash_={};var timingData=this.opsTimingData_;var op;var opIndex;for(var i=0;i<ops.length;i++){op=ops[i];if(op.cmd_time===undefined)
-continue;opIndex=opsTimingDataIndexHash_[op.cmd_string]||null;if(opIndex===null){timingData.push({cmd_time:0,cmd_string:op.cmd_string});opIndex=timingData.length-1;opsTimingDataIndexHash_[op.cmd_string]=opIndex;}
+this.layerTreeImpl.iterLayers(function(layer,depth,isMask,isReplica){if(!this.showOtherLayers&&this.selectedLayer!==layer)return;if(alreadyVisitedLayerIds[layer.layerId])return;const layerQuad=layer.layerQuad;const stackingGroupId=nextStackingGroupId++;if(this.showBottlenecks){this.appendBottleneckQuads_(quads,layer,layerQuad,stackingGroupId);}},this);const tracedInputLatencies=this.layerTreeImpl.tracedInputLatencies;if(this.showInputEvents&&tracedInputLatencies){for(let i=0;i<tracedInputLatencies.length;i++){const coordinatesArray=tracedInputLatencies[i].args.data.coordinates;for(let j=0;j<coordinatesArray.length;j++){const inputQuad=tr.b.math.Quad.fromXYWH(coordinatesArray[j].x-25,coordinatesArray[j].y-25,50,50);inputQuad.borderColor='rgba(0, 0, 0, 0)';inputQuad.imageData=this.inputEventImageData_;quads.push(inputQuad);}}}
+return quads;},updateInfoBar_(infoBarMessages){if(infoBarMessages.length){this.infoBar_.removeAllButtons();this.infoBar_.message='Some problems were encountered...';this.infoBar_.addButton('More info...',function(e){const overlay=new tr.ui.b.Overlay();Polymer.dom(overlay).textContent='';infoBarMessages.forEach(function(message){const title=document.createElement('h3');Polymer.dom(title).textContent=message.header;const details=document.createElement('div');Polymer.dom(details).textContent=message.details;Polymer.dom(overlay).appendChild(title);Polymer.dom(overlay).appendChild(details);});overlay.visible=true;e.stopPropagation();return false;});this.infoBar_.visible=true;}else{this.infoBar_.removeAllButtons();this.infoBar_.message='';this.infoBar_.visible=false;}},getWhatRasterized_(){const lthi=this.layerTreeImpl_.layerTreeHostImpl;const renderProcess=lthi.objectInstance.parent;const tasks=[];for(const event of renderProcess.getDescendantEvents()){if(!(event instanceof tr.model.Slice))continue;const tile=tr.e.cc.getTileFromRasterTaskSlice(event);if(tile===undefined)continue;if(tile.containingSnapshot===lthi){tasks.push(event);}}
+return tasks;},updateWhatRasterizedLinkState_(){const tasks=this.getWhatRasterized_();if(tasks.length){Polymer.dom(this.whatRasterizedLink_).textContent=tasks.length+' raster tasks';this.whatRasterizedLink_.style.display='';}else{Polymer.dom(this.whatRasterizedLink_).textContent='';this.whatRasterizedLink_.style.display='none';}},getWhatRasterizedEventSet_(){return new tr.model.EventSet(this.getWhatRasterized_());}};return{LayerTreeQuadStackView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const constants=tr.e.cc.constants;const LayerView=tr.ui.b.define('tr-ui-e-chrome-cc-layer-view');LayerView.prototype={__proto__:HTMLDivElement.prototype,decorate(){this.style.flexDirection='column';this.style.display='flex';this.layerTreeQuadStackView_=new tr.ui.e.chrome.cc.LayerTreeQuadStackView();this.dragBar_=document.createElement('tr-ui-b-drag-handle');this.analysisEl_=document.createElement('tr-ui-e-chrome-cc-layer-view-analysis');this.analysisEl_.style.flexGrow=0;this.analysisEl_.style.flexShrink=0;this.analysisEl_.style.flexBasis='auto';this.analysisEl_.style.height='150px';this.analysisEl_.style.overflow='auto';this.analysisEl_.addEventListener('requestSelectionChange',this.onRequestSelectionChangeFromAnalysisEl_.bind(this));this.dragBar_.target=this.analysisEl_;Polymer.dom(this).appendChild(this.layerTreeQuadStackView_);Polymer.dom(this).appendChild(this.dragBar_);Polymer.dom(this).appendChild(this.analysisEl_);this.layerTreeQuadStackView_.addEventListener('selection-change',function(){this.layerTreeQuadStackViewSelectionChanged_();}.bind(this));this.layerTreeQuadStackViewSelectionChanged_();},get layerTreeImpl(){return this.layerTreeQuadStackView_.layerTreeImpl;},set layerTreeImpl(newValue){return this.layerTreeQuadStackView_.layerTreeImpl=newValue;},set isRenderPassQuads(newValue){return this.layerTreeQuadStackView_.isRenderPassQuads=newValue;},get selection(){return this.layerTreeQuadStackView_.selection;},set selection(newValue){this.layerTreeQuadStackView_.selection=newValue;},regenerateContent(){this.layerTreeQuadStackView_.regenerateContent();},layerTreeQuadStackViewSelectionChanged_(){const selection=this.layerTreeQuadStackView_.selection;if(selection){this.dragBar_.style.display='';this.analysisEl_.style.display='';Polymer.dom(this.analysisEl_).textContent='';const layer=selection.layer;if(tr.e.cc.PictureSnapshot.CanDebugPicture()&&layer&&layer.args&&layer.args.pictures&&layer.args.pictures.length){Polymer.dom(this.analysisEl_).appendChild(this.createPictureBtn_(layer.args.pictures));}
+const analysis=selection.createAnalysis();Polymer.dom(this.analysisEl_).appendChild(analysis);for(const child of this.analysisEl_.children){child.style.userSelect='text';}}else{this.dragBar_.style.display='none';this.analysisEl_.style.display='none';const analysis=Polymer.dom(this.analysisEl_).firstChild;if(analysis){Polymer.dom(this.analysisEl_).removeChild(analysis);}
+this.layerTreeQuadStackView_.style.height=window.getComputedStyle(this).height;}
+tr.b.dispatchSimpleEvent(this,'selection-change');},createPictureBtn_(pictures){if(!(pictures instanceof Array)){pictures=[pictures];}
+const link=document.createElement('tr-ui-a-analysis-link');link.selection=function(){const layeredPicture=new tr.e.cc.LayeredPicture(pictures);const snapshot=new tr.e.cc.PictureSnapshot(layeredPicture);snapshot.picture=layeredPicture;const selection=new tr.model.EventSet();selection.push(snapshot);return selection;};Polymer.dom(link).textContent='View in Picture Debugger';return link;},onRequestSelectionChangeFromAnalysisEl_(e){if(!(e.selection instanceof tr.ui.e.chrome.cc.Selection)){return;}
+e.stopPropagation();this.selection=e.selection;},get extraHighlightsByLayerId(){return this.layerTreeQuadStackView_.extraHighlightsByLayerId;},set extraHighlightsByLayerId(extraHighlightsByLayerId){this.layerTreeQuadStackView_.extraHighlightsByLayerId=extraHighlightsByLayerId;}};return{LayerView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const LayerTreeHostImplSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-layer-tree-host-impl-snapshot-view',tr.ui.analysis.ObjectSnapshotView);LayerTreeHostImplSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate(){Polymer.dom(this).classList.add('tr-ui-e-chrome-cc-lthi-s-view');this.style.display='flex';this.style.flexDirection='row';this.style.flexGrow=1;this.style.flexShrink=1;this.style.flexBasis='auto';this.style.minWidth=0;this.selection_=undefined;this.layerPicker_=new tr.ui.e.chrome.cc.LayerPicker();this.layerPicker_.style.flexGrow=0;this.layerPicker_.style.flexShrink=0;this.layerPicker_.style.flexBasis='auto';this.layerPicker_.style.minWidth='200px';this.layerPicker_.addEventListener('selection-change',this.onLayerPickerSelectionChanged_.bind(this));this.layerView_=new tr.ui.e.chrome.cc.LayerView();this.layerView_.addEventListener('selection-change',this.onLayerViewSelectionChanged_.bind(this));this.layerView_.style.flexGrow=1;this.layerView_.style.flexShrink=1;this.layerView_.style.flexBasis='auto';this.layerView_.style.minWidth=0;this.dragHandle_=document.createElement('tr-ui-b-drag-handle');this.dragHandle_.style.flexGrow=0;this.dragHandle_.style.flexShrink=0;this.dragHandle_.style.flexBasis='auto';this.dragHandle_.horizontal=false;this.dragHandle_.target=this.layerPicker_;Polymer.dom(this).appendChild(this.layerPicker_);Polymer.dom(this).appendChild(this.dragHandle_);Polymer.dom(this).appendChild(this.layerView_);this.onLayerViewSelectionChanged_();this.onLayerPickerSelectionChanged_();},get objectSnapshot(){return this.objectSnapshot_;},set objectSnapshot(objectSnapshot){this.objectSnapshot_=objectSnapshot;const lthi=this.objectSnapshot;let layerTreeImpl;if(lthi){layerTreeImpl=lthi.getTree(this.layerPicker_.whichTree);}
+this.layerPicker_.lthiSnapshot=lthi;this.layerView_.layerTreeImpl=layerTreeImpl;this.layerView_.regenerateContent();if(!this.selection_)return;this.selection=this.selection_.findEquivalent(lthi);},get selection(){return this.selection_;},set selection(selection){if(this.selection_===selection)return;this.selection_=selection;this.layerPicker_.selection=selection;this.layerView_.selection=selection;tr.b.dispatchSimpleEvent(this,'cc-selection-change');},onLayerPickerSelectionChanged_(){this.selection_=this.layerPicker_.selection;this.layerView_.selection=this.selection;this.layerView_.layerTreeImpl=this.layerPicker_.layerTreeImpl;this.layerView_.isRenderPassQuads=this.layerPicker_.isRenderPassQuads;this.layerView_.regenerateContent();tr.b.dispatchSimpleEvent(this,'cc-selection-change');},onLayerViewSelectionChanged_(){this.selection_=this.layerView_.selection;this.layerPicker_.selection=this.selection;tr.b.dispatchSimpleEvent(this,'cc-selection-change');},get extraHighlightsByLayerId(){return this.layerView_.extraHighlightsByLayerId;},set extraHighlightsByLayerId(extraHighlightsByLayerId){this.layerView_.extraHighlightsByLayerId=extraHighlightsByLayerId;}};tr.ui.analysis.ObjectSnapshotView.register(LayerTreeHostImplSnapshotView,{typeName:'cc::LayerTreeHostImpl'});return{LayerTreeHostImplSnapshotView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const OPS_TIMING_ITERATIONS=3;const CHART_PADDING_LEFT=65;const CHART_PADDING_RIGHT=40;const AXIS_PADDING_LEFT=60;const AXIS_PADDING_RIGHT=35;const AXIS_PADDING_TOP=25;const AXIS_PADDING_BOTTOM=45;const AXIS_LABEL_PADDING=5;const AXIS_TICK_SIZE=10;const LABEL_PADDING=5;const LABEL_INTERLEAVE_OFFSET=15;const BAR_PADDING=5;const VERTICAL_TICKS=5;const HUE_CHAR_CODE_ADJUSTMENT=5.7;const PictureOpsChartSummaryView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-ops-chart-summary-view');PictureOpsChartSummaryView.prototype={__proto__:HTMLDivElement.prototype,decorate(){this.style.flexGrow=0;this.style.flexShrink=0;this.style.flexBasis='auto';this.style.fontSize=0;this.style.margin=0;this.style.minHeight='200px';this.style.minWidth='200px';this.style.overflow='hidden';this.style.padding=0;this.picture_=undefined;this.pictureDataProcessed_=false;this.chartScale_=window.devicePixelRatio;this.chart_=document.createElement('canvas');this.chartCtx_=this.chart_.getContext('2d');Polymer.dom(this).appendChild(this.chart_);this.opsTimingData_=[];this.chartWidth_=0;this.chartHeight_=0;this.requiresRedraw_=true;this.currentBarMouseOverTarget_=null;this.chart_.addEventListener('mousemove',this.onMouseMove_.bind(this));new ResizeObserver(this.onResize_.bind(this)).observe(this);},get requiresRedraw(){return this.requiresRedraw_;},set requiresRedraw(requiresRedraw){this.requiresRedraw_=requiresRedraw;},get picture(){return this.picture_;},set picture(picture){this.picture_=picture;this.pictureDataProcessed_=false;if(Polymer.dom(this).classList.contains('hidden'))return;this.processPictureData_();this.requiresRedraw=true;this.updateChartContents();},hide(){Polymer.dom(this).classList.add('hidden');this.style.display='none';},show(){Polymer.dom(this).classList.remove('hidden');this.style.display='';if(!this.pictureDataProcessed_){this.processPictureData_();}
+this.requiresRedraw=true;this.updateChartContents();},onMouseMove_(e){const lastBarMouseOverTarget=this.currentBarMouseOverTarget_;this.currentBarMouseOverTarget_=null;const x=e.offsetX;const y=e.offsetY;const chartLeft=CHART_PADDING_LEFT;const chartRight=this.chartWidth_-CHART_PADDING_RIGHT;const chartTop=AXIS_PADDING_TOP;const chartBottom=this.chartHeight_-AXIS_PADDING_BOTTOM;const chartInnerWidth=chartRight-chartLeft;if(x>chartLeft&&x<chartRight&&y>chartTop&&y<chartBottom){this.currentBarMouseOverTarget_=Math.floor((x-chartLeft)/chartInnerWidth*this.opsTimingData_.length);this.currentBarMouseOverTarget_=tr.b.math.clamp(this.currentBarMouseOverTarget_,0,this.opsTimingData_.length-1);}
+if(this.currentBarMouseOverTarget_===lastBarMouseOverTarget)return;this.drawChartContents_();},onResize_(){this.requiresRedraw=true;this.updateChartContents();},updateChartContents(){if(this.requiresRedraw){this.updateChartDimensions_();}
+this.drawChartContents_();},updateChartDimensions_(){this.chartWidth_=this.offsetWidth;this.chartHeight_=this.offsetHeight;this.chart_.width=this.chartWidth_*this.chartScale_;this.chart_.height=this.chartHeight_*this.chartScale_;this.chart_.style.width=this.chartWidth_+'px';this.chart_.style.height=this.chartHeight_+'px';this.chartCtx_.scale(this.chartScale_,this.chartScale_);},processPictureData_(){this.resetOpsTimingData_();this.pictureDataProcessed_=true;if(!this.picture_)return;let ops=this.picture_.getOps();if(!ops)return;ops=this.picture_.tagOpsWithTimings(ops);if(ops[0].cmd_time===undefined)return;this.collapseOpsToTimingBuckets_(ops);},drawChartContents_(){this.clearChartContents_();if(this.opsTimingData_.length===0){this.showNoTimingDataMessage_();return;}
+this.drawChartAxes_();this.drawBars_();this.drawLineAtBottomOfChart_();if(this.currentBarMouseOverTarget_===null)return;this.drawTooltip_();},drawLineAtBottomOfChart_(){this.chartCtx_.strokeStyle='#AAA';this.chartCtx_.moveTo(0,this.chartHeight_-0.5);this.chartCtx_.lineTo(this.chartWidth_,this.chartHeight_-0.5);this.chartCtx_.stroke();},drawTooltip_(){const tooltipData=this.opsTimingData_[this.currentBarMouseOverTarget_];const tooltipTitle=tooltipData.cmd_string;const tooltipTime=tooltipData.cmd_time.toFixed(4);const tooltipWidth=110;const tooltipHeight=40;const chartInnerWidth=this.chartWidth_-CHART_PADDING_RIGHT-
+CHART_PADDING_LEFT;const barWidth=chartInnerWidth/this.opsTimingData_.length;const tooltipOffset=Math.round((tooltipWidth-barWidth)*0.5);const left=CHART_PADDING_LEFT+this.currentBarMouseOverTarget_*barWidth-tooltipOffset;const top=Math.round((this.chartHeight_-tooltipHeight)*0.5);this.chartCtx_.save();this.chartCtx_.shadowOffsetX=0;this.chartCtx_.shadowOffsetY=5;this.chartCtx_.shadowBlur=4;this.chartCtx_.shadowColor='rgba(0,0,0,0.4)';this.chartCtx_.strokeStyle='#888';this.chartCtx_.fillStyle='#EEE';this.chartCtx_.fillRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.shadowColor='transparent';this.chartCtx_.translate(0.5,0.5);this.chartCtx_.strokeRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.restore();this.chartCtx_.fillStyle='#222';this.chartCtx_.textBaseline='top';this.chartCtx_.font='800 12px Arial';this.chartCtx_.fillText(tooltipTitle,left+8,top+8);this.chartCtx_.fillStyle='#555';this.chartCtx_.textBaseline='top';this.chartCtx_.font='400 italic 10px Arial';this.chartCtx_.fillText('Total: '+tooltipTime+'ms',left+8,top+22);},drawBars_(){const len=this.opsTimingData_.length;const max=this.opsTimingData_[0].cmd_time;const min=this.opsTimingData_[len-1].cmd_time;const width=this.chartWidth_-CHART_PADDING_LEFT-CHART_PADDING_RIGHT;const height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;const barWidth=Math.floor(width/len);let opData;let opTiming;let opHeight;let opLabel;let barLeft;for(let b=0;b<len;b++){opData=this.opsTimingData_[b];opTiming=opData.cmd_time/max;opHeight=Math.round(Math.max(1,opTiming*height));opLabel=opData.cmd_string;barLeft=CHART_PADDING_LEFT+b*barWidth;this.chartCtx_.fillStyle=this.getOpColor_(opLabel);this.chartCtx_.fillRect(barLeft+BAR_PADDING,AXIS_PADDING_TOP+
+height-opHeight,barWidth-2*BAR_PADDING,opHeight);}},getOpColor_(opName){const characters=opName.split('');const hue=characters.reduce(this.reduceNameToHue,0)%360;return'hsl('+hue+', 30%, 50%)';},reduceNameToHue(previousValue,currentValue,index,array){return Math.round(previousValue+currentValue.charCodeAt(0)*HUE_CHAR_CODE_ADJUSTMENT);},drawChartAxes_(){const len=this.opsTimingData_.length;const max=this.opsTimingData_[0].cmd_time;const min=this.opsTimingData_[len-1].cmd_time;const width=this.chartWidth_-AXIS_PADDING_LEFT-AXIS_PADDING_RIGHT;const height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;const totalBarWidth=this.chartWidth_-CHART_PADDING_LEFT-
+CHART_PADDING_RIGHT;const barWidth=Math.floor(totalBarWidth/len);const tickYInterval=height/(VERTICAL_TICKS-1);let tickYPosition=0;const tickValInterval=(max-min)/(VERTICAL_TICKS-1);let tickVal=0;this.chartCtx_.fillStyle='#333';this.chartCtx_.strokeStyle='#777';this.chartCtx_.save();this.chartCtx_.translate(0.5,0.5);this.chartCtx_.save();this.chartCtx_.translate(AXIS_PADDING_LEFT,AXIS_PADDING_TOP);this.chartCtx_.moveTo(0,0);this.chartCtx_.lineTo(0,height);this.chartCtx_.lineTo(width,height);this.chartCtx_.font='10px Arial';this.chartCtx_.textAlign='right';this.chartCtx_.textBaseline='middle';for(let t=0;t<VERTICAL_TICKS;t++){tickYPosition=Math.round(t*tickYInterval);tickVal=(max-t*tickValInterval).toFixed(4);this.chartCtx_.moveTo(0,tickYPosition);this.chartCtx_.lineTo(-AXIS_TICK_SIZE,tickYPosition);this.chartCtx_.fillText(tickVal,-AXIS_TICK_SIZE-AXIS_LABEL_PADDING,tickYPosition);}
+this.chartCtx_.stroke();this.chartCtx_.restore();this.chartCtx_.save();this.chartCtx_.translate(CHART_PADDING_LEFT+Math.round(barWidth*0.5),AXIS_PADDING_TOP+height+LABEL_PADDING);this.chartCtx_.font='10px Arial';this.chartCtx_.textAlign='center';this.chartCtx_.textBaseline='top';let labelTickLeft;let labelTickBottom;for(let l=0;l<len;l++){labelTickLeft=Math.round(l*barWidth);labelTickBottom=l%2*LABEL_INTERLEAVE_OFFSET;this.chartCtx_.save();this.chartCtx_.moveTo(labelTickLeft,-LABEL_PADDING);this.chartCtx_.lineTo(labelTickLeft,labelTickBottom);this.chartCtx_.stroke();this.chartCtx_.restore();this.chartCtx_.fillText(this.opsTimingData_[l].cmd_string,labelTickLeft,labelTickBottom);}
+this.chartCtx_.restore();this.chartCtx_.restore();},clearChartContents_(){this.chartCtx_.clearRect(0,0,this.chartWidth_,this.chartHeight_);},showNoTimingDataMessage_(){this.chartCtx_.font='800 italic 14px Arial';this.chartCtx_.fillStyle='#333';this.chartCtx_.textAlign='center';this.chartCtx_.textBaseline='middle';this.chartCtx_.fillText('No timing data available.',this.chartWidth_*0.5,this.chartHeight_*0.5);},collapseOpsToTimingBuckets_(ops){const opsTimingDataIndexHash_={};const timingData=this.opsTimingData_;let op;let opIndex;for(let i=0;i<ops.length;i++){op=ops[i];if(op.cmd_time===undefined)continue;opIndex=opsTimingDataIndexHash_[op.cmd_string]||null;if(opIndex===null){timingData.push({cmd_time:0,cmd_string:op.cmd_string});opIndex=timingData.length-1;opsTimingDataIndexHash_[op.cmd_string]=opIndex;}
 timingData[opIndex].cmd_time+=op.cmd_time;}
-timingData.sort(this.sortTimingBucketsByOpTimeDescending_);this.collapseTimingBucketsToOther_(4);},collapseTimingBucketsToOther_:function(count){var timingData=this.opsTimingData_;var otherSource=timingData.splice(count,timingData.length-count);var otherDestination=null;if(!otherSource.length)
-return;timingData.push({cmd_time:0,cmd_string:'Other'});otherDestination=timingData[timingData.length-1];for(var i=0;i<otherSource.length;i++){otherDestination.cmd_time+=otherSource[i].cmd_time;}},sortTimingBucketsByOpTimeDescending_:function(a,b){return b.cmd_time-a.cmd_time;},resetOpsTimingData_:function(){this.opsTimingData_.length=0;}};return{PictureOpsChartSummaryView:PictureOpsChartSummaryView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var BAR_PADDING=1;var BAR_WIDTH=5;var CHART_PADDING_LEFT=65;var CHART_PADDING_RIGHT=30;var CHART_PADDING_BOTTOM=35;var CHART_PADDING_TOP=20;var AXIS_PADDING_LEFT=55;var AXIS_PADDING_RIGHT=30;var AXIS_PADDING_BOTTOM=35;var AXIS_PADDING_TOP=20;var AXIS_TICK_SIZE=5;var AXIS_LABEL_PADDING=5;var VERTICAL_TICKS=5;var HUE_CHAR_CODE_ADJUSTMENT=5.7;var PictureOpsChartView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-ops-chart-view');PictureOpsChartView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.picture_=undefined;this.pictureOps_=undefined;this.opCosts_=undefined;this.chartScale_=window.devicePixelRatio;this.chart_=document.createElement('canvas');this.chartCtx_=this.chart_.getContext('2d');this.appendChild(this.chart_);this.selectedOpIndex_=undefined;this.chartWidth_=0;this.chartHeight_=0;this.dimensionsHaveChanged_=true;this.currentBarMouseOverTarget_=undefined;this.ninetyFifthPercentileCost_=0;this.totalOpCost_=0;this.chart_.addEventListener('click',this.onClick_.bind(this));this.chart_.addEventListener('mousemove',this.onMouseMove_.bind(this));this.usePercentileScale_=false;this.usePercentileScaleCheckbox_=tr.ui.b.createCheckBox(this,'usePercentileScale','PictureOpsChartView.usePercentileScale',false,'Limit to 95%-ile');this.usePercentileScaleCheckbox_.classList.add('use-percentile-scale');this.appendChild(this.usePercentileScaleCheckbox_);},get dimensionsHaveChanged(){return this.dimensionsHaveChanged_;},set dimensionsHaveChanged(dimensionsHaveChanged){this.dimensionsHaveChanged_=dimensionsHaveChanged;},get usePercentileScale(){return this.usePercentileScale_;},set usePercentileScale(usePercentileScale){this.usePercentileScale_=usePercentileScale;this.drawChartContents_();},get numOps(){return this.opCosts_.length;},get selectedOpIndex(){return this.selectedOpIndex_;},set selectedOpIndex(selectedOpIndex){if(selectedOpIndex<0)throw new Error('Invalid index');if(selectedOpIndex>=this.numOps)throw new Error('Invalid index');this.selectedOpIndex_=selectedOpIndex;},get picture(){return this.picture_;},set picture(picture){this.picture_=picture;this.pictureOps_=picture.tagOpsWithTimings(picture.getOps());this.currentBarMouseOverTarget_=undefined;this.processPictureData_();this.dimensionsHaveChanged=true;},processPictureData_:function(){if(this.pictureOps_===undefined)
-return;var totalOpCost=0;this.opCosts_=this.pictureOps_.map(function(op){totalOpCost+=op.cmd_time;return op.cmd_time;});this.opCosts_.sort();var ninetyFifthPercentileCostIndex=Math.floor(this.opCosts_.length*0.95);this.ninetyFifthPercentileCost_=this.opCosts_[ninetyFifthPercentileCostIndex];this.maxCost_=this.opCosts_[this.opCosts_.length-1];this.totalOpCost_=totalOpCost;},extractBarIndex_:function(e){var index=undefined;if(this.pictureOps_===undefined||this.pictureOps_.length===0)
-return index;var x=e.offsetX;var y=e.offsetY;var totalBarWidth=(BAR_WIDTH+BAR_PADDING)*this.pictureOps_.length;var chartLeft=CHART_PADDING_LEFT;var chartTop=0;var chartBottom=this.chartHeight_-CHART_PADDING_BOTTOM;var chartRight=chartLeft+totalBarWidth;if(x<chartLeft||x>chartRight||y<chartTop||y>chartBottom)
-return index;index=Math.floor((x-chartLeft)/totalBarWidth*this.pictureOps_.length);index=tr.b.clamp(index,0,this.pictureOps_.length-1);return index;},onClick_:function(e){var barClicked=this.extractBarIndex_(e);if(barClicked===undefined)
-return;if(barClicked===this.selectedOpIndex)
-this.selectedOpIndex=undefined;else
-this.selectedOpIndex=barClicked;e.preventDefault();tr.b.dispatchSimpleEvent(this,'selection-changed',false);},onMouseMove_:function(e){var lastBarMouseOverTarget=this.currentBarMouseOverTarget_;this.currentBarMouseOverTarget_=this.extractBarIndex_(e);if(this.currentBarMouseOverTarget_===lastBarMouseOverTarget)
-return;this.drawChartContents_();},scrollSelectedItemIntoViewIfNecessary:function(){if(this.selectedOpIndex===undefined)
-return;var width=this.offsetWidth;var left=this.scrollLeft;var right=left+width;var targetLeft=CHART_PADDING_LEFT+
-(BAR_WIDTH+BAR_PADDING)*this.selectedOpIndex;if(targetLeft>left&&targetLeft<right)
-return;this.scrollLeft=(targetLeft-width*0.5);},updateChartContents:function(){if(this.dimensionsHaveChanged)
-this.updateChartDimensions_();this.drawChartContents_();},updateChartDimensions_:function(){if(!this.pictureOps_)
-return;var width=CHART_PADDING_LEFT+CHART_PADDING_RIGHT+
-((BAR_WIDTH+BAR_PADDING)*this.pictureOps_.length);if(width<this.offsetWidth)
-width=this.offsetWidth;this.chartWidth_=width;this.chartHeight_=this.getBoundingClientRect().height;this.chart_.width=this.chartWidth_*this.chartScale_;this.chart_.height=this.chartHeight_*this.chartScale_;this.chart_.style.width=this.chartWidth_+'px';this.chart_.style.height=this.chartHeight_+'px';this.chartCtx_.scale(this.chartScale_,this.chartScale_);this.dimensionsHaveChanged=false;},drawChartContents_:function(){this.clearChartContents_();if(this.pictureOps_===undefined||this.pictureOps_.length===0||this.pictureOps_[0].cmd_time===undefined){this.showNoTimingDataMessage_();return;}
-this.drawSelection_();this.drawBars_();this.drawChartAxes_();this.drawLinesAtTickMarks_();this.drawLineAtBottomOfChart_();if(this.currentBarMouseOverTarget_===undefined)
-return;this.drawTooltip_();},drawSelection_:function(){if(this.selectedOpIndex===undefined)
-return;var width=(BAR_WIDTH+BAR_PADDING)*this.selectedOpIndex;this.chartCtx_.fillStyle='rgb(223, 235, 230)';this.chartCtx_.fillRect(CHART_PADDING_LEFT,CHART_PADDING_TOP,width,this.chartHeight_-CHART_PADDING_TOP-CHART_PADDING_BOTTOM);},drawChartAxes_:function(){var min=this.opCosts_[0];var max=this.opCosts_[this.opCosts_.length-1];var height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;var tickYInterval=height/(VERTICAL_TICKS-1);var tickYPosition=0;var tickValInterval=(max-min)/(VERTICAL_TICKS-1);var tickVal=0;this.chartCtx_.fillStyle='#333';this.chartCtx_.strokeStyle='#777';this.chartCtx_.save();this.chartCtx_.translate(0.5,0.5);this.chartCtx_.beginPath();this.chartCtx_.moveTo(AXIS_PADDING_LEFT,AXIS_PADDING_TOP);this.chartCtx_.lineTo(AXIS_PADDING_LEFT,this.chartHeight_-
-AXIS_PADDING_BOTTOM);this.chartCtx_.lineTo(this.chartWidth_-AXIS_PADDING_RIGHT,this.chartHeight_-AXIS_PADDING_BOTTOM);this.chartCtx_.stroke();this.chartCtx_.closePath();this.chartCtx_.translate(AXIS_PADDING_LEFT,AXIS_PADDING_TOP);this.chartCtx_.font='10px Arial';this.chartCtx_.textAlign='right';this.chartCtx_.textBaseline='middle';this.chartCtx_.beginPath();for(var t=0;t<VERTICAL_TICKS;t++){tickYPosition=Math.round(t*tickYInterval);tickVal=(max-t*tickValInterval).toFixed(4);this.chartCtx_.moveTo(0,tickYPosition);this.chartCtx_.lineTo(-AXIS_TICK_SIZE,tickYPosition);this.chartCtx_.fillText(tickVal,-AXIS_TICK_SIZE-AXIS_LABEL_PADDING,tickYPosition);}
-this.chartCtx_.stroke();this.chartCtx_.closePath();this.chartCtx_.restore();},drawLinesAtTickMarks_:function(){var height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;var width=this.chartWidth_-AXIS_PADDING_LEFT-AXIS_PADDING_RIGHT;var tickYInterval=height/(VERTICAL_TICKS-1);var tickYPosition=0;this.chartCtx_.save();this.chartCtx_.translate(AXIS_PADDING_LEFT+0.5,AXIS_PADDING_TOP+0.5);this.chartCtx_.beginPath();this.chartCtx_.strokeStyle='rgba(0,0,0,0.05)';for(var t=0;t<VERTICAL_TICKS;t++){tickYPosition=Math.round(t*tickYInterval);this.chartCtx_.moveTo(0,tickYPosition);this.chartCtx_.lineTo(width,tickYPosition);this.chartCtx_.stroke();}
-this.chartCtx_.restore();this.chartCtx_.closePath();},drawLineAtBottomOfChart_:function(){this.chartCtx_.strokeStyle='#AAA';this.chartCtx_.beginPath();this.chartCtx_.moveTo(0,this.chartHeight_-0.5);this.chartCtx_.lineTo(this.chartWidth_,this.chartHeight_-0.5);this.chartCtx_.stroke();this.chartCtx_.closePath();},drawTooltip_:function(){var tooltipData=this.pictureOps_[this.currentBarMouseOverTarget_];var tooltipTitle=tooltipData.cmd_string;var tooltipTime=tooltipData.cmd_time.toFixed(4);var toolTipTimePercentage=((tooltipData.cmd_time/this.totalOpCost_)*100).toFixed(2);var tooltipWidth=120;var tooltipHeight=40;var chartInnerWidth=this.chartWidth_-CHART_PADDING_RIGHT-
-CHART_PADDING_LEFT;var barWidth=BAR_WIDTH+BAR_PADDING;var tooltipOffset=Math.round((tooltipWidth-barWidth)*0.5);var left=CHART_PADDING_LEFT+this.currentBarMouseOverTarget_*barWidth-tooltipOffset;var top=Math.round((this.chartHeight_-tooltipHeight)*0.5);this.chartCtx_.save();this.chartCtx_.shadowOffsetX=0;this.chartCtx_.shadowOffsetY=5;this.chartCtx_.shadowBlur=4;this.chartCtx_.shadowColor='rgba(0,0,0,0.4)';this.chartCtx_.strokeStyle='#888';this.chartCtx_.fillStyle='#EEE';this.chartCtx_.fillRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.shadowColor='transparent';this.chartCtx_.translate(0.5,0.5);this.chartCtx_.strokeRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.restore();this.chartCtx_.fillStyle='#222';this.chartCtx_.textAlign='left';this.chartCtx_.textBaseline='top';this.chartCtx_.font='800 12px Arial';this.chartCtx_.fillText(tooltipTitle,left+8,top+8);this.chartCtx_.fillStyle='#555';this.chartCtx_.font='400 italic 10px Arial';this.chartCtx_.fillText(tooltipTime+'ms ('+
-toolTipTimePercentage+'%)',left+8,top+22);},drawBars_:function(){var op;var opColor=0;var opHeight=0;var opWidth=BAR_WIDTH+BAR_PADDING;var opHover=false;var bottom=this.chartHeight_-CHART_PADDING_BOTTOM;var maxHeight=this.chartHeight_-CHART_PADDING_BOTTOM-
-CHART_PADDING_TOP;var maxValue;if(this.usePercentileScale)
-maxValue=this.ninetyFifthPercentileCost_;else
-maxValue=this.maxCost_;for(var b=0;b<this.pictureOps_.length;b++){op=this.pictureOps_[b];opHeight=Math.round((op.cmd_time/maxValue)*maxHeight);opHeight=Math.max(opHeight,1);opHover=(b===this.currentBarMouseOverTarget_);opColor=this.getOpColor_(op.cmd_string,opHover);if(b===this.selectedOpIndex)
-this.chartCtx_.fillStyle='#FFFF00';else
-this.chartCtx_.fillStyle=opColor;this.chartCtx_.fillRect(CHART_PADDING_LEFT+b*opWidth,bottom-opHeight,BAR_WIDTH,opHeight);}},getOpColor_:function(opName,hover){var characters=opName.split('');var hue=characters.reduce(this.reduceNameToHue,0)%360;var saturation=30;var lightness=hover?'75%':'50%';return'hsl('+hue+', '+saturation+'%, '+lightness+'%)';},reduceNameToHue:function(previousValue,currentValue,index,array){return Math.round(previousValue+currentValue.charCodeAt(0)*HUE_CHAR_CODE_ADJUSTMENT);},clearChartContents_:function(){this.chartCtx_.clearRect(0,0,this.chartWidth_,this.chartHeight_);},showNoTimingDataMessage_:function(){this.chartCtx_.font='800 italic 14px Arial';this.chartCtx_.fillStyle='#333';this.chartCtx_.textAlign='center';this.chartCtx_.textBaseline='middle';this.chartCtx_.fillText('No timing data available.',this.chartWidth_*0.5,this.chartHeight_*0.5);}};return{PictureOpsChartView:PictureOpsChartView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var THIS_DOC=document.currentScript.ownerDocument;var PictureDebugger=tr.ui.b.define('tr-ui-e-chrome-cc-picture-debugger');PictureDebugger.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){var node=tr.ui.b.instantiateTemplate('#tr-ui-e-chrome-cc-picture-debugger-template',THIS_DOC);this.appendChild(node);this.pictureAsImageData_=undefined;this.showOverdraw_=false;this.zoomScaleValue_=1;this.sizeInfo_=this.querySelector('.size');this.rasterArea_=this.querySelector('raster-area');this.rasterCanvas_=this.rasterArea_.querySelector('canvas');this.rasterCtx_=this.rasterCanvas_.getContext('2d');this.filename_=this.querySelector('.filename');this.drawOpsChartSummaryView_=new tr.ui.e.chrome.cc.PictureOpsChartSummaryView();this.drawOpsChartView_=new tr.ui.e.chrome.cc.PictureOpsChartView();this.drawOpsChartView_.addEventListener('selection-changed',this.onChartBarClicked_.bind(this));this.exportButton_=this.querySelector('.export');this.exportButton_.addEventListener('click',this.onSaveAsSkPictureClicked_.bind(this));this.trackMouse_();var overdrawCheckbox=tr.ui.b.createCheckBox(this,'showOverdraw','pictureView.showOverdraw',false,'Show overdraw');var chartCheckbox=tr.ui.b.createCheckBox(this,'showSummaryChart','pictureView.showSummaryChart',false,'Show timing summary');var pictureInfo=this.querySelector('picture-info');pictureInfo.appendChild(overdrawCheckbox);pictureInfo.appendChild(chartCheckbox);this.drawOpsView_=new tr.ui.e.chrome.cc.PictureOpsListView();this.drawOpsView_.addEventListener('selection-changed',this.onChangeDrawOps_.bind(this));var leftPanel=this.querySelector('left-panel');leftPanel.appendChild(this.drawOpsChartSummaryView_);leftPanel.appendChild(this.drawOpsView_);var middleDragHandle=document.createElement('tr-ui-b-drag-handle');middleDragHandle.horizontal=false;middleDragHandle.target=leftPanel;var rightPanel=this.querySelector('right-panel');rightPanel.replaceChild(this.drawOpsChartView_,rightPanel.querySelector('tr-ui-e-chrome-cc-picture-ops-chart-view'));this.infoBar_=document.createElement('tr-ui-b-info-bar');this.rasterArea_.appendChild(this.infoBar_);this.insertBefore(middleDragHandle,rightPanel);this.picture_=undefined;var hkc=document.createElement('tv-ui-b-hotkey-controller');hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',thisArg:this,keyCode:'h'.charCodeAt(0),callback:function(e){this.moveSelectedOpBy(-1);e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',thisArg:this,keyCode:'l'.charCodeAt(0),callback:function(e){this.moveSelectedOpBy(1);e.stopPropagation();}}));this.appendChild(hkc);this.mutationObserver_=new MutationObserver(this.onMutation_.bind(this));this.mutationObserver_.observe(leftPanel,{attributes:true});},onMutation_:function(mutations){for(var m=0;m<mutations.length;m++){if(mutations[m].attributeName==='style'){this.drawOpsChartSummaryView_.requiresRedraw=true;this.drawOpsChartSummaryView_.updateChartContents();this.drawOpsChartView_.dimensionsHaveChanged=true;this.drawOpsChartView_.updateChartContents();break;}}},onSaveAsSkPictureClicked_:function(){var rawData=tr.b.Base64.atob(this.picture_.getBase64SkpData());var length=rawData.length;var arrayBuffer=new ArrayBuffer(length);var uint8Array=new Uint8Array(arrayBuffer);for(var c=0;c<length;c++)
-uint8Array[c]=rawData.charCodeAt(c);var blob=new Blob([uint8Array],{type:'application/octet-binary'});var blobUrl=window.webkitURL.createObjectURL(blob);var link=document.createElementNS('http://www.w3.org/1999/xhtml','a');link.href=blobUrl;link.download=this.filename_.value;var event=document.createEvent('MouseEvents');event.initMouseEvent('click',true,false,window,0,0,0,0,0,false,false,false,false,0,null);link.dispatchEvent(event);},get picture(){return this.picture_;},set picture(picture){this.drawOpsView_.picture=picture;this.drawOpsChartView_.picture=picture;this.drawOpsChartSummaryView_.picture=picture;this.picture_=picture;this.exportButton_.disabled=!this.picture_.canSave;if(picture){var size=this.getRasterCanvasSize_();this.rasterCanvas_.width=size.width;this.rasterCanvas_.height=size.height;}
-var bounds=this.rasterArea_.getBoundingClientRect();var selectorBounds=this.mouseModeSelector_.getBoundingClientRect();this.mouseModeSelector_.pos={x:(bounds.right-selectorBounds.width-10),y:bounds.top};this.rasterize_();this.scheduleUpdateContents_();},getRasterCanvasSize_:function(){var style=window.getComputedStyle(this.rasterArea_);var width=Math.max(parseInt(style.width),this.picture_.layerRect.width);var height=Math.max(parseInt(style.height),this.picture_.layerRect.height);return{width:width,height:height};},scheduleUpdateContents_:function(){if(this.updateContentsPending_)
-return;this.updateContentsPending_=true;tr.b.requestAnimationFrameInThisFrameIfPossible(this.updateContents_.bind(this));},updateContents_:function(){this.updateContentsPending_=false;if(this.picture_){this.sizeInfo_.textContent='('+
+timingData.sort(this.sortTimingBucketsByOpTimeDescending_);this.collapseTimingBucketsToOther_(4);},collapseTimingBucketsToOther_(count){const timingData=this.opsTimingData_;const otherSource=timingData.splice(count,timingData.length-count);let otherDestination=null;if(!otherSource.length)return;timingData.push({cmd_time:0,cmd_string:'Other'});otherDestination=timingData[timingData.length-1];for(let i=0;i<otherSource.length;i++){otherDestination.cmd_time+=otherSource[i].cmd_time;}},sortTimingBucketsByOpTimeDescending_(a,b){return b.cmd_time-a.cmd_time;},resetOpsTimingData_(){this.opsTimingData_.length=0;}};return{PictureOpsChartSummaryView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const BAR_PADDING=1;const BAR_WIDTH=5;const CHART_PADDING_LEFT=65;const CHART_PADDING_RIGHT=30;const CHART_PADDING_BOTTOM=35;const CHART_PADDING_TOP=20;const AXIS_PADDING_LEFT=55;const AXIS_PADDING_RIGHT=30;const AXIS_PADDING_BOTTOM=35;const AXIS_PADDING_TOP=20;const AXIS_TICK_SIZE=5;const AXIS_LABEL_PADDING=5;const VERTICAL_TICKS=5;const HUE_CHAR_CODE_ADJUSTMENT=5.7;const PictureOpsChartView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-ops-chart-view');PictureOpsChartView.prototype={__proto__:HTMLDivElement.prototype,decorate(){this.style.display='block';this.style.height='180px';this.style.margin=0;this.style.padding=0;this.style.position='relative';this.picture_=undefined;this.pictureOps_=undefined;this.opCosts_=undefined;this.chartScale_=window.devicePixelRatio;this.chart_=document.createElement('canvas');this.chartCtx_=this.chart_.getContext('2d');Polymer.dom(this).appendChild(this.chart_);this.selectedOpIndex_=undefined;this.chartWidth_=0;this.chartHeight_=0;this.dimensionsHaveChanged_=true;this.currentBarMouseOverTarget_=undefined;this.ninetyFifthPercentileCost_=0;this.totalOpCost_=0;this.chart_.addEventListener('click',this.onClick_.bind(this));this.chart_.addEventListener('mousemove',this.onMouseMove_.bind(this));new ResizeObserver(this.onResize_.bind(this)).observe(this);this.usePercentileScale_=false;this.usePercentileScaleCheckbox_=tr.ui.b.createCheckBox(this,'usePercentileScale','PictureOpsChartView.usePercentileScale',false,'Limit to 95%-ile');Polymer.dom(this.usePercentileScaleCheckbox_).classList.add('use-percentile-scale');this.usePercentileScaleCheckbox_.style.position='absolute';this.usePercentileScaleCheckbox_.style.left=0;this.usePercentileScaleCheckbox_.style.top=0;Polymer.dom(this).appendChild(this.usePercentileScaleCheckbox_);},get dimensionsHaveChanged(){return this.dimensionsHaveChanged_;},set dimensionsHaveChanged(dimensionsHaveChanged){this.dimensionsHaveChanged_=dimensionsHaveChanged;},get usePercentileScale(){return this.usePercentileScale_;},set usePercentileScale(usePercentileScale){this.usePercentileScale_=usePercentileScale;this.drawChartContents_();},get numOps(){return this.opCosts_.length;},get selectedOpIndex(){return this.selectedOpIndex_;},set selectedOpIndex(selectedOpIndex){if(selectedOpIndex<0)throw new Error('Invalid index');if(selectedOpIndex>=this.numOps)throw new Error('Invalid index');this.selectedOpIndex_=selectedOpIndex;},get picture(){return this.picture_;},set picture(picture){this.picture_=picture;this.pictureOps_=picture.tagOpsWithTimings(picture.getOps());this.currentBarMouseOverTarget_=undefined;this.processPictureData_();this.dimensionsHaveChanged=true;},processPictureData_(){if(this.pictureOps_===undefined)return;let totalOpCost=0;this.opCosts_=this.pictureOps_.map(function(op){totalOpCost+=op.cmd_time;return op.cmd_time;});this.opCosts_.sort();const ninetyFifthPercentileCostIndex=Math.floor(this.opCosts_.length*0.95);this.ninetyFifthPercentileCost_=this.opCosts_[ninetyFifthPercentileCostIndex];this.maxCost_=this.opCosts_[this.opCosts_.length-1];this.totalOpCost_=totalOpCost;},extractBarIndex_(e){let index=undefined;if(this.pictureOps_===undefined||this.pictureOps_.length===0){return index;}
+const x=e.offsetX;const y=e.offsetY;const totalBarWidth=(BAR_WIDTH+BAR_PADDING)*this.pictureOps_.length;const chartLeft=CHART_PADDING_LEFT;const chartTop=0;const chartBottom=this.chartHeight_-CHART_PADDING_BOTTOM;const chartRight=chartLeft+totalBarWidth;if(x<chartLeft||x>chartRight||y<chartTop||y>chartBottom){return index;}
+index=Math.floor((x-chartLeft)/totalBarWidth*this.pictureOps_.length);index=tr.b.math.clamp(index,0,this.pictureOps_.length-1);return index;},onClick_(e){const barClicked=this.extractBarIndex_(e);if(barClicked===undefined)return;if(barClicked===this.selectedOpIndex){this.selectedOpIndex=undefined;}else{this.selectedOpIndex=barClicked;}
+e.preventDefault();tr.b.dispatchSimpleEvent(this,'selection-changed',false);},onMouseMove_(e){const lastBarMouseOverTarget=this.currentBarMouseOverTarget_;this.currentBarMouseOverTarget_=this.extractBarIndex_(e);if(this.currentBarMouseOverTarget_===lastBarMouseOverTarget){return;}
+this.drawChartContents_();},onResize_(){this.dimensionsHaveChanged=true;this.updateChartContents();},scrollSelectedItemIntoViewIfNecessary(){if(this.selectedOpIndex===undefined){return;}
+const width=this.offsetWidth;const left=this.scrollLeft;const right=left+width;const targetLeft=CHART_PADDING_LEFT+
+(BAR_WIDTH+BAR_PADDING)*this.selectedOpIndex;if(targetLeft>left&&targetLeft<right){return;}
+this.scrollLeft=(targetLeft-width*0.5);},updateChartContents(){if(this.dimensionsHaveChanged){this.updateChartDimensions_();}
+this.drawChartContents_();},updateChartDimensions_(){if(!this.pictureOps_)return;let width=CHART_PADDING_LEFT+CHART_PADDING_RIGHT+
+((BAR_WIDTH+BAR_PADDING)*this.pictureOps_.length);if(width<this.offsetWidth){width=this.offsetWidth;}
+this.chartWidth_=width;this.chartHeight_=this.getBoundingClientRect().height;this.chart_.width=this.chartWidth_*this.chartScale_;this.chart_.height=this.chartHeight_*this.chartScale_;this.chart_.style.width=this.chartWidth_+'px';this.chart_.style.height=this.chartHeight_+'px';this.chartCtx_.scale(this.chartScale_,this.chartScale_);this.dimensionsHaveChanged=false;},drawChartContents_(){this.clearChartContents_();if(this.pictureOps_===undefined||this.pictureOps_.length===0||this.pictureOps_[0].cmd_time===undefined){this.showNoTimingDataMessage_();return;}
+this.drawSelection_();this.drawBars_();this.drawChartAxes_();this.drawLinesAtTickMarks_();this.drawLineAtBottomOfChart_();if(this.currentBarMouseOverTarget_===undefined){return;}
+this.drawTooltip_();},drawSelection_(){if(this.selectedOpIndex===undefined){return;}
+const width=(BAR_WIDTH+BAR_PADDING)*this.selectedOpIndex;this.chartCtx_.fillStyle='rgb(223, 235, 230)';this.chartCtx_.fillRect(CHART_PADDING_LEFT,CHART_PADDING_TOP,width,this.chartHeight_-CHART_PADDING_TOP-CHART_PADDING_BOTTOM);},drawChartAxes_(){const min=this.opCosts_[0];const max=this.opCosts_[this.opCosts_.length-1];const height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;const tickYInterval=height/(VERTICAL_TICKS-1);let tickYPosition=0;const tickValInterval=(max-min)/(VERTICAL_TICKS-1);let tickVal=0;this.chartCtx_.fillStyle='#333';this.chartCtx_.strokeStyle='#777';this.chartCtx_.save();this.chartCtx_.translate(0.5,0.5);this.chartCtx_.beginPath();this.chartCtx_.moveTo(AXIS_PADDING_LEFT,AXIS_PADDING_TOP);this.chartCtx_.lineTo(AXIS_PADDING_LEFT,this.chartHeight_-
+AXIS_PADDING_BOTTOM);this.chartCtx_.lineTo(this.chartWidth_-AXIS_PADDING_RIGHT,this.chartHeight_-AXIS_PADDING_BOTTOM);this.chartCtx_.stroke();this.chartCtx_.closePath();this.chartCtx_.translate(AXIS_PADDING_LEFT,AXIS_PADDING_TOP);this.chartCtx_.font='10px Arial';this.chartCtx_.textAlign='right';this.chartCtx_.textBaseline='middle';this.chartCtx_.beginPath();for(let t=0;t<VERTICAL_TICKS;t++){tickYPosition=Math.round(t*tickYInterval);tickVal=(max-t*tickValInterval).toFixed(4);this.chartCtx_.moveTo(0,tickYPosition);this.chartCtx_.lineTo(-AXIS_TICK_SIZE,tickYPosition);this.chartCtx_.fillText(tickVal,-AXIS_TICK_SIZE-AXIS_LABEL_PADDING,tickYPosition);}
+this.chartCtx_.stroke();this.chartCtx_.closePath();this.chartCtx_.restore();},drawLinesAtTickMarks_(){const height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;const width=this.chartWidth_-AXIS_PADDING_LEFT-AXIS_PADDING_RIGHT;const tickYInterval=height/(VERTICAL_TICKS-1);let tickYPosition=0;this.chartCtx_.save();this.chartCtx_.translate(AXIS_PADDING_LEFT+0.5,AXIS_PADDING_TOP+0.5);this.chartCtx_.beginPath();this.chartCtx_.strokeStyle='rgba(0,0,0,0.05)';for(let t=0;t<VERTICAL_TICKS;t++){tickYPosition=Math.round(t*tickYInterval);this.chartCtx_.moveTo(0,tickYPosition);this.chartCtx_.lineTo(width,tickYPosition);this.chartCtx_.stroke();}
+this.chartCtx_.restore();this.chartCtx_.closePath();},drawLineAtBottomOfChart_(){this.chartCtx_.strokeStyle='#AAA';this.chartCtx_.beginPath();this.chartCtx_.moveTo(0,this.chartHeight_-0.5);this.chartCtx_.lineTo(this.chartWidth_,this.chartHeight_-0.5);this.chartCtx_.stroke();this.chartCtx_.closePath();},drawTooltip_(){const tooltipData=this.pictureOps_[this.currentBarMouseOverTarget_];const tooltipTitle=tooltipData.cmd_string;const tooltipTime=tooltipData.cmd_time.toFixed(4);const toolTipTimePercentage=((tooltipData.cmd_time/this.totalOpCost_)*100).toFixed(2);const tooltipWidth=120;const tooltipHeight=40;const chartInnerWidth=this.chartWidth_-CHART_PADDING_RIGHT-
+CHART_PADDING_LEFT;const barWidth=BAR_WIDTH+BAR_PADDING;const tooltipOffset=Math.round((tooltipWidth-barWidth)*0.5);const left=CHART_PADDING_LEFT+this.currentBarMouseOverTarget_*barWidth-tooltipOffset;const top=Math.round((this.chartHeight_-tooltipHeight)*0.5);this.chartCtx_.save();this.chartCtx_.shadowOffsetX=0;this.chartCtx_.shadowOffsetY=5;this.chartCtx_.shadowBlur=4;this.chartCtx_.shadowColor='rgba(0,0,0,0.4)';this.chartCtx_.strokeStyle='#888';this.chartCtx_.fillStyle='#EEE';this.chartCtx_.fillRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.shadowColor='transparent';this.chartCtx_.translate(0.5,0.5);this.chartCtx_.strokeRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.restore();this.chartCtx_.fillStyle='#222';this.chartCtx_.textAlign='left';this.chartCtx_.textBaseline='top';this.chartCtx_.font='800 12px Arial';this.chartCtx_.fillText(tooltipTitle,left+8,top+8);this.chartCtx_.fillStyle='#555';this.chartCtx_.font='400 italic 10px Arial';this.chartCtx_.fillText(tooltipTime+'ms ('+
+toolTipTimePercentage+'%)',left+8,top+22);},drawBars_(){let op;let opColor=0;let opHeight=0;const opWidth=BAR_WIDTH+BAR_PADDING;let opHover=false;const bottom=this.chartHeight_-CHART_PADDING_BOTTOM;const maxHeight=this.chartHeight_-CHART_PADDING_BOTTOM-
+CHART_PADDING_TOP;let maxValue;if(this.usePercentileScale){maxValue=this.ninetyFifthPercentileCost_;}else{maxValue=this.maxCost_;}
+for(let b=0;b<this.pictureOps_.length;b++){op=this.pictureOps_[b];opHeight=Math.round((op.cmd_time/maxValue)*maxHeight);opHeight=Math.max(opHeight,1);opHover=(b===this.currentBarMouseOverTarget_);opColor=this.getOpColor_(op.cmd_string,opHover);if(b===this.selectedOpIndex){this.chartCtx_.fillStyle='#FFFF00';}else{this.chartCtx_.fillStyle=opColor;}
+this.chartCtx_.fillRect(CHART_PADDING_LEFT+b*opWidth,bottom-opHeight,BAR_WIDTH,opHeight);}},getOpColor_(opName,hover){const characters=opName.split('');const hue=characters.reduce(this.reduceNameToHue,0)%360;const saturation=30;const lightness=hover?'75%':'50%';return'hsl('+hue+', '+saturation+'%, '+lightness+'%)';},reduceNameToHue(previousValue,currentValue,index,array){return Math.round(previousValue+currentValue.charCodeAt(0)*HUE_CHAR_CODE_ADJUSTMENT);},clearChartContents_(){this.chartCtx_.clearRect(0,0,this.chartWidth_,this.chartHeight_);},showNoTimingDataMessage_(){this.chartCtx_.font='800 italic 14px Arial';this.chartCtx_.fillStyle='#333';this.chartCtx_.textAlign='center';this.chartCtx_.textBaseline='middle';this.chartCtx_.fillText('No timing data available.',this.chartWidth_*0.5,this.chartHeight_*0.5);}};return{PictureOpsChartView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const THIS_DOC=document.currentScript.ownerDocument;const PictureDebugger=tr.ui.b.define('tr-ui-e-chrome-cc-picture-debugger');PictureDebugger.prototype={__proto__:HTMLDivElement.prototype,decorate(){const node=tr.ui.b.instantiateTemplate('#tr-ui-e-chrome-cc-picture-debugger-template',THIS_DOC);Polymer.dom(this).appendChild(node);this.style.display='flex';this.style.flexDirection='row';const title=this.querySelector('.title');title.style.fontWeight='bold';title.style.marginLeft='5px';title.style.marginRight='5px';this.pictureAsImageData_=undefined;this.showOverdraw_=false;this.zoomScaleValue_=1;this.sizeInfo_=Polymer.dom(this).querySelector('.size');this.rasterArea_=Polymer.dom(this).querySelector('raster-area');this.rasterArea_.style.backgroundColor='#ddd';this.rasterArea_.style.minHeight='100px';this.rasterArea_.style.minWidth='200px';this.rasterArea_.style.overflow='auto';this.rasterArea_.style.paddingLeft='5px';this.rasterCanvas_=Polymer.dom(this.rasterArea_).querySelector('canvas');this.rasterCtx_=this.rasterCanvas_.getContext('2d');this.filename_=Polymer.dom(this).querySelector('.filename');this.filename_.style.userSelect='text';this.filename_.style.marginLeft='5px';this.drawOpsChartSummaryView_=new tr.ui.e.chrome.cc.PictureOpsChartSummaryView();this.drawOpsChartView_=new tr.ui.e.chrome.cc.PictureOpsChartView();this.drawOpsChartView_.addEventListener('selection-changed',this.onChartBarClicked_.bind(this));this.exportButton_=Polymer.dom(this).querySelector('.export');this.exportButton_.addEventListener('click',this.onSaveAsSkPictureClicked_.bind(this));this.trackMouse_();const overdrawCheckbox=tr.ui.b.createCheckBox(this,'showOverdraw','pictureView.showOverdraw',false,'Show overdraw');const chartCheckbox=tr.ui.b.createCheckBox(this,'showSummaryChart','pictureView.showSummaryChart',false,'Show timing summary');const pictureInfo=Polymer.dom(this).querySelector('picture-info');pictureInfo.style.flexGrow=0;pictureInfo.style.flexShrink=0;pictureInfo.style.flexBasis='auto';pictureInfo.style.paddingTop='2px';Polymer.dom(pictureInfo).appendChild(overdrawCheckbox);Polymer.dom(pictureInfo).appendChild(chartCheckbox);this.drawOpsView_=new tr.ui.e.chrome.cc.PictureOpsListView();this.drawOpsView_.flexGrow=1;this.drawOpsView_.flexShrink=1;this.drawOpsView_.flexBasis='auto';this.drawOpsView_.addEventListener('selection-changed',this.onChangeDrawOps_.bind(this));const leftPanel=Polymer.dom(this).querySelector('left-panel');leftPanel.style.flexDirection='column';leftPanel.style.display='flex';leftPanel.style.flexGrow=0;leftPanel.style.flexShrink=0;leftPanel.style.flexBasis='auto';leftPanel.style.minWidth='200px';leftPanel.style.overflow='auto';Polymer.dom(leftPanel).appendChild(this.drawOpsChartSummaryView_);Polymer.dom(leftPanel).appendChild(this.drawOpsView_);const middleDragHandle=document.createElement('tr-ui-b-drag-handle');middleDragHandle.style.flexGrow=0;middleDragHandle.style.flexShrink=0;middleDragHandle.style.flexBasis='auto';middleDragHandle.horizontal=false;middleDragHandle.target=leftPanel;const rightPanel=Polymer.dom(this).querySelector('right-panel');rightPanel.style.flexGrow=1;rightPanel.style.flexShrink=1;rightPanel.style.flexBasis='auto';rightPanel.style.minWidth=0;rightPanel.style.flexDirection='column';rightPanel.style.display='flex';const chartView=Polymer.dom(rightPanel).querySelector('tr-ui-e-chrome-cc-picture-ops-chart-view');this.drawOpsChartView_.style.flexGrow=0;this.drawOpsChartView_.style.flexShrink=0;this.drawOpsChartView_.style.flexBasis='auto';this.drawOpsChartView_.style.minWidth=0;this.drawOpsChartView_.style.overflowX='auto';this.drawOpsChartView_.style.overflowY='hidden';rightPanel.replaceChild(this.drawOpsChartView_,chartView);this.infoBar_=document.createElement('tr-ui-b-info-bar');Polymer.dom(this.rasterArea_).appendChild(this.infoBar_);Polymer.dom(this).insertBefore(middleDragHandle,rightPanel);this.picture_=undefined;const hkc=document.createElement('tv-ui-b-hotkey-controller');hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',thisArg:this,keyCode:'h'.charCodeAt(0),callback(e){this.moveSelectedOpBy(-1);e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',thisArg:this,keyCode:'l'.charCodeAt(0),callback(e){this.moveSelectedOpBy(1);e.stopPropagation();}}));Polymer.dom(this).appendChild(hkc);},onSaveAsSkPictureClicked_(){const rawData=tr.b.Base64.atob(this.picture_.getBase64SkpData());const length=rawData.length;const arrayBuffer=new ArrayBuffer(length);const uint8Array=new Uint8Array(arrayBuffer);for(let c=0;c<length;c++){uint8Array[c]=rawData.charCodeAt(c);}
+const blob=new Blob([uint8Array],{type:'application/octet-binary'});const blobUrl=window.webkitURL.createObjectURL(blob);const link=document.createElementNS('http://www.w3.org/1999/xhtml','a');link.href=blobUrl;link.download=this.filename_.value;const event=document.createEvent('MouseEvents');event.initMouseEvent('click',true,false,window,0,0,0,0,0,false,false,false,false,0,null);link.dispatchEvent(event);},get picture(){return this.picture_;},set picture(picture){this.drawOpsView_.picture=picture;this.drawOpsChartView_.picture=picture;this.drawOpsChartSummaryView_.picture=picture;this.picture_=picture;this.exportButton_.disabled=!this.picture_.canSave;if(picture){const size=this.getRasterCanvasSize_();this.rasterCanvas_.width=size.width;this.rasterCanvas_.height=size.height;}
+const bounds=this.rasterArea_.getBoundingClientRect();const selectorBounds=this.mouseModeSelector_.getBoundingClientRect();this.mouseModeSelector_.pos={x:(bounds.right-selectorBounds.width-10),y:bounds.top};this.rasterize_();this.scheduleUpdateContents_();},getRasterCanvasSize_(){const style=window.getComputedStyle(this.rasterArea_);const width=Math.max(parseInt(style.width),this.picture_.layerRect.width);const height=Math.max(parseInt(style.height),this.picture_.layerRect.height);return{width,height};},scheduleUpdateContents_(){if(this.updateContentsPending_)return;this.updateContentsPending_=true;tr.b.requestAnimationFrameInThisFrameIfPossible(this.updateContents_.bind(this));},updateContents_(){this.updateContentsPending_=false;if(this.picture_){Polymer.dom(this.sizeInfo_).textContent='('+
 this.picture_.layerRect.width+' x '+
 this.picture_.layerRect.height+')';}
-this.drawOpsChartView_.updateChartContents();this.drawOpsChartView_.scrollSelectedItemIntoViewIfNecessary();if(!this.pictureAsImageData_)
-return;this.infoBar_.visible=false;this.infoBar_.removeAllButtons();if(this.pictureAsImageData_.error){this.infoBar_.message='Cannot rasterize...';this.infoBar_.addButton('More info...',function(e){var overlay=new tr.ui.b.Overlay();overlay.textContent=this.pictureAsImageData_.error;overlay.visible=true;e.stopPropagation();return false;}.bind(this));this.infoBar_.visible=true;}
-this.drawPicture_();},drawPicture_:function(){var size=this.getRasterCanvasSize_();if(size.width!==this.rasterCanvas_.width)
-this.rasterCanvas_.width=size.width;if(size.height!==this.rasterCanvas_.height)
-this.rasterCanvas_.height=size.height;this.rasterCtx_.clearRect(0,0,size.width,size.height);if(!this.pictureAsImageData_.imageData)
-return;var imgCanvas=this.pictureAsImageData_.asCanvas();var w=imgCanvas.width;var h=imgCanvas.height;this.rasterCtx_.drawImage(imgCanvas,0,0,w,h,0,0,w*this.zoomScaleValue_,h*this.zoomScaleValue_);},rasterize_:function(){if(this.picture_){this.picture_.rasterize({stopIndex:this.drawOpsView_.selectedOpIndex,showOverdraw:this.showOverdraw_},this.onRasterComplete_.bind(this));}},onRasterComplete_:function(pictureAsImageData){this.pictureAsImageData_=pictureAsImageData;this.scheduleUpdateContents_();},moveSelectedOpBy:function(increment){if(this.selectedOpIndex===undefined){this.selectedOpIndex=0;return;}
-this.selectedOpIndex=tr.b.clamp(this.selectedOpIndex+increment,0,this.numOps);},get numOps(){return this.drawOpsView_.numOps;},get selectedOpIndex(){return this.drawOpsView_.selectedOpIndex;},set selectedOpIndex(index){this.drawOpsView_.selectedOpIndex=index;this.drawOpsChartView_.selectedOpIndex=index;},onChartBarClicked_:function(e){this.drawOpsView_.selectedOpIndex=this.drawOpsChartView_.selectedOpIndex;},onChangeDrawOps_:function(e){this.rasterize_();this.scheduleUpdateContents_();this.drawOpsChartView_.selectedOpIndex=this.drawOpsView_.selectedOpIndex;},set showOverdraw(v){this.showOverdraw_=v;this.rasterize_();},set showSummaryChart(chartShouldBeVisible){if(chartShouldBeVisible)
-this.drawOpsChartSummaryView_.show();else
-this.drawOpsChartSummaryView_.hide();},trackMouse_:function(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this.rasterArea_;this.rasterArea_.appendChild(this.mouseModeSelector_);this.mouseModeSelector_.supportedModeMask=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.mode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.defaultMode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.settingsKey='pictureDebugger.mouseModeSelector';this.mouseModeSelector_.addEventListener('beginzoom',this.onBeginZoom_.bind(this));this.mouseModeSelector_.addEventListener('updatezoom',this.onUpdateZoom_.bind(this));this.mouseModeSelector_.addEventListener('endzoom',this.onEndZoom_.bind(this));},onBeginZoom_:function(e){this.isZooming_=true;this.lastMouseViewPos_=this.extractRelativeMousePosition_(e);e.preventDefault();},onUpdateZoom_:function(e){if(!this.isZooming_)
-return;var currentMouseViewPos=this.extractRelativeMousePosition_(e);this.zoomScaleValue_+=((this.lastMouseViewPos_.y-currentMouseViewPos.y)*0.001);this.zoomScaleValue_=Math.max(this.zoomScaleValue_,0.1);this.drawPicture_();this.lastMouseViewPos_=currentMouseViewPos;},onEndZoom_:function(e){this.lastMouseViewPos_=undefined;this.isZooming_=false;e.preventDefault();},extractRelativeMousePosition_:function(e){return{x:e.clientX-this.rasterArea_.offsetLeft,y:e.clientY-this.rasterArea_.offsetTop};}};return{PictureDebugger:PictureDebugger};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var PictureSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-snapshot-view',tr.ui.analysis.ObjectSnapshotView);PictureSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-chrome-cc-picture-snapshot-view');this.pictureDebugger_=new tr.ui.e.chrome.cc.PictureDebugger();this.appendChild(this.pictureDebugger_);},updateContents:function(){if(this.objectSnapshot_&&this.pictureDebugger_)
-this.pictureDebugger_.picture=this.objectSnapshot_;}};tr.ui.analysis.ObjectSnapshotView.register(PictureSnapshotView,{typeNames:['cc::Picture','cc::LayeredPicture'],showInstances:false});return{PictureSnapshotView:PictureSnapshotView};});'use strict';tr.exportTo('tr.e.cc',function(){var knownRasterTaskNames=['TileManager::RunRasterTask','RasterWorkerPoolTaskImpl::RunRasterOnThread','RasterWorkerPoolTaskImpl::Raster','RasterTaskImpl::Raster','cc::RasterTask','RasterTask'];var knownAnalysisTaskNames=['TileManager::RunAnalyzeTask','RasterWorkerPoolTaskImpl::RunAnalysisOnThread','RasterWorkerPoolTaskImpl::Analyze','RasterTaskImpl::Analyze','cc::AnalyzeTask','AnalyzeTask'];function getTileFromRasterTaskSlice(slice){if(!(isSliceDoingRasterization(slice)||isSliceDoingAnalysis(slice)))
-return undefined;var tileData;if(slice.args.data)
-tileData=slice.args.data;else
-tileData=slice.args.tileData;if(tileData===undefined)
-return undefined;if(tileData.tile_id)
-return tileData.tile_id;var tile=tileData.tileId;if(!(tile instanceof tr.e.cc.TileSnapshot))
-return undefined;return tileData.tileId;}
-function isSliceDoingRasterization(slice){if(knownRasterTaskNames.indexOf(slice.title)!==-1)
-return true;return false;}
-function isSliceDoingAnalysis(slice){if(knownAnalysisTaskNames.indexOf(slice.title)!==-1)
-return true;return false;}
-return{getTileFromRasterTaskSlice:getTileFromRasterTaskSlice,isSliceDoingRasterization:isSliceDoingRasterization,isSliceDoingAnalysis:isSliceDoingAnalysis};});'use strict';Polymer('tr-ui-a-sub-view',{set tabLabel(label){return this.setAttribute('tab-label',label);},get tabLabel(){return this.getAttribute('tab-label');},get requiresTallView(){return false;},get relatedEventsToHighlight(){return undefined;},set selection(selection){throw new Error('Not implemented!');},get selection(){throw new Error('Not implemented!');}});'use strict';Polymer('tr-ui-a-stack-frame',{ready:function(){this.stackFrame_=undefined;this.$.table.tableColumns=[];this.$.table.showHeader=true;},get stackFrame(){return this.stackFrame_;},set stackFrame(stackFrame){var table=this.$.table;this.stackFrame_=stackFrame;if(stackFrame===undefined){table.tableColumns=[];table.tableRows=[];table.rebuild();return;}
-var hasName=false;var hasTitle=false;table.tableRows=stackFrame.stackTrace;table.tableRows.forEach(function(row){hasName|=row.name!==undefined;hasTitle|=row.title!==undefined;});var cols=[];if(hasName){cols.push({title:'Name',value:function(row){return row.name;}});}
-if(hasTitle){cols.push({title:'Title',value:function(row){return row.title;}});}
-table.tableColumns=cols;table.rebuild();},tableForTesting:function(){return this.$.table;}});'use strict';Polymer('tr-ui-a-single-event-sub-view',{ready:function(){this.currentSelection_=undefined;this.$.table.tableColumns=[{title:'Label',value:function(row){return row.name;},width:'150px'},{title:'Value',width:'100%',value:function(row){return row.value;}}];this.$.table.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1)
-throw new Error('Only supports single slices');this.setSelectionWithoutErrorChecks(selection);},setSelectionWithoutErrorChecks:function(selection){this.currentSelection_=selection;this.updateContents_();},getEventRows_:function(event){var rows=[];if(event.error)
-rows.push({name:'Error',value:event.error});if(event.title)
-rows.push({name:'Title',value:event.title});if(event.category)
-rows.push({name:'Category',value:event.category});if(event.model!==undefined){var ufc=event.model.getUserFriendlyCategoryFromEvent(event);if(ufc!==undefined)
-rows.push({name:'User Friendly Category',value:ufc});}
-if(event.name)
-rows.push({name:'Name',value:event.name});rows.push({name:'Start',value:tr.v.ui.createScalarSpan(event.start,{unit:tr.v.Unit.byName.timeStampInMs})});if(event.duration){rows.push({name:'Wall Duration',value:tr.v.ui.createScalarSpan(event.duration,{unit:tr.v.Unit.byName.timeDurationInMs})});}
-if(event.cpuDuration){rows.push({name:'CPU Duration',value:tr.v.ui.createScalarSpan(event.cpuDuration,{unit:tr.v.Unit.byName.timeDurationInMs})});}
-if(event.subSlices!==undefined&&event.subSlices.length!==0){if(event.selfTime){rows.push({name:'Self Time',value:tr.v.ui.createScalarSpan(event.selfTime,{unit:tr.v.Unit.byName.timeDurationInMs})});}
-if(event.cpuSelfTime){var cpuSelfTimeEl=tr.v.ui.createScalarSpan(event.cpuSelfTime,{unit:tr.v.Unit.byName.timeDurationInMs});if(event.cpuSelfTime>event.selfTime){cpuSelfTimeEl.warning=' Note that CPU Self Time is larger than Self Time. '+'This is a known limitation of this system, which occurs '+'due to several subslices, rounding issues, and imprecise '+'time at which we get cpu- and real-time.';}
+this.drawOpsChartView_.updateChartContents();this.drawOpsChartView_.scrollSelectedItemIntoViewIfNecessary();if(!this.pictureAsImageData_)return;this.infoBar_.visible=false;this.infoBar_.removeAllButtons();if(this.pictureAsImageData_.error){this.infoBar_.message='Cannot rasterize...';this.infoBar_.addButton('More info...',function(e){const overlay=new tr.ui.b.Overlay();Polymer.dom(overlay).textContent=this.pictureAsImageData_.error;overlay.visible=true;e.stopPropagation();return false;}.bind(this));this.infoBar_.visible=true;}
+this.drawPicture_();},drawPicture_(){const size=this.getRasterCanvasSize_();if(size.width!==this.rasterCanvas_.width){this.rasterCanvas_.width=size.width;}
+if(size.height!==this.rasterCanvas_.height){this.rasterCanvas_.height=size.height;}
+this.rasterCtx_.clearRect(0,0,size.width,size.height);if(!this.pictureAsImageData_.imageData)return;const imgCanvas=this.pictureAsImageData_.asCanvas();const w=imgCanvas.width;const h=imgCanvas.height;this.rasterCtx_.drawImage(imgCanvas,0,0,w,h,0,0,w*this.zoomScaleValue_,h*this.zoomScaleValue_);},rasterize_(){if(this.picture_){this.picture_.rasterize({stopIndex:this.drawOpsView_.selectedOpIndex,showOverdraw:this.showOverdraw_},this.onRasterComplete_.bind(this));}},onRasterComplete_(pictureAsImageData){this.pictureAsImageData_=pictureAsImageData;this.scheduleUpdateContents_();},moveSelectedOpBy(increment){if(this.selectedOpIndex===undefined){this.selectedOpIndex=0;return;}
+this.selectedOpIndex=tr.b.math.clamp(this.selectedOpIndex+increment,0,this.numOps);},get numOps(){return this.drawOpsView_.numOps;},get selectedOpIndex(){return this.drawOpsView_.selectedOpIndex;},set selectedOpIndex(index){this.drawOpsView_.selectedOpIndex=index;this.drawOpsChartView_.selectedOpIndex=index;},onChartBarClicked_(e){this.drawOpsView_.selectedOpIndex=this.drawOpsChartView_.selectedOpIndex;},onChangeDrawOps_(e){this.rasterize_();this.scheduleUpdateContents_();this.drawOpsChartView_.selectedOpIndex=this.drawOpsView_.selectedOpIndex;},set showOverdraw(v){this.showOverdraw_=v;this.rasterize_();},set showSummaryChart(chartShouldBeVisible){if(chartShouldBeVisible){this.drawOpsChartSummaryView_.show();}else{this.drawOpsChartSummaryView_.hide();}},trackMouse_(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this.rasterArea_;Polymer.dom(this.rasterArea_).appendChild(this.mouseModeSelector_);this.mouseModeSelector_.supportedModeMask=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.mode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.defaultMode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.settingsKey='pictureDebugger.mouseModeSelector';this.mouseModeSelector_.addEventListener('beginzoom',this.onBeginZoom_.bind(this));this.mouseModeSelector_.addEventListener('updatezoom',this.onUpdateZoom_.bind(this));this.mouseModeSelector_.addEventListener('endzoom',this.onEndZoom_.bind(this));},onBeginZoom_(e){this.isZooming_=true;this.lastMouseViewPos_=this.extractRelativeMousePosition_(e);e.preventDefault();},onUpdateZoom_(e){if(!this.isZooming_)return;const currentMouseViewPos=this.extractRelativeMousePosition_(e);this.zoomScaleValue_+=((this.lastMouseViewPos_.y-currentMouseViewPos.y)*0.001);this.zoomScaleValue_=Math.max(this.zoomScaleValue_,0.1);this.drawPicture_();this.lastMouseViewPos_=currentMouseViewPos;},onEndZoom_(e){this.lastMouseViewPos_=undefined;this.isZooming_=false;e.preventDefault();},extractRelativeMousePosition_(e){return{x:e.clientX-this.rasterArea_.offsetLeft,y:e.clientY-this.rasterArea_.offsetTop};}};return{PictureDebugger,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const PictureSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-snapshot-view',tr.ui.analysis.ObjectSnapshotView);PictureSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate(){Polymer.dom(this).classList.add('tr-ui-e-chrome-cc-picture-snapshot-view');this.style.display='flex';this.style.flexGrow=1;this.style.flexShrink=1;this.style.flexBasis='auto';this.style.minWidth=0;this.pictureDebugger_=new tr.ui.e.chrome.cc.PictureDebugger();this.pictureDebugger_.style.flexGrow=1;this.pictureDebugger_.style.flexShrink=1;this.pictureDebugger_.style.flexBasis='auto';this.pictureDebugger_.style.minWidth=0;Polymer.dom(this).appendChild(this.pictureDebugger_);},updateContents(){if(this.objectSnapshot_&&this.pictureDebugger_){this.pictureDebugger_.picture=this.objectSnapshot_;}}};tr.ui.analysis.ObjectSnapshotView.register(PictureSnapshotView,{typeNames:['cc::Picture','cc::LayeredPicture'],showInstances:false});return{PictureSnapshotView,};});'use strict';tr.exportTo('tr.e.cc',function(){const knownRasterTaskNames=['TileManager::RunRasterTask','RasterWorkerPoolTaskImpl::RunRasterOnThread','RasterWorkerPoolTaskImpl::Raster','RasterTaskImpl::Raster','cc::RasterTask','RasterTask'];const knownAnalysisTaskNames=['TileManager::RunAnalyzeTask','RasterWorkerPoolTaskImpl::RunAnalysisOnThread','RasterWorkerPoolTaskImpl::Analyze','RasterTaskImpl::Analyze','cc::AnalyzeTask','AnalyzeTask'];function getTileFromRasterTaskSlice(slice){if(!(isSliceDoingRasterization(slice)||isSliceDoingAnalysis(slice))){return undefined;}
+let tileData;if(slice.args.data){tileData=slice.args.data;}else{tileData=slice.args.tileData;}
+if(tileData===undefined)return undefined;if(tileData.tile_id)return tileData.tile_id;const tile=tileData.tileId;if(!(tile instanceof tr.e.cc.TileSnapshot)){return undefined;}
+return tileData.tileId;}
+function isSliceDoingRasterization(slice){return knownRasterTaskNames.includes(slice.title);}
+function isSliceDoingAnalysis(slice){return knownAnalysisTaskNames.includes(slice.title);}
+return{getTileFromRasterTaskSlice,isSliceDoingRasterization,isSliceDoingAnalysis};});'use strict';tr.exportTo('tr.ui.analysis',function(){const AnalysisSubView={set tabLabel(label){Polymer.dom(this).setAttribute('tab-label',label);},get tabLabel(){return this.getAttribute('tab-label');},get requiresTallView(){return false;},get relatedEventsToHighlight(){return undefined;},set selection(selection){throw new Error('Not implemented!');},get selection(){throw new Error('Not implemented!');}};const allTypeInfosByEventProto=new Map();let onlyRootTypeInfosByEventProto=undefined;let eventProtoToRootTypeInfoMap=undefined;function AnalysisSubViewTypeInfo(eventConstructor,options){if(options.multi===undefined){throw new Error('missing field: multi');}
+if(options.title===undefined){throw new Error('missing field: title');}
+this.eventConstructor=eventConstructor;this.singleTagName=undefined;this.singleTitle=undefined;this.multiTagName=undefined;this.multiTitle=undefined;this.childrenTypeInfos_=undefined;}
+AnalysisSubViewTypeInfo.prototype={get childrenTypeInfos(){return this.childrenTypeInfos_;},resetchildrenTypeInfos(){this.childrenTypeInfos_=[];}};AnalysisSubView.register=function(tagName,eventConstructor,options){let typeInfo=allTypeInfosByEventProto.get(eventConstructor.prototype);if(typeInfo===undefined){typeInfo=new AnalysisSubViewTypeInfo(eventConstructor,options);allTypeInfosByEventProto.set(typeInfo.eventConstructor.prototype,typeInfo);onlyRootTypeInfosByEventProto=undefined;}
+if(!options.multi){if(typeInfo.singleTagName!==undefined){throw new Error('SingleTagName already set');}
+typeInfo.singleTagName=tagName;typeInfo.singleTitle=options.title;}else{if(typeInfo.multiTagName!==undefined){throw new Error('MultiTagName already set');}
+typeInfo.multiTagName=tagName;typeInfo.multiTitle=options.title;}
+return typeInfo;};function rebuildRootSubViewTypeInfos(){onlyRootTypeInfosByEventProto=new Map();allTypeInfosByEventProto.forEach(function(typeInfo){typeInfo.resetchildrenTypeInfos();});allTypeInfosByEventProto.forEach(function(typeInfo,eventProto){const eventPrototype=typeInfo.eventConstructor.prototype;let lastEventProto=eventPrototype;let curEventProto=eventPrototype.__proto__;while(true){if(!allTypeInfosByEventProto.has(curEventProto)){const rootTypeInfo=allTypeInfosByEventProto.get(lastEventProto);const rootEventProto=lastEventProto;const isNew=onlyRootTypeInfosByEventProto.has(rootEventProto);onlyRootTypeInfosByEventProto.set(rootEventProto,rootTypeInfo);break;}
+lastEventProto=curEventProto;curEventProto=curEventProto.__proto__;}});allTypeInfosByEventProto.forEach(function(typeInfo,eventProto){const eventPrototype=typeInfo.eventConstructor.prototype;const parentEventProto=eventPrototype.__proto__;const parentTypeInfo=allTypeInfosByEventProto.get(parentEventProto);if(!parentTypeInfo)return;parentTypeInfo.childrenTypeInfos.push(typeInfo);});eventProtoToRootTypeInfoMap=new Map();allTypeInfosByEventProto.forEach(function(typeInfo,eventProto){const eventPrototype=typeInfo.eventConstructor.prototype;let curEventProto=eventPrototype;while(true){if(onlyRootTypeInfosByEventProto.has(curEventProto)){const rootTypeInfo=onlyRootTypeInfosByEventProto.get(curEventProto);eventProtoToRootTypeInfoMap.set(eventPrototype,rootTypeInfo);break;}
+curEventProto=curEventProto.__proto__;}});}
+function findLowestTypeInfoForEvents(thisTypeInfo,events){if(events.length===0)return thisTypeInfo;const event0=tr.b.getFirstElement(events);let candidateSubTypeInfo;for(let i=0;i<thisTypeInfo.childrenTypeInfos.length;i++){const childTypeInfo=thisTypeInfo.childrenTypeInfos[i];if(event0 instanceof childTypeInfo.eventConstructor){candidateSubTypeInfo=childTypeInfo;break;}}
+if(!candidateSubTypeInfo)return thisTypeInfo;let allMatch=true;for(const event of events){if(event instanceof candidateSubTypeInfo.eventConstructor)continue;allMatch=false;break;}
+if(!allMatch){return thisTypeInfo;}
+return findLowestTypeInfoForEvents(candidateSubTypeInfo,events);}
+const primaryEventProtoToTypeInfoMap=new Map();function getRootTypeInfoForEvent(event){const curProto=event.__proto__;const typeInfo=primaryEventProtoToTypeInfoMap.get(curProto);if(typeInfo)return typeInfo;return getRootTypeInfoForEventSlow(event);}
+function getRootTypeInfoForEventSlow(event){let typeInfo;let curProto=event.__proto__;while(true){if(curProto===Object.prototype){throw new Error('No view registered for '+event.toString());}
+typeInfo=onlyRootTypeInfosByEventProto.get(curProto);if(typeInfo){primaryEventProtoToTypeInfoMap.set(event.__proto__,typeInfo);return typeInfo;}
+curProto=curProto.__proto__;}}
+AnalysisSubView.getEventsOrganizedByTypeInfo=function(selection){if(onlyRootTypeInfosByEventProto===undefined){rebuildRootSubViewTypeInfos();}
+const eventsByRootTypeInfo=tr.b.groupIntoMap(selection,function(event){return getRootTypeInfoForEvent(event);},this,tr.model.EventSet);const eventsByLowestTypeInfo=new Map();eventsByRootTypeInfo.forEach(function(events,typeInfo){const lowestTypeInfo=findLowestTypeInfoForEvents(typeInfo,events);eventsByLowestTypeInfo.set(lowestTypeInfo,events);});return eventsByLowestTypeInfo;};return{AnalysisSubView,AnalysisSubViewTypeInfo,};});Polymer({is:'tr-ui-a-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView]});'use strict';Polymer({is:'tr-ui-a-stack-frame',ready(){this.stackFrame_=undefined;this.$.table.tableColumns=[];this.$.table.showHeader=true;},get stackFrame(){return this.stackFrame_;},set stackFrame(stackFrame){const table=this.$.table;this.stackFrame_=stackFrame;if(stackFrame===undefined){table.tableColumns=[];table.tableRows=[];table.rebuild();return;}
+let hasName=false;let hasTitle=false;table.tableRows=stackFrame.stackTrace;table.tableRows.forEach(function(row){hasName|=row.name!==undefined;hasTitle|=row.title!==undefined;});const cols=[];if(hasName){cols.push({title:'Name',value(row){return row.name;}});}
+if(hasTitle){cols.push({title:'Title',value(row){return row.title;}});}
+table.tableColumns=cols;table.rebuild();},tableForTesting(){return this.$.table;}});'use strict';Polymer({is:'tr-ui-a-single-event-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],properties:{isFlow:{type:Boolean,value:false}},ready(){this.currentSelection_=undefined;this.$.table.tableColumns=[{title:'Label',value(row){return row.name;},width:'150px'},{title:'Value',width:'100%',value(row){return row.value;}}];this.$.table.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1){throw new Error('Only supports single slices');}
+this.setSelectionWithoutErrorChecks(selection);},setSelectionWithoutErrorChecks(selection){this.currentSelection_=selection;this.updateContents_();},getFlowEventRows_(event){const rows=this.getEventRowsHelper_(event);rows.splice(0,0,{name:'ID',value:event.id});function createLinkTo(slice){const linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(slice);});Polymer.dom(linkEl).textContent=slice.userFriendlyName;return linkEl;}
+rows.push({name:'From',value:createLinkTo(event.startSlice)});rows.push({name:'To',value:createLinkTo(event.endSlice)});return rows;},getEventRowsHelper_(event){const rows=[];if(event.error){rows.push({name:'Error',value:event.error});}
+if(event.title){let title=event.title;if(tr.isExported('tr-ui-e-chrome-codesearch')){const container=document.createElement('div');container.appendChild(document.createTextNode(title));const link=document.createElement('tr-ui-e-chrome-codesearch');link.searchPhrase=title;container.appendChild(link);title=container;}
+rows.push({name:'Title',value:title});}
+if(event.category){rows.push({name:'Category',value:event.category});}
+if(event.model!==undefined){const ufc=event.model.getUserFriendlyCategoryFromEvent(event);if(ufc!==undefined){rows.push({name:'User Friendly Category',value:ufc});}}
+if(event.name){rows.push({name:'Name',value:event.name});}
+rows.push({name:'Start',value:tr.v.ui.createScalarSpan(event.start,{unit:tr.b.Unit.byName.timeStampInMs})});if(event.duration){rows.push({name:'Wall Duration',value:tr.v.ui.createScalarSpan(event.duration,{unit:tr.b.Unit.byName.timeDurationInMs})});}
+if(event.cpuDuration){rows.push({name:'CPU Duration',value:tr.v.ui.createScalarSpan(event.cpuDuration,{unit:tr.b.Unit.byName.timeDurationInMs})});}
+if(event.subSlices!==undefined&&event.subSlices.length!==0){if(event.selfTime){rows.push({name:'Self Time',value:tr.v.ui.createScalarSpan(event.selfTime,{unit:tr.b.Unit.byName.timeDurationInMs})});}
+if(event.cpuSelfTime){const cpuSelfTimeEl=tr.v.ui.createScalarSpan(event.cpuSelfTime,{unit:tr.b.Unit.byName.timeDurationInMs});if(event.cpuSelfTime>event.selfTime){cpuSelfTimeEl.warning=' Note that CPU Self Time is larger than Self Time. '+'This is a known limitation of this system, which occurs '+'due to several subslices, rounding issues, and imprecise '+'time at which we get cpu- and real-time.';}
 rows.push({name:'CPU Self Time',value:cpuSelfTimeEl});}}
-if(event.durationInUserTime){rows.push({name:'Duration (U)',value:tr.v.ui.createScalarSpan(event.durationInUserTime,{unit:tr.v.Unit.byName.timeDurationInMs})});}
-function createStackFrameEl(sf){var sfEl=document.createElement('tr-ui-a-stack-frame');sfEl.stackFrame=sf;return sfEl;}
+if(event.durationInUserTime){rows.push({name:'Duration (U)',value:tr.v.ui.createScalarSpan(event.durationInUserTime,{unit:tr.b.Unit.byName.timeDurationInMs})});}
+function createStackFrameEl(sf){const sfEl=document.createElement('tr-ui-a-stack-frame');sfEl.stackFrame=sf;return sfEl;}
 if(event.startStackFrame&&event.endStackFrame){if(event.startStackFrame===event.endStackFrame){rows.push({name:'Start+End Stack Trace',value:createStackFrameEl(event.startStackFrame)});}else{rows.push({name:'Start Stack Trace',value:createStackFrameEl(event.startStackFrame)});rows.push({name:'End Stack Trace',value:createStackFrameEl(event.endStackFrame)});}}else if(event.startStackFrame){rows.push({name:'Start Stack Trace',value:createStackFrameEl(event.startStackFrame)});}else if(event.endStackFrame){rows.push({name:'End Stack Trace',value:createStackFrameEl(event.endStackFrame)});}
-if(event.info){var descriptionEl=tr.ui.b.createDiv({textContent:event.info.description,maxWidth:'300px'});rows.push({name:'Description',value:descriptionEl});if(event.info.docLinks){event.info.docLinks.forEach(function(linkObject){var linkEl=document.createElement('a');linkEl.target='_blank';linkEl.href=linkObject.href;linkEl.textContent=linkObject.textContent;rows.push({name:linkObject.label,value:linkEl});});}}
-if(event.associatedAlerts.length){var alertSubRows=[];event.associatedAlerts.forEach(function(alert){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(alert);},alert.info.description);alertSubRows.push({name:alert.title,value:linkEl});});rows.push({name:'Alerts',value:'',isExpanded:true,subRows:alertSubRows});}
-return rows;},addArgsToRows_:function(rows,args){var n=0;for(var argName in args){n+=1;}
-if(n>0){var subRows=[];for(var argName in args){var argView=document.createElement('tr-ui-a-generic-object-view');argView.object=args[argName];subRows.push({name:argName,value:argView});}
-rows.push({name:'Args',value:'',isExpanded:true,subRows:subRows});}
-return rows;},updateContents_:function(){if(this.currentSelection_===undefined){this.$.table.rows=[];this.$.table.rebuild();return;}
-var event=this.currentSelection_[0];var rows=this.getEventRows_(event);if(event.argsStripped)
-rows.push({name:'Args',value:'Stripped'});else
-this.addArgsToRows_(rows,event.args);var event=new tr.b.Event('customize-rows');event.rows=rows;this.dispatchEvent(event);this.$.table.tableRows=rows;this.$.table.rebuild();}});'use strict';Polymer('tr-ui-e-chrome-cc-raster-task-view',{created:function(){this.selection_=undefined;},set selection(selection){this.selection_=selection;this.updateContents_();},updateColumns_:function(hadCpuDurations){var timeSpanConfig={unit:tr.v.Unit.byName.timeDurationInMs,ownerDocument:this.ownerDocument};var columns=[{title:'Layer',value:function(row){if(row.isTotals)
-return'Totals';if(row.layer){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.ui.e.chrome.cc.LayerSelection(costs.layer);},'Layer '+row.layerId);return linkEl;}else{return'Layer '+row.layerId;}},width:'250px'},{title:'Num Tiles',value:function(row){return row.numTiles;},cmp:function(a,b){return a.numTiles-b.numTiles;}},{title:'Num Analysis Tasks',value:function(row){return row.numAnalysisTasks;},cmp:function(a,b){return a.numAnalysisTasks-b.numAnalysisTasks;}},{title:'Num Raster Tasks',value:function(row){return row.numRasterTasks;},cmp:function(a,b){return a.numRasterTasks-b.numRasterTasks;}},{title:'Wall Duration (ms)',value:function(row){return tr.v.ui.createScalarSpan(row.duration,timeSpanConfig);},cmp:function(a,b){return a.duration-b.duration;}}];if(hadCpuDurations){columns.push({title:'CPU Duration (ms)',value:function(row){return tr.v.ui.createScalarSpan(row.cpuDuration,timeSpanConfig);},cmp:function(a,b){return a.cpuDuration-b.cpuDuration;}});}
-var colWidthPercentage;if(columns.length==1)
-colWidthPercentage='100%';else
-colWidthPercentage=(100/(columns.length-1)).toFixed(3)+'%';for(var i=1;i<columns.length;i++)
-columns[i].width=colWidthPercentage;this.$.content.tableColumns=columns;this.$.content.sortColumnIndex=columns.length-1;},updateContents_:function(){var table=this.$.content;if(this.selection_.length===0){this.$.link.setSelectionAndContent(undefined,'');table.tableRows=[];table.footerRows=[];table.rebuild();return;}
-var lthi=tr.e.cc.getTileFromRasterTaskSlice(this.selection_[0]).containingSnapshot;this.$.link.setSelectionAndContent(function(){return new tr.model.EventSet(lthi);},lthi.userFriendlyName);var costsByLayerId={};function getCurrentCostsForLayerId(tile){var layerId=tile.layerId;var lthi=tile.containingSnapshot;var layer;if(lthi.activeTree)
-layer=lthi.activeTree.findLayerWithId(layerId);if(layer===undefined&&lthi.pendingTree)
-layer=lthi.pendingTree.findLayerWithId(layerId);if(costsByLayerId[layerId]===undefined){costsByLayerId[layerId]={layerId:layerId,layer:layer,numTiles:0,numAnalysisTasks:0,numRasterTasks:0,duration:0,cpuDuration:0};}
+if(event.info){const descriptionEl=tr.ui.b.createDiv({textContent:event.info.description,maxWidth:'300px'});rows.push({name:'Description',value:descriptionEl});if(event.info.docLinks){event.info.docLinks.forEach(function(linkObject){const linkEl=document.createElement('a');linkEl.target='_blank';linkEl.href=linkObject.href;Polymer.dom(linkEl).textContent=Polymer.dom(linkObject).textContent;rows.push({name:linkObject.label,value:linkEl});});}}
+if(event.associatedAlerts.length){const alertSubRows=[];event.associatedAlerts.forEach(function(alert){const linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(alert);},alert.info.description);alertSubRows.push({name:alert.title,value:linkEl});});rows.push({name:'Alerts',value:'',isExpanded:true,subRows:alertSubRows});}
+return rows;},getEventRows_(event){if(this.isFlow){return this.getFlowEventRows_(event);}
+return this.getEventRowsHelper_(event);},addArgsToRows_(rows,args){let n=0;for(const argName in args){n+=1;}
+if(n>0){const subRows=[];for(const argName in args){n+=1;}
+if(n>0){const subRows=[];for(const argName in args){const argView=document.createElement('tr-ui-a-generic-object-view');argView.object=args[argName];subRows.push({name:argName,value:argView});}
+rows.push({name:'Args',value:'',isExpanded:true,subRows});}}},addContextsToRows_(rows,contexts){if(contexts.length){const subRows=contexts.map(function(context){const contextView=document.createElement('tr-ui-a-generic-object-view');contextView.object=context;return{name:'Context',value:contextView};});rows.push({name:'Contexts',value:'',isExpanded:true,subRows});}},updateContents_(){if(this.currentSelection_===undefined){this.$.table.rows=[];this.$.table.rebuild();return;}
+const event=tr.b.getOnlyElement(this.currentSelection_);const rows=this.getEventRows_(event);if(event.argsStripped){rows.push({name:'Args',value:'Stripped'});}else{this.addArgsToRows_(rows,event.args);}
+this.addContextsToRows_(rows,event.contexts);const customizeRowsEvent=new tr.b.Event('customize-rows');customizeRowsEvent.rows=rows;this.dispatchEvent(customizeRowsEvent);this.$.table.tableRows=rows;this.$.table.rebuild();}});'use strict';Polymer({is:'tr-ui-e-chrome-cc-raster-task-view',created(){this.selection_=undefined;},set selection(selection){this.selection_=selection;this.updateContents_();},updateColumns_(hadCpuDurations){const timeSpanConfig={unit:tr.b.Unit.byName.timeDurationInMs,ownerDocument:this.ownerDocument};const columns=[{title:'Layer',value(row){if(row.isTotals)return'Totals';if(row.layer){const linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.ui.e.chrome.cc.LayerSelection(row.layer);},'Layer '+row.layerId);return linkEl;}
+return'Layer '+row.layerId;},width:'250px'},{title:'Num Tiles',value(row){return row.numTiles;},cmp(a,b){return a.numTiles-b.numTiles;}},{title:'Num Analysis Tasks',value(row){return row.numAnalysisTasks;},cmp(a,b){return a.numAnalysisTasks-b.numAnalysisTasks;}},{title:'Num Raster Tasks',value(row){return row.numRasterTasks;},cmp(a,b){return a.numRasterTasks-b.numRasterTasks;}},{title:'Wall Duration (ms)',value(row){return tr.v.ui.createScalarSpan(row.duration,timeSpanConfig);},cmp(a,b){return a.duration-b.duration;}}];if(hadCpuDurations){columns.push({title:'CPU Duration (ms)',value(row){return tr.v.ui.createScalarSpan(row.cpuDuration,timeSpanConfig);},cmp(a,b){return a.cpuDuration-b.cpuDuration;}});}
+let colWidthPercentage;if(columns.length===1){colWidthPercentage='100%';}else{colWidthPercentage=(100/(columns.length-1)).toFixed(3)+'%';}
+for(let i=1;i<columns.length;i++){columns[i].width=colWidthPercentage;}
+this.$.content.tableColumns=columns;this.$.content.sortColumnIndex=columns.length-1;},updateContents_(){const table=this.$.content;if(this.selection_.length===0){this.$.link.setSelectionAndContent(undefined,'');table.tableRows=[];table.footerRows=[];table.rebuild();return;}
+const lthi=tr.e.cc.getTileFromRasterTaskSlice(tr.b.getFirstElement(this.selection_)).containingSnapshot;this.$.link.setSelectionAndContent(function(){return new tr.model.EventSet(lthi);},lthi.userFriendlyName);const costsByLayerId={};function getCurrentCostsForLayerId(tile){const layerId=tile.layerId;const lthi=tile.containingSnapshot;let layer;if(lthi.activeTree){layer=lthi.activeTree.findLayerWithId(layerId);}
+if(layer===undefined&&lthi.pendingTree){layer=lthi.pendingTree.findLayerWithId(layerId);}
+if(costsByLayerId[layerId]===undefined){costsByLayerId[layerId]={layerId,layer,numTiles:0,numAnalysisTasks:0,numRasterTasks:0,duration:0,cpuDuration:0};}
 return costsByLayerId[layerId];}
-var totalDuration=0;var totalCpuDuration=0;var totalNumAnalyzeTasks=0;var totalNumRasterizeTasks=0;var hadCpuDurations=false;var tilesThatWeHaveSeen={};this.selection_.forEach(function(slice){var tile=tr.e.cc.getTileFromRasterTaskSlice(slice);var curCosts=getCurrentCostsForLayerId(tile);if(!tilesThatWeHaveSeen[tile.objectInstance.id]){tilesThatWeHaveSeen[tile.objectInstance.id]=true;curCosts.numTiles+=1;}
+let totalDuration=0;let totalCpuDuration=0;let totalNumAnalyzeTasks=0;let totalNumRasterizeTasks=0;let hadCpuDurations=false;const tilesThatWeHaveSeen={};this.selection_.forEach(function(slice){const tile=tr.e.cc.getTileFromRasterTaskSlice(slice);const curCosts=getCurrentCostsForLayerId(tile);if(!tilesThatWeHaveSeen[tile.objectInstance.id]){tilesThatWeHaveSeen[tile.objectInstance.id]=true;curCosts.numTiles+=1;}
 if(tr.e.cc.isSliceDoingAnalysis(slice)){curCosts.numAnalysisTasks+=1;totalNumAnalyzeTasks+=1;}else{curCosts.numRasterTasks+=1;totalNumRasterizeTasks+=1;}
-curCosts.duration+=slice.duration;totalDuration+=slice.duration;if(slice.cpuDuration!==undefined){curCosts.cpuDuration+=slice.cpuDuration;totalCpuDuration+=slice.cpuDuration;hadCpuDurations=true;}});this.updateColumns_(hadCpuDurations);table.tableRows=tr.b.dictionaryValues(costsByLayerId);table.rebuild();table.footerRows=[{isTotals:true,numTiles:tr.b.dictionaryLength(tilesThatWeHaveSeen),numAnalysisTasks:totalNumAnalyzeTasks,numRasterTasks:totalNumRasterizeTasks,duration:totalDuration,cpuDuration:totalCpuDuration}];}});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){function RasterTaskSelection(selection){tr.ui.e.chrome.cc.Selection.call(this);var whySupported=RasterTaskSelection.whySuported(selection);if(!whySupported.ok)
-throw new Error('Fail: '+whySupported.why);this.slices_=tr.b.asArray(selection);this.tiles_=this.slices_.map(function(slice){var tile=tr.e.cc.getTileFromRasterTaskSlice(slice);if(tile===undefined)
-throw new Error('This should never happen due to .supports check.');return tile;});}
-RasterTaskSelection.whySuported=function(selection){if(!(selection instanceof tr.model.EventSet))
-return{ok:false,why:'Must be selection'};if(selection.length===0)
-return{ok:false,why:'Selection must be non empty'};var tile0;for(var i=0;i<selection.length;i++){var event=selection[i];if(!(event instanceof tr.model.Slice))
-return{ok:false,why:'Not a slice'};var tile=tr.e.cc.getTileFromRasterTaskSlice(selection[i]);if(tile===undefined)
-return{ok:false,why:'No tile found'};if(i===0){tile0=tile;}else{if(tile.containingSnapshot!=tile0.containingSnapshot){return{ok:false,why:'Raster tasks are from different compositor instances'};}}}
-return{ok:true};}
-RasterTaskSelection.supports=function(selection){return RasterTaskSelection.whySuported(selection).ok;};RasterTaskSelection.prototype={__proto__:tr.ui.e.chrome.cc.Selection.prototype,get specicifity(){return 3;},get associatedLayerId(){var tile0=this.tiles_[0];var allSameLayer=this.tiles_.every(function(tile){tile.layerId==tile0.layerId;});if(allSameLayer)
-return tile0.layerId;return undefined;},get extraHighlightsByLayerId(){var highlights={};this.tiles_.forEach(function(tile,i){if(highlights[tile.layerId]===undefined)
-highlights[tile.layerId]=[];var slice=this.slices_[i];highlights[tile.layerId].push({colorKey:slice.title,rect:tile.layerRect});},this);return highlights;},createAnalysis:function(){var sel=new tr.model.EventSet();this.slices_.forEach(function(slice){sel.push(slice);});var analysis;if(sel.length==1)
-analysis=document.createElement('tr-ui-a-single-event-sub-view');else
-analysis=document.createElement('tr-ui-e-chrome-cc-raster-task-view');analysis.selection=sel;return analysis;},findEquivalent:function(lthi){return undefined;},get containingSnapshot(){return this.tiles_[0].containingSnapshot;}};return{RasterTaskSelection:RasterTaskSelection};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var TileSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-tile-snapshot-view',tr.ui.analysis.ObjectSnapshotView);TileSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-chrome-cc-tile-snapshot-view');this.layerTreeView_=new tr.ui.e.chrome.cc.LayerTreeHostImplSnapshotView();this.appendChild(this.layerTreeView_);},updateContents:function(){var tile=this.objectSnapshot_;var layerTreeHostImpl=tile.containingSnapshot;if(!layerTreeHostImpl)
-return;this.layerTreeView_.objectSnapshot=layerTreeHostImpl;this.layerTreeView_.selection=new tr.ui.e.chrome.cc.TileSelection(tile);}};tr.ui.analysis.ObjectSnapshotView.register(TileSnapshotView,{typeName:'cc::Tile',showInTrackView:false});return{TileSnapshotView:TileSnapshotView};});'use strict';tr.exportTo('tr.e.gpu',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function StateSnapshot(){ObjectSnapshot.apply(this,arguments);}
-StateSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){this.screenshot_=undefined;},initialize:function(){if(this.args.screenshot)
-this.screenshot_=this.args.screenshot;},get screenshot(){return this.screenshot_;}};ObjectSnapshot.register(StateSnapshot,{typeName:'gpu::State'});return{StateSnapshot:StateSnapshot};});'use strict';tr.exportTo('tr.e.gpu',function(){var AsyncSlice=tr.model.AsyncSlice;function GpuAsyncSlice(){AsyncSlice.apply(this,arguments);}
-GpuAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get viewSubGroupTitle(){if(this.args.channel){if(this.category=='disabled-by-default-gpu.device')
-return'Device.'+this.args.channel;else
+curCosts.duration+=slice.duration;totalDuration+=slice.duration;if(slice.cpuDuration!==undefined){curCosts.cpuDuration+=slice.cpuDuration;totalCpuDuration+=slice.cpuDuration;hadCpuDurations=true;}});this.updateColumns_(hadCpuDurations);table.tableRows=Object.values(costsByLayerId);table.rebuild();table.footerRows=[{isTotals:true,numTiles:Object.keys(tilesThatWeHaveSeen).length,numAnalysisTasks:totalNumAnalyzeTasks,numRasterTasks:totalNumRasterizeTasks,duration:totalDuration,cpuDuration:totalCpuDuration}];}});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){function RasterTaskSelection(selection){tr.ui.e.chrome.cc.Selection.call(this);const whySupported=RasterTaskSelection.whySuported(selection);if(!whySupported.ok){throw new Error('Fail: '+whySupported.why);}
+this.slices_=Array.from(selection);this.tiles_=this.slices_.map(function(slice){const tile=tr.e.cc.getTileFromRasterTaskSlice(slice);if(tile===undefined){throw new Error('This should never happen due to .supports check.');}
+return tile;});}
+RasterTaskSelection.whySuported=function(selection){if(!(selection instanceof tr.model.EventSet)){return{ok:false,why:'Must be selection'};}
+if(selection.length===0){return{ok:false,why:'Selection must be non empty'};}
+let referenceSnapshot=undefined;for(const event of selection){if(!(event instanceof tr.model.Slice)){return{ok:false,why:'Not a slice'};}
+const tile=tr.e.cc.getTileFromRasterTaskSlice(event);if(tile===undefined){return{ok:false,why:'No tile found'};}
+if(!referenceSnapshot){referenceSnapshot=tile.containingSnapshot;}else{if(tile.containingSnapshot!==referenceSnapshot){return{ok:false,why:'Raster tasks are from different compositor instances'};}}}
+return{ok:true};};RasterTaskSelection.supports=function(selection){return RasterTaskSelection.whySuported(selection).ok;};RasterTaskSelection.prototype={__proto__:tr.ui.e.chrome.cc.Selection.prototype,get specicifity(){return 3;},get associatedLayerId(){const tile0=this.tiles_[0];const allSameLayer=this.tiles_.every(function(tile){tile.layerId===tile0.layerId;});if(allSameLayer){return tile0.layerId;}
+return undefined;},get extraHighlightsByLayerId(){const highlights={};this.tiles_.forEach(function(tile,i){if(highlights[tile.layerId]===undefined){highlights[tile.layerId]=[];}
+const slice=this.slices_[i];highlights[tile.layerId].push({colorKey:slice.title,rect:tile.layerRect});},this);return highlights;},createAnalysis(){const sel=new tr.model.EventSet();this.slices_.forEach(function(slice){sel.push(slice);});let analysis;if(sel.length===1){analysis=document.createElement('tr-ui-a-single-event-sub-view');}else{analysis=document.createElement('tr-ui-e-chrome-cc-raster-task-view');}
+analysis.selection=sel;return analysis;},findEquivalent(lthi){return undefined;},get containingSnapshot(){return this.tiles_[0].containingSnapshot;}};return{RasterTaskSelection,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const TileSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-tile-snapshot-view',tr.ui.analysis.ObjectSnapshotView);TileSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate(){Polymer.dom(this).classList.add('tr-ui-e-chrome-cc-tile-snapshot-view');this.layerTreeView_=new tr.ui.e.chrome.cc.LayerTreeHostImplSnapshotView();Polymer.dom(this).appendChild(this.layerTreeView_);},updateContents(){const tile=this.objectSnapshot_;const layerTreeHostImpl=tile.containingSnapshot;if(!layerTreeHostImpl)return;this.layerTreeView_.objectSnapshot=layerTreeHostImpl;this.layerTreeView_.selection=new tr.ui.e.chrome.cc.TileSelection(tile);}};tr.ui.analysis.ObjectSnapshotView.register(TileSnapshotView,{typeName:'cc::Tile',showInTrackView:false});return{TileSnapshotView,};});'use strict';tr.exportTo('tr.ui.e.chrome',function(){Polymer({is:'tr-ui-e-chrome-codesearch',set searchPhrase(phrase){const link=Polymer.dom(this.$.codesearchLink);const codeSearchURL='https://cs.chromium.org/search/?sq=package:chromium&type=cs&q=';link.setAttribute('href',codeSearchURL+encodeURIComponent(phrase));},onClick(clickEvent){clickEvent.stopPropagation();}});return{};});'use strict';tr.exportTo('tr.e.gpu',function(){const AsyncSlice=tr.model.AsyncSlice;function GpuAsyncSlice(){AsyncSlice.apply(this,arguments);}
+GpuAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get viewSubGroupTitle(){if(this.args.channel){if(this.category==='disabled-by-default-gpu.device'){return'Device.'+this.args.channel;}
 return'Service.'+this.args.channel;}
-return this.title;}};AsyncSlice.register(GpuAsyncSlice,{categoryParts:['disabled-by-default-gpu.device','disabled-by-default-gpu.service']});return{GpuAsyncSlice:GpuAsyncSlice};});'use strict';tr.exportTo('tr.ui.e.chrome.gpu',function(){var StateSnapshotView=tr.ui.b.define('tr-ui-e-chrome-gpu-state-snapshot-view',tr.ui.analysis.ObjectSnapshotView);StateSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-chrome-gpu-state-snapshot-view');this.screenshotImage_=document.createElement('img');this.appendChild(this.screenshotImage_);},updateContents:function(){if(this.objectSnapshot_&&this.objectSnapshot_.screenshot){this.screenshotImage_.src='data:image/png;base64,'+
-this.objectSnapshot_.screenshot;}}};tr.ui.analysis.ObjectSnapshotView.register(StateSnapshotView,{typeName:'gpu::State'});return{StateSnapshotView:StateSnapshotView};});!function(){function n(n){return null!=n&&!isNaN(n)}function t(n){return n.length}function e(n){for(var t=1;n*t%1;)t*=10;return t}function r(n,t){try{for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}catch(r){n.prototype=t}}function u(){}function i(n){return aa+n in this}function o(n){return n=aa+n,n in this&&delete this[n]}function a(){var n=[];return this.forEach(function(t){n.push(t)}),n}function c(){var n=0;for(var t in this)t.charCodeAt(0)===ca&&++n;return n}function s(){for(var n in this)if(n.charCodeAt(0)===ca)return!1;return!0}function l(){}function f(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function h(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.substring(1);for(var e=0,r=sa.length;r>e;++e){var u=sa[e]+t;if(u in n)return u}}function g(){}function p(){}function v(n){function t(){for(var t,r=e,u=-1,i=r.length;++u<i;)(t=r[u].on)&&t.apply(this,arguments);return n}var e=[],r=new u;return t.on=function(t,u){var i,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,i=e.indexOf(o)).concat(e.slice(i+1)),r.remove(t)),u&&e.push(r.set(t,{on:u})),n)},t}function d(){Xo.event.preventDefault()}function m(){for(var n,t=Xo.event;n=t.sourceEvent;)t=n;return t}function y(n){for(var t=new p,e=0,r=arguments.length;++e<r;)t[arguments[e]]=v(t);return t.of=function(e,r){return function(u){try{var i=u.sourceEvent=Xo.event;u.target=n,Xo.event=u,t[u.type].apply(e,r)}finally{Xo.event=i}}},t}function x(n){return fa(n,da),n}function M(n){return"function"==typeof n?n:function(){return ha(n,this)}}function _(n){return"function"==typeof n?n:function(){return ga(n,this)}}function b(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function u(){this.setAttribute(n,t)}function i(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=Xo.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?i:u}function w(n){return n.trim().replace(/\s+/g," ")}function S(n){return new RegExp("(?:^|\\s+)"+Xo.requote(n)+"(?:\\s+|$)","g")}function k(n){return n.trim().split(/^|\s+/)}function E(n,t){function e(){for(var e=-1;++e<u;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<u;)n[e](this,r)}n=k(n).map(A);var u=n.length;return"function"==typeof t?r:e}function A(n){var t=S(n);return function(e,r){if(u=e.classList)return r?u.add(n):u.remove(n);var u=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(u)||e.setAttribute("class",w(u+" "+n))):e.setAttribute("class",w(u.replace(t," ")))}}function C(n,t,e){function r(){this.style.removeProperty(n)}function u(){this.style.setProperty(n,t,e)}function i(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?i:u}function N(n,t){function e(){delete this[n]}function r(){this[n]=t}function u(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?u:r}function L(n){return"function"==typeof n?n:(n=Xo.ns.qualify(n)).local?function(){return this.ownerDocument.createElementNS(n.space,n.local)}:function(){return this.ownerDocument.createElementNS(this.namespaceURI,n)}}function T(n){return{__data__:n}}function q(n){return function(){return va(this,n)}}function z(n){return arguments.length||(n=Xo.ascending),function(t,e){return t&&e?n(t.__data__,e.__data__):!t-!e}}function R(n,t){for(var e=0,r=n.length;r>e;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function D(n){return fa(n,ya),n}function P(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t<c;);return o}}function U(){var n=this.__transition__;n&&++n.active}function j(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function u(){var u=c(t,Bo(arguments));r.call(this),this.addEventListener(n,this[o]=u,u.$=e),u._=t}function i(){var t,e=new RegExp("^__on([^.]+)"+Xo.requote(n)+"$");for(var r in this)if(t=r.match(e)){var u=this[r];this.removeEventListener(t[1],u,u.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),c=H;a>0&&(n=n.substring(0,a));var s=Ma.get(n);return s&&(n=s,c=F),a?t?u:r:t?g:i}function H(n,t){return function(e){var r=Xo.event;Xo.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{Xo.event=r}}}function F(n,t){var e=H(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function O(){var n=".dragsuppress-"+ ++ba,t="click"+n,e=Xo.select(Go).on("touchmove"+n,d).on("dragstart"+n,d).on("selectstart"+n,d);if(_a){var r=Jo.style,u=r[_a];r[_a]="none"}return function(i){function o(){e.on(t,null)}e.on(n,null),_a&&(r[_a]=u),i&&(e.on(t,function(){d(),o()},!0),setTimeout(o,0))}}function Y(n,t){t.changedTouches&&(t=t.changedTouches[0]);var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>wa&&(Go.scrollX||Go.scrollY)){e=Xo.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var u=e[0][0].getScreenCTM();wa=!(u.f||u.e),e.remove()}return wa?(r.x=t.pageX,r.y=t.pageY):(r.x=t.clientX,r.y=t.clientY),r=r.matrixTransform(n.getScreenCTM().inverse()),[r.x,r.y]}var i=n.getBoundingClientRect();return[t.clientX-i.left-n.clientLeft,t.clientY-i.top-n.clientTop]}function I(n){return n>0?1:0>n?-1:0}function Z(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function V(n){return n>1?0:-1>n?Sa:Math.acos(n)}function X(n){return n>1?Ea:-1>n?-Ea:Math.asin(n)}function $(n){return((n=Math.exp(n))-1/n)/2}function B(n){return((n=Math.exp(n))+1/n)/2}function W(n){return((n=Math.exp(2*n))-1)/(n+1)}function J(n){return(n=Math.sin(n/2))*n}function G(){}function K(n,t,e){return new Q(n,t,e)}function Q(n,t,e){this.h=n,this.s=t,this.l=e}function nt(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,gt(u(n+120),u(n),u(n-120))}function tt(n,t,e){return new et(n,t,e)}function et(n,t,e){this.h=n,this.c=t,this.l=e}function rt(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),ut(e,Math.cos(n*=Na)*t,Math.sin(n)*t)}function ut(n,t,e){return new it(n,t,e)}function it(n,t,e){this.l=n,this.a=t,this.b=e}function ot(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=ct(u)*Fa,r=ct(r)*Oa,i=ct(i)*Ya,gt(lt(3.2404542*u-1.5371385*r-.4985314*i),lt(-.969266*u+1.8760108*r+.041556*i),lt(.0556434*u-.2040259*r+1.0572252*i))}function at(n,t,e){return n>0?tt(Math.atan2(e,t)*La,Math.sqrt(t*t+e*e),n):tt(0/0,0/0,n)}function ct(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function st(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function lt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function ft(n){return gt(n>>16,255&n>>8,255&n)}function ht(n){return ft(n)+""}function gt(n,t,e){return new pt(n,t,e)}function pt(n,t,e){this.r=n,this.g=t,this.b=e}function vt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function dt(n,t,e){var r,u,i,o,a=0,c=0,s=0;if(u=/([a-z]+)\((.*)\)/i.exec(n))switch(i=u[2].split(","),u[1]){case"hsl":return e(parseFloat(i[0]),parseFloat(i[1])/100,parseFloat(i[2])/100);case"rgb":return t(Mt(i[0]),Mt(i[1]),Mt(i[2]))}return(o=Va.get(n))?t(o.r,o.g,o.b):(null!=n&&"#"===n.charAt(0)&&(r=parseInt(n.substring(1),16),isNaN(r)||(4===n.length?(a=(3840&r)>>4,a=a>>4|a,c=240&r,c=c>>4|c,s=15&r,s=s<<4|s):7===n.length&&(a=(16711680&r)>>16,c=(65280&r)>>8,s=255&r))),t(a,c,s))}function mt(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),K(r,u,c)}function yt(n,t,e){n=xt(n),t=xt(t),e=xt(e);var r=st((.4124564*n+.3575761*t+.1804375*e)/Fa),u=st((.2126729*n+.7151522*t+.072175*e)/Oa),i=st((.0193339*n+.119192*t+.9503041*e)/Ya);return ut(116*u-16,500*(r-u),200*(u-i))}function xt(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function Mt(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function _t(n){return"function"==typeof n?n:function(){return n}}function bt(n){return n}function wt(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),St(t,e,n,r)}}function St(n,t,e,r){function u(){var n,t=c.status;if(!t&&c.responseText||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return o.error.call(i,r),void 0}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=Xo.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,s=null;return!Go.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=Xo.event;Xo.event=n;try{o.progress.call(i,c)}finally{Xo.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(s=n,i):s},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(Bo(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var l in a)c.setRequestHeader(l,a[l]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=s&&(c.responseType=s),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},Xo.rebind(i,o,"on"),null==r?i:i.get(kt(r))}function kt(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Et(){var n=At(),t=Ct()-n;t>24?(isFinite(t)&&(clearTimeout(Wa),Wa=setTimeout(Et,t)),Ba=0):(Ba=1,Ga(Et))}function At(){var n=Date.now();for(Ja=Xa;Ja;)n>=Ja.t&&(Ja.f=Ja.c(n-Ja.t)),Ja=Ja.n;return n}function Ct(){for(var n,t=Xa,e=1/0;t;)t.f?t=n?n.n=t.n:Xa=t.n:(t.t<e&&(e=t.t),t=(n=t).n);return $a=n,e}function Nt(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Lt(n,t){var e=Math.pow(10,3*oa(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Tt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r?function(n){for(var t=n.length,u=[],i=0,o=r[0];t>0&&o>0;)u.push(n.substring(t-=o,t+o)),o=r[i=(i+1)%r.length];return u.reverse().join(e)}:bt;return function(n){var e=Qa.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"",c=e[4]||"",s=e[5],l=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1;switch(h&&(h=+h.substring(1)),(s||"0"===r&&"="===o)&&(s=r="0",o="=",f&&(l-=Math.floor((l-1)/4))),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=nc.get(g)||qt;var y=s&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):a;if(0>p){var c=Xo.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x=n.lastIndexOf("."),M=0>x?n:n.substring(0,x),_=0>x?"":t+n.substring(x+1);!s&&f&&(M=i(M));var b=v.length+M.length+_.length+(y?0:u.length),w=l>b?new Array(b=l-b+1).join(r):"";return y&&(M=i(w+M)),u+=v,n=M+_,("<"===o?u+n+w:">"===o?w+u+n:"^"===o?w.substring(0,b>>=1)+u+n+w.substring(b):u+(y?n:w+n))+e}}}function qt(n){return n+""}function zt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Rt(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new ec(e-1)),1),e}function i(n,e){return t(n=new ec(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{ec=zt;var r=new zt;return r._=n,o(r,t,e)}finally{ec=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Dt(n);return c.floor=c,c.round=Dt(r),c.ceil=Dt(u),c.offset=Dt(i),c.range=a,n}function Dt(n){return function(t,e){try{ec=zt;var r=new zt;return r._=t,n(r,e)._}finally{ec=Date}}}function Pt(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.substring(c,a)),null!=(u=uc[e=n.charAt(++a)])&&(e=n.charAt(++a)),(i=C[e])&&(e=i(t,null==u?"e"===e?" ":"0":u)),o.push(e),c=a+1);return o.push(n.substring(c,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},u=e(r,n,t,0);if(u!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var i=null!=r.Z&&ec!==zt,o=new(i?zt:ec);return"j"in r?o.setFullYear(r.y,0,r.j):"w"in r&&("W"in r||"U"in r)?(o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+Math.floor(r.Z/100),r.M+r.Z%100,r.S,r.L),i?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var u,i,o,a=0,c=t.length,s=e.length;c>a;){if(r>=s)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=N[o in uc?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){b.lastIndex=0;var r=b.exec(t.substring(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){M.lastIndex=0;var r=M.exec(t.substring(e));return r?(n.w=_.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.substring(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.substring(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,C.c.toString(),t,r)}function c(n,t,r){return e(n,C.x.toString(),t,r)}function s(n,t,r){return e(n,C.X.toString(),t,r)}function l(n,t,e){var r=x.get(t.substring(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{ec=zt;var t=new ec;return t._=n,r(t)}finally{ec=Date}}var r=t(n);return e.parse=function(n){try{ec=zt;var t=r.parse(n);return t&&t._}finally{ec=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ee;var x=Xo.map(),M=jt(v),_=Ht(v),b=jt(d),w=Ht(d),S=jt(m),k=Ht(m),E=jt(y),A=Ht(y);p.forEach(function(n,t){x.set(n.toLowerCase(),t)});var C={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return Ut(n.getDate(),t,2)},e:function(n,t){return Ut(n.getDate(),t,2)},H:function(n,t){return Ut(n.getHours(),t,2)},I:function(n,t){return Ut(n.getHours()%12||12,t,2)},j:function(n,t){return Ut(1+tc.dayOfYear(n),t,3)},L:function(n,t){return Ut(n.getMilliseconds(),t,3)},m:function(n,t){return Ut(n.getMonth()+1,t,2)},M:function(n,t){return Ut(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return Ut(n.getSeconds(),t,2)},U:function(n,t){return Ut(tc.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Ut(tc.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return Ut(n.getFullYear()%100,t,2)},Y:function(n,t){return Ut(n.getFullYear()%1e4,t,4)},Z:ne,"%":function(){return"%"}},N={a:r,A:u,b:i,B:o,c:a,d:Bt,e:Bt,H:Jt,I:Jt,j:Wt,L:Qt,m:$t,M:Gt,p:l,S:Kt,U:Ot,w:Ft,W:Yt,x:c,X:s,y:Zt,Y:It,Z:Vt,"%":te};return t}function Ut(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function jt(n){return new RegExp("^(?:"+n.map(Xo.requote).join("|")+")","i")}function Ht(n){for(var t=new u,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function Ft(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Ot(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e));return r?(n.U=+r[0],e+r[0].length):-1}function Yt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e));return r?(n.W=+r[0],e+r[0].length):-1}function It(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Zt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.y=Xt(+r[0]),e+r[0].length):-1}function Vt(n,t,e){return/^[+-]\d{4}$/.test(t=t.substring(e,e+5))?(n.Z=+t,e+5):-1}function Xt(n){return n+(n>68?1900:2e3)}function $t(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Bt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function Wt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function Jt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function Gt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function Kt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function Qt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ne(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=~~(oa(t)/60),u=oa(t)%60;return e+Ut(r,"0",2)+Ut(u,"0",2)}function te(n,t,e){oc.lastIndex=0;var r=oc.exec(t.substring(e,e+1));return r?e+r[0].length:-1}function ee(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function re(){}function ue(n,t,e){var r=e.s=n+t,u=r-n,i=r-u;e.t=n-i+(t-u)}function ie(n,t){n&&lc.hasOwnProperty(n.type)&&lc[n.type](n,t)}function oe(n,t,e){var r,u=-1,i=n.length-e;for(t.lineStart();++u<i;)r=n[u],t.point(r[0],r[1],r[2]);t.lineEnd()}function ae(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)oe(n[e],t,1);t.polygonEnd()}function ce(){function n(n,t){n*=Na,t=t*Na/2+Sa/4;var e=n-r,o=e>=0?1:-1,a=o*e,c=Math.cos(t),s=Math.sin(t),l=i*s,f=u*c+l*Math.cos(a),h=l*o*Math.sin(a);hc.add(Math.atan2(h,f)),r=n,u=c,i=s}var t,e,r,u,i;gc.point=function(o,a){gc.point=n,r=(t=o)*Na,u=Math.cos(a=(e=a)*Na/2+Sa/4),i=Math.sin(a)},gc.lineEnd=function(){n(t,e)}}function se(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function le(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function fe(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function he(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ge(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function pe(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function ve(n){return[Math.atan2(n[1],n[0]),X(n[2])]}function de(n,t){return oa(n[0]-t[0])<Aa&&oa(n[1]-t[1])<Aa}function me(n,t){n*=Na;var e=Math.cos(t*=Na);ye(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function ye(n,t,e){++pc,dc+=(n-dc)/pc,mc+=(t-mc)/pc,yc+=(e-yc)/pc}function xe(){function n(n,u){n*=Na;var i=Math.cos(u*=Na),o=i*Math.cos(n),a=i*Math.sin(n),c=Math.sin(u),s=Math.atan2(Math.sqrt((s=e*c-r*a)*s+(s=r*o-t*c)*s+(s=t*a-e*o)*s),t*o+e*a+r*c);vc+=s,xc+=s*(t+(t=o)),Mc+=s*(e+(e=a)),_c+=s*(r+(r=c)),ye(t,e,r)}var t,e,r;kc.point=function(u,i){u*=Na;var o=Math.cos(i*=Na);t=o*Math.cos(u),e=o*Math.sin(u),r=Math.sin(i),kc.point=n,ye(t,e,r)}}function Me(){kc.point=me}function _e(){function n(n,t){n*=Na;var e=Math.cos(t*=Na),o=e*Math.cos(n),a=e*Math.sin(n),c=Math.sin(t),s=u*c-i*a,l=i*o-r*c,f=r*a-u*o,h=Math.sqrt(s*s+l*l+f*f),g=r*o+u*a+i*c,p=h&&-V(g)/h,v=Math.atan2(h,g);bc+=p*s,wc+=p*l,Sc+=p*f,vc+=v,xc+=v*(r+(r=o)),Mc+=v*(u+(u=a)),_c+=v*(i+(i=c)),ye(r,u,i)}var t,e,r,u,i;kc.point=function(o,a){t=o,e=a,kc.point=n,o*=Na;var c=Math.cos(a*=Na);r=c*Math.cos(o),u=c*Math.sin(o),i=Math.sin(a),ye(r,u,i)},kc.lineEnd=function(){n(t,e),kc.lineEnd=Me,kc.point=me}}function be(){return!0}function we(n,t,e,r,u){var i=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(de(e,r)){u.lineStart();for(var a=0;t>a;++a)u.point((e=n[a])[0],e[1]);return u.lineEnd(),void 0}var c=new ke(e,n,null,!0),s=new ke(e,null,c,!1);c.o=s,i.push(c),o.push(s),c=new ke(r,n,null,!1),s=new ke(r,null,c,!0),c.o=s,i.push(c),o.push(s)}}),o.sort(t),Se(i),Se(o),i.length){for(var a=0,c=e,s=o.length;s>a;++a)o[a].e=c=!c;for(var l,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;l=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,s=l.length;s>a;++a)u.point((f=l[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){l=g.p.z;for(var a=l.length-1;a>=0;--a)u.point((f=l[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,l=g.z,p=!p}while(!g.v);u.lineEnd()}}}function Se(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r<t;)u.n=e=n[r],e.p=u,u=e;u.n=e=n[0],e.p=u}}function ke(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Ee(n,t,e,r){return function(u,i){function o(t,e){var r=u(t,e);n(t=r[0],e=r[1])&&i.point(t,e)}function a(n,t){var e=u(n,t);d.point(e[0],e[1])}function c(){y.point=a,d.lineStart()}function s(){y.point=o,d.lineEnd()}function l(n,t){v.push([n,t]);var e=u(n,t);M.point(e[0],e[1])}function f(){M.lineStart(),v=[]}function h(){l(v[0][0],v[0][1]),M.lineEnd();var n,t=M.clean(),e=x.buffer(),r=e.length;if(v.pop(),p.push(v),v=null,r){if(1&t){n=e[0];var u,r=n.length-1,o=-1;for(i.lineStart();++o<r;)i.point((u=n[o])[0],u[1]);return i.lineEnd(),void 0}r>1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Ae))}}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:s,polygonStart:function(){y.point=l,y.lineStart=f,y.lineEnd=h,g=[],p=[],i.polygonStart()},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=s,g=Xo.merge(g);var n=Le(m,p);g.length?we(g,Ne,n,e,i):n&&(i.lineStart(),e(null,null,1,i),i.lineEnd()),i.polygonEnd(),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},x=Ce(),M=t(x);return y}}function Ae(n){return n.length>1}function Ce(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:g,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Ne(n,t){return((n=n.x)[0]<0?n[1]-Ea-Aa:Ea-n[1])-((t=t.x)[0]<0?t[1]-Ea-Aa:Ea-t[1])}function Le(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;hc.reset();for(var a=0,c=t.length;c>a;++a){var s=t[a],l=s.length;if(l)for(var f=s[0],h=f[0],g=f[1]/2+Sa/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===l&&(d=0),n=s[d];var m=n[0],y=n[1]/2+Sa/4,x=Math.sin(y),M=Math.cos(y),_=m-h,b=_>=0?1:-1,w=b*_,S=w>Sa,k=p*x;if(hc.add(Math.atan2(k*b*Math.sin(w),v*M+k*Math.cos(w))),i+=S?_+b*ka:_,S^h>=e^m>=e){var E=fe(se(f),se(n));pe(E);var A=fe(u,E);pe(A);var C=(S^_>=0?-1:1)*X(A[2]);(r>C||r===C&&(E[0]||E[1]))&&(o+=S^_>=0?1:-1)}if(!d++)break;h=m,p=x,v=M,f=n}}return(-Aa>i||Aa>i&&0>hc)^1&o}function Te(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?Sa:-Sa,c=oa(i-e);oa(c-Sa)<Aa?(n.point(e,r=(r+o)/2>0?Ea:-Ea),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=Sa&&(oa(e-u)<Aa&&(e-=u*Aa),oa(i-a)<Aa&&(i-=a*Aa),r=qe(e,r,i,o),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=i,r=o),u=a},lineEnd:function(){n.lineEnd(),e=r=0/0},clean:function(){return 2-t}}}function qe(n,t,e,r){var u,i,o=Math.sin(n-e);return oa(o)>Aa?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function ze(n,t,e,r){var u;if(null==n)u=e*Ea,r.point(-Sa,u),r.point(0,u),r.point(Sa,u),r.point(Sa,0),r.point(Sa,-u),r.point(0,-u),r.point(-Sa,-u),r.point(-Sa,0),r.point(-Sa,u);else if(oa(n[0]-t[0])>Aa){var i=n[0]<t[0]?Sa:-Sa;u=e*i/2,r.point(-i,u),r.point(0,u),r.point(i,u)}else r.point(t[0],t[1])}function Re(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,s,l;return{lineStart:function(){s=c=!1,l=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?Sa:-Sa),h):0;if(!e&&(s=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(de(e,g)||de(p,g))&&(p[0]+=Aa,p[1]+=Aa,v=t(p[0],p[1]))),v!==c)l=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(l=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&de(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return l|(s&&c)<<1}}}function r(n,t,e){var r=se(n),u=se(t),o=[1,0,0],a=fe(r,u),c=le(a,a),s=a[0],l=c-s*s;if(!l)return!e&&n;var f=i*c/l,h=-i*s/l,g=fe(o,a),p=ge(o,f),v=ge(a,h);he(p,v);var d=g,m=le(p,d),y=le(d,d),x=m*m-y*(le(p,p)-1);if(!(0>x)){var M=Math.sqrt(x),_=ge(d,(-m-M)/y);if(he(_,p),_=ve(_),!e)return _;var b,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(b=w,w=S,S=b);var A=S-w,C=oa(A-Sa)<Aa,N=C||Aa>A;if(!C&&k>E&&(b=k,k=E,E=b),N?C?k+E>0^_[1]<(oa(_[0]-w)<Aa?k:E):k<=_[1]&&_[1]<=E:A>Sa^(w<=_[0]&&_[0]<=S)){var L=ge(d,(-m+M)/y);return he(L,p),[_,ve(L)]}}}function u(t,e){var r=o?n:Sa-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=oa(i)>Aa,c=cr(n,6*Na);return Ee(t,e,c,o?[0,-n]:[-Sa,n-Sa])}function De(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,s=o.y,l=a.x,f=a.y,h=0,g=1,p=l-c,v=f-s;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-s,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-s,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:s+h*v}),1>g&&(u.b={x:c+g*p,y:s+g*v}),u}}}}}}function Pe(n,t,e,r){function u(r,u){return oa(r[0]-n)<Aa?u>0?0:3:oa(r[0]-e)<Aa?u>0?2:1:oa(r[1]-t)<Aa?u>0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,s=a[0];c>o;++o)i=a[o],s[1]<=r?i[1]>r&&Z(s,i,n)>0&&++t:i[1]<=r&&Z(s,i,n)<0&&--t,s=i;return 0!==t}function s(i,a,c,s){var l=0,f=0;if(null==i||(l=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do s.point(0===l||3===l?n:e,l>1?r:t);while((l=(l+c+4)%4)!==f)}else s.point(a[0],a[1])}function l(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){l(n,t)&&a.point(n,t)}function h(){N.point=p,d&&d.push(m=[]),S=!0,w=!1,_=b=0/0}function g(){v&&(p(y,x),M&&w&&A.rejoin(),v.push(A.buffer())),N.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Ac,Math.min(Ac,n)),t=Math.max(-Ac,Math.min(Ac,t));var e=l(n,t);if(d&&m.push([n,t]),S)y=n,x=t,M=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:_,y:b},b:{x:n,y:t}};C(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}_=n,b=t,w=e}var v,d,m,y,x,M,_,b,w,S,k,E=a,A=Ce(),C=De(n,t,e,r),N={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=Xo.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),s(null,null,1,a),a.lineEnd()),u&&we(v,i,t,s,a),a.polygonEnd()),v=d=m=null}};return N}}function Ue(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function je(n){var t=0,e=Sa/3,r=nr(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*Sa/180,e=n[1]*Sa/180):[180*(t/Sa),180*(e/Sa)]},u}function He(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,X((i-(n*n+e*e)*u*u)/(2*u))]},e}function Fe(){function n(n,t){Nc+=u*n-r*t,r=n,u=t}var t,e,r,u;Rc.point=function(i,o){Rc.point=n,t=r=i,e=u=o},Rc.lineEnd=function(){n(t,e)}}function Oe(n,t){Lc>n&&(Lc=n),n>qc&&(qc=n),Tc>t&&(Tc=t),t>zc&&(zc=t)}function Ye(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Ie(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Ie(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Ie(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Ze(n,t){dc+=n,mc+=t,++yc}function Ve(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);xc+=o*(t+n)/2,Mc+=o*(e+r)/2,_c+=o,Ze(t=n,e=r)}var t,e;Pc.point=function(r,u){Pc.point=n,Ze(t=r,e=u)}}function Xe(){Pc.point=Ze}function $e(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);xc+=o*(r+n)/2,Mc+=o*(u+t)/2,_c+=o,o=u*n-r*t,bc+=o*(r+n),wc+=o*(u+t),Sc+=3*o,Ze(r=n,u=t)}var t,e,r,u;Pc.point=function(i,o){Pc.point=n,Ze(t=r=i,e=u=o)},Pc.lineEnd=function(){n(t,e)}}function Be(n){function t(t,e){n.moveTo(t,e),n.arc(t,e,o,0,ka)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:g};return a}function We(n){function t(n){return(a?r:e)(n)}function e(t){return Ke(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){x=0/0,S.point=i,t.lineStart()}function i(e,r){var i=se([e,r]),o=n(e,r);u(x,M,y,_,b,w,x=o[0],M=o[1],y=e,_=i[0],b=i[1],w=i[2],a,t),t.point(x,M)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=s,S.lineEnd=l}function s(n,t){i(f=n,h=t),g=x,p=M,v=_,d=b,m=w,S.point=i}function l(){u(x,M,y,_,b,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,x,M,_,b,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,s,l,f,h,g,p,v,d,m){var y=l-t,x=f-e,M=y*y+x*x;if(M>4*i&&d--){var _=a+g,b=c+p,w=s+v,S=Math.sqrt(_*_+b*b+w*w),k=Math.asin(w/=S),E=oa(oa(w)-1)<Aa||oa(r-h)<Aa?(r+h)/2:Math.atan2(b,_),A=n(E,k),C=A[0],N=A[1],L=C-t,T=N-e,q=x*L-y*T;(q*q/M>i||oa((y*L+x*T)/M-.5)>.3||o>a*g+c*p+s*v)&&(u(t,e,r,a,c,s,C,N,E,_/=S,b/=S,w,d,m),m.point(C,N),u(C,N,E,_,b,w,l,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Na),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function Je(n){var t=We(function(t,e){return n([t*La,e*La])});return function(n){return tr(t(n))}}function Ge(n){this.stream=n}function Ke(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function Qe(n){return nr(function(){return n})()}function nr(n){function t(n){return n=a(n[0]*Na,n[1]*Na),[n[0]*h+c,s-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(s-n[1])/h),n&&[n[0]*La,n[1]*La]}function r(){a=Ue(o=ur(m,y,x),i);var n=i(v,d);return c=g-n[0]*h,s=p+n[1]*h,u()}function u(){return l&&(l.valid=!1,l=null),t}var i,o,a,c,s,l,f=We(function(n,t){return n=i(n,t),[n[0]*h+c,s-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,y=0,x=0,M=Ec,_=bt,b=null,w=null;return t.stream=function(n){return l&&(l.valid=!1),l=tr(M(o,f(_(n)))),l.valid=!0,l},t.clipAngle=function(n){return arguments.length?(M=null==n?(b=n,Ec):Re((b=+n)*Na),u()):b},t.clipExtent=function(n){return arguments.length?(w=n,_=n?Pe(n[0][0],n[0][1],n[1][0],n[1][1]):bt,u()):w},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Na,d=n[1]%360*Na,r()):[v*La,d*La]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Na,y=n[1]%360*Na,x=n.length>2?n[2]%360*Na:0,r()):[m*La,y*La,x*La]},Xo.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function tr(n){return Ke(n,function(t,e){n.point(t*Na,e*Na)})}function er(n,t){return[n,t]}function rr(n,t){return[n>Sa?n-ka:-Sa>n?n+ka:n,t]}function ur(n,t,e){return n?t||e?Ue(or(n),ar(t,e)):or(n):t||e?ar(t,e):rr}function ir(n){return function(t,e){return t+=n,[t>Sa?t-ka:-Sa>t?t+ka:t,e]}}function or(n){var t=ir(n);return t.invert=ir(-n),t}function ar(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*r+a*u;return[Math.atan2(c*i-l*o,a*r-s*u),X(l*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*i-c*o;return[Math.atan2(c*i+s*o,a*r+l*u),X(l*r-a*u)]},e}function cr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=sr(e,u),i=sr(e,i),(o>0?i>u:u>i)&&(u+=o*ka)):(u=n+o*ka,i=n-.5*c);for(var s,l=u;o>0?l>i:i>l;l-=c)a.point((s=ve([e,-r*Math.cos(l),-r*Math.sin(l)]))[0],s[1])}}function sr(n,t){var e=se(t);e[0]-=n,pe(e);var r=V(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Aa)%(2*Math.PI)}function lr(n,t,e){var r=Xo.range(n,t-Aa,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function fr(n,t,e){var r=Xo.range(n,t-Aa,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function hr(n){return n.source}function gr(n){return n.target}function pr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),s=u*Math.sin(n),l=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(J(r-t)+u*o*J(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*l,u=e*s+t*f,o=e*i+t*a;return[Math.atan2(u,r)*La,Math.atan2(o,Math.sqrt(r*r+u*u))*La]}:function(){return[n*La,t*La]};return p.distance=h,p}function vr(){function n(n,u){var i=Math.sin(u*=Na),o=Math.cos(u),a=oa((n*=Na)-t),c=Math.cos(a);Uc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;jc.point=function(u,i){t=u*Na,e=Math.sin(i*=Na),r=Math.cos(i),jc.point=n},jc.lineEnd=function(){jc.point=jc.lineEnd=g}}function dr(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function mr(n,t){function e(n,t){var e=oa(oa(t)-Ea)<Aa?0:o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(Sa/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=I(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Ea]},e):xr}function yr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return oa(u)<Aa?er:(e.invert=function(n,t){var e=i-t;return[Math.atan2(n,e)/u,i-I(u)*Math.sqrt(n*n+e*e)]},e)}function xr(n,t){return[n,Math.log(Math.tan(Sa/4+t/2))]}function Mr(n){var t,e=Qe(n),r=e.scale,u=e.translate,i=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=u.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=i.apply(e,arguments);if(o===e){if(t=null==n){var a=Sa*r(),c=u();i([[c[0]-a,c[1]-a],[c[0]+a,c[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function _r(n,t){return[Math.log(Math.tan(Sa/4+t/2)),-n]}function br(n){return n[0]}function wr(n){return n[1]}function Sr(n){for(var t=n.length,e=[0,1],r=2,u=2;t>u;u++){for(;r>1&&Z(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function kr(n,t){return n[0]-t[0]||n[1]-t[1]}function Er(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Ar(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],s=e[1],l=t[1]-c,f=r[1]-s,h=(a*(c-s)-f*(u-i))/(f*o-a*l);return[u+h*o,c+h*l]}function Cr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Nr(){Jr(this),this.edge=this.site=this.circle=null}function Lr(n){var t=Jc.pop()||new Nr;return t.site=n,t}function Tr(n){Or(n),$c.remove(n),Jc.push(n),Jr(n)}function qr(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Tr(n);for(var c=i;c.circle&&oa(e-c.circle.x)<Aa&&oa(r-c.circle.cy)<Aa;)i=c.P,a.unshift(c),Tr(c),c=i;a.unshift(c),Or(c);for(var s=o;s.circle&&oa(e-s.circle.x)<Aa&&oa(r-s.circle.cy)<Aa;)o=s.N,a.push(s),Tr(s),s=o;a.push(s),Or(s);var l,f=a.length;for(l=1;f>l;++l)s=a[l],c=a[l-1],$r(s.edge,c.site,s.site,u);c=a[0],s=a[f-1],s.edge=Vr(c.site,s.site,null,u),Fr(c),Fr(s)}function zr(n){for(var t,e,r,u,i=n.x,o=n.y,a=$c._;a;)if(r=Rr(a,o)-i,r>Aa)a=a.L;else{if(u=i-Dr(a,o),!(u>Aa)){r>-Aa?(t=a.P,e=a):u>-Aa?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Lr(n);if($c.insert(t,c),t||e){if(t===e)return Or(t),e=Lr(t.site),$c.insert(c,e),c.edge=e.edge=Vr(t.site,c.site),Fr(t),Fr(e),void 0;if(!e)return c.edge=Vr(t.site,c.site),void 0;Or(t),Or(e);var s=t.site,l=s.x,f=s.y,h=n.x-l,g=n.y-f,p=e.site,v=p.x-l,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,x=v*v+d*d,M={x:(d*y-g*x)/m+l,y:(h*x-v*y)/m+f};$r(e.edge,s,p,M),c.edge=Vr(s,n,null,M),e.edge=Vr(n,p,null,M),Fr(t),Fr(e)}}function Rr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,s=c-t;if(!s)return a;var l=a-r,f=1/i-1/s,h=l/s;return f?(-h+Math.sqrt(h*h-2*f*(l*l/(-2*s)-c+s/2+u-i/2)))/f+r:(r+a)/2}function Dr(n,t){var e=n.N;if(e)return Rr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Pr(n){this.site=n,this.edges=[]}function Ur(n){for(var t,e,r,u,i,o,a,c,s,l,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Xc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)l=a[o].end(),r=l.x,u=l.y,s=a[++o%c].start(),t=s.x,e=s.y,(oa(r-t)>Aa||oa(u-e)>Aa)&&(a.splice(o,0,new Br(Xr(i.site,l,oa(r-f)<Aa&&p-u>Aa?{x:f,y:oa(t-f)<Aa?e:p}:oa(u-p)<Aa&&h-r>Aa?{x:oa(e-p)<Aa?t:h,y:p}:oa(r-h)<Aa&&u-g>Aa?{x:h,y:oa(t-h)<Aa?e:g}:oa(u-g)<Aa&&r-f>Aa?{x:oa(e-g)<Aa?t:f,y:g}:null),i.site,null)),++c)}function jr(n,t){return t.angle-n.angle}function Hr(){Jr(this),this.x=this.y=this.arc=this.site=this.cy=null}function Fr(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,u=n.site,i=e.site;if(r!==i){var o=u.x,a=u.y,c=r.x-o,s=r.y-a,l=i.x-o,f=i.y-a,h=2*(c*f-s*l);if(!(h>=-Ca)){var g=c*c+s*s,p=l*l+f*f,v=(f*g-s*p)/h,d=(c*p-l*g)/h,f=d+a,m=Gc.pop()||new Hr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,x=Wc._;x;)if(m.y<x.y||m.y===x.y&&m.x<=x.x){if(!x.L){y=x.P;break}x=x.L}else{if(!x.R){y=x;break}x=x.R}Wc.insert(y,m),y||(Bc=m)}}}}function Or(n){var t=n.circle;t&&(t.P||(Bc=t.N),Wc.remove(t),Gc.push(t),Jr(t),n.circle=null)}function Yr(n){for(var t,e=Vc,r=De(n[0][0],n[0][1],n[1][0],n[1][1]),u=e.length;u--;)t=e[u],(!Ir(t,n)||!r(t)||oa(t.a.x-t.b.x)<Aa&&oa(t.a.y-t.b.y)<Aa)&&(t.a=t.b=null,e.splice(u,1))}function Ir(n,t){var e=n.b;if(e)return!0;var r,u,i=n.a,o=t[0][0],a=t[1][0],c=t[0][1],s=t[1][1],l=n.l,f=n.r,h=l.x,g=l.y,p=f.x,v=f.y,d=(h+p)/2,m=(g+v)/2;if(v===g){if(o>d||d>=a)return;if(h>p){if(i){if(i.y>=s)return}else i={x:d,y:c};e={x:d,y:s}}else{if(i){if(i.y<c)return}else i={x:d,y:s};e={x:d,y:c}}}else if(r=(h-p)/(v-g),u=m-r*d,-1>r||r>1)if(h>p){if(i){if(i.y>=s)return}else i={x:(c-u)/r,y:c};e={x:(s-u)/r,y:s}}else{if(i){if(i.y<c)return}else i={x:(s-u)/r,y:s};e={x:(c-u)/r,y:c}}else if(v>g){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.x<o)return}else i={x:a,y:r*a+u};e={x:o,y:r*o+u}}return n.a=i,n.b=e,!0}function Zr(n,t){this.l=n,this.r=t,this.a=this.b=null}function Vr(n,t,e,r){var u=new Zr(n,t);return Vc.push(u),e&&$r(u,n,t,e),r&&$r(u,t,n,r),Xc[n.i].edges.push(new Br(u,n,t)),Xc[t.i].edges.push(new Br(u,t,n)),u}function Xr(n,t,e){var r=new Zr(n,null);return r.a=t,r.b=e,Vc.push(r),r}function $r(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function Br(n,t,e){var r=n.a,u=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(u.x-r.x,r.y-u.y):Math.atan2(r.x-u.x,u.y-r.y)}function Wr(){this._=null}function Jr(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function Gr(n,t){var e=t,r=t.R,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function Kr(n,t){var e=t,r=t.L,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function Qr(n){for(;n.L;)n=n.L;return n}function nu(n,t){var e,r,u,i=n.sort(tu).pop();for(Vc=[],Xc=new Array(n.length),$c=new Wr,Wc=new Wr;;)if(u=Bc,i&&(!u||i.y<u.y||i.y===u.y&&i.x<u.x))(i.x!==e||i.y!==r)&&(Xc[i.i]=new Pr(i),zr(i),e=i.x,r=i.y),i=n.pop();else{if(!u)break;qr(u.arc)}t&&(Yr(t),Ur(t));var o={cells:Xc,edges:Vc};return $c=Wc=Vc=Xc=null,o}function tu(n,t){return t.y-n.y||t.x-n.x}function eu(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function ru(n){return n.x}function uu(n){return n.y}function iu(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function ou(n,t,e,r,u,i){if(!n(t,e,r,u,i)){var o=.5*(e+u),a=.5*(r+i),c=t.nodes;c[0]&&ou(n,c[0],e,r,o,a),c[1]&&ou(n,c[1],o,r,u,a),c[2]&&ou(n,c[2],e,a,o,i),c[3]&&ou(n,c[3],o,a,u,i)}}function au(n,t){n=Xo.rgb(n),t=Xo.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+vt(Math.round(e+i*n))+vt(Math.round(r+o*n))+vt(Math.round(u+a*n))}}function cu(n,t){var e,r={},u={};for(e in n)e in t?r[e]=fu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function su(n,t){return t-=n=+n,function(e){return n+t*e}}function lu(n,t){var e,r,u,i,o,a=0,c=0,s=[],l=[];for(n+="",t+="",Qc.lastIndex=0,r=0;e=Qc.exec(t);++r)e.index&&s.push(t.substring(a,c=e.index)),l.push({i:s.length,x:e[0]}),s.push(null),a=Qc.lastIndex;for(a<t.length&&s.push(t.substring(a)),r=0,i=l.length;(e=Qc.exec(n))&&i>r;++r)if(o=l[r],o.x==e[0]){if(o.i)if(null==s[o.i+1])for(s[o.i-1]+=o.x,s.splice(o.i,1),u=r+1;i>u;++u)l[u].i--;else for(s[o.i-1]+=o.x+s[o.i+1],s.splice(o.i,2),u=r+1;i>u;++u)l[u].i-=2;else if(null==s[o.i+1])s[o.i]=o.x;else for(s[o.i]=o.x+s[o.i+1],s.splice(o.i+1,1),u=r+1;i>u;++u)l[u].i--;l.splice(r,1),i--,r--}else o.x=su(parseFloat(e[0]),parseFloat(o.x));for(;i>r;)o=l.pop(),null==s[o.i+1]?s[o.i]=o.x:(s[o.i]=o.x+s[o.i+1],s.splice(o.i+1,1)),i--;return 1===s.length?null==s[0]?(o=l[0].x,function(n){return o(n)+""}):function(){return t}:function(n){for(r=0;i>r;++r)s[(o=l[r]).i]=o.x(n);return s.join("")}}function fu(n,t){for(var e,r=Xo.interpolators.length;--r>=0&&!(e=Xo.interpolators[r](n,t)););return e}function hu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(fu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function gu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function pu(n){return function(t){return 1-n(1-t)}}function vu(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function du(n){return n*n}function mu(n){return n*n*n}function yu(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function xu(n){return function(t){return Math.pow(t,n)}}function Mu(n){return 1-Math.cos(n*Ea)}function _u(n){return Math.pow(2,10*(n-1))}function bu(n){return 1-Math.sqrt(1-n*n)}function wu(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/ka*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*ka/t)}}function Su(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function ku(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Eu(n,t){n=Xo.hcl(n),t=Xo.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return rt(e+i*n,r+o*n,u+a*n)+""}}function Au(n,t){n=Xo.hsl(n),t=Xo.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return nt(e+i*n,r+o*n,u+a*n)+""}}function Cu(n,t){n=Xo.lab(n),t=Xo.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ot(e+i*n,r+o*n,u+a*n)+""}}function Nu(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Lu(n){var t=[n.a,n.b],e=[n.c,n.d],r=qu(t),u=Tu(t,e),i=qu(zu(e,t,-u))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,u*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*La,this.translate=[n.e,n.f],this.scale=[r,i],this.skew=i?Math.atan2(u,i)*La:0}function Tu(n,t){return n[0]*t[0]+n[1]*t[1]}function qu(n){var t=Math.sqrt(Tu(n,n));return t&&(n[0]/=t,n[1]/=t),t}function zu(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Ru(n,t){var e,r=[],u=[],i=Xo.transform(n),o=Xo.transform(t),a=i.translate,c=o.translate,s=i.rotate,l=o.rotate,f=i.skew,h=o.skew,g=i.scale,p=o.scale;return a[0]!=c[0]||a[1]!=c[1]?(r.push("translate(",null,",",null,")"),u.push({i:1,x:su(a[0],c[0])},{i:3,x:su(a[1],c[1])})):c[0]||c[1]?r.push("translate("+c+")"):r.push(""),s!=l?(s-l>180?l+=360:l-s>180&&(s+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:su(s,l)})):l&&r.push(r.pop()+"rotate("+l+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:su(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:su(g[0],p[0])},{i:e-2,x:su(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i<e;)r[(t=u[i]).i]=t.x(n);return r.join("")}}function Du(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return(e-n)*t}}function Pu(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return Math.max(0,Math.min(1,(e-n)*t))}}function Uu(n){for(var t=n.source,e=n.target,r=Hu(t,e),u=[t];t!==r;)t=t.parent,u.push(t);for(var i=u.length;e!==r;)u.splice(i,0,e),e=e.parent;return u}function ju(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Hu(n,t){if(n===t)return n;for(var e=ju(n),r=ju(t),u=e.pop(),i=r.pop(),o=null;u===i;)o=u,u=e.pop(),i=r.pop();return o}function Fu(n){n.fixed|=2}function Ou(n){n.fixed&=-7}function Yu(n){n.fixed|=4,n.px=n.x,n.py=n.y}function Iu(n){n.fixed&=-5}function Zu(n,t,e){var r=0,u=0;if(n.charge=0,!n.leaf)for(var i,o=n.nodes,a=o.length,c=-1;++c<a;)i=o[c],null!=i&&(Zu(i,t,e),n.charge+=i.charge,r+=i.charge*i.cx,u+=i.charge*i.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var s=t*e[n.point.index];n.charge+=n.pointCharge=s,r+=s*n.point.x,u+=s*n.point.y}n.cx=r/n.charge,n.cy=u/n.charge}function Vu(n,t){return Xo.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=Wu,n}function Xu(n){return n.children}function $u(n){return n.value}function Bu(n,t){return t.value-n.value}function Wu(n){return Xo.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function Ju(n){return n.x}function Gu(n){return n.y}function Ku(n,t,e){n.y0=t,n.y=e}function Qu(n){return Xo.range(n.length)}function ni(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function ti(n){for(var t,e=1,r=0,u=n[0][1],i=n.length;i>e;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function ei(n){return n.reduce(ri,0)}function ri(n,t){return n+t[1]}function ui(n,t){return ii(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function ii(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function oi(n){return[Xo.min(n),Xo.max(n)]}function ai(n,t){return n.parent==t.parent?1:2}function ci(n){var t=n.children;return t&&t.length?t[0]:n._tree.thread}function si(n){var t,e=n.children;return e&&(t=e.length)?e[t-1]:n._tree.thread}function li(n,t){var e=n.children;if(e&&(u=e.length))for(var r,u,i=-1;++i<u;)t(r=li(e[i],t),n)>0&&(n=r);return n}function fi(n,t){return n.x-t.x}function hi(n,t){return t.x-n.x}function gi(n,t){return n.depth-t.depth}function pi(n,t){function e(n,r){var u=n.children;if(u&&(o=u.length))for(var i,o,a=null,c=-1;++c<o;)i=u[c],e(i,a),a=i;t(n,r)}e(n,null)}function vi(n){for(var t,e=0,r=0,u=n.children,i=u.length;--i>=0;)t=u[i]._tree,t.prelim+=e,t.mod+=e,e+=t.shift+(r+=t.change)}function di(n,t,e){n=n._tree,t=t._tree;var r=e/(t.number-n.number);n.change+=r,t.change-=r,t.shift+=e,t.prelim+=e,t.mod+=e}function mi(n,t,e){return n._tree.ancestor.parent==t.parent?n._tree.ancestor:e}function yi(n,t){return n.value-t.value}function xi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function Mi(n,t){n._pack_next=t,t._pack_prev=n}function _i(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function bi(n){function t(n){l=Math.min(n.x-n.r,l),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(s=e.length)){var e,r,u,i,o,a,c,s,l=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(wi),r=e[0],r.x=-r.r,r.y=0,t(r),s>1&&(u=e[1],u.x=u.r,u.y=0,t(u),s>2))for(i=e[2],Ei(r,u,i),t(i),xi(r,i),r._pack_prev=i,xi(i,u),u=r._pack_next,o=3;s>o;o++){Ei(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(_i(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!_i(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.r<r.r?Mi(r,u=a):Mi(r=c,u),o--):(xi(r,i),u=i,t(i))}var m=(l+f)/2,y=(h+g)/2,x=0;for(o=0;s>o;o++)i=e[o],i.x-=m,i.y-=y,x=Math.max(x,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=x,e.forEach(Si)}}function wi(n){n._pack_next=n._pack_prev=n}function Si(n){delete n._pack_next,delete n._pack_prev}function ki(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i<o;)ki(u[i],t,e,r)}function Ei(n,t,e){var r=n.r+e.r,u=t.x-n.x,i=t.y-n.y;if(r&&(u||i)){var o=t.r+e.r,a=u*u+i*i;o*=o,r*=r;var c=.5+(r-o)/(2*a),s=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+c*u+s*i,e.y=n.y+c*i-s*u}else e.x=n.x+r,e.y=n.y}function Ai(n){return 1+Xo.max(n,function(n){return n.y})}function Ci(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Ni(n){var t=n.children;return t&&t.length?Ni(t[0]):n}function Li(n){var t,e=n.children;return e&&(t=e.length)?Li(e[t-1]):n}function Ti(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function qi(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function zi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ri(n){return n.rangeExtent?n.rangeExtent():zi(n.range())}function Di(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Pi(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Ui(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:ls}function ji(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)u.push(e(n[o-1],n[o])),i.push(r(t[o-1],t[o]));return function(t){var e=Xo.bisect(n,t,1,a)-1;return i[e](u[e](t))}}function Hi(n,t,e,r){function u(){var u=Math.min(n.length,t.length)>2?ji:Di,c=r?Pu:Du;return o=u(n,t,c,e),a=u(t,n,c,fu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Nu)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Ii(n,t)},i.tickFormat=function(t,e){return Zi(n,t,e)},i.nice=function(t){return Oi(n,t),u()},i.copy=function(){return Hi(n,t,e,r)},u()}function Fi(n,t){return Xo.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Oi(n,t){return Pi(n,Ui(Yi(n,t)[2]))}function Yi(n,t){null==t&&(t=10);var e=zi(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Ii(n,t){return Xo.range.apply(Xo,Yi(n,t))}function Zi(n,t,e){var r=Yi(n,t);return Xo.format(e?e.replace(Qa,function(n,t,e,u,i,o,a,c,s,l){return[t,e,u,i,o,a,c,s||"."+Xi(l,r),l].join("")}):",."+Vi(r[2])+"f")}function Vi(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Xi(n,t){var e=Vi(t[2]);return n in fs?Math.abs(e-Vi(Math.max(Math.abs(t[0]),Math.abs(t[1]))))+ +("e"!==n):e-2*("%"===n)}function $i(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Pi(r.map(u),e?Math:gs);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=zi(r),o=[],a=n[0],c=n[1],s=Math.floor(u(a)),l=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(l-s)){if(e){for(;l>s;s++)for(var h=1;f>h;h++)o.push(i(s)*h);o.push(i(s))}else for(o.push(i(s));s++<l;)for(var h=f-1;h>0;h--)o.push(i(s)*h);for(s=0;o[s]<a;s++);for(l=o.length;o[l-1]>c;l--);o=o.slice(s,l)}return o},o.tickFormat=function(n,t){if(!arguments.length)return hs;arguments.length<2?t=hs:"function"!=typeof t&&(t=Xo.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return $i(n.copy(),t,e,r)},Fi(o,n)}function Bi(n,t,e){function r(t){return n(u(t))}var u=Wi(t),i=Wi(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Ii(e,n)},r.tickFormat=function(n,t){return Zi(e,n,t)},r.nice=function(n){return r.domain(Oi(e,n))},r.exponent=function(o){return arguments.length?(u=Wi(t=o),i=Wi(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Bi(n.copy(),t,e)},Fi(r,n)}function Wi(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Ji(n,t){function e(e){return o[((i.get(e)||"range"===t.t&&i.set(e,n.push(e)))-1)%o.length]}function r(t,e){return Xo.range(n.length).map(function(n){return t+e*n})}var i,o,a;return e.domain=function(r){if(!arguments.length)return n;n=[],i=new u;for(var o,a=-1,c=r.length;++a<c;)i.has(o=r[a])||i.set(o,n.push(o));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(o=n,a=0,t={t:"range",a:arguments},e):o},e.rangePoints=function(u,i){arguments.length<2&&(i=0);var c=u[0],s=u[1],l=(s-c)/(Math.max(1,n.length-1)+i);return o=r(n.length<2?(c+s)/2:c+l*i/2,l),a=0,t={t:"rangePoints",a:arguments},e},e.rangeBands=function(u,i,c){arguments.length<2&&(i=0),arguments.length<3&&(c=i);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=(f-l)/(n.length-i+2*c);return o=r(l+h*c,h),s&&o.reverse(),a=h*(1-i),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(u,i,c){arguments.length<2&&(i=0),arguments.length<3&&(c=i);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=Math.floor((f-l)/(n.length-i+2*c)),g=f-l-(n.length-i)*h;return o=r(l+Math.round(g/2),h),s&&o.reverse(),a=Math.round(h*(1-i)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return a},e.rangeExtent=function(){return zi(t.a[0])},e.copy=function(){return Ji(n,t)},e.domain(n)}function Gi(n,t){function e(){var e=0,i=t.length;for(u=[];++e<i;)u[e-1]=Xo.quantile(n,e/i);return r}function r(n){return isNaN(n=+n)?void 0:t[Xo.bisect(u,n)]}var u;return r.domain=function(t){return arguments.length?(n=t.filter(function(n){return!isNaN(n)}).sort(Xo.ascending),e()):n},r.range=function(n){return arguments.length?(t=n,e()):t},r.quantiles=function(){return u},r.invertExtent=function(e){return e=t.indexOf(e),0>e?[0/0,0/0]:[e>0?u[e-1]:n[0],e<u.length?u[e]:n[n.length-1]]},r.copy=function(){return Gi(n,t)},e()}function Ki(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(i*(t-n))))]}function u(){return i=e.length/(t-n),o=e.length-1,r}var i,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],u()):[n,t]},r.range=function(n){return arguments.length?(e=n,u()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return Ki(n,t,e)},u()}function Qi(n,t){function e(e){return e>=e?t[Xo.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return Qi(n,t)},e}function no(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Ii(n,t)},t.tickFormat=function(t,e){return Zi(n,t,e)},t.copy=function(){return no(n)},t}function to(n){return n.innerRadius}function eo(n){return n.outerRadius}function ro(n){return n.startAngle}function uo(n){return n.endAngle}function io(n){function t(t){function o(){s.push("M",i(n(l),a))}for(var c,s=[],l=[],f=-1,h=t.length,g=_t(e),p=_t(r);++f<h;)u.call(this,c=t[f],f)?l.push([+g.call(this,c,f),+p.call(this,c,f)]):l.length&&(o(),l=[]);return l.length&&o(),s.length?s.join(""):null}var e=br,r=wr,u=be,i=oo,o=i.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(u=n,t):u},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?i=n:(i=Ms.get(n)||oo).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function oo(n){return n.join("L")}function ao(n){return oo(n)+"Z"}function co(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&u.push("H",r[0]),u.join("")}function so(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("V",(r=n[t])[1],"H",r[0]);return u.join("")}function lo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r=n[t])[0],"V",r[1]);return u.join("")}function fo(n,t){return n.length<4?oo(n):n[1]+po(n.slice(1,n.length-1),vo(n,t))}function ho(n,t){return n.length<3?oo(n):n[0]+po((n.push(n[0]),n),vo([n[n.length-2]].concat(n,[n[1]]),t))}function go(n,t){return n.length<3?oo(n):n[0]+po(n,vo(n,t))}function po(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return oo(n);var e=n.length!=t.length,r="",u=n[0],i=n[1],o=t[0],a=o,c=1;if(e&&(r+="Q"+(i[0]-2*o[0]/3)+","+(i[1]-2*o[1]/3)+","+i[0]+","+i[1],u=n[1],c=2),t.length>1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var s=2;s<t.length;s++,c++)i=n[c],a=t[s],r+="S"+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1]}if(e){var l=n[c];r+="Q"+(i[0]+2*a[0]/3)+","+(i[1]+2*a[1]/3)+","+l[0]+","+l[1]}return r}function vo(n,t){for(var e,r=[],u=(1-t)/2,i=n[0],o=n[1],a=1,c=n.length;++a<c;)e=i,i=o,o=n[a],r.push([u*(o[0]-e[0]),u*(o[1]-e[1])]);return r}function mo(n){if(n.length<3)return oo(n);var t=1,e=n.length,r=n[0],u=r[0],i=r[1],o=[u,u,u,(r=n[1])[0]],a=[i,i,i,r[1]],c=[u,",",i,"L",_o(ws,o),",",_o(ws,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),bo(c,o,a);return n.pop(),c.push("L",r),c.join("")}function yo(n){if(n.length<4)return oo(n);for(var t,e=[],r=-1,u=n.length,i=[0],o=[0];++r<3;)t=n[r],i.push(t[0]),o.push(t[1]);for(e.push(_o(ws,i)+","+_o(ws,o)),--r;++r<u;)t=n[r],i.shift(),i.push(t[0]),o.shift(),o.push(t[1]),bo(e,i,o);return e.join("")}function xo(n){for(var t,e,r=-1,u=n.length,i=u+4,o=[],a=[];++r<4;)e=n[r%u],o.push(e[0]),a.push(e[1]);for(t=[_o(ws,o),",",_o(ws,a)],--r;++r<i;)e=n[r%u],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),bo(t,o,a);return t.join("")}function Mo(n,t){var e=n.length-1;if(e)for(var r,u,i=n[0][0],o=n[0][1],a=n[e][0]-i,c=n[e][1]-o,s=-1;++s<=e;)r=n[s],u=s/e,r[0]=t*r[0]+(1-t)*(i+u*a),r[1]=t*r[1]+(1-t)*(o+u*c);return mo(n)}function _o(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function bo(n,t,e){n.push("C",_o(_s,t),",",_o(_s,e),",",_o(bs,t),",",_o(bs,e),",",_o(ws,t),",",_o(ws,e))}function wo(n,t){return(t[1]-n[1])/(t[0]-n[0])}function So(n){for(var t=0,e=n.length-1,r=[],u=n[0],i=n[1],o=r[0]=wo(u,i);++t<e;)r[t]=(o+(o=wo(u=i,i=n[t+1])))/2;return r[t]=o,r}function ko(n){for(var t,e,r,u,i=[],o=So(n),a=-1,c=n.length-1;++a<c;)t=wo(n[a],n[a+1]),oa(t)<Aa?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,u=e*e+r*r,u>9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function Eo(n){return n.length<3?oo(n):n[0]+po(n,ko(n))}function Ao(n){for(var t,e,r,u=-1,i=n.length;++u<i;)t=n[u],e=t[0],r=t[1]+ys,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Co(n){function t(t){function c(){v.push("M",a(n(m),f),l,s(n(d.reverse()),f),"Z")}for(var h,g,p,v=[],d=[],m=[],y=-1,x=t.length,M=_t(e),_=_t(u),b=e===r?function(){return g}:_t(r),w=u===i?function(){return p}:_t(i);++y<x;)o.call(this,h=t[y],y)?(d.push([g=+M.call(this,h,y),p=+_.call(this,h,y)]),m.push([+b.call(this,h,y),+w.call(this,h,y)])):d.length&&(c(),d=[],m=[]);return d.length&&c(),v.length?v.join(""):null}var e=br,r=br,u=0,i=wr,o=be,a=oo,c=a.key,s=a,l="L",f=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r},t.y=function(n){return arguments.length?(u=i=n,t):i},t.y0=function(n){return arguments.length?(u=n,t):u},t.y1=function(n){return arguments.length?(i=n,t):i},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(c="function"==typeof n?a=n:(a=Ms.get(n)||oo).key,s=a.reverse||a,l=a.closed?"M":"L",t):c},t.tension=function(n){return arguments.length?(f=n,t):f},t}function No(n){return n.radius}function Lo(n){return[n.x,n.y]}function To(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]+ys;return[e*Math.cos(r),e*Math.sin(r)]}}function qo(){return 64}function zo(){return"circle"}function Ro(n){var t=Math.sqrt(n/Sa);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function Do(n,t){return fa(n,Ns),n.id=t,n}function Po(n,t,e,r){var u=n.id;return R(n,"function"==typeof e?function(n,i,o){n.__transition__[u].tween.set(t,r(e.call(n,n.__data__,i,o)))}:(e=r(e),function(n){n.__transition__[u].tween.set(t,e)}))}function Uo(n){return null==n&&(n=""),function(){this.textContent=n}}function jo(n,t,e,r){var i=n.__transition__||(n.__transition__={active:0,count:0}),o=i[e];if(!o){var a=r.time;o=i[e]={tween:new u,time:a,ease:r.ease,delay:r.delay,duration:r.duration},++i.count,Xo.timer(function(r){function u(r){return i.active>e?s():(i.active=e,o.event&&o.event.start.call(n,l,t),o.tween.forEach(function(e,r){(r=r.call(n,l,t))&&v.push(r)}),Xo.timer(function(){return p.c=c(r||1)?be:c,1},0,a),void 0)}function c(r){if(i.active!==e)return s();for(var u=r/g,a=f(u),c=v.length;c>0;)v[--c].call(n,a);return u>=1?(o.event&&o.event.end.call(n,l,t),s()):void 0}function s(){return--i.count?delete i[e]:delete n.__transition__,1}var l=n.__data__,f=o.ease,h=o.delay,g=o.duration,p=Ja,v=[];return p.t=h+a,r>=h?u(r-h):(p.c=u,void 0)},0,a)}}function Ho(n,t){n.attr("transform",function(n){return"translate("+t(n)+",0)"})}function Fo(n,t){n.attr("transform",function(n){return"translate(0,"+t(n)+")"})}function Oo(n){return n.toISOString()}function Yo(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=Xo.bisect(js,u);return i==js.length?[t.year,Yi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/js[i-1]<js[i]/u?i-1:i]:[Os,Yi(n,e)[2]]}return r.invert=function(t){return Io(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(Io)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,Io(+e+1),t).length}var i=r.domain(),o=zi(i),a=null==n?u(o,10):"number"==typeof n&&u(o,n);return a&&(n=a[0],t=a[1]),r.domain(Pi(i,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=Io(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Io(+t+1);return t}}:n))},r.ticks=function(n,t){var e=zi(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Io(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Yo(n.copy(),t,e)},Fi(r,n)}function Io(n){return new Date(n)}function Zo(n){return JSON.parse(n.responseText)}function Vo(n){var t=Wo.createRange();return t.selectNode(Wo.body),t.createContextualFragment(n.responseText)}var Xo={version:"3.4.3"};Date.now||(Date.now=function(){return+new Date});var $o=[].slice,Bo=function(n){return $o.call(n)},Wo=document,Jo=Wo.documentElement,Go=window;try{Bo(Jo.childNodes)[0].nodeType}catch(Ko){Bo=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}try{Wo.createElement("div").style.setProperty("opacity",0,"")}catch(Qo){var na=Go.Element.prototype,ta=na.setAttribute,ea=na.setAttributeNS,ra=Go.CSSStyleDeclaration.prototype,ua=ra.setProperty;na.setAttribute=function(n,t){ta.call(this,n,t+"")},na.setAttributeNS=function(n,t,e){ea.call(this,n,t,e+"")},ra.setProperty=function(n,t,e){ua.call(this,n,t+"",e)}}Xo.ascending=function(n,t){return t>n?-1:n>t?1:n>=t?0:0/0},Xo.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},Xo.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&e>r&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&e>r&&(e=r)}return e},Xo.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&r>e&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&r>e&&(e=r)}return e},Xo.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i<o&&!(null!=(e=u=n[i])&&e>=e);)e=u=void 0;for(;++i<o;)null!=(r=n[i])&&(e>r&&(e=r),r>u&&(u=r))}else{for(;++i<o&&!(null!=(e=u=t.call(n,n[i],i))&&e>=e);)e=void 0;for(;++i<o;)null!=(r=t.call(n,n[i],i))&&(e>r&&(e=r),r>u&&(u=r))}return[e,u]},Xo.sum=function(n,t){var e,r=0,u=n.length,i=-1;if(1===arguments.length)for(;++i<u;)isNaN(e=+n[i])||(r+=e);else for(;++i<u;)isNaN(e=+t.call(n,n[i],i))||(r+=e);return r},Xo.mean=function(t,e){var r,u=t.length,i=0,o=-1,a=0;if(1===arguments.length)for(;++o<u;)n(r=t[o])&&(i+=(r-i)/++a);else for(;++o<u;)n(r=e.call(t,t[o],o))&&(i+=(r-i)/++a);return a?i:void 0},Xo.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),u=+n[r-1],i=e-r;return i?u+i*(n[r]-u):u},Xo.median=function(t,e){return arguments.length>1&&(t=t.map(e)),t=t.filter(n),t.length?Xo.quantile(t.sort(Xo.ascending),.5):void 0},Xo.bisector=function(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n.call(t,t[i],i)<e?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;e<n.call(t,t[i],i)?u=i:r=i+1}return r}}};var ia=Xo.bisector(function(n){return n});Xo.bisectLeft=ia.left,Xo.bisect=Xo.bisectRight=ia.right,Xo.shuffle=function(n){for(var t,e,r=n.length;r;)e=0|Math.random()*r--,t=n[r],n[r]=n[e],n[e]=t;return n},Xo.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},Xo.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},Xo.zip=function(){if(!(u=arguments.length))return[];for(var n=-1,e=Xo.min(arguments,t),r=new Array(e);++n<e;)for(var u,i=-1,o=r[n]=new Array(u);++i<u;)o[i]=arguments[i][n];return r},Xo.transpose=function(n){return Xo.zip.apply(Xo,n)},Xo.keys=function(n){var t=[];for(var e in n)t.push(e);return t},Xo.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},Xo.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},Xo.merge=function(n){for(var t,e,r,u=n.length,i=-1,o=0;++i<u;)o+=n[i].length;for(e=new Array(o);--u>=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var oa=Math.abs;Xo.range=function(n,t,r){if(arguments.length<3&&(r=1,arguments.length<2&&(t=n,n=0)),1/0===(t-n)/r)throw new Error("infinite range");var u,i=[],o=e(oa(r)),a=-1;if(n*=o,t*=o,r*=o,0>r)for(;(u=n+r*++a)>t;)i.push(u/o);else for(;(u=n+r*++a)<t;)i.push(u/o);return i},Xo.map=function(n){var t=new u;if(n instanceof u)n.forEach(function(n,e){t.set(n,e)});else for(var e in n)t.set(e,n[e]);return t},r(u,{has:i,get:function(n){return this[aa+n]},set:function(n,t){return this[aa+n]=t},remove:o,keys:a,values:function(){var n=[];return this.forEach(function(t,e){n.push(e)}),n},entries:function(){var n=[];return this.forEach(function(t,e){n.push({key:t,value:e})}),n},size:c,empty:s,forEach:function(n){for(var t in this)t.charCodeAt(0)===ca&&n.call(this,t.substring(1),this[t])}});var aa="\x00",ca=aa.charCodeAt(0);Xo.nest=function(){function n(t,a,c){if(c>=o.length)return r?r.call(i,a):e?a.sort(e):a;for(var s,l,f,h,g=-1,p=a.length,v=o[c++],d=new u;++g<p;)(h=d.get(s=v(l=a[g])))?h.push(l):d.set(s,[l]);return t?(l=t(),f=function(e,r){l.set(e,n(t,r,c))}):(l={},f=function(e,r){l[e]=n(t,r,c)}),d.forEach(f),l}function t(n,e){if(e>=o.length)return n;var r=[],u=a[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,i={},o=[],a=[];return i.map=function(t,e){return n(e,t,0)},i.entries=function(e){return t(n(Xo.map,e,0),0)},i.key=function(n){return o.push(n),i},i.sortKeys=function(n){return a[o.length-1]=n,i},i.sortValues=function(n){return e=n,i},i.rollup=function(n){return r=n,i},i},Xo.set=function(n){var t=new l;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},r(l,{has:i,add:function(n){return this[aa+n]=!0,n},remove:function(n){return n=aa+n,n in this&&delete this[n]},values:a,size:c,empty:s,forEach:function(n){for(var t in this)t.charCodeAt(0)===ca&&n.call(this,t.substring(1))}}),Xo.behavior={},Xo.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r<u;)n[e=arguments[r]]=f(n,t,t[e]);return n};var sa=["webkit","ms","moz","Moz","o","O"];Xo.dispatch=function(){for(var n=new p,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=v(n);return n},p.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.substring(e+1),n=n.substring(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},Xo.event=null,Xo.requote=function(n){return n.replace(la,"\\$&")};var la=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,fa={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},ha=function(n,t){return t.querySelector(n)},ga=function(n,t){return t.querySelectorAll(n)},pa=Jo[h(Jo,"matchesSelector")],va=function(n,t){return pa.call(n,t)};"function"==typeof Sizzle&&(ha=function(n,t){return Sizzle(n,t)[0]||null},ga=Sizzle,va=Sizzle.matchesSelector),Xo.selection=function(){return xa};var da=Xo.selection.prototype=[];da.select=function(n){var t,e,r,u,i=[];n=M(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var c=-1,s=r.length;++c<s;)(u=r[c])?(t.push(e=n.call(u,u.__data__,c,o)),e&&"__data__"in u&&(e.__data__=u.__data__)):t.push(null)}return x(i)},da.selectAll=function(n){var t,e,r=[];n=_(n);for(var u=-1,i=this.length;++u<i;)for(var o=this[u],a=-1,c=o.length;++a<c;)(e=o[a])&&(r.push(t=Bo(n.call(e,e.__data__,a,u))),t.parentNode=e);return x(r)};var ma={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};Xo.ns={prefix:ma,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&(e=n.substring(0,t),n=n.substring(t+1)),ma.hasOwnProperty(e)?{space:ma[e],local:n}:n}},da.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=Xo.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(b(t,n[t]));return this}return this.each(b(n,t))},da.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=k(n)).length,u=-1;if(t=e.classList){for(;++u<r;)if(!t.contains(n[u]))return!1}else for(t=e.getAttribute("class");++u<r;)if(!S(n[u]).test(t))return!1;return!0}for(t in n)this.each(E(t,n[t]));return this}return this.each(E(n,t))},da.style=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(C(e,n[e],t));return this}if(2>r)return Go.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(C(n,t,e))},da.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(N(t,n[t]));return this}return this.each(N(n,t))},da.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},da.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},da.append=function(n){return n=L(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},da.insert=function(n,t){return n=L(n),t=M(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},da.remove=function(){return this.each(function(){var n=this.parentNode;n&&n.removeChild(this)})},da.data=function(n,t){function e(n,e){var r,i,o,a=n.length,f=e.length,h=Math.min(a,f),g=new Array(f),p=new Array(f),v=new Array(a);if(t){var d,m=new u,y=new u,x=[];for(r=-1;++r<a;)d=t.call(i=n[r],i.__data__,r),m.has(d)?v[r]=i:m.set(d,i),x.push(d);for(r=-1;++r<f;)d=t.call(e,o=e[r],r),(i=m.get(d))?(g[r]=i,i.__data__=o):y.has(d)||(p[r]=T(o)),y.set(d,o),m.remove(d);for(r=-1;++r<a;)m.has(x[r])&&(v[r]=n[r])}else{for(r=-1;++r<h;)i=n[r],o=e[r],i?(i.__data__=o,g[r]=i):p[r]=T(o);for(;f>r;++r)p[r]=T(e[r]);for(;a>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,c.push(p),s.push(g),l.push(v)}var r,i,o=-1,a=this.length;if(!arguments.length){for(n=new Array(a=(r=this[0]).length);++o<a;)(i=r[o])&&(n[o]=i.__data__);return n}var c=D([]),s=x([]),l=x([]);if("function"==typeof n)for(;++o<a;)e(r=this[o],n.call(r,r.parentNode.__data__,o));else for(;++o<a;)e(r=this[o],n);return s.enter=function(){return c},s.exit=function(){return l},s},da.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},da.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=q(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return x(u)},da.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],u=r.length-1,i=r[u];--u>=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},da.sort=function(n){n=z.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},da.each=function(n){return R(this,function(t,e,r){n.call(t,t.__data__,e,r)})},da.call=function(n){var t=Bo(arguments);return n.apply(t[0]=this,t),this},da.empty=function(){return!this.node()},da.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},da.size=function(){var n=0;return this.each(function(){++n}),n};var ya=[];Xo.selection.enter=D,Xo.selection.enter.prototype=ya,ya.append=da.append,ya.empty=da.empty,ya.node=da.node,ya.call=da.call,ya.size=da.size,ya.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++a<c;){r=(u=this[a]).update,o.push(t=[]),t.parentNode=u.parentNode;for(var s=-1,l=u.length;++s<l;)(i=u[s])?(t.push(r[s]=e=n.call(u.parentNode,i.__data__,s,a)),e.__data__=i.__data__):t.push(null)}return x(o)},ya.insert=function(n,t){return arguments.length<2&&(t=P(this)),da.insert.call(this,n,t)},da.transition=function(){for(var n,t,e=ks||++Ls,r=[],u=Es||{time:Date.now(),ease:yu,delay:0,duration:250},i=-1,o=this.length;++i<o;){r.push(n=[]);for(var a=this[i],c=-1,s=a.length;++c<s;)(t=a[c])&&jo(t,c,e,u),n.push(t)}return Do(r,e)},da.interrupt=function(){return this.each(U)},Xo.select=function(n){var t=["string"==typeof n?ha(n,Wo):n];return t.parentNode=Jo,x([t])},Xo.selectAll=function(n){var t=Bo("string"==typeof n?ga(n,Wo):n);return t.parentNode=Jo,x([t])};var xa=Xo.select(Jo);da.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(j(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(j(n,t,e))};var Ma=Xo.map({mouseenter:"mouseover",mouseleave:"mouseout"});Ma.forEach(function(n){"on"+n in Wo&&Ma.remove(n)});var _a="onselectstart"in Wo?null:h(Jo.style,"userSelect"),ba=0;Xo.mouse=function(n){return Y(n,m())};var wa=/WebKit/.test(Go.navigator.userAgent)?-1:0;Xo.touches=function(n,t){return arguments.length<2&&(t=m().touches),t?Bo(t).map(function(t){var e=Y(n,t);return e.identifier=t.identifier,e}):[]},Xo.behavior.drag=function(){function n(){this.on("mousedown.drag",o).on("touchstart.drag",a)}function t(){return Xo.event.changedTouches[0].identifier}function e(n,t){return Xo.touches(n).filter(function(n){return n.identifier===t})[0]}function r(n,t,e,r){return function(){function o(){var n=t(l,g),e=n[0]-v[0],r=n[1]-v[1];d|=e|r,v=n,f({type:"drag",x:n[0]+c[0],y:n[1]+c[1],dx:e,dy:r})}function a(){m.on(e+"."+p,null).on(r+"."+p,null),y(d&&Xo.event.target===h),f({type:"dragend"})}var c,s=this,l=s.parentNode,f=u.of(s,arguments),h=Xo.event.target,g=n(),p=null==g?"drag":"drag-"+g,v=t(l,g),d=0,m=Xo.select(Go).on(e+"."+p,o).on(r+"."+p,a),y=O();i?(c=i.apply(s,arguments),c=[c.x-v[0],c.y-v[1]]):c=[0,0],f({type:"dragstart"})}}var u=y(n,"drag","dragstart","dragend"),i=null,o=r(g,Xo.mouse,"mousemove","mouseup"),a=r(t,e,"touchmove","touchend");return n.origin=function(t){return arguments.length?(i=t,n):i},Xo.rebind(n,u,"on")};var Sa=Math.PI,ka=2*Sa,Ea=Sa/2,Aa=1e-6,Ca=Aa*Aa,Na=Sa/180,La=180/Sa,Ta=Math.SQRT2,qa=2,za=4;Xo.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=B(v),o=i/(qa*h)*(e*W(Ta*t+v)-$(v));return[r+o*s,u+o*l,i*e/B(Ta*t+v)]}return[r+n*s,u+n*l,i*Math.exp(Ta*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],s=o-r,l=a-u,f=s*s+l*l,h=Math.sqrt(f),g=(c*c-i*i+za*f)/(2*i*qa*h),p=(c*c-i*i-za*f)/(2*c*qa*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Ta;return e.duration=1e3*y,e},Xo.behavior.zoom=function(){function n(n){n.on(A,s).on(Pa+".zoom",f).on(C,h).on("dblclick.zoom",g).on(L,l)}function t(n){return[(n[0]-S.x)/S.k,(n[1]-S.y)/S.k]}function e(n){return[n[0]*S.k+S.x,n[1]*S.k+S.y]}function r(n){S.k=Math.max(E[0],Math.min(E[1],n))}function u(n,t){t=e(t),S.x+=n[0]-t[0],S.y+=n[1]-t[1]}function i(){_&&_.domain(M.range().map(function(n){return(n-S.x)/S.k}).map(M.invert)),w&&w.domain(b.range().map(function(n){return(n-S.y)/S.k}).map(b.invert))}function o(n){n({type:"zoomstart"})}function a(n){i(),n({type:"zoom",scale:S.k,translate:[S.x,S.y]})}function c(n){n({type:"zoomend"})}function s(){function n(){l=1,u(Xo.mouse(r),g),a(i)}function e(){f.on(C,Go===r?h:null).on(N,null),p(l&&Xo.event.target===s),c(i)}var r=this,i=T.of(r,arguments),s=Xo.event.target,l=0,f=Xo.select(Go).on(C,n).on(N,e),g=t(Xo.mouse(r)),p=O();U.call(r),o(i)}function l(){function n(){var n=Xo.touches(g);return h=S.k,n.forEach(function(n){n.identifier in v&&(v[n.identifier]=t(n))}),n}function e(){for(var t=Xo.event.changedTouches,e=0,i=t.length;i>e;++e)v[t[e].identifier]=null;var o=n(),c=Date.now();if(1===o.length){if(500>c-x){var s=o[0],l=v[s.identifier];r(2*S.k),u(s,l),d(),a(p)}x=c}else if(o.length>1){var s=o[0],f=o[1],h=s[0]-f[0],g=s[1]-f[1];m=h*h+g*g}}function i(){for(var n,t,e,i,o=Xo.touches(g),c=0,s=o.length;s>c;++c,i=null)if(e=o[c],i=v[e.identifier]){if(t)break;n=e,t=i}if(i){var l=(l=e[0]-n[0])*l+(l=e[1]-n[1])*l,f=m&&Math.sqrt(l/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+i[0])/2,(t[1]+i[1])/2],r(f*h)}x=null,u(n,t),a(p)}function f(){if(Xo.event.touches.length){for(var t=Xo.event.changedTouches,e=0,r=t.length;r>e;++e)delete v[t[e].identifier];for(var u in v)return void n()}b.on(M,null).on(_,null),w.on(A,s).on(L,l),k(),c(p)}var h,g=this,p=T.of(g,arguments),v={},m=0,y=Xo.event.changedTouches[0].identifier,M="touchmove.zoom-"+y,_="touchend.zoom-"+y,b=Xo.select(Go).on(M,i).on(_,f),w=Xo.select(g).on(A,null).on(L,e),k=O();U.call(g),e(),o(p)}function f(){var n=T.of(this,arguments);m?clearTimeout(m):(U.call(this),o(n)),m=setTimeout(function(){m=null,c(n)},50),d();var e=v||Xo.mouse(this);p||(p=t(e)),r(Math.pow(2,.002*Ra())*S.k),u(e,p),a(n)}function h(){p=null}function g(){var n=T.of(this,arguments),e=Xo.mouse(this),i=t(e),s=Math.log(S.k)/Math.LN2;o(n),r(Math.pow(2,Xo.event.shiftKey?Math.ceil(s)-1:Math.floor(s)+1)),u(e,i),a(n),c(n)}var p,v,m,x,M,_,b,w,S={x:0,y:0,k:1},k=[960,500],E=Da,A="mousedown.zoom",C="mousemove.zoom",N="mouseup.zoom",L="touchstart.zoom",T=y(n,"zoomstart","zoom","zoomend");return n.event=function(n){n.each(function(){var n=T.of(this,arguments),t=S;ks?Xo.select(this).transition().each("start.zoom",function(){S=this.__chart__||{x:0,y:0,k:1},o(n)}).tween("zoom:zoom",function(){var e=k[0],r=k[1],u=e/2,i=r/2,o=Xo.interpolateZoom([(u-S.x)/S.k,(i-S.y)/S.k,e/S.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),c=e/r[2];this.__chart__=S={x:u-r[0]*c,y:i-r[1]*c,k:c},a(n)}}).each("end.zoom",function(){c(n)}):(this.__chart__=S,o(n),a(n),c(n))})},n.translate=function(t){return arguments.length?(S={x:+t[0],y:+t[1],k:S.k},i(),n):[S.x,S.y]},n.scale=function(t){return arguments.length?(S={x:S.x,y:S.y,k:+t},i(),n):S.k},n.scaleExtent=function(t){return arguments.length?(E=null==t?Da:[+t[0],+t[1]],n):E},n.center=function(t){return arguments.length?(v=t&&[+t[0],+t[1]],n):v},n.size=function(t){return arguments.length?(k=t&&[+t[0],+t[1]],n):k},n.x=function(t){return arguments.length?(_=t,M=t.copy(),S={x:0,y:0,k:1},n):_},n.y=function(t){return arguments.length?(w=t,b=t.copy(),S={x:0,y:0,k:1},n):w},Xo.rebind(n,T,"on")};var Ra,Da=[0,1/0],Pa="onwheel"in Wo?(Ra=function(){return-Xo.event.deltaY*(Xo.event.deltaMode?120:1)},"wheel"):"onmousewheel"in Wo?(Ra=function(){return Xo.event.wheelDelta},"mousewheel"):(Ra=function(){return-Xo.event.detail},"MozMousePixelScroll");G.prototype.toString=function(){return this.rgb()+""},Xo.hsl=function(n,t,e){return 1===arguments.length?n instanceof Q?K(n.h,n.s,n.l):dt(""+n,mt,K):K(+n,+t,+e)};var Ua=Q.prototype=new G;Ua.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),K(this.h,this.s,this.l/n)},Ua.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),K(this.h,this.s,n*this.l)},Ua.rgb=function(){return nt(this.h,this.s,this.l)},Xo.hcl=function(n,t,e){return 1===arguments.length?n instanceof et?tt(n.h,n.c,n.l):n instanceof it?at(n.l,n.a,n.b):at((n=yt((n=Xo.rgb(n)).r,n.g,n.b)).l,n.a,n.b):tt(+n,+t,+e)};var ja=et.prototype=new G;ja.brighter=function(n){return tt(this.h,this.c,Math.min(100,this.l+Ha*(arguments.length?n:1)))},ja.darker=function(n){return tt(this.h,this.c,Math.max(0,this.l-Ha*(arguments.length?n:1)))},ja.rgb=function(){return rt(this.h,this.c,this.l).rgb()},Xo.lab=function(n,t,e){return 1===arguments.length?n instanceof it?ut(n.l,n.a,n.b):n instanceof et?rt(n.l,n.c,n.h):yt((n=Xo.rgb(n)).r,n.g,n.b):ut(+n,+t,+e)};var Ha=18,Fa=.95047,Oa=1,Ya=1.08883,Ia=it.prototype=new G;Ia.brighter=function(n){return ut(Math.min(100,this.l+Ha*(arguments.length?n:1)),this.a,this.b)},Ia.darker=function(n){return ut(Math.max(0,this.l-Ha*(arguments.length?n:1)),this.a,this.b)},Ia.rgb=function(){return ot(this.l,this.a,this.b)},Xo.rgb=function(n,t,e){return 1===arguments.length?n instanceof pt?gt(n.r,n.g,n.b):dt(""+n,gt,nt):gt(~~n,~~t,~~e)};var Za=pt.prototype=new G;Za.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),gt(Math.min(255,~~(t/n)),Math.min(255,~~(e/n)),Math.min(255,~~(r/n)))):gt(u,u,u)},Za.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),gt(~~(n*this.r),~~(n*this.g),~~(n*this.b))},Za.hsl=function(){return mt(this.r,this.g,this.b)},Za.toString=function(){return"#"+vt(this.r)+vt(this.g)+vt(this.b)};var Va=Xo.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});Va.forEach(function(n,t){Va.set(n,ft(t))}),Xo.functor=_t,Xo.xhr=wt(bt),Xo.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=St(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(l>=s)return o;if(u)return u=!1,i;var t=l;if(34===n.charCodeAt(t)){for(var e=t;e++<s;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}l=e+2;var r=n.charCodeAt(e+1);return 13===r?(u=!0,10===n.charCodeAt(e+2)&&++l):10===r&&(u=!0),n.substring(t+1,e).replace(/""/g,'"')}for(;s>l;){var r=n.charCodeAt(l++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(l)&&(++l,++a);else if(r!==c)continue;return n.substring(t,l-a)}return n.substring(t)}for(var r,u,i={},o={},a=[],s=n.length,l=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();(!t||(h=t(h,f++)))&&a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new l,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},Xo.csv=Xo.dsv(",","text/csv"),Xo.tsv=Xo.dsv("	","text/tab-separated-values");var Xa,$a,Ba,Wa,Ja,Ga=Go[h(Go,"requestAnimationFrame")]||function(n){setTimeout(n,17)};Xo.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};$a?$a.n=i:Xa=i,$a=i,Ba||(Wa=clearTimeout(Wa),Ba=1,Ga(Et))},Xo.timer.flush=function(){At(),Ct()},Xo.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var Ka=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Lt);Xo.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=Xo.round(n,Nt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((0>=e?e+1:e-1)/3)))),Ka[8+e/3]};var Qa=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,nc=Xo.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=Xo.round(n,Nt(n,t))).toFixed(Math.max(0,Math.min(20,Nt(n*(1+1e-15),t))))}}),tc=Xo.time={},ec=Date;zt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){rc.setUTCDate.apply(this._,arguments)},setDay:function(){rc.setUTCDay.apply(this._,arguments)},setFullYear:function(){rc.setUTCFullYear.apply(this._,arguments)},setHours:function(){rc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){rc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){rc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){rc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){rc.setUTCSeconds.apply(this._,arguments)},setTime:function(){rc.setTime.apply(this._,arguments)}};var rc=Date.prototype;tc.year=Rt(function(n){return n=tc.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),tc.years=tc.year.range,tc.years.utc=tc.year.utc.range,tc.day=Rt(function(n){var t=new ec(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),tc.days=tc.day.range,tc.days.utc=tc.day.utc.range,tc.dayOfYear=function(n){var t=tc.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=tc[n]=Rt(function(n){return(n=tc.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=tc.year(n).getDay();return Math.floor((tc.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});tc[n+"s"]=e.range,tc[n+"s"].utc=e.utc.range,tc[n+"OfYear"]=function(n){var e=tc.year(n).getDay();return Math.floor((tc.dayOfYear(n)+(e+t)%7)/7)}}),tc.week=tc.sunday,tc.weeks=tc.sunday.range,tc.weeks.utc=tc.sunday.utc.range,tc.weekOfYear=tc.sundayOfYear;var uc={"-":"",_:" ",0:"0"},ic=/^\s*\d+/,oc=/^%/;Xo.locale=function(n){return{numberFormat:Tt(n),timeFormat:Pt(n)}};var ac=Xo.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});Xo.format=ac.numberFormat,Xo.geo={},re.prototype={s:0,t:0,add:function(n){ue(n,this.t,cc),ue(cc.s,this.s,this),this.s?this.t+=cc.t:this.s=cc.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var cc=new re;Xo.geo.stream=function(n,t){n&&sc.hasOwnProperty(n.type)?sc[n.type](n,t):ie(n,t)};var sc={Feature:function(n,t){ie(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++r<u;)ie(e[r].geometry,t)}},lc={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){oe(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)oe(e[r],t,0)},Polygon:function(n,t){ae(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)ae(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,u=e.length;++r<u;)ie(e[r],t)}};Xo.geo.area=function(n){return fc=0,Xo.geo.stream(n,gc),fc};var fc,hc=new re,gc={sphere:function(){fc+=4*Sa},point:g,lineStart:g,lineEnd:g,polygonStart:function(){hc.reset(),gc.lineStart=ce},polygonEnd:function(){var n=2*hc;fc+=0>n?4*Sa+n:n,gc.lineStart=gc.lineEnd=gc.point=g}};Xo.geo.bounds=function(){function n(n,t){x.push(M=[l=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=se([t*Na,e*Na]);if(m){var u=fe(m,r),i=[u[1],-u[0],0],o=fe(i,u);pe(o),o=ve(o);var c=t-p,s=c>0?1:-1,v=o[0]*La*s,d=oa(c)>180;if(d^(v>s*p&&s*t>v)){var y=o[1]*La;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>s*p&&s*t>v)){var y=-o[1]*La;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t):h>=l?(l>t&&(l=t),t>h&&(h=t)):t>p?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t)}else n(t,e);m=r,p=t}function e(){_.point=t}function r(){M[0]=l,M[1]=h,_.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=oa(r)>180?r+(r>0?360:-360):r}else v=n,d=e;gc.point(n,e),t(n,e)}function i(){gc.lineStart()}function o(){u(v,d),gc.lineEnd(),oa(y)>Aa&&(l=-(h=180)),M[0]=l,M[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function s(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var l,f,h,g,p,v,d,m,y,x,M,_={point:n,lineStart:e,lineEnd:r,polygonStart:function(){_.point=u,_.lineStart=i,_.lineEnd=o,y=0,gc.polygonStart()},polygonEnd:function(){gc.polygonEnd(),_.point=n,_.lineStart=e,_.lineEnd=r,0>hc?(l=-(h=180),f=-(g=90)):y>Aa?g=90:-Aa>y&&(f=-90),M[0]=l,M[1]=h}};return function(n){g=h=-(l=f=1/0),x=[],Xo.geo.stream(n,_);var t=x.length;if(t){x.sort(c);for(var e,r=1,u=x[0],i=[u];t>r;++r)e=x[r],s(e[0],u)||s(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,l=e[0],h=u[1])}return x=M=null,1/0===l||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[l,f],[h,g]]}}(),Xo.geo.centroid=function(n){pc=vc=dc=mc=yc=xc=Mc=_c=bc=wc=Sc=0,Xo.geo.stream(n,kc);var t=bc,e=wc,r=Sc,u=t*t+e*e+r*r;return Ca>u&&(t=xc,e=Mc,r=_c,Aa>vc&&(t=dc,e=mc,r=yc),u=t*t+e*e+r*r,Ca>u)?[0/0,0/0]:[Math.atan2(e,t)*La,X(r/Math.sqrt(u))*La]};var pc,vc,dc,mc,yc,xc,Mc,_c,bc,wc,Sc,kc={sphere:g,point:me,lineStart:xe,lineEnd:Me,polygonStart:function(){kc.lineStart=_e},polygonEnd:function(){kc.lineStart=xe}},Ec=Ee(be,Te,ze,[-Sa,-Sa/2]),Ac=1e9;Xo.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Pe(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(Xo.geo.conicEqualArea=function(){return je(He)}).raw=He,Xo.geo.albers=function(){return Xo.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},Xo.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=Xo.geo.albers(),o=Xo.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=Xo.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var s=i.scale(),l=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[l-.455*s,f-.238*s],[l+.455*s,f+.238*s]]).stream(c).point,r=o.translate([l-.307*s,f+.201*s]).clipExtent([[l-.425*s+Aa,f+.12*s+Aa],[l-.214*s-Aa,f+.234*s-Aa]]).stream(c).point,u=a.translate([l-.205*s,f+.212*s]).clipExtent([[l-.214*s+Aa,f+.166*s+Aa],[l-.115*s-Aa,f+.234*s-Aa]]).stream(c).point,n},n.scale(1070)};var Cc,Nc,Lc,Tc,qc,zc,Rc={point:g,lineStart:g,lineEnd:g,polygonStart:function(){Nc=0,Rc.lineStart=Fe},polygonEnd:function(){Rc.lineStart=Rc.lineEnd=Rc.point=g,Cc+=oa(Nc/2)}},Dc={point:Oe,lineStart:g,lineEnd:g,polygonStart:g,polygonEnd:g},Pc={point:Ze,lineStart:Ve,lineEnd:Xe,polygonStart:function(){Pc.lineStart=$e},polygonEnd:function(){Pc.point=Ze,Pc.lineStart=Ve,Pc.lineEnd=Xe}};Xo.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),Xo.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Cc=0,Xo.geo.stream(n,u(Rc)),Cc},n.centroid=function(n){return dc=mc=yc=xc=Mc=_c=bc=wc=Sc=0,Xo.geo.stream(n,u(Pc)),Sc?[bc/Sc,wc/Sc]:_c?[xc/_c,Mc/_c]:yc?[dc/yc,mc/yc]:[0/0,0/0]},n.bounds=function(n){return qc=zc=-(Lc=Tc=1/0),Xo.geo.stream(n,u(Dc)),[[Lc,Tc],[qc,zc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||Je(n):bt,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new Ye:new Be(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(Xo.geo.albersUsa()).context(null)},Xo.geo.transform=function(n){return{stream:function(t){var e=new Ge(t);for(var r in n)e[r]=n[r];return e}}},Ge.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},Xo.geo.projection=Qe,Xo.geo.projectionMutator=nr,(Xo.geo.equirectangular=function(){return Qe(er)}).raw=er.invert=er,Xo.geo.rotation=function(n){function t(t){return t=n(t[0]*Na,t[1]*Na),t[0]*=La,t[1]*=La,t}return n=ur(n[0]%360*Na,n[1]*Na,n.length>2?n[2]*Na:0),t.invert=function(t){return t=n.invert(t[0]*Na,t[1]*Na),t[0]*=La,t[1]*=La,t},t},rr.invert=er,Xo.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=ur(-n[0]*Na,-n[1]*Na,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=La,n[1]*=La}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=cr((t=+r)*Na,u*Na),n):t},n.precision=function(r){return arguments.length?(e=cr(t*Na,(u=+r)*Na),n):u},n.angle(90)},Xo.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Na,u=n[1]*Na,i=t[1]*Na,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),s=Math.cos(u),l=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=s*l-c*f*a)*e),c*l+s*f*a)},Xo.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return Xo.range(Math.ceil(i/d)*d,u,d).map(h).concat(Xo.range(Math.ceil(s/m)*m,c,m).map(g)).concat(Xo.range(Math.ceil(r/p)*p,e,p).filter(function(n){return oa(n%d)>Aa}).map(l)).concat(Xo.range(Math.ceil(a/v)*v,o,v).filter(function(n){return oa(n%m)>Aa}).map(f))}var e,r,u,i,o,a,c,s,l,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(s).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],s=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),s>c&&(t=s,s=c,c=t),n.precision(y)):[[i,s],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,l=lr(a,o,90),f=fr(r,e,y),h=lr(s,c,90),g=fr(i,u,y),n):y},n.majorExtent([[-180,-90+Aa],[180,90-Aa]]).minorExtent([[-180,-80-Aa],[180,80+Aa]])},Xo.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=hr,u=gr;return n.distance=function(){return Xo.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},Xo.geo.interpolate=function(n,t){return pr(n[0]*Na,n[1]*Na,t[0]*Na,t[1]*Na)},Xo.geo.length=function(n){return Uc=0,Xo.geo.stream(n,jc),Uc};var Uc,jc={sphere:g,point:g,lineStart:vr,lineEnd:g,polygonStart:g,polygonEnd:g},Hc=dr(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(Xo.geo.azimuthalEqualArea=function(){return Qe(Hc)}).raw=Hc;var Fc=dr(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},bt);(Xo.geo.azimuthalEquidistant=function(){return Qe(Fc)}).raw=Fc,(Xo.geo.conicConformal=function(){return je(mr)}).raw=mr,(Xo.geo.conicEquidistant=function(){return je(yr)}).raw=yr;var Oc=dr(function(n){return 1/n},Math.atan);(Xo.geo.gnomonic=function(){return Qe(Oc)}).raw=Oc,xr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Ea]},(Xo.geo.mercator=function(){return Mr(xr)}).raw=xr;var Yc=dr(function(){return 1},Math.asin);(Xo.geo.orthographic=function(){return Qe(Yc)}).raw=Yc;var Ic=dr(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(Xo.geo.stereographic=function(){return Qe(Ic)}).raw=Ic,_r.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Ea]},(Xo.geo.transverseMercator=function(){var n=Mr(_r),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[-n[1],n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},n.rotate([0,0])}).raw=_r,Xo.geom={},Xo.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=_t(e),i=_t(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(kr),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var s=Sr(a),l=Sr(c),f=l[0]===s[0],h=l[l.length-1]===s[s.length-1],g=[];for(t=s.length-1;t>=0;--t)g.push(n[a[s[t]][2]]);for(t=+f;t<l.length-h;++t)g.push(n[a[l[t]][2]]);return g}var e=br,r=wr;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},Xo.geom.polygon=function(n){return fa(n,Zc),n};var Zc=Xo.geom.polygon.prototype=[];Zc.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],u=0;++t<e;)n=r,r=this[t],u+=n[1]*r[0]-n[0]*r[1];return.5*u},Zc.centroid=function(n){var t,e,r=-1,u=this.length,i=0,o=0,a=this[u-1];for(arguments.length||(n=-1/(6*this.area()));++r<u;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],i+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[i*n,o*n]},Zc.clip=function(n){for(var t,e,r,u,i,o,a=Cr(n),c=-1,s=this.length-Cr(this),l=this[s-1];++c<s;){for(t=n.slice(),n.length=0,u=this[c],i=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],Er(o,l,u)?(Er(i,l,u)||n.push(Ar(i,o,l,u)),n.push(o)):Er(i,l,u)&&n.push(Ar(i,o,l,u)),i=o;a&&n.push(n[0]),l=u}return n};var Vc,Xc,$c,Bc,Wc,Jc=[],Gc=[];Pr.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(jr),t.length},Br.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},Wr.prototype={insert:function(n,t){var e,r,u;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=Qr(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(u=r.R,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.R&&(Gr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Kr(this,r))):(u=r.L,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.L&&(Kr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Gr(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,u=n.U,i=n.L,o=n.R;if(e=i?o?Qr(o):i:o,u?u.L===n?u.L=e:u.R=e:this._=e,i&&o?(r=e.C,e.C=n.C,e.L=i,i.U=e,e!==o?(u=e.U,e.U=n.U,n=e.R,u.L=n,e.R=o,o.U=e):(e.U=u,u=e,n=e.R)):(r=n.C,n=e),n&&(n.U=u),!r){if(n&&n.C)return n.C=!1,void 0;do{if(n===this._)break;if(n===u.L){if(t=u.R,t.C&&(t.C=!1,u.C=!0,Gr(this,u),t=u.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,Kr(this,t),t=u.R),t.C=u.C,u.C=t.R.C=!1,Gr(this,u),n=this._;break}}else if(t=u.L,t.C&&(t.C=!1,u.C=!0,Kr(this,u),t=u.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,Gr(this,t),t=u.L),t.C=u.C,u.C=t.L.C=!1,Kr(this,u),n=this._;break}t.C=!0,n=u,u=u.U}while(!n.C);n&&(n.C=!1)}}},Xo.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],u=a[0][1],i=a[1][0],o=a[1][1];return nu(e(n),a).cells.forEach(function(e,a){var c=e.edges,s=e.site,l=t[a]=c.length?c.map(function(n){var t=n.start();return[t.x,t.y]}):s.x>=r&&s.x<=i&&s.y>=u&&s.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];l.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Aa)*Aa,y:Math.round(o(n,t)/Aa)*Aa,i:t}})}var r=br,u=wr,i=r,o=u,a=Kc;return n?t(n):(t.links=function(n){return nu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return nu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(jr),c=-1,s=a.length,l=a[s-1].edge,f=l.l===o?l.r:l.l;++c<s;)u=l,i=f,l=a[c].edge,f=l.l===o?l.r:l.l,r<i.i&&r<f.i&&eu(o,i,f)<0&&t.push([n[r],n[i.i],n[f.i]])}),t},t.x=function(n){return arguments.length?(i=_t(r=n),t):r},t.y=function(n){return arguments.length?(o=_t(u=n),t):u},t.clipExtent=function(n){return arguments.length?(a=null==n?Kc:n,t):a===Kc?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===Kc?null:a&&a[1]},t)};var Kc=[[-1e6,-1e6],[1e6,1e6]];Xo.geom.delaunay=function(n){return Xo.geom.voronoi().triangles(n)},Xo.geom.quadtree=function(n,t,e,r,u){function i(n){function i(n,t,e,r,u,i,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var c=n.x,l=n.y;if(null!=c)if(oa(c-e)+oa(l-r)<.01)s(n,t,e,r,u,i,o,a);else{var f=n.point;n.x=n.y=n.point=null,s(n,f,c,l,u,i,o,a),s(n,t,e,r,u,i,o,a)}else n.x=e,n.y=r,n.point=t}else s(n,t,e,r,u,i,o,a)}function s(n,t,e,r,u,o,a,c){var s=.5*(u+a),l=.5*(o+c),f=e>=s,h=r>=l,g=(h<<1)+f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=iu()),f?u=s:a=s,h?o=l:c=l,i(n,t,e,r,u,o,a,c)}var l,f,h,g,p,v,d,m,y,x=_t(a),M=_t(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)l=n[g],l.x<v&&(v=l.x),l.y<d&&(d=l.y),l.x>m&&(m=l.x),l.y>y&&(y=l.y),f.push(l.x),h.push(l.y);else for(g=0;p>g;++g){var _=+x(l=n[g],g),b=+M(l,g);v>_&&(v=_),d>b&&(d=b),_>m&&(m=_),b>y&&(y=b),f.push(_),h.push(b)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=iu();if(k.add=function(n){i(k,n,+x(n,++g),+M(n,g),v,d,m,y)},k.visit=function(n){ou(n,k,v,d,m,y)},g=-1,null==t){for(;++g<p;)i(k,n[g],f[g],h[g],v,d,m,y);--g}else n.forEach(k.add);return f=h=n=l=null,k}var o,a=br,c=wr;return(o=arguments.length)?(a=ru,c=uu,3===o&&(u=e,r=t,e=t=0),i(n)):(i.x=function(n){return arguments.length?(a=n,i):a},i.y=function(n){return arguments.length?(c=n,i):c},i.extent=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],u=+n[1][1]),i):null==t?null:[[t,e],[r,u]]},i.size=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=e=0,r=+n[0],u=+n[1]),i):null==t?null:[r-t,u-e]},i)},Xo.interpolateRgb=au,Xo.interpolateObject=cu,Xo.interpolateNumber=su,Xo.interpolateString=lu;var Qc=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g;Xo.interpolate=fu,Xo.interpolators=[function(n,t){var e=typeof t;return("string"===e?Va.has(t)||/^(#|rgb\(|hsl\()/.test(t)?au:lu:t instanceof G?au:"object"===e?Array.isArray(t)?hu:cu:su)(n,t)}],Xo.interpolateArray=hu;var ns=function(){return bt},ts=Xo.map({linear:ns,poly:xu,quad:function(){return du},cubic:function(){return mu},sin:function(){return Mu},exp:function(){return _u},circle:function(){return bu},elastic:wu,back:Su,bounce:function(){return ku}}),es=Xo.map({"in":bt,out:pu,"in-out":vu,"out-in":function(n){return vu(pu(n))}});Xo.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.substring(0,t):n,r=t>=0?n.substring(t+1):"in";return e=ts.get(e)||ns,r=es.get(r)||bt,gu(r(e.apply(null,$o.call(arguments,1))))},Xo.interpolateHcl=Eu,Xo.interpolateHsl=Au,Xo.interpolateLab=Cu,Xo.interpolateRound=Nu,Xo.transform=function(n){var t=Wo.createElementNS(Xo.ns.prefix.svg,"g");return(Xo.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Lu(e?e.matrix:rs)})(n)},Lu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var rs={a:1,b:0,c:0,d:1,e:0,f:0};Xo.interpolateTransform=Ru,Xo.layout={},Xo.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(Uu(n[e]));return t}},Xo.layout.chord=function(){function n(){var n,s,f,h,g,p={},v=[],d=Xo.range(i),m=[];for(e=[],r=[],n=0,h=-1;++h<i;){for(s=0,g=-1;++g<i;)s+=u[h][g];v.push(s),m.push(Xo.range(i)),n+=s}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&m.forEach(function(n,t){n.sort(function(n,e){return a(u[t][n],u[t][e])})}),n=(ka-l*i)/n,s=0,h=-1;++h<i;){for(f=s,g=-1;++g<i;){var y=d[h],x=m[y][g],M=u[y][x],_=s,b=s+=M*n;p[y+"-"+x]={index:y,subindex:x,startAngle:_,endAngle:b,value:M}}r[y]={index:y,startAngle:f,endAngle:s,value:(s-f)/n},s+=l}for(h=-1;++h<i;)for(g=h-1;++g<i;){var w=p[h+"-"+g],S=p[g+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}c&&t()}function t(){e.sort(function(n,t){return c((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,u,i,o,a,c,s={},l=0;return s.matrix=function(n){return arguments.length?(i=(u=n)&&u.length,e=r=null,s):u},s.padding=function(n){return arguments.length?(l=n,e=r=null,s):l},s.sortGroups=function(n){return arguments.length?(o=n,e=r=null,s):o},s.sortSubgroups=function(n){return arguments.length?(a=n,e=null,s):a},s.sortChords=function(n){return arguments.length?(c=n,e&&t(),s):c},s.chords=function(){return e||n(),e},s.groups=function(){return r||n(),r},s},Xo.layout.force=function(){function n(n){return function(t,e,r,u){if(t.point!==n){var i=t.cx-n.x,o=t.cy-n.y,a=u-e,c=i*i+o*o;if(c>a*a/d){if(p>c){var s=t.charge/c;n.px-=i*s,n.py-=o*s}return!0}if(t.point&&c&&p>c){var s=t.pointCharge/c;n.px-=i*s,n.py-=o*s}}return!t.charge}}function t(n){n.px=Xo.event.x,n.py=Xo.event.y,a.resume()}var e,r,u,i,o,a={},c=Xo.dispatch("start","tick","end"),s=[1,1],l=.9,f=us,h=is,g=-30,p=os,v=.1,d=.64,m=[],y=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,x,M,_=m.length,b=y.length;for(e=0;b>e;++e)a=y[e],f=a.source,h=a.target,x=h.x-f.x,M=h.y-f.y,(p=x*x+M*M)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,x*=p,M*=p,h.x-=x*(d=f.weight/(h.weight+f.weight)),h.y-=M*d,f.x+=x*(d=1-d),f.y+=M*d);if((d=r*v)&&(x=s[0]/2,M=s[1]/2,e=-1,d))for(;++e<_;)a=m[e],a.x+=(x-a.x)*d,a.y+=(M-a.y)*d;if(g)for(Zu(t=Xo.geom.quadtree(m),r,o),e=-1;++e<_;)(a=m[e]).fixed||t.visit(n(a));for(e=-1;++e<_;)a=m[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*l,a.y-=(a.py-(a.py=a.y))*l);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(m=n,a):m},a.links=function(n){return arguments.length?(y=n,a):y},a.size=function(n){return arguments.length?(s=n,a):s},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(l=+n,a):l},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.chargeDistance=function(n){return arguments.length?(p=n*n,a):Math.sqrt(p)},a.gravity=function(n){return arguments.length?(v=+n,a):v},a.theta=function(n){return arguments.length?(d=n*n,a):Math.sqrt(d)},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),Xo.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=y[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,s=o.length;++a<s;)if(!isNaN(i=o[a][n]))return i;return Math.random()*r}var t,e,r,c=m.length,l=y.length,p=s[0],v=s[1];for(t=0;c>t;++t)(r=m[t]).index=t,r.weight=0;for(t=0;l>t;++t)r=y[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;l>t;++t)u[t]=+f.call(this,y[t],t);else for(t=0;l>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;l>t;++t)i[t]=+h.call(this,y[t],t);else for(t=0;l>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=Xo.behavior.drag().origin(bt).on("dragstart.force",Fu).on("drag.force",t).on("dragend.force",Ou)),arguments.length?(this.on("mouseover.force",Yu).on("mouseout.force",Iu).call(e),void 0):e},Xo.rebind(a,c,"on")};var us=20,is=1,os=1/0;Xo.layout.hierarchy=function(){function n(t,o,a){var c=u.call(e,t,o);if(t.depth=o,a.push(t),c&&(s=c.length)){for(var s,l,f=-1,h=t.children=new Array(s),g=0,p=o+1;++f<s;)l=h[f]=n(c[f],p,a),l.parent=t,g+=l.value;r&&h.sort(r),i&&(t.value=g)}else delete t.children,i&&(t.value=+i.call(e,t,o)||0);return t}function t(n,r){var u=n.children,o=0;if(u&&(a=u.length))for(var a,c=-1,s=r+1;++c<a;)o+=t(u[c],s);else i&&(o=+i.call(e,n,r)||0);return i&&(n.value=o),o}function e(t){var e=[];return n(t,0,e),e}var r=Bu,u=Xu,i=$u;return e.sort=function(n){return arguments.length?(r=n,e):r},e.children=function(n){return arguments.length?(u=n,e):u},e.value=function(n){return arguments.length?(i=n,e):i},e.revalue=function(n){return t(n,0),n},e},Xo.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,s=-1;for(r=t.value?r/t.value:0;++s<o;)n(a=i[s],e,c=a.value*r,u),e+=c}}function t(n){var e=n.children,r=0;if(e&&(u=e.length))for(var u,i=-1;++i<u;)r=Math.max(r,t(e[i]));return 1+r}function e(e,i){var o=r.call(this,e,i);return n(o[0],0,u[0],u[1]/t(o[0])),o}var r=Xo.layout.hierarchy(),u=[1,1];return e.size=function(n){return arguments.length?(u=n,e):u},Vu(e,r)},Xo.layout.pie=function(){function n(i){var o=i.map(function(e,r){return+t.call(n,e,r)}),a=+("function"==typeof r?r.apply(this,arguments):r),c=(("function"==typeof u?u.apply(this,arguments):u)-a)/Xo.sum(o),s=Xo.range(i.length);null!=e&&s.sort(e===as?function(n,t){return o[t]-o[n]}:function(n,t){return e(i[n],i[t])});var l=[];return s.forEach(function(n){var t;l[n]={data:i[n],value:t=o[n],startAngle:a,endAngle:a+=t*c}}),l}var t=Number,e=as,r=0,u=ka;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n};var as={};Xo.layout.stack=function(){function n(a,c){var s=a.map(function(e,r){return t.call(n,e,r)}),l=s.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,l,c);s=Xo.permute(s,f),l=Xo.permute(l,f);var h,g,p,v=r.call(n,l,c),d=s.length,m=s[0].length;for(g=0;m>g;++g)for(u.call(n,s[0][g],p=v[g],l[0][g][1]),h=1;d>h;++h)u.call(n,s[h][g],p+=l[h-1][g][1],l[h][g][1]);return a}var t=bt,e=Qu,r=ni,u=Ku,i=Ju,o=Gu;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:cs.get(t)||Qu,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:ss.get(t)||ni,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var cs=Xo.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(ti),i=n.map(ei),o=Xo.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,s=[],l=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],s.push(e)):(c+=i[e],l.push(e));return l.reverse().concat(s)},reverse:function(n){return Xo.range(n.length).reverse()},"default":Qu}),ss=Xo.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,s,l=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=s=0,e=1;h>e;++e){for(t=0,u=0;l>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];l>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,s>c&&(s=c)}for(e=0;h>e;++e)g[e]-=s;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ni});Xo.layout.histogram=function(){function n(n,i){for(var o,a,c=[],s=n.map(e,this),l=r.call(this,s,i),f=u.call(this,l,s,i),i=-1,h=s.length,g=f.length-1,p=t?1:1/h;++i<g;)o=c[i]=[],o.dx=f[i+1]-(o.x=f[i]),o.y=0;if(g>0)for(i=-1;++i<h;)a=s[i],a>=l[0]&&a<=l[1]&&(o=c[Xo.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=oi,u=ui;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=_t(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return ii(n,t)}:_t(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},Xo.layout.tree=function(){function n(n,i){function o(n,t){var r=n.children,u=n._tree;if(r&&(i=r.length)){for(var i,a,s,l=r[0],f=l,h=-1;++h<i;)s=r[h],o(s,a),f=c(s,a,f),a=s;vi(n);var g=.5*(l._tree.prelim+s._tree.prelim);t?(u.prelim=t._tree.prelim+e(n,t),u.mod=u.prelim-g):u.prelim=g}else t&&(u.prelim=t._tree.prelim+e(n,t))}function a(n,t){n.x=n._tree.prelim+t;var e=n.children;if(e&&(r=e.length)){var r,u=-1;for(t+=n._tree.mod;++u<r;)a(e[u],t)}}function c(n,t,r){if(t){for(var u,i=n,o=n,a=t,c=n.parent.children[0],s=i._tree.mod,l=o._tree.mod,f=a._tree.mod,h=c._tree.mod;a=si(a),i=ci(i),a&&i;)c=ci(c),o=si(o),o._tree.ancestor=n,u=a._tree.prelim+f-i._tree.prelim-s+e(a,i),u>0&&(di(mi(a,n,r),n,u),s+=u,l+=u),f+=a._tree.mod,s+=i._tree.mod,h+=c._tree.mod,l+=o._tree.mod;a&&!si(o)&&(o._tree.thread=a,o._tree.mod+=f-l),i&&!ci(c)&&(c._tree.thread=i,c._tree.mod+=s-h,r=n)}return r}var s=t.call(this,n,i),l=s[0];pi(l,function(n,t){n._tree={ancestor:n,prelim:0,mod:0,change:0,shift:0,number:t?t._tree.number+1:0}}),o(l),a(l,-l._tree.prelim);var f=li(l,hi),h=li(l,fi),g=li(l,gi),p=f.x-e(f,h)/2,v=h.x+e(h,f)/2,d=g.depth||1;return pi(l,u?function(n){n.x*=r[0],n.y=n.depth*r[1],delete n._tree}:function(n){n.x=(n.x-p)/(v-p)*r[0],n.y=n.depth/d*r[1],delete n._tree}),s}var t=Xo.layout.hierarchy().sort(null).value(null),e=ai,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Vu(n,t)},Xo.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],s=u[1],l=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,pi(a,function(n){n.r=+l(n.value)}),pi(a,bi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/s))/2;pi(a,function(n){n.r+=f}),pi(a,bi),pi(a,function(n){n.r-=f})}return ki(a,c/2,s/2,t?1:1/Math.max(2*a.r/c,2*a.r/s)),o}var t,e=Xo.layout.hierarchy().sort(yi),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Vu(n,e)},Xo.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],s=0;pi(c,function(n){var t=n.children;t&&t.length?(n.x=Ci(t),n.y=Ai(t)):(n.x=o?s+=e(n,o):0,n.y=0,o=n)});var l=Ni(c),f=Li(c),h=l.x-e(l,f)/2,g=f.x+e(f,l)/2;return pi(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=Xo.layout.hierarchy().sort(null).value(null),e=ai,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Vu(n,t)},Xo.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++u<i;)r=(e=n[u]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,s=f(e),l=[],h=i.slice(),p=1/0,v="slice"===g?s.dx:"dice"===g?s.dy:"slice-dice"===g?1&e.depth?s.dy:s.dx:Math.min(s.dx,s.dy);for(n(h,s.dx*s.dy/e.value),l.area=0;(c=h.length)>0;)l.push(o=h[c-1]),l.area+=o.area,"squarify"!==g||(a=r(l,v))<=p?(h.pop(),p=a):(l.area-=l.pop().area,u(l,v,s,!1),v=Math.min(s.dx,s.dy),l.length=l.area=0,p=1/0);l.length&&(u(l,v,s,!0),l.length=l.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(i>e&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,s=e.y,l=t?c(n.area/t):0;if(t==e.dx){for((r||l>e.dy)&&(l=e.dy);++i<o;)u=n[i],u.x=a,u.y=s,u.dy=l,a+=u.dx=Math.min(e.x+e.dx-a,l?c(u.area/l):0);u.z=!0,u.dx+=e.x+e.dx-a,e.y+=l,e.dy-=l}else{for((r||l>e.dx)&&(l=e.dx);++i<o;)u=n[i],u.x=a,u.y=s,u.dx=l,s+=u.dy=Math.min(e.y+e.dy-s,l?c(u.area/l):0);u.z=!1,u.dy+=e.y+e.dy-s,e.x+=l,e.dx-=l}}function i(r){var u=o||a(r),i=u[0];return i.x=0,i.y=0,i.dx=s[0],i.dy=s[1],o&&a.revalue(i),n([i],i.dx*i.dy/i.value),(o?e:t)(i),h&&(o=u),u}var o,a=Xo.layout.hierarchy(),c=Math.round,s=[1,1],l=null,f=Ti,h=!1,g="squarify",p=.5*(1+Math.sqrt(5));return i.size=function(n){return arguments.length?(s=n,i):s},i.padding=function(n){function t(t){var e=n.call(i,t,t.depth);return null==e?Ti(t):qi(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return qi(t,n)}if(!arguments.length)return l;var r;return f=null==(l=n)?Ti:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,i},i.round=function(n){return arguments.length?(c=n?Math.round:Number,i):c!=Number},i.sticky=function(n){return arguments.length?(h=n,o=null,i):h},i.ratio=function(n){return arguments.length?(p=n,i):p},i.mode=function(n){return arguments.length?(g=n+"",i):g},Vu(i,a)},Xo.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=Xo.random.normal.apply(Xo,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=Xo.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},Xo.scale={};var ls={floor:bt,ceil:bt};Xo.scale.linear=function(){return Hi([0,1],[0,1],fu,!1)};var fs={s:1,g:1,p:1,r:1,e:1};Xo.scale.log=function(){return $i(Xo.scale.linear().domain([0,1]),10,!0,[1,10])};var hs=Xo.format(".0e"),gs={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};Xo.scale.pow=function(){return Bi(Xo.scale.linear(),1,[0,1])},Xo.scale.sqrt=function(){return Xo.scale.pow().exponent(.5)},Xo.scale.ordinal=function(){return Ji([],{t:"range",a:[[]]})},Xo.scale.category10=function(){return Xo.scale.ordinal().range(ps)},Xo.scale.category20=function(){return Xo.scale.ordinal().range(vs)},Xo.scale.category20b=function(){return Xo.scale.ordinal().range(ds)},Xo.scale.category20c=function(){return Xo.scale.ordinal().range(ms)};var ps=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(ht),vs=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(ht),ds=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(ht),ms=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(ht);Xo.scale.quantile=function(){return Gi([],[])},Xo.scale.quantize=function(){return Ki(0,1,[0,1])},Xo.scale.threshold=function(){return Qi([.5],[0,1])},Xo.scale.identity=function(){return no([0,1])},Xo.svg={},Xo.svg.arc=function(){function n(){var n=t.apply(this,arguments),i=e.apply(this,arguments),o=r.apply(this,arguments)+ys,a=u.apply(this,arguments)+ys,c=(o>a&&(c=o,o=a,a=c),a-o),s=Sa>c?"0":"1",l=Math.cos(o),f=Math.sin(o),h=Math.cos(a),g=Math.sin(a);return c>=xs?n?"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"M0,"+n+"A"+n+","+n+" 0 1,0 0,"+-n+"A"+n+","+n+" 0 1,0 0,"+n+"Z":"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"Z":n?"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L"+n*h+","+n*g+"A"+n+","+n+" 0 "+s+",0 "+n*l+","+n*f+"Z":"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L0,0"+"Z"}var t=to,e=eo,r=ro,u=uo;return n.innerRadius=function(e){return arguments.length?(t=_t(e),n):t},n.outerRadius=function(t){return arguments.length?(e=_t(t),n):e},n.startAngle=function(t){return arguments.length?(r=_t(t),n):r},n.endAngle=function(t){return arguments.length?(u=_t(t),n):u},n.centroid=function(){var n=(t.apply(this,arguments)+e.apply(this,arguments))/2,i=(r.apply(this,arguments)+u.apply(this,arguments))/2+ys;return[Math.cos(i)*n,Math.sin(i)*n]},n};var ys=-Ea,xs=ka-Aa;Xo.svg.line=function(){return io(bt)};var Ms=Xo.map({linear:oo,"linear-closed":ao,step:co,"step-before":so,"step-after":lo,basis:mo,"basis-open":yo,"basis-closed":xo,bundle:Mo,cardinal:go,"cardinal-open":fo,"cardinal-closed":ho,monotone:Eo});Ms.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var _s=[0,2/3,1/3,0],bs=[0,1/3,2/3,0],ws=[0,1/6,2/3,1/6];Xo.svg.line.radial=function(){var n=io(Ao);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},so.reverse=lo,lo.reverse=so,Xo.svg.area=function(){return Co(bt)},Xo.svg.area.radial=function(){var n=Co(Ao);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},Xo.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),s=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,s)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,s.r,s.p0)+r(s.r,s.p1,s.a1-s.a0)+u(s.r,s.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)+ys,l=s.call(n,u,r)+ys;return{r:i,a0:o,a1:l,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(l),i*Math.sin(l)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Sa)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=hr,o=gr,a=No,c=ro,s=uo;return n.radius=function(t){return arguments.length?(a=_t(t),n):a},n.source=function(t){return arguments.length?(i=_t(t),n):i},n.target=function(t){return arguments.length?(o=_t(t),n):o},n.startAngle=function(t){return arguments.length?(c=_t(t),n):c},n.endAngle=function(t){return arguments.length?(s=_t(t),n):s},n},Xo.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=hr,e=gr,r=Lo;return n.source=function(e){return arguments.length?(t=_t(e),n):t},n.target=function(t){return arguments.length?(e=_t(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},Xo.svg.diagonal.radial=function(){var n=Xo.svg.diagonal(),t=Lo,e=n.projection;return n.projection=function(n){return arguments.length?e(To(t=n)):t},n},Xo.svg.symbol=function(){function n(n,r){return(Ss.get(t.call(this,n,r))||Ro)(e.call(this,n,r))}var t=zo,e=qo;return n.type=function(e){return arguments.length?(t=_t(e),n):t},n.size=function(t){return arguments.length?(e=_t(t),n):e},n};var Ss=Xo.map({circle:Ro,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Cs)),e=t*Cs;return"M0,"+-t+"L"+e+",0"+" 0,"+t+" "+-e+",0"+"Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/As),e=t*As/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/As),e=t*As/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});Xo.svg.symbolTypes=Ss.keys();var ks,Es,As=Math.sqrt(3),Cs=Math.tan(30*Na),Ns=[],Ls=0;Ns.call=da.call,Ns.empty=da.empty,Ns.node=da.node,Ns.size=da.size,Xo.transition=function(n){return arguments.length?ks?n.transition():n:xa.transition()},Xo.transition.prototype=Ns,Ns.select=function(n){var t,e,r,u=this.id,i=[];n=M(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]);for(var c=this[o],s=-1,l=c.length;++s<l;)(r=c[s])&&(e=n.call(r,r.__data__,s,o))?("__data__"in r&&(e.__data__=r.__data__),jo(e,s,u,r.__transition__[u]),t.push(e)):t.push(null)}return Do(i,u)},Ns.selectAll=function(n){var t,e,r,u,i,o=this.id,a=[];n=_(n);for(var c=-1,s=this.length;++c<s;)for(var l=this[c],f=-1,h=l.length;++f<h;)if(r=l[f]){i=r.__transition__[o],e=n.call(r,r.__data__,f,c),a.push(t=[]);for(var g=-1,p=e.length;++g<p;)(u=e[g])&&jo(u,g,o,i),t.push(u)}return Do(a,o)},Ns.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=q(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return Do(u,this.id)},Ns.tween=function(n,t){var e=this.id;return arguments.length<2?this.node().__transition__[e].tween.get(n):R(this,null==t?function(t){t.__transition__[e].tween.remove(n)}:function(r){r.__transition__[e].tween.set(n,t)})},Ns.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Ru:fu,a=Xo.ns.qualify(n);return Po(this,"attr."+n,t,a.local?i:u)},Ns.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=Xo.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Ns.style=function(n,t,e){function r(){this.style.removeProperty(n)}function u(t){return null==t?r:(t+="",function(){var r,u=Go.getComputedStyle(this,null).getPropertyValue(n);return u!==t&&(r=fu(u,t),function(t){this.style.setProperty(n,r(t),e)})})}var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(t="");for(e in n)this.style(e,n[e],t);return this}e=""}return Po(this,"style."+n,t,u)},Ns.styleTween=function(n,t,e){function r(r,u){var i=t.call(this,r,u,Go.getComputedStyle(this,null).getPropertyValue(n));return i&&function(t){this.style.setProperty(n,i(t),e)}}return arguments.length<3&&(e=""),this.tween("style."+n,r)},Ns.text=function(n){return Po(this,"text",n,Uo)},Ns.remove=function(){return this.each("end.transition",function(){var n;this.__transition__.count<2&&(n=this.parentNode)&&n.removeChild(this)})},Ns.ease=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].ease:("function"!=typeof n&&(n=Xo.ease.apply(Xo,arguments)),R(this,function(e){e.__transition__[t].ease=n}))},Ns.delay=function(n){var t=this.id;return R(this,"function"==typeof n?function(e,r,u){e.__transition__[t].delay=+n.call(e,e.__data__,r,u)}:(n=+n,function(e){e.__transition__[t].delay=n}))},Ns.duration=function(n){var t=this.id;return R(this,"function"==typeof n?function(e,r,u){e.__transition__[t].duration=Math.max(1,n.call(e,e.__data__,r,u))}:(n=Math.max(1,n),function(e){e.__transition__[t].duration=n}))},Ns.each=function(n,t){var e=this.id;if(arguments.length<2){var r=Es,u=ks;ks=e,R(this,function(t,r,u){Es=t.__transition__[e],n.call(t,t.__data__,r,u)}),Es=r,ks=u}else R(this,function(r){var u=r.__transition__[e];(u.event||(u.event=Xo.dispatch("start","end"))).on(n,t)});return this},Ns.transition=function(){for(var n,t,e,r,u=this.id,i=++Ls,o=[],a=0,c=this.length;c>a;a++){o.push(n=[]);for(var t=this[a],s=0,l=t.length;l>s;s++)(e=t[s])&&(r=Object.create(e.__transition__[u]),r.delay+=r.duration,jo(e,s,i,r)),n.push(e)}return Do(o,i)},Xo.svg.axis=function(){function n(n){n.each(function(){var n,s=Xo.select(this),l=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):bt:t,p=s.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Aa),d=Xo.transition(p.exit()).style("opacity",Aa).remove(),m=Xo.transition(p).style("opacity",1),y=Ri(f),x=s.selectAll(".domain").data([0]),M=(x.enter().append("path").attr("class","domain"),Xo.transition(x));v.append("line"),v.append("text");var _=v.select("line"),b=m.select("line"),w=p.select("text").text(g),S=v.select("text"),k=m.select("text");switch(r){case"bottom":n=Ho,_.attr("y2",u),S.attr("y",Math.max(u,0)+o),b.attr("x2",0).attr("y2",u),k.attr("x",0).attr("y",Math.max(u,0)+o),w.attr("dy",".71em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+i+"V0H"+y[1]+"V"+i);break;case"top":n=Ho,_.attr("y2",-u),S.attr("y",-(Math.max(u,0)+o)),b.attr("x2",0).attr("y2",-u),k.attr("x",0).attr("y",-(Math.max(u,0)+o)),w.attr("dy","0em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+-i+"V0H"+y[1]+"V"+-i);break;case"left":n=Fo,_.attr("x2",-u),S.attr("x",-(Math.max(u,0)+o)),b.attr("x2",-u).attr("y2",0),k.attr("x",-(Math.max(u,0)+o)).attr("y",0),w.attr("dy",".32em").style("text-anchor","end"),M.attr("d","M"+-i+","+y[0]+"H0V"+y[1]+"H"+-i);break;case"right":n=Fo,_.attr("x2",u),S.attr("x",Math.max(u,0)+o),b.attr("x2",u).attr("y2",0),k.attr("x",Math.max(u,0)+o).attr("y",0),w.attr("dy",".32em").style("text-anchor","start"),M.attr("d","M"+i+","+y[0]+"H0V"+y[1]+"H"+i)}if(f.rangeBand){var E=f,A=E.rangeBand()/2;l=f=function(n){return E(n)+A}}else l.rangeBand?l=f:d.call(n,f);v.call(n,l),m.call(n,f)})}var t,e=Xo.scale.linear(),r=Ts,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in qs?t+"":Ts,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Ts="bottom",qs={top:1,right:1,bottom:1,left:1};Xo.svg.brush=function(){function n(i){i.each(function(){var i=Xo.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=i.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),i.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=i.selectAll(".resize").data(p,bt);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return zs[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,f=Xo.transition(i),h=Xo.transition(o);c&&(l=Ri(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),e(f)),s&&(l=Ri(s),h.attr("y",l[0]).attr("height",l[1]-l[0]),r(f)),t(f)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+l[+/e$/.test(n)]+","+f[+/^s/.test(n)]+")"})}function e(n){n.select(".extent").attr("x",l[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",l[1]-l[0])}function r(n){n.select(".extent").attr("y",f[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",f[1]-f[0])}function u(){function u(){32==Xo.event.keyCode&&(C||(x=null,L[0]-=l[1],L[1]-=f[1],C=2),d())}function p(){32==Xo.event.keyCode&&2==C&&(L[0]+=l[1],L[1]+=f[1],C=0,d())}function v(){var n=Xo.mouse(_),u=!1;M&&(n[0]+=M[0],n[1]+=M[1]),C||(Xo.event.altKey?(x||(x=[(l[0]+l[1])/2,(f[0]+f[1])/2]),L[0]=l[+(n[0]<x[0])],L[1]=f[+(n[1]<x[1])]):x=null),E&&m(n,c,0)&&(e(S),u=!0),A&&m(n,s,1)&&(r(S),u=!0),u&&(t(S),w({type:"brush",mode:C?"move":"resize"}))}function m(n,t,e){var r,u,a=Ri(t),c=a[0],s=a[1],p=L[e],v=e?f:l,d=v[1]-v[0];return C&&(c-=p,s-=d+p),r=(e?g:h)?Math.max(c,Math.min(s,n[e])):n[e],C?u=(r+=p)+d:(x&&(p=Math.max(c,Math.min(s,2*x[e]-r))),r>p?(u=r,r=p):u=p),v[0]!=r||v[1]!=u?(e?o=null:i=null,v[0]=r,v[1]=u,!0):void 0}function y(){v(),S.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),Xo.select("body").style("cursor",null),T.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),N(),w({type:"brushend"})}var x,M,_=this,b=Xo.select(Xo.event.target),w=a.of(_,arguments),S=Xo.select(_),k=b.datum(),E=!/^(n|s)$/.test(k)&&c,A=!/^(e|w)$/.test(k)&&s,C=b.classed("extent"),N=O(),L=Xo.mouse(_),T=Xo.select(Go).on("keydown.brush",u).on("keyup.brush",p);if(Xo.event.changedTouches?T.on("touchmove.brush",v).on("touchend.brush",y):T.on("mousemove.brush",v).on("mouseup.brush",y),S.interrupt().selectAll("*").interrupt(),C)L[0]=l[0]-L[0],L[1]=f[0]-L[1];else if(k){var q=+/w$/.test(k),z=+/^n/.test(k);M=[l[1-q]-L[0],f[1-z]-L[1]],L[0]=l[q],L[1]=f[z]}else Xo.event.altKey&&(x=L.slice());S.style("pointer-events","none").selectAll(".resize").style("display",null),Xo.select("body").style("cursor",b.style("cursor")),w({type:"brushstart"}),v()}var i,o,a=y(n,"brushstart","brush","brushend"),c=null,s=null,l=[0,0],f=[0,0],h=!0,g=!0,p=Rs[0];return n.event=function(n){n.each(function(){var n=a.of(this,arguments),t={x:l,y:f,i:i,j:o},e=this.__chart__||t;this.__chart__=t,ks?Xo.select(this).transition().each("start.brush",function(){i=e.i,o=e.j,l=e.x,f=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=hu(l,t.x),r=hu(f,t.y);return i=o=null,function(u){l=t.x=e(u),f=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){i=t.i,o=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,p=Rs[!c<<1|!s],n):c},n.y=function(t){return arguments.length?(s=t,p=Rs[!c<<1|!s],n):s},n.clamp=function(t){return arguments.length?(c&&s?(h=!!t[0],g=!!t[1]):c?h=!!t:s&&(g=!!t),n):c&&s?[h,g]:c?h:s?g:null},n.extent=function(t){var e,r,u,a,h;return arguments.length?(c&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),i=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(h=e,e=r,r=h),(e!=l[0]||r!=l[1])&&(l=[e,r])),s&&(u=t[0],a=t[1],c&&(u=u[1],a=a[1]),o=[u,a],s.invert&&(u=s(u),a=s(a)),u>a&&(h=u,u=a,a=h),(u!=f[0]||a!=f[1])&&(f=[u,a])),n):(c&&(i?(e=i[0],r=i[1]):(e=l[0],r=l[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(h=e,e=r,r=h))),s&&(o?(u=o[0],a=o[1]):(u=f[0],a=f[1],s.invert&&(u=s.invert(u),a=s.invert(a)),u>a&&(h=u,u=a,a=h))),c&&s?[[e,u],[r,a]]:c?[e,r]:s&&[u,a])},n.clear=function(){return n.empty()||(l=[0,0],f=[0,0],i=o=null),n},n.empty=function(){return!!c&&l[0]==l[1]||!!s&&f[0]==f[1]},Xo.rebind(n,a,"on")};var zs={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Rs=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Ds=tc.format=ac.timeFormat,Ps=Ds.utc,Us=Ps("%Y-%m-%dT%H:%M:%S.%LZ");Ds.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Oo:Us,Oo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Oo.toString=Us.toString,tc.second=Rt(function(n){return new ec(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),tc.seconds=tc.second.range,tc.seconds.utc=tc.second.utc.range,tc.minute=Rt(function(n){return new ec(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),tc.minutes=tc.minute.range,tc.minutes.utc=tc.minute.utc.range,tc.hour=Rt(function(n){var t=n.getTimezoneOffset()/60;return new ec(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),tc.hours=tc.hour.range,tc.hours.utc=tc.hour.utc.range,tc.month=Rt(function(n){return n=tc.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),tc.months=tc.month.range,tc.months.utc=tc.month.utc.range;var js=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Hs=[[tc.second,1],[tc.second,5],[tc.second,15],[tc.second,30],[tc.minute,1],[tc.minute,5],[tc.minute,15],[tc.minute,30],[tc.hour,1],[tc.hour,3],[tc.hour,6],[tc.hour,12],[tc.day,1],[tc.day,2],[tc.week,1],[tc.month,1],[tc.month,3],[tc.year,1]],Fs=Ds.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",be]]),Os={range:function(n,t,e){return Xo.range(Math.ceil(n/e)*e,+t,e).map(Io)},floor:bt,ceil:bt};Hs.year=tc.year,tc.scale=function(){return Yo(Xo.scale.linear(),Hs,Fs)};var Ys=Hs.map(function(n){return[n[0].utc,n[1]]}),Is=Ps.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",be]]);Ys.year=tc.year.utc,tc.scale.utc=function(){return Yo(Xo.scale.linear(),Ys,Is)},Xo.text=wt(function(n){return n.responseText}),Xo.json=function(n,t){return St(n,"application/json",Zo,t)},Xo.html=function(n,t){return St(n,"text/html",Vo,t)},Xo.xml=wt(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(Xo):"object"==typeof module&&module.exports?module.exports=Xo:this.d3=Xo}();'use strict';tr.exportTo('tr.ui.b',function(){var THIS_DOC=document.currentScript.ownerDocument;var svgNS='http://www.w3.org/2000/svg';var ColorScheme=tr.b.ColorScheme;function getColorOfKey(key,selected){var id=ColorScheme.getColorIdForGeneralPurposeString(key);if(selected)
-id+=ColorScheme.properties.brightenedOffsets[0];return ColorScheme.colorsAsStrings[id];}
-var ChartBase=tr.ui.b.define('svg',undefined,svgNS);ChartBase.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.classList.add('chart-base');this.chartTitle_=undefined;this.seriesKeys_=undefined;this.width_=400;this.height_=300;var template=THIS_DOC.querySelector('#chart-base-template');var svgEl=template.content.querySelector('svg');for(var i=0;i<svgEl.children.length;i++)
-this.appendChild(svgEl.children[i].cloneNode(true));Object.defineProperty(this,'width',{get:function(){return this.width_;},set:function(width){this.width_=width;this.updateContents_();}});Object.defineProperty(this,'height',{get:function(){return this.height_;},set:function(height){this.height_=height;this.updateContents_();}});},get chartTitle(){return this.chartTitle_;},set chartTitle(chartTitle){this.chartTitle_=chartTitle;this.updateContents_();},get chartAreaElement(){return this.querySelector('#chart-area');},setSize:function(size){this.width_=size.width;this.height_=size.height;this.updateContents_();},getMargin_:function(){var margin={top:20,right:20,bottom:30,left:50};if(this.chartTitle_)
-margin.top+=20;return margin;},get margin(){return this.getMargin_();},get chartAreaSize(){var margin=this.margin;return{width:this.width_-margin.left-margin.right,height:this.height_-margin.top-margin.bottom};},getLegendKeys_:function(){throw new Error('Not implemented');},updateScales_:function(){throw new Error('Not implemented');},updateContents_:function(){var margin=this.margin;var thisSel=d3.select(this);thisSel.attr('width',this.width_);thisSel.attr('height',this.height_);var chartAreaSel=d3.select(this.chartAreaElement);chartAreaSel.attr('transform','translate('+margin.left+','+margin.top+')');this.updateScales_();this.updateTitle_(chartAreaSel);this.updateLegend_();},updateTitle_:function(chartAreaSel){var titleSel=chartAreaSel.select('#title');if(!this.chartTitle_){titleSel.style('display','none');return;}
-var width=this.chartAreaSize.width;titleSel.attr('transform','translate('+width*0.5+',-5)').style('display',undefined).style('text-anchor','middle').attr('class','title').attr('width',width).text(this.chartTitle_);},updateLegend_:function(){var keys=this.getLegendKeys_();if(keys===undefined)
-return;var chartAreaSel=d3.select(this.chartAreaElement);var chartAreaSize=this.chartAreaSize;var legendEntriesSel=chartAreaSel.selectAll('.legend').data(keys.slice().reverse());legendEntriesSel.enter().append('g').attr('class','legend').attr('transform',function(d,i){return'translate(0,'+i*20+')';}).append('text').text(function(key){return key;});legendEntriesSel.exit().remove();legendEntriesSel.attr('x',chartAreaSize.width-18).attr('width',18).attr('height',18).style('fill',function(key){var selected=this.currentHighlightedLegendKey===key;return getColorOfKey(key,selected);}.bind(this));legendEntriesSel.selectAll('text').attr('x',chartAreaSize.width-24).attr('y',9).attr('dy','.35em').style('text-anchor','end').text(function(d){return d;});},get highlightedLegendKey(){return this.highlightedLegendKey_;},set highlightedLegendKey(highlightedLegendKey){this.highlightedLegendKey_=highlightedLegendKey;this.updateHighlight_();},get currentHighlightedLegendKey(){if(this.tempHighlightedLegendKey_)
-return this.tempHighlightedLegendKey_;return this.highlightedLegendKey_;},pushTempHighlightedLegendKey:function(key){if(this.tempHighlightedLegendKey_)
-throw new Error('push cannot nest');this.tempHighlightedLegendKey_=key;this.updateHighlight_();},popTempHighlightedLegendKey:function(key){if(this.tempHighlightedLegendKey_!=key)
-throw new Error('pop cannot happen');this.tempHighlightedLegendKey_=undefined;this.updateHighlight_();},updateHighlight_:function(){var chartAreaSel=d3.select(this.chartAreaElement);var legendEntriesSel=chartAreaSel.selectAll('.legend');var that=this;legendEntriesSel.each(function(key){var highlighted=key==that.currentHighlightedLegendKey;var color=getColorOfKey(key,highlighted);this.style.fill=color;if(highlighted)
-this.style.fontWeight='bold';else
-this.style.fontWeight='';});}};return{getColorOfKey:getColorOfKey,ChartBase:ChartBase};});'use strict';tr.exportTo('tr.ui.b',function(){var ChartBase=tr.ui.b.ChartBase;var ChartBase2D=tr.ui.b.define('chart-base-2d',ChartBase);ChartBase2D.prototype={__proto__:ChartBase.prototype,decorate:function(){ChartBase.prototype.decorate.call(this);this.classList.add('chart-base-2d');this.xScale_=d3.scale.linear();this.yScale_=d3.scale.linear();this.isYLogScale_=false;this.yLogScaleMin_=undefined;this.dataRange_=new tr.b.Range();this.data_=[];this.seriesKeys_=[];this.leftMargin_=50;d3.select(this.chartAreaElement).append('g').attr('id','brushes');d3.select(this.chartAreaElement).append('g').attr('id','series');this.addEventListener('mousedown',this.onMouseDown_.bind(this));},get data(){return this.data_;},set data(data){if(data===undefined)
-throw new Error('data must be an Array');this.data_=data;this.updateSeriesKeys_();this.updateDataRange_();this.updateContents_();},set isYLogScale(logScale){if(logScale)
-this.yScale_=d3.scale.log(10);else
-this.yScale_=d3.scale.linear();this.isYLogScale_=logScale;},getYScaleMin_:function(){return this.isYLogScale_?this.yLogScaleMin_:0;},getYScaleDomain_:function(minValue,maxValue){if(this.isYLogScale_)
-return[this.getYScaleMin_(),maxValue];return[Math.min(minValue,this.getYScaleMin_()),maxValue];},getSampleWidth_:function(data,index,leftSide){var leftIndex,rightIndex;if(leftSide){leftIndex=Math.max(index-1,0);rightIndex=index;}else{leftIndex=index;rightIndex=Math.min(index+1,data.length-1);}
-var leftWidth=this.getXForDatum_(data[index],index)-
-this.getXForDatum_(data[leftIndex],leftIndex);var rightWidth=this.getXForDatum_(data[rightIndex],rightIndex)-
-this.getXForDatum_(data[index],index);return leftWidth*0.5+rightWidth*0.5;},getLegendKeys_:function(){if(this.seriesKeys_&&this.seriesKeys_.length>1)
-return this.seriesKeys_.slice();return[];},updateSeriesKeys_:function(){var keySet={};this.data_.forEach(function(datum){Object.keys(datum).forEach(function(key){if(this.isDatumFieldSeries_(key))
-keySet[key]=true;},this);},this);this.seriesKeys_=Object.keys(keySet);},isDatumFieldSeries_:function(fieldName){throw new Error('Not implemented');},getXForDatum_:function(datum,index){throw new Error('Not implemented');},updateScales_:function(){if(this.data_.length===0)
-return;var width=this.chartAreaSize.width;var height=this.chartAreaSize.height;this.xScale_.range([0,width]);this.xScale_.domain(d3.extent(this.data_,this.getXForDatum_.bind(this)));var yRange=new tr.b.Range();this.data_.forEach(function(datum){this.seriesKeys_.forEach(function(key){if(datum[key]!==undefined)
-yRange.addValue(datum[key]);});},this);this.yScale_.range([height,0]);this.yScale_.domain([yRange.min,yRange.max]);},updateBrushContents_:function(brushSel){brushSel.selectAll('*').remove();},updateXAxis_:function(xAxis){xAxis.selectAll('*').remove();xAxis[0][0].style.opacity=0;xAxis.attr('transform','translate(0,'+this.chartAreaSize.height+')').call(d3.svg.axis().scale(this.xScale_).orient('bottom'));window.requestAnimationFrame(function(){var previousRight=undefined;xAxis.selectAll('.tick')[0].forEach(function(tick){var currentLeft=tick.transform.baseVal[0].matrix.e;if((previousRight===undefined)||(currentLeft>(previousRight+3))){var currentWidth=tick.getBBox().width;previousRight=currentLeft+currentWidth;}else{tick.style.opacity=0;}});xAxis[0][0].style.opacity=1;});},getMargin_:function(){var margin=ChartBase.prototype.getMargin_.call(this);margin.left=this.leftMargin_;return margin;},updateDataRange_:function(){var dataBySeriesKey=this.getDataBySeriesKey_();this.dataRange_.reset();tr.b.iterItems(dataBySeriesKey,function(series,values){for(var i=0;i<values.length;i++){this.dataRange_.addValue(values[i][series]);}},this);this.yLogScaleMin_=undefined;if(this.dataRange_.min!==undefined){var minValue=this.dataRange_.min;if(minValue==0)
-minValue=1;var onePowerLess=Math.floor(Math.log(minValue)/Math.log(10))-1;this.yLogScaleMin_=Math.pow(10,onePowerLess);}},updateYAxis_:function(yAxis){yAxis.selectAll('*').remove();yAxis[0][0].style.opacity=0;var axisModifier=d3.svg.axis().scale(this.yScale_).orient('left');if(this.isYLogScale_){if(this.yLogScaleMin_===undefined)
-return;var minValue=this.dataRange_.min;if(minValue==0)
-minValue=1;var largestPower=Math.ceil(Math.log(this.dataRange_.max)/Math.log(10))+1;var smallestPower=Math.floor(Math.log(minValue)/Math.log(10));var tickValues=[];for(var i=smallestPower;i<largestPower;i++){tickValues.push(Math.pow(10,i));}
-axisModifier=axisModifier.tickValues(tickValues).tickFormat(function(d){return d;});}
-yAxis.call(axisModifier);window.requestAnimationFrame(function(){var previousTop=undefined;var leftMargin=0;yAxis.selectAll('.tick')[0].forEach(function(tick){var bbox=tick.getBBox();leftMargin=Math.max(leftMargin,bbox.width);var currentTop=tick.transform.baseVal[0].matrix.f;var currentBottom=currentTop+bbox.height;if((previousTop===undefined)||(previousTop>(currentBottom+3))){previousTop=currentTop;}else{tick.style.opacity=0;}});if(leftMargin>this.leftMargin_){this.leftMargin_=leftMargin;this.updateContents_();}else{yAxis[0][0].style.opacity=1;}}.bind(this));},updateContents_:function(){ChartBase.prototype.updateContents_.call(this);var chartAreaSel=d3.select(this.chartAreaElement);this.updateXAxis_(chartAreaSel.select('.x.axis'));this.updateYAxis_(chartAreaSel.select('.y.axis'));this.updateBrushContents_(chartAreaSel.select('#brushes'));this.updateDataContents_(chartAreaSel.select('#series'));},updateDataContents_:function(seriesSel){throw new Error('Not implemented');},getDataBySeriesKey_:function(){var dataBySeriesKey={};this.seriesKeys_.forEach(function(seriesKey){dataBySeriesKey[seriesKey]=[];});this.data_.forEach(function(multiSeriesDatum,index){var x=this.getXForDatum_(multiSeriesDatum,index);d3.keys(multiSeriesDatum).forEach(function(seriesKey){if(seriesKey==='x')
-return;if(multiSeriesDatum[seriesKey]===undefined)
-return;if(!this.isDatumFieldSeries_(seriesKey))
-return;var singleSeriesDatum={x:x};singleSeriesDatum[seriesKey]=multiSeriesDatum[seriesKey];dataBySeriesKey[seriesKey].push(singleSeriesDatum);},this);},this);return dataBySeriesKey;},getDataPointAtClientPoint_:function(clientX,clientY){var rect=this.getBoundingClientRect();var margin=this.margin;var x=clientX-rect.left-margin.left;var y=clientY-rect.top-margin.top;x=this.xScale_.invert(x);y=this.yScale_.invert(y);x=tr.b.clamp(x,this.xScale_.domain()[0],this.xScale_.domain()[1]);y=tr.b.clamp(y,this.yScale_.domain()[0],this.yScale_.domain()[1]);return{x:x,y:y};},prepareDataEvent_:function(mouseEvent,dataEvent){var dataPoint=this.getDataPointAtClientPoint_(mouseEvent.clientX,mouseEvent.clientY);dataEvent.x=dataPoint.x;dataEvent.y=dataPoint.y;},onMouseDown_:function(mouseEvent){tr.ui.b.trackMouseMovesUntilMouseUp(this.onMouseMove_.bind(this,mouseEvent.button),this.onMouseUp_.bind(this,mouseEvent.button));mouseEvent.preventDefault();mouseEvent.stopPropagation();var dataEvent=new tr.b.Event('item-mousedown');dataEvent.button=mouseEvent.button;this.classList.add('updating-brushing-state');this.prepareDataEvent_(mouseEvent,dataEvent);this.dispatchEvent(dataEvent);},onMouseMove_:function(button,mouseEvent){if(mouseEvent.buttons!==undefined){mouseEvent.preventDefault();mouseEvent.stopPropagation();}
-var dataEvent=new tr.b.Event('item-mousemove');dataEvent.button=button;this.prepareDataEvent_(mouseEvent,dataEvent);this.dispatchEvent(dataEvent);},onMouseUp_:function(button,mouseEvent){mouseEvent.preventDefault();mouseEvent.stopPropagation();var dataEvent=new tr.b.Event('item-mouseup');dataEvent.button=button;this.prepareDataEvent_(mouseEvent,dataEvent);this.dispatchEvent(dataEvent);this.classList.remove('updating-brushing-state');}};return{ChartBase2D:ChartBase2D};});'use strict';tr.exportTo('tr.ui.b',function(){var ChartBase2D=tr.ui.b.ChartBase2D;var ChartBase2DBrushX=tr.ui.b.define('chart-base-2d-brush-1d',ChartBase2D);ChartBase2DBrushX.prototype={__proto__:ChartBase2D.prototype,decorate:function(){ChartBase2D.prototype.decorate.call(this);this.brushedRange_=new tr.b.Range();},set brushedRange(range){this.brushedRange_.reset();this.brushedRange_.addRange(range);this.updateContents_();},computeBrushRangeFromIndices:function(indexA,indexB){indexA=tr.b.clamp(indexA,0,this.data_.length-1);indexB=tr.b.clamp(indexB,0,this.data_.length-1);var leftIndex=Math.min(indexA,indexB);var rightIndex=Math.max(indexA,indexB);var r=new tr.b.Range();r.addValue(this.getXForDatum_(this.data_[leftIndex],leftIndex)-
-this.getSampleWidth_(this.data_,leftIndex,true));r.addValue(this.getXForDatum_(this.data_[rightIndex],rightIndex)+
-this.getSampleWidth_(this.data_,rightIndex,false));return r;},getDataIndex_:function(dataX){if(!this.data_)
-return undefined;var bisect=d3.bisector(this.getXForDatum_.bind(this)).right;return bisect(this.data_,dataX)-1;},prepareDataEvent_:function(mouseEvent,dataEvent){ChartBase2D.prototype.prepareDataEvent_.call(this,mouseEvent,dataEvent);dataEvent.index=this.getDataIndex_(dataEvent.x);if(dataEvent.index!==undefined)
-dataEvent.data=this.data_[dataEvent.index];},updateBrushContents_:function(brushSel){brushSel.selectAll('*').remove();var brushes=this.brushedRange_.isEmpty?[]:[this.brushedRange_];var brushRectsSel=brushSel.selectAll('rect').data(brushes);brushRectsSel.enter().append('rect');brushRectsSel.exit().remove();brushRectsSel.attr('x',function(d){return this.xScale_(d.min);}.bind(this)).attr('y',0).attr('width',function(d){return this.xScale_(d.max)-this.xScale_(d.min);}.bind(this)).attr('height',this.chartAreaSize.height);}};return{ChartBase2DBrushX:ChartBase2DBrushX};});'use strict';tr.exportTo('tr.ui.b',function(){var ChartBase2DBrushX=tr.ui.b.ChartBase2DBrushX;var LineChart=tr.ui.b.define('line-chart',ChartBase2DBrushX);LineChart.prototype={__proto__:ChartBase2DBrushX.prototype,decorate:function(){ChartBase2DBrushX.prototype.decorate.call(this);this.classList.add('line-chart');},isDatumFieldSeries_:function(fieldName){return fieldName!='x';},getXForDatum_:function(datum,index){return datum.x;},updateDataContents_:function(dataSel){dataSel.selectAll('*').remove();var dataBySeriesKey=this.getDataBySeriesKey_();var pathsSel=dataSel.selectAll('path').data(this.seriesKeys_);pathsSel.enter().append('path').attr('class','line').style('stroke',function(key){return tr.ui.b.getColorOfKey(key);}).attr('d',function(key){var line=d3.svg.line().x(function(d){return this.xScale_(d.x);}.bind(this)).y(function(d){return this.yScale_(d[key]);}.bind(this));return line(dataBySeriesKey[key]);}.bind(this));pathsSel.exit().remove();}};return{LineChart:LineChart};});'use strict';Polymer('tr-ui-side-panel',{ready:function(){},get rangeOfInterest(){throw new Error('Not implemented');},set rangeOfInterest(rangeOfInterest){throw new Error('Not implemented');},get selection(){throw new Error('Not implemented');},set selection(selection){throw new Error('Not implemented');},get model(){throw new Error('Not implemented');},set model(model){throw new Error('Not implemented');},supportsModel:function(m){throw new Error('Not implemented');}});'use strict';Polymer('tr-ui-e-s-input-latency-side-panel',{ready:function(){this.rangeOfInterest_=new tr.b.Range();this.frametimeType_=tr.model.helpers.IMPL_FRAMETIME_TYPE;this.latencyChart_=undefined;this.frametimeChart_=undefined;this.selectedProcessId_=undefined;this.mouseDownIndex_=undefined;this.curMouseIndex_=undefined;},get model(){return this.model_;},set model(model){this.model_=model;if(this.model_){this.modelHelper_=this.model_.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);}else{this.modelHelper_=undefined;}
-this.updateToolbar_();this.updateContents_();},get frametimeType(){return this.frametimeType_;},set frametimeType(type){if(this.frametimeType_===type)
-return;this.frametimeType_=type;this.updateContents_();},get selectedProcessId(){return this.selectedProcessId_;},set selectedProcessId(process){if(this.selectedProcessId_===process)
-return;this.selectedProcessId_=process;this.updateContents_();},set selection(selection){if(this.latencyChart_===undefined)
-return;this.latencyChart_.brushedRange=selection.bounds;},setBrushedIndices:function(mouseDownIndex,curIndex){this.mouseDownIndex_=mouseDownIndex;this.curMouseIndex_=curIndex;this.updateBrushedRange_();},updateBrushedRange_:function(){if(this.latencyChart_===undefined)
-return;var r=new tr.b.Range();if(this.mouseDownIndex_===undefined){this.latencyChart_.brushedRange=r;return;}
-r=this.latencyChart_.computeBrushRangeFromIndices(this.mouseDownIndex_,this.curMouseIndex_);this.latencyChart_.brushedRange=r;var latencySlices=[];this.model_.getAllThreads().forEach(function(thread){thread.iterateAllEvents(function(event){if(event.title.indexOf('InputLatency:')===0)
-latencySlices.push(event);});});latencySlices=tr.model.helpers.getSlicesIntersectingRange(r,latencySlices);var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(latencySlices);this.latencyChart_.dispatchEvent(event);},registerMouseEventForLatencyChart_:function(){this.latencyChart_.addEventListener('item-mousedown',function(e){this.mouseDownIndex_=e.index;this.curMouseIndex_=e.index;this.updateBrushedRange_();}.bind(this));this.latencyChart_.addEventListener('item-mousemove',function(e){if(e.button==undefined)
-return;this.curMouseIndex_=e.index;this.updateBrushedRange_();}.bind(this));this.latencyChart_.addEventListener('item-mouseup',function(e){this.curMouseIndex=e.index;this.updateBrushedRange_();}.bind(this));},updateToolbar_:function(){var browserProcess=this.modelHelper_.browserProcess;var labels=[];if(browserProcess!==undefined){var label_str='Browser: '+browserProcess.pid;labels.push({label:label_str,value:browserProcess.pid});}
-tr.b.iterItems(this.modelHelper_.rendererHelpers,function(pid,rendererHelper){var rendererProcess=rendererHelper.process;var label_str='Renderer: '+rendererProcess.userFriendlyName;labels.push({label:label_str,value:rendererProcess.userFriendlyName});},this);if(labels.length===0)
-return;this.selectedProcessId_=labels[0].value;var toolbarEl=this.$.toolbar;toolbarEl.appendChild(tr.ui.b.createSelector(this,'frametimeType','inputLatencySidePanel.frametimeType',this.frametimeType_,[{label:'Main Thread Frame Times',value:tr.model.helpers.MAIN_FRAMETIME_TYPE},{label:'Impl Thread Frame Times',value:tr.model.helpers.IMPL_FRAMETIME_TYPE}]));toolbarEl.appendChild(tr.ui.b.createSelector(this,'selectedProcessId','inputLatencySidePanel.selectedProcessId',this.selectedProcessId_,labels));},get currentRangeOfInterest(){if(this.rangeOfInterest_.isEmpty)
-return this.model_.bounds;else
-return this.rangeOfInterest_;},createLatencyLineChart:function(data,title){var chart=new tr.ui.b.LineChart();var width=600;if(document.body.clientWidth!=undefined)
-width=document.body.clientWidth*0.5;chart.setSize({width:width,height:chart.height});chart.chartTitle=title;chart.data=data;return chart;},updateContents_:function(){var resultArea=this.$.result_area;this.latencyChart_=undefined;this.frametimeChart_=undefined;resultArea.textContent='';if(this.modelHelper_===undefined)
-return;var rangeOfInterest=this.currentRangeOfInterest;var chromeProcess;if(this.modelHelper_.rendererHelpers[this.selectedProcessId_])
-chromeProcess=this.modelHelper_.rendererHelpers[this.selectedProcessId_];else
-chromeProcess=this.modelHelper_.browserHelper;var frameEvents=chromeProcess.getFrameEventsInRange(this.frametimeType,rangeOfInterest);var frametimeData=tr.model.helpers.getFrametimeDataFromEvents(frameEvents);var averageFrametime=tr.b.Statistics.mean(frametimeData,function(d){return d.frametime;});var latencyEvents=this.modelHelper_.browserHelper.getLatencyEventsInRange(rangeOfInterest);var latencyData=[];latencyEvents.forEach(function(event){if(event.inputLatency===undefined)
-return;latencyData.push({x:event.start,latency:event.inputLatency/1000});});var averageLatency=tr.b.Statistics.mean(latencyData,function(d){return d.latency;});var latencySummaryText=document.createElement('div');latencySummaryText.appendChild(tr.ui.b.createSpan({textContent:'Average Latency '+averageLatency+' ms',bold:true}));resultArea.appendChild(latencySummaryText);var frametimeSummaryText=document.createElement('div');frametimeSummaryText.appendChild(tr.ui.b.createSpan({textContent:'Average Frame Time '+averageFrametime+' ms',bold:true}));resultArea.appendChild(frametimeSummaryText);if(latencyData.length!==0){this.latencyChart_=this.createLatencyLineChart(latencyData,'Latency Over Time');this.registerMouseEventForLatencyChart_();resultArea.appendChild(this.latencyChart_);}
-if(frametimeData.length!=0){this.frametimeChart_=this.createLatencyLineChart(frametimeData,'Frame Times');this.frametimeChart_.style.display='block';resultArea.appendChild(this.frametimeChart_);}},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(rangeOfInterest){this.rangeOfInterest_=rangeOfInterest;this.updateContents_();},supportsModel:function(m){if(m==undefined){return{supported:false,reason:'Unknown tracing model'};}
+return this.title;}};AsyncSlice.subTypes.register(GpuAsyncSlice,{categoryParts:['disabled-by-default-gpu.device','disabled-by-default-gpu.service']});return{GpuAsyncSlice,};});'use strict';tr.exportTo('tr.e.gpu',function(){const ObjectSnapshot=tr.model.ObjectSnapshot;function StateSnapshot(){ObjectSnapshot.apply(this,arguments);}
+StateSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize(){this.screenshot_=undefined;},initialize(){if(this.args.screenshot){this.screenshot_=this.args.screenshot;}},get screenshot(){return this.screenshot_;}};ObjectSnapshot.subTypes.register(StateSnapshot,{typeName:'gpu::State'});return{StateSnapshot,};});'use strict';tr.exportTo('tr.ui.e.chrome.gpu',function(){const StateSnapshotView=tr.ui.b.define('tr-ui-e-chrome-gpu-state-snapshot-view',tr.ui.analysis.ObjectSnapshotView);StateSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate(){Polymer.dom(this).classList.add('tr-ui-e-chrome-gpu-state-snapshot-view');this.screenshotImage_=document.createElement('img');Polymer.dom(this).appendChild(this.screenshotImage_);},updateContents(){if(this.objectSnapshot_&&this.objectSnapshot_.screenshot){this.screenshotImage_.src='data:image/png;base64,'+
+this.objectSnapshot_.screenshot;}}};tr.ui.analysis.ObjectSnapshotView.register(StateSnapshotView,{typeName:'gpu::State'});return{StateSnapshotView,};});'use strict';tr.exportTo('tr.ui.analysis',function(){Polymer({is:'tr-ui-a-layout-tree-sub-view',behaviors:['tr-ui-a-sub-view'],set selection(selection){this.currentSelection_=selection;this.updateContents_();},get selection(){return this.currentSelection_;},updateContents_(){this.set('$.content.textContent','');if(!this.currentSelection_)return;const columns=[{title:'Tag/Name',value(layoutObject){return layoutObject.tag||':'+layoutObject.name;}},{title:'htmlId',value(layoutObject){return layoutObject.htmlId||'';}},{title:'classNames',value(layoutObject){return layoutObject.classNames||'';}},{title:'reasons',value(layoutObject){return layoutObject.needsLayoutReasons.join(', ');}},{title:'width',value(layoutObject){return layoutObject.absoluteRect.width;}},{title:'height',value(layoutObject){return layoutObject.absoluteRect.height;}},{title:'absX',value(layoutObject){return layoutObject.absoluteRect.left;}},{title:'absY',value(layoutObject){return layoutObject.absoluteRect.top;}},{title:'relX',value(layoutObject){return layoutObject.relativeRect.left;}},{title:'relY',value(layoutObject){return layoutObject.relativeRect.top;}},{title:'float',value(layoutObject){return layoutObject.isFloat?'float':'';}},{title:'positioned',value(layoutObject){return layoutObject.isPositioned?'positioned':'';}},{title:'relative',value(layoutObject){return layoutObject.isRelativePositioned?'relative':'';}},{title:'sticky',value(layoutObject){return layoutObject.isStickyPositioned?'sticky':'';}},{title:'anonymous',value(layoutObject){return layoutObject.isAnonymous?'anonymous':'';}},{title:'row',value(layoutObject){if(layoutObject.tableRow===undefined){return'';}
+return layoutObject.tableRow;}},{title:'col',value(layoutObject){if(layoutObject.tableCol===undefined){return'';}
+return layoutObject.tableCol;}},{title:'rowSpan',value(layoutObject){if(layoutObject.tableRowSpan===undefined){return'';}
+return layoutObject.tableRowSpan;}},{title:'colSpan',value(layoutObject){if(layoutObject.tableColSpan===undefined){return'';}
+return layoutObject.tableColSpan;}},{title:'address',value(layoutObject){return layoutObject.id.toString(16);}}];const table=this.ownerDocument.createElement('tr-ui-b-table');table.defaultExpansionStateCallback=function(layoutObject,parentLayoutObject){return true;};table.subRowsPropertyName='childLayoutObjects';table.tableColumns=columns;table.tableRows=this.currentSelection_.map(function(snapshot){return snapshot.rootLayoutObject;});table.rebuild();Polymer.dom(this.$.content).appendChild(table);},});return{};});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-layout-tree-sub-view',tr.e.chrome.LayoutTreeSnapshot,{multi:false,title:'Layout Tree',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-layout-tree-sub-view',tr.e.chrome.LayoutTreeSnapshot,{multi:true,title:'Layout Trees',});'use strict';tr.exportTo('tr.ui.behaviors',function(){const SidePanel={get rangeOfInterest(){throw new Error('Not implemented');},set rangeOfInterest(rangeOfInterest){throw new Error('Not implemented');},get selection(){throw new Error('Not implemented');},set selection(selection){throw new Error('Not implemented');},get model(){throw new Error('Not implemented');},set model(model){throw new Error('Not implemented');},supportsModel(m){throw new Error('Not implemented');}};return{SidePanel,};});'use strict';tr.exportTo('tr.ui.side_panel',function(){function SidePanelRegistry(){}
+const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(SidePanelRegistry,options);return{SidePanelRegistry,};});'use strict';tr.exportTo('tr.ui.e.s',function(){const BlameContextSnapshot=tr.e.chrome.BlameContextSnapshot;const FrameTreeNodeSnapshot=tr.e.chrome.FrameTreeNodeSnapshot;const RenderFrameSnapshot=tr.e.chrome.RenderFrameSnapshot;const TopLevelSnapshot=tr.e.chrome.TopLevelSnapshot;const BlameContextInstance=tr.e.chrome.BlameContextInstance;const FrameTreeNodeInstance=tr.e.chrome.FrameTreeNodeInstance;const RenderFrameInstance=tr.e.chrome.RenderFrameInstance;const TopLevelInstance=tr.e.chrome.TopLevelInstance;function Row(context){this.subRows=undefined;this.contexts=[];this.type=undefined;this.renderer='N/A';this.url=undefined;this.time=0;this.eventsOfInterest=new tr.model.EventSet();if(context===undefined)return;this.type=context.objectInstance.blameContextType;this.contexts.push(context);if(context instanceof FrameTreeNodeSnapshot){if(context.renderFrame){this.contexts.push(context.renderFrame);this.renderer=context.renderFrame.objectInstance.parent.pid;}}else if(context instanceof RenderFrameSnapshot){if(context.frameTreeNode){this.contexts.push(context.frameTreeNode);}
+this.renderer=context.objectInstance.parent.pid;}else if(context instanceof TopLevelSnapshot){this.renderer=context.objectInstance.parent.pid;}else{throw new Error('Unknown context type');}
+this.eventsOfInterest.addEventSet(this.contexts);this.url=context.url;}
+const groupFunctions={none:rows=>rows,tree(rows,rowMap){const getParentRow=function(row){let pivot;row.contexts.forEach(function(context){if(context instanceof tr.e.chrome.FrameTreeNodeSnapshot){pivot=context;}});if(pivot&&pivot.parentContext){return rowMap[pivot.parentContext.guid];}
+return undefined;};const rootRows=[];rows.forEach(function(row){const parentRow=getParentRow(row);if(parentRow===undefined){rootRows.push(row);return;}
+if(parentRow.subRows===undefined){parentRow.subRows=[];}
+parentRow.subRows.push(row);});const aggregateAllDescendants=function(row){if(!row.subRows){if(getParentRow(row)){row.type='Subframe';}
+return row;}
+const result=new Row();result.type='Frame Tree';result.renderer=row.renderer;result.url=row.url;result.subRows=[row];row.subRows.forEach(subRow=>result.subRows.push(aggregateAllDescendants(subRow)));result.subRows.forEach(function(subRow){result.time+=subRow.time;result.eventsOfInterest.addEventSet(subRow.eventsOfInterest);});row.subRows=undefined;return result;};return rootRows.map(rootRow=>aggregateAllDescendants(rootRow));}};Polymer({is:'tr-ui-e-s-frame-data-side-panel',behaviors:[tr.ui.behaviors.SidePanel],ready(){this.model_=undefined;this.rangeOfInterest_=new tr.b.math.Range();this.$.table.showHeader=true;this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;this.$.table.tableColumns=this.createFrameDataTableColumns_();this.$.table.addEventListener('selection-changed',function(e){this.selectEventSet_(this.$.table.selectedTableRow.eventsOfInterest);}.bind(this));this.$.select.addEventListener('change',function(e){this.updateContents_();}.bind(this));},selectEventSet_(eventSet){const event=new tr.model.RequestSelectionChangeEvent();event.selection=eventSet;this.dispatchEvent(event);},createFrameDataTableColumns_(){return[{title:'Renderer',value:row=>row.renderer,cmp:(a,b)=>a.renderer-b.renderer},{title:'Type',value:row=>row.type},{title:'Time',value:row=>tr.v.ui.createScalarSpan(row.time,{unit:tr.b.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument}),cmp:(a,b)=>a.time-b.time},{title:'URL',value:row=>row.url,cmp:(a,b)=>(a.url||'').localeCompare(b.url||'')}];},createFrameDataTableRows_(){if(!this.model_)return[];const rows=[];const rowMap={};for(const proc of Object.values(this.model_.processes)){proc.objects.iterObjectInstances(function(objectInstance){if(!(objectInstance instanceof BlameContextInstance)){return;}
+objectInstance.snapshots.forEach(function(snapshot){if(rowMap[snapshot.guid])return;const row=new Row(snapshot);row.contexts.forEach(context=>rowMap[context.guid]=row);rows.push(row);},this);},this);}
+for(const proc of Object.values(this.model_.processes)){for(const thread of Object.values(proc.threads)){thread.sliceGroup.iterSlicesInTimeRange(function(topLevelSlice){topLevelSlice.contexts.forEach(function(context){if(!context.snapshot.guid||!rowMap[context.snapshot.guid]){return;}
+const row=rowMap[context.snapshot.guid];row.eventsOfInterest.push(topLevelSlice);row.time+=topLevelSlice.selfTime||0;});},this.currentRangeOfInterest.min,this.currentRangeOfInterest.max);}}
+const select=this.$.select;const groupOption=select.options[select.selectedIndex].value;const groupFunction=groupFunctions[groupOption];return groupFunction(rows,rowMap);},updateContents_(){this.$.table.tableRows=this.createFrameDataTableRows_();this.$.table.rebuild();},supportsModel(m){if(!m){return{supported:false,reason:'No model available.'};}
+const ans={supported:false};for(const proc of Object.values(m.processes)){proc.objects.iterObjectInstances(function(instance){if(instance instanceof BlameContextInstance){ans.supported=true;}});}
+if(!ans.supported){ans.reason='No frame data available';}
+return ans;},get currentRangeOfInterest(){if(this.rangeOfInterest_.isEmpty){return this.model_.bounds;}
+return this.rangeOfInterest_;},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(rangeOfInterest){this.rangeOfInterest_=rangeOfInterest;this.updateContents_();},get selection(){},set selection(_){},get textLabel(){return'Frame Data';},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();}});tr.ui.side_panel.SidePanelRegistry.register(function(){return document.createElement('tr-ui-e-s-frame-data-side-panel');});});'use strict';Polymer({is:'tr-ui-b-chart-legend-key',ready(){this.$.checkbox.addEventListener('change',this.onCheckboxChange_.bind(this));},onCheckboxChange_(){tr.b.dispatchSimpleEvent(this,tr.ui.b.DataSeriesEnableChangeEventType,true,false,{key:Polymer.dom(this).textContent,enabled:this.enabled});},set textContent(t){Polymer.dom(this.$.label).textContent=t;Polymer.dom(this.$.link).textContent=t;this.updateContents_();},set width(w){w-=20;this.$.link.style.width=w+'px';this.$.label.style.width=w+'px';},get textContent(){return Polymer.dom(this.$.label).textContent;},set optional(optional){this.$.checkbox.style.visibility=optional?'visible':'hidden';},get optional(){return this.$.checkbox.style.visibility==='visible';},set enabled(enabled){this.$.checkbox.checked=enabled?'checked':'';},get enabled(){return this.$.checkbox.checked;},set color(c){this.$.label.style.color=c;this.$.link.color=c;},set target(target){this.$.link.setSelectionAndContent(target,Polymer.dom(this.$.label).textContent);this.updateContents_();},get target(){return this.$.link.selection;},set title(title){this.$.link.title=title;},updateContents_(){this.$.link.style.display=this.target?'':'none';this.$.label.style.display=this.target?'none':'';this.$.label.htmlFor=this.optional?'checkbox':'';}});'use strict';(function(window){window.define=function(x){window.d3=x;};window.define.amd=true;})(this);!function(){function n(n){return null!=n&&!isNaN(n)}function t(n){return n.length}function e(n){for(var t=1;n*t%1;)t*=10;return t}function r(n,t){try{for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}catch(r){n.prototype=t}}function u(){}function i(n){return aa+n in this}function o(n){return n=aa+n,n in this&&delete this[n]}function a(){var n=[];return this.forEach(function(t){n.push(t)}),n}function c(){var n=0;for(var t in this)t.charCodeAt(0)===ca&&++n;return n}function s(){for(var n in this)if(n.charCodeAt(0)===ca)return!1;return!0}function l(){}function f(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function h(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.substring(1);for(var e=0,r=sa.length;r>e;++e){var u=sa[e]+t;if(u in n)return u}}function g(){}function p(){}function v(n){function t(){for(var t,r=e,u=-1,i=r.length;++u<i;)(t=r[u].on)&&t.apply(this,arguments);return n}var e=[],r=new u;return t.on=function(t,u){var i,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,i=e.indexOf(o)).concat(e.slice(i+1)),r.remove(t)),u&&e.push(r.set(t,{on:u})),n)},t}function d(){Xo.event.preventDefault()}function m(){for(var n,t=Xo.event;n=t.sourceEvent;)t=n;return t}function y(n){for(var t=new p,e=0,r=arguments.length;++e<r;)t[arguments[e]]=v(t);return t.of=function(e,r){return function(u){try{var i=u.sourceEvent=Xo.event;u.target=n,Xo.event=u,t[u.type].apply(e,r)}finally{Xo.event=i}}},t}function x(n){return fa(n,da),n}function M(n){return"function"==typeof n?n:function(){return ha(n,this)}}function _(n){return"function"==typeof n?n:function(){return ga(n,this)}}function b(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function u(){this.setAttribute(n,t)}function i(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=Xo.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?i:u}function w(n){return n.trim().replace(/\s+/g," ")}function S(n){return new RegExp("(?:^|\\s+)"+Xo.requote(n)+"(?:\\s+|$)","g")}function k(n){return n.trim().split(/^|\s+/)}function E(n,t){function e(){for(var e=-1;++e<u;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<u;)n[e](this,r)}n=k(n).map(A);var u=n.length;return"function"==typeof t?r:e}function A(n){var t=S(n);return function(e,r){if(u=e.classList)return r?u.add(n):u.remove(n);var u=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(u)||e.setAttribute("class",w(u+" "+n))):e.setAttribute("class",w(u.replace(t," ")))}}function C(n,t,e){function r(){this.style.removeProperty(n)}function u(){this.style.setProperty(n,t,e)}function i(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?i:u}function N(n,t){function e(){delete this[n]}function r(){this[n]=t}function u(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?u:r}function L(n){return"function"==typeof n?n:(n=Xo.ns.qualify(n)).local?function(){return this.ownerDocument.createElementNS(n.space,n.local)}:function(){return this.ownerDocument.createElementNS(this.namespaceURI,n)}}function T(n){return{__data__:n}}function q(n){return function(){return va(this,n)}}function z(n){return arguments.length||(n=Xo.ascending),function(t,e){return t&&e?n(t.__data__,e.__data__):!t-!e}}function R(n,t){for(var e=0,r=n.length;r>e;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function D(n){return fa(n,ya),n}function P(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t<c;);return o}}function U(){var n=this.__transition__;n&&++n.active}function j(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function u(){var u=c(t,Bo(arguments));r.call(this),this.addEventListener(n,this[o]=u,u.$=e),u._=t}function i(){var t,e=new RegExp("^__on([^.]+)"+Xo.requote(n)+"$");for(var r in this)if(t=r.match(e)){var u=this[r];this.removeEventListener(t[1],u,u.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),c=H;a>0&&(n=n.substring(0,a));var s=Ma.get(n);return s&&(n=s,c=F),a?t?u:r:t?g:i}function H(n,t){return function(e){var r=Xo.event;Xo.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{Xo.event=r}}}function F(n,t){var e=H(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function O(){var n=".dragsuppress-"+ ++ba,t="click"+n,e=Xo.select(Go).on("touchmove"+n,d).on("dragstart"+n,d).on("selectstart"+n,d);if(_a){var r=Jo.style,u=r[_a];r[_a]="none"}return function(i){function o(){e.on(t,null)}e.on(n,null),_a&&(r[_a]=u),i&&(e.on(t,function(){d(),o()},!0),setTimeout(o,0))}}function Y(n,t){t.changedTouches&&(t=t.changedTouches[0]);var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>wa&&(Go.scrollX||Go.scrollY)){e=Xo.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var u=e[0][0].getScreenCTM();wa=!(u.f||u.e),e.remove()}return wa?(r.x=t.pageX,r.y=t.pageY):(r.x=t.clientX,r.y=t.clientY),r=r.matrixTransform(n.getScreenCTM().inverse()),[r.x,r.y]}var i=n.getBoundingClientRect();return[t.clientX-i.left-n.clientLeft,t.clientY-i.top-n.clientTop]}function I(n){return n>0?1:0>n?-1:0}function Z(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function V(n){return n>1?0:-1>n?Sa:Math.acos(n)}function X(n){return n>1?Ea:-1>n?-Ea:Math.asin(n)}function $(n){return((n=Math.exp(n))-1/n)/2}function B(n){return((n=Math.exp(n))+1/n)/2}function W(n){return((n=Math.exp(2*n))-1)/(n+1)}function J(n){return(n=Math.sin(n/2))*n}function G(){}function K(n,t,e){return new Q(n,t,e)}function Q(n,t,e){this.h=n,this.s=t,this.l=e}function nt(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,gt(u(n+120),u(n),u(n-120))}function tt(n,t,e){return new et(n,t,e)}function et(n,t,e){this.h=n,this.c=t,this.l=e}function rt(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),ut(e,Math.cos(n*=Na)*t,Math.sin(n)*t)}function ut(n,t,e){return new it(n,t,e)}function it(n,t,e){this.l=n,this.a=t,this.b=e}function ot(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=ct(u)*Fa,r=ct(r)*Oa,i=ct(i)*Ya,gt(lt(3.2404542*u-1.5371385*r-.4985314*i),lt(-.969266*u+1.8760108*r+.041556*i),lt(.0556434*u-.2040259*r+1.0572252*i))}function at(n,t,e){return n>0?tt(Math.atan2(e,t)*La,Math.sqrt(t*t+e*e),n):tt(0/0,0/0,n)}function ct(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function st(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function lt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function ft(n){return gt(n>>16,255&n>>8,255&n)}function ht(n){return ft(n)+""}function gt(n,t,e){return new pt(n,t,e)}function pt(n,t,e){this.r=n,this.g=t,this.b=e}function vt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function dt(n,t,e){var r,u,i,o,a=0,c=0,s=0;if(u=/([a-z]+)\((.*)\)/i.exec(n))switch(i=u[2].split(","),u[1]){case"hsl":return e(parseFloat(i[0]),parseFloat(i[1])/100,parseFloat(i[2])/100);case"rgb":return t(Mt(i[0]),Mt(i[1]),Mt(i[2]))}return(o=Va.get(n))?t(o.r,o.g,o.b):(null!=n&&"#"===n.charAt(0)&&(r=parseInt(n.substring(1),16),isNaN(r)||(4===n.length?(a=(3840&r)>>4,a=a>>4|a,c=240&r,c=c>>4|c,s=15&r,s=s<<4|s):7===n.length&&(a=(16711680&r)>>16,c=(65280&r)>>8,s=255&r))),t(a,c,s))}function mt(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),K(r,u,c)}function yt(n,t,e){n=xt(n),t=xt(t),e=xt(e);var r=st((.4124564*n+.3575761*t+.1804375*e)/Fa),u=st((.2126729*n+.7151522*t+.072175*e)/Oa),i=st((.0193339*n+.119192*t+.9503041*e)/Ya);return ut(116*u-16,500*(r-u),200*(u-i))}function xt(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function Mt(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function _t(n){return"function"==typeof n?n:function(){return n}}function bt(n){return n}function wt(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),St(t,e,n,r)}}function St(n,t,e,r){function u(){var n,t=c.status;if(!t&&c.responseText||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return o.error.call(i,r),void 0}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=Xo.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,s=null;return!Go.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=Xo.event;Xo.event=n;try{o.progress.call(i,c)}finally{Xo.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(s=n,i):s},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(Bo(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var l in a)c.setRequestHeader(l,a[l]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=s&&(c.responseType=s),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},Xo.rebind(i,o,"on"),null==r?i:i.get(kt(r))}function kt(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Et(){var n=At(),t=Ct()-n;t>24?(isFinite(t)&&(clearTimeout(Wa),Wa=setTimeout(Et,t)),Ba=0):(Ba=1,Ga(Et))}function At(){var n=Date.now();for(Ja=Xa;Ja;)n>=Ja.t&&(Ja.f=Ja.c(n-Ja.t)),Ja=Ja.n;return n}function Ct(){for(var n,t=Xa,e=1/0;t;)t.f?t=n?n.n=t.n:Xa=t.n:(t.t<e&&(e=t.t),t=(n=t).n);return $a=n,e}function Nt(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Lt(n,t){var e=Math.pow(10,3*oa(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Tt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r?function(n){for(var t=n.length,u=[],i=0,o=r[0];t>0&&o>0;)u.push(n.substring(t-=o,t+o)),o=r[i=(i+1)%r.length];return u.reverse().join(e)}:bt;return function(n){var e=Qa.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"",c=e[4]||"",s=e[5],l=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1;switch(h&&(h=+h.substring(1)),(s||"0"===r&&"="===o)&&(s=r="0",o="=",f&&(l-=Math.floor((l-1)/4))),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=nc.get(g)||qt;var y=s&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):a;if(0>p){var c=Xo.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x=n.lastIndexOf("."),M=0>x?n:n.substring(0,x),_=0>x?"":t+n.substring(x+1);!s&&f&&(M=i(M));var b=v.length+M.length+_.length+(y?0:u.length),w=l>b?new Array(b=l-b+1).join(r):"";return y&&(M=i(w+M)),u+=v,n=M+_,("<"===o?u+n+w:">"===o?w+u+n:"^"===o?w.substring(0,b>>=1)+u+n+w.substring(b):u+(y?n:w+n))+e}}}function qt(n){return n+""}function zt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Rt(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new ec(e-1)),1),e}function i(n,e){return t(n=new ec(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{ec=zt;var r=new zt;return r._=n,o(r,t,e)}finally{ec=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Dt(n);return c.floor=c,c.round=Dt(r),c.ceil=Dt(u),c.offset=Dt(i),c.range=a,n}function Dt(n){return function(t,e){try{ec=zt;var r=new zt;return r._=t,n(r,e)._}finally{ec=Date}}}function Pt(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.substring(c,a)),null!=(u=uc[e=n.charAt(++a)])&&(e=n.charAt(++a)),(i=C[e])&&(e=i(t,null==u?"e"===e?" ":"0":u)),o.push(e),c=a+1);return o.push(n.substring(c,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},u=e(r,n,t,0);if(u!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var i=null!=r.Z&&ec!==zt,o=new(i?zt:ec);return"j"in r?o.setFullYear(r.y,0,r.j):"w"in r&&("W"in r||"U"in r)?(o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+Math.floor(r.Z/100),r.M+r.Z%100,r.S,r.L),i?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var u,i,o,a=0,c=t.length,s=e.length;c>a;){if(r>=s)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=N[o in uc?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){b.lastIndex=0;var r=b.exec(t.substring(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){M.lastIndex=0;var r=M.exec(t.substring(e));return r?(n.w=_.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.substring(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.substring(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,C.c.toString(),t,r)}function c(n,t,r){return e(n,C.x.toString(),t,r)}function s(n,t,r){return e(n,C.X.toString(),t,r)}function l(n,t,e){var r=x.get(t.substring(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{ec=zt;var t=new ec;return t._=n,r(t)}finally{ec=Date}}var r=t(n);return e.parse=function(n){try{ec=zt;var t=r.parse(n);return t&&t._}finally{ec=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ee;var x=Xo.map(),M=jt(v),_=Ht(v),b=jt(d),w=Ht(d),S=jt(m),k=Ht(m),E=jt(y),A=Ht(y);p.forEach(function(n,t){x.set(n.toLowerCase(),t)});var C={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return Ut(n.getDate(),t,2)},e:function(n,t){return Ut(n.getDate(),t,2)},H:function(n,t){return Ut(n.getHours(),t,2)},I:function(n,t){return Ut(n.getHours()%12||12,t,2)},j:function(n,t){return Ut(1+tc.dayOfYear(n),t,3)},L:function(n,t){return Ut(n.getMilliseconds(),t,3)},m:function(n,t){return Ut(n.getMonth()+1,t,2)},M:function(n,t){return Ut(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return Ut(n.getSeconds(),t,2)},U:function(n,t){return Ut(tc.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Ut(tc.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return Ut(n.getFullYear()%100,t,2)},Y:function(n,t){return Ut(n.getFullYear()%1e4,t,4)},Z:ne,"%":function(){return"%"}},N={a:r,A:u,b:i,B:o,c:a,d:Bt,e:Bt,H:Jt,I:Jt,j:Wt,L:Qt,m:$t,M:Gt,p:l,S:Kt,U:Ot,w:Ft,W:Yt,x:c,X:s,y:Zt,Y:It,Z:Vt,"%":te};return t}function Ut(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function jt(n){return new RegExp("^(?:"+n.map(Xo.requote).join("|")+")","i")}function Ht(n){for(var t=new u,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function Ft(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Ot(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e));return r?(n.U=+r[0],e+r[0].length):-1}function Yt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e));return r?(n.W=+r[0],e+r[0].length):-1}function It(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Zt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.y=Xt(+r[0]),e+r[0].length):-1}function Vt(n,t,e){return/^[+-]\d{4}$/.test(t=t.substring(e,e+5))?(n.Z=+t,e+5):-1}function Xt(n){return n+(n>68?1900:2e3)}function $t(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Bt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function Wt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function Jt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function Gt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function Kt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function Qt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ne(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=~~(oa(t)/60),u=oa(t)%60;return e+Ut(r,"0",2)+Ut(u,"0",2)}function te(n,t,e){oc.lastIndex=0;var r=oc.exec(t.substring(e,e+1));return r?e+r[0].length:-1}function ee(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function re(){}function ue(n,t,e){var r=e.s=n+t,u=r-n,i=r-u;e.t=n-i+(t-u)}function ie(n,t){n&&lc.hasOwnProperty(n.type)&&lc[n.type](n,t)}function oe(n,t,e){var r,u=-1,i=n.length-e;for(t.lineStart();++u<i;)r=n[u],t.point(r[0],r[1],r[2]);t.lineEnd()}function ae(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)oe(n[e],t,1);t.polygonEnd()}function ce(){function n(n,t){n*=Na,t=t*Na/2+Sa/4;var e=n-r,o=e>=0?1:-1,a=o*e,c=Math.cos(t),s=Math.sin(t),l=i*s,f=u*c+l*Math.cos(a),h=l*o*Math.sin(a);hc.add(Math.atan2(h,f)),r=n,u=c,i=s}var t,e,r,u,i;gc.point=function(o,a){gc.point=n,r=(t=o)*Na,u=Math.cos(a=(e=a)*Na/2+Sa/4),i=Math.sin(a)},gc.lineEnd=function(){n(t,e)}}function se(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function le(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function fe(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function he(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ge(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function pe(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function ve(n){return[Math.atan2(n[1],n[0]),X(n[2])]}function de(n,t){return oa(n[0]-t[0])<Aa&&oa(n[1]-t[1])<Aa}function me(n,t){n*=Na;var e=Math.cos(t*=Na);ye(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function ye(n,t,e){++pc,dc+=(n-dc)/pc,mc+=(t-mc)/pc,yc+=(e-yc)/pc}function xe(){function n(n,u){n*=Na;var i=Math.cos(u*=Na),o=i*Math.cos(n),a=i*Math.sin(n),c=Math.sin(u),s=Math.atan2(Math.sqrt((s=e*c-r*a)*s+(s=r*o-t*c)*s+(s=t*a-e*o)*s),t*o+e*a+r*c);vc+=s,xc+=s*(t+(t=o)),Mc+=s*(e+(e=a)),_c+=s*(r+(r=c)),ye(t,e,r)}var t,e,r;kc.point=function(u,i){u*=Na;var o=Math.cos(i*=Na);t=o*Math.cos(u),e=o*Math.sin(u),r=Math.sin(i),kc.point=n,ye(t,e,r)}}function Me(){kc.point=me}function _e(){function n(n,t){n*=Na;var e=Math.cos(t*=Na),o=e*Math.cos(n),a=e*Math.sin(n),c=Math.sin(t),s=u*c-i*a,l=i*o-r*c,f=r*a-u*o,h=Math.sqrt(s*s+l*l+f*f),g=r*o+u*a+i*c,p=h&&-V(g)/h,v=Math.atan2(h,g);bc+=p*s,wc+=p*l,Sc+=p*f,vc+=v,xc+=v*(r+(r=o)),Mc+=v*(u+(u=a)),_c+=v*(i+(i=c)),ye(r,u,i)}var t,e,r,u,i;kc.point=function(o,a){t=o,e=a,kc.point=n,o*=Na;var c=Math.cos(a*=Na);r=c*Math.cos(o),u=c*Math.sin(o),i=Math.sin(a),ye(r,u,i)},kc.lineEnd=function(){n(t,e),kc.lineEnd=Me,kc.point=me}}function be(){return!0}function we(n,t,e,r,u){var i=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(de(e,r)){u.lineStart();for(var a=0;t>a;++a)u.point((e=n[a])[0],e[1]);return u.lineEnd(),void 0}var c=new ke(e,n,null,!0),s=new ke(e,null,c,!1);c.o=s,i.push(c),o.push(s),c=new ke(r,n,null,!1),s=new ke(r,null,c,!0),c.o=s,i.push(c),o.push(s)}}),o.sort(t),Se(i),Se(o),i.length){for(var a=0,c=e,s=o.length;s>a;++a)o[a].e=c=!c;for(var l,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;l=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,s=l.length;s>a;++a)u.point((f=l[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){l=g.p.z;for(var a=l.length-1;a>=0;--a)u.point((f=l[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,l=g.z,p=!p}while(!g.v);u.lineEnd()}}}function Se(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r<t;)u.n=e=n[r],e.p=u,u=e;u.n=e=n[0],e.p=u}}function ke(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Ee(n,t,e,r){return function(u,i){function o(t,e){var r=u(t,e);n(t=r[0],e=r[1])&&i.point(t,e)}function a(n,t){var e=u(n,t);d.point(e[0],e[1])}function c(){y.point=a,d.lineStart()}function s(){y.point=o,d.lineEnd()}function l(n,t){v.push([n,t]);var e=u(n,t);M.point(e[0],e[1])}function f(){M.lineStart(),v=[]}function h(){l(v[0][0],v[0][1]),M.lineEnd();var n,t=M.clean(),e=x.buffer(),r=e.length;if(v.pop(),p.push(v),v=null,r){if(1&t){n=e[0];var u,r=n.length-1,o=-1;for(i.lineStart();++o<r;)i.point((u=n[o])[0],u[1]);return i.lineEnd(),void 0}r>1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Ae))}}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:s,polygonStart:function(){y.point=l,y.lineStart=f,y.lineEnd=h,g=[],p=[],i.polygonStart()},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=s,g=Xo.merge(g);var n=Le(m,p);g.length?we(g,Ne,n,e,i):n&&(i.lineStart(),e(null,null,1,i),i.lineEnd()),i.polygonEnd(),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},x=Ce(),M=t(x);return y}}function Ae(n){return n.length>1}function Ce(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:g,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Ne(n,t){return((n=n.x)[0]<0?n[1]-Ea-Aa:Ea-n[1])-((t=t.x)[0]<0?t[1]-Ea-Aa:Ea-t[1])}function Le(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;hc.reset();for(var a=0,c=t.length;c>a;++a){var s=t[a],l=s.length;if(l)for(var f=s[0],h=f[0],g=f[1]/2+Sa/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===l&&(d=0),n=s[d];var m=n[0],y=n[1]/2+Sa/4,x=Math.sin(y),M=Math.cos(y),_=m-h,b=_>=0?1:-1,w=b*_,S=w>Sa,k=p*x;if(hc.add(Math.atan2(k*b*Math.sin(w),v*M+k*Math.cos(w))),i+=S?_+b*ka:_,S^h>=e^m>=e){var E=fe(se(f),se(n));pe(E);var A=fe(u,E);pe(A);var C=(S^_>=0?-1:1)*X(A[2]);(r>C||r===C&&(E[0]||E[1]))&&(o+=S^_>=0?1:-1)}if(!d++)break;h=m,p=x,v=M,f=n}}return(-Aa>i||Aa>i&&0>hc)^1&o}function Te(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?Sa:-Sa,c=oa(i-e);oa(c-Sa)<Aa?(n.point(e,r=(r+o)/2>0?Ea:-Ea),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=Sa&&(oa(e-u)<Aa&&(e-=u*Aa),oa(i-a)<Aa&&(i-=a*Aa),r=qe(e,r,i,o),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=i,r=o),u=a},lineEnd:function(){n.lineEnd(),e=r=0/0},clean:function(){return 2-t}}}function qe(n,t,e,r){var u,i,o=Math.sin(n-e);return oa(o)>Aa?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function ze(n,t,e,r){var u;if(null==n)u=e*Ea,r.point(-Sa,u),r.point(0,u),r.point(Sa,u),r.point(Sa,0),r.point(Sa,-u),r.point(0,-u),r.point(-Sa,-u),r.point(-Sa,0),r.point(-Sa,u);else if(oa(n[0]-t[0])>Aa){var i=n[0]<t[0]?Sa:-Sa;u=e*i/2,r.point(-i,u),r.point(0,u),r.point(i,u)}else r.point(t[0],t[1])}function Re(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,s,l;return{lineStart:function(){s=c=!1,l=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?Sa:-Sa),h):0;if(!e&&(s=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(de(e,g)||de(p,g))&&(p[0]+=Aa,p[1]+=Aa,v=t(p[0],p[1]))),v!==c)l=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(l=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&de(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return l|(s&&c)<<1}}}function r(n,t,e){var r=se(n),u=se(t),o=[1,0,0],a=fe(r,u),c=le(a,a),s=a[0],l=c-s*s;if(!l)return!e&&n;var f=i*c/l,h=-i*s/l,g=fe(o,a),p=ge(o,f),v=ge(a,h);he(p,v);var d=g,m=le(p,d),y=le(d,d),x=m*m-y*(le(p,p)-1);if(!(0>x)){var M=Math.sqrt(x),_=ge(d,(-m-M)/y);if(he(_,p),_=ve(_),!e)return _;var b,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(b=w,w=S,S=b);var A=S-w,C=oa(A-Sa)<Aa,N=C||Aa>A;if(!C&&k>E&&(b=k,k=E,E=b),N?C?k+E>0^_[1]<(oa(_[0]-w)<Aa?k:E):k<=_[1]&&_[1]<=E:A>Sa^(w<=_[0]&&_[0]<=S)){var L=ge(d,(-m+M)/y);return he(L,p),[_,ve(L)]}}}function u(t,e){var r=o?n:Sa-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=oa(i)>Aa,c=cr(n,6*Na);return Ee(t,e,c,o?[0,-n]:[-Sa,n-Sa])}function De(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,s=o.y,l=a.x,f=a.y,h=0,g=1,p=l-c,v=f-s;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-s,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-s,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:s+h*v}),1>g&&(u.b={x:c+g*p,y:s+g*v}),u}}}}}}function Pe(n,t,e,r){function u(r,u){return oa(r[0]-n)<Aa?u>0?0:3:oa(r[0]-e)<Aa?u>0?2:1:oa(r[1]-t)<Aa?u>0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,s=a[0];c>o;++o)i=a[o],s[1]<=r?i[1]>r&&Z(s,i,n)>0&&++t:i[1]<=r&&Z(s,i,n)<0&&--t,s=i;return 0!==t}function s(i,a,c,s){var l=0,f=0;if(null==i||(l=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do s.point(0===l||3===l?n:e,l>1?r:t);while((l=(l+c+4)%4)!==f)}else s.point(a[0],a[1])}function l(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){l(n,t)&&a.point(n,t)}function h(){N.point=p,d&&d.push(m=[]),S=!0,w=!1,_=b=0/0}function g(){v&&(p(y,x),M&&w&&A.rejoin(),v.push(A.buffer())),N.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Ac,Math.min(Ac,n)),t=Math.max(-Ac,Math.min(Ac,t));var e=l(n,t);if(d&&m.push([n,t]),S)y=n,x=t,M=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:_,y:b},b:{x:n,y:t}};C(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}_=n,b=t,w=e}var v,d,m,y,x,M,_,b,w,S,k,E=a,A=Ce(),C=De(n,t,e,r),N={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=Xo.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),s(null,null,1,a),a.lineEnd()),u&&we(v,i,t,s,a),a.polygonEnd()),v=d=m=null}};return N}}function Ue(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function je(n){var t=0,e=Sa/3,r=nr(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*Sa/180,e=n[1]*Sa/180):[180*(t/Sa),180*(e/Sa)]},u}function He(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,X((i-(n*n+e*e)*u*u)/(2*u))]},e}function Fe(){function n(n,t){Nc+=u*n-r*t,r=n,u=t}var t,e,r,u;Rc.point=function(i,o){Rc.point=n,t=r=i,e=u=o},Rc.lineEnd=function(){n(t,e)}}function Oe(n,t){Lc>n&&(Lc=n),n>qc&&(qc=n),Tc>t&&(Tc=t),t>zc&&(zc=t)}function Ye(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Ie(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Ie(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Ie(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Ze(n,t){dc+=n,mc+=t,++yc}function Ve(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);xc+=o*(t+n)/2,Mc+=o*(e+r)/2,_c+=o,Ze(t=n,e=r)}var t,e;Pc.point=function(r,u){Pc.point=n,Ze(t=r,e=u)}}function Xe(){Pc.point=Ze}function $e(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);xc+=o*(r+n)/2,Mc+=o*(u+t)/2,_c+=o,o=u*n-r*t,bc+=o*(r+n),wc+=o*(u+t),Sc+=3*o,Ze(r=n,u=t)}var t,e,r,u;Pc.point=function(i,o){Pc.point=n,Ze(t=r=i,e=u=o)},Pc.lineEnd=function(){n(t,e)}}function Be(n){function t(t,e){n.moveTo(t,e),n.arc(t,e,o,0,ka)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:g};return a}function We(n){function t(n){return(a?r:e)(n)}function e(t){return Ke(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){x=0/0,S.point=i,t.lineStart()}function i(e,r){var i=se([e,r]),o=n(e,r);u(x,M,y,_,b,w,x=o[0],M=o[1],y=e,_=i[0],b=i[1],w=i[2],a,t),t.point(x,M)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=s,S.lineEnd=l}function s(n,t){i(f=n,h=t),g=x,p=M,v=_,d=b,m=w,S.point=i}function l(){u(x,M,y,_,b,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,x,M,_,b,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,s,l,f,h,g,p,v,d,m){var y=l-t,x=f-e,M=y*y+x*x;if(M>4*i&&d--){var _=a+g,b=c+p,w=s+v,S=Math.sqrt(_*_+b*b+w*w),k=Math.asin(w/=S),E=oa(oa(w)-1)<Aa||oa(r-h)<Aa?(r+h)/2:Math.atan2(b,_),A=n(E,k),C=A[0],N=A[1],L=C-t,T=N-e,q=x*L-y*T;(q*q/M>i||oa((y*L+x*T)/M-.5)>.3||o>a*g+c*p+s*v)&&(u(t,e,r,a,c,s,C,N,E,_/=S,b/=S,w,d,m),m.point(C,N),u(C,N,E,_,b,w,l,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Na),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function Je(n){var t=We(function(t,e){return n([t*La,e*La])});return function(n){return tr(t(n))}}function Ge(n){this.stream=n}function Ke(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function Qe(n){return nr(function(){return n})()}function nr(n){function t(n){return n=a(n[0]*Na,n[1]*Na),[n[0]*h+c,s-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(s-n[1])/h),n&&[n[0]*La,n[1]*La]}function r(){a=Ue(o=ur(m,y,x),i);var n=i(v,d);return c=g-n[0]*h,s=p+n[1]*h,u()}function u(){return l&&(l.valid=!1,l=null),t}var i,o,a,c,s,l,f=We(function(n,t){return n=i(n,t),[n[0]*h+c,s-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,y=0,x=0,M=Ec,_=bt,b=null,w=null;return t.stream=function(n){return l&&(l.valid=!1),l=tr(M(o,f(_(n)))),l.valid=!0,l},t.clipAngle=function(n){return arguments.length?(M=null==n?(b=n,Ec):Re((b=+n)*Na),u()):b},t.clipExtent=function(n){return arguments.length?(w=n,_=n?Pe(n[0][0],n[0][1],n[1][0],n[1][1]):bt,u()):w},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Na,d=n[1]%360*Na,r()):[v*La,d*La]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Na,y=n[1]%360*Na,x=n.length>2?n[2]%360*Na:0,r()):[m*La,y*La,x*La]},Xo.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function tr(n){return Ke(n,function(t,e){n.point(t*Na,e*Na)})}function er(n,t){return[n,t]}function rr(n,t){return[n>Sa?n-ka:-Sa>n?n+ka:n,t]}function ur(n,t,e){return n?t||e?Ue(or(n),ar(t,e)):or(n):t||e?ar(t,e):rr}function ir(n){return function(t,e){return t+=n,[t>Sa?t-ka:-Sa>t?t+ka:t,e]}}function or(n){var t=ir(n);return t.invert=ir(-n),t}function ar(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*r+a*u;return[Math.atan2(c*i-l*o,a*r-s*u),X(l*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*i-c*o;return[Math.atan2(c*i+s*o,a*r+l*u),X(l*r-a*u)]},e}function cr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=sr(e,u),i=sr(e,i),(o>0?i>u:u>i)&&(u+=o*ka)):(u=n+o*ka,i=n-.5*c);for(var s,l=u;o>0?l>i:i>l;l-=c)a.point((s=ve([e,-r*Math.cos(l),-r*Math.sin(l)]))[0],s[1])}}function sr(n,t){var e=se(t);e[0]-=n,pe(e);var r=V(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Aa)%(2*Math.PI)}function lr(n,t,e){var r=Xo.range(n,t-Aa,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function fr(n,t,e){var r=Xo.range(n,t-Aa,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function hr(n){return n.source}function gr(n){return n.target}function pr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),s=u*Math.sin(n),l=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(J(r-t)+u*o*J(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*l,u=e*s+t*f,o=e*i+t*a;return[Math.atan2(u,r)*La,Math.atan2(o,Math.sqrt(r*r+u*u))*La]}:function(){return[n*La,t*La]};return p.distance=h,p}function vr(){function n(n,u){var i=Math.sin(u*=Na),o=Math.cos(u),a=oa((n*=Na)-t),c=Math.cos(a);Uc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;jc.point=function(u,i){t=u*Na,e=Math.sin(i*=Na),r=Math.cos(i),jc.point=n},jc.lineEnd=function(){jc.point=jc.lineEnd=g}}function dr(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function mr(n,t){function e(n,t){var e=oa(oa(t)-Ea)<Aa?0:o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(Sa/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=I(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Ea]},e):xr}function yr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return oa(u)<Aa?er:(e.invert=function(n,t){var e=i-t;return[Math.atan2(n,e)/u,i-I(u)*Math.sqrt(n*n+e*e)]},e)}function xr(n,t){return[n,Math.log(Math.tan(Sa/4+t/2))]}function Mr(n){var t,e=Qe(n),r=e.scale,u=e.translate,i=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=u.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=i.apply(e,arguments);if(o===e){if(t=null==n){var a=Sa*r(),c=u();i([[c[0]-a,c[1]-a],[c[0]+a,c[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function _r(n,t){return[Math.log(Math.tan(Sa/4+t/2)),-n]}function br(n){return n[0]}function wr(n){return n[1]}function Sr(n){for(var t=n.length,e=[0,1],r=2,u=2;t>u;u++){for(;r>1&&Z(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function kr(n,t){return n[0]-t[0]||n[1]-t[1]}function Er(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Ar(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],s=e[1],l=t[1]-c,f=r[1]-s,h=(a*(c-s)-f*(u-i))/(f*o-a*l);return[u+h*o,c+h*l]}function Cr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Nr(){Jr(this),this.edge=this.site=this.circle=null}function Lr(n){var t=Jc.pop()||new Nr;return t.site=n,t}function Tr(n){Or(n),$c.remove(n),Jc.push(n),Jr(n)}function qr(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Tr(n);for(var c=i;c.circle&&oa(e-c.circle.x)<Aa&&oa(r-c.circle.cy)<Aa;)i=c.P,a.unshift(c),Tr(c),c=i;a.unshift(c),Or(c);for(var s=o;s.circle&&oa(e-s.circle.x)<Aa&&oa(r-s.circle.cy)<Aa;)o=s.N,a.push(s),Tr(s),s=o;a.push(s),Or(s);var l,f=a.length;for(l=1;f>l;++l)s=a[l],c=a[l-1],$r(s.edge,c.site,s.site,u);c=a[0],s=a[f-1],s.edge=Vr(c.site,s.site,null,u),Fr(c),Fr(s)}function zr(n){for(var t,e,r,u,i=n.x,o=n.y,a=$c._;a;)if(r=Rr(a,o)-i,r>Aa)a=a.L;else{if(u=i-Dr(a,o),!(u>Aa)){r>-Aa?(t=a.P,e=a):u>-Aa?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Lr(n);if($c.insert(t,c),t||e){if(t===e)return Or(t),e=Lr(t.site),$c.insert(c,e),c.edge=e.edge=Vr(t.site,c.site),Fr(t),Fr(e),void 0;if(!e)return c.edge=Vr(t.site,c.site),void 0;Or(t),Or(e);var s=t.site,l=s.x,f=s.y,h=n.x-l,g=n.y-f,p=e.site,v=p.x-l,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,x=v*v+d*d,M={x:(d*y-g*x)/m+l,y:(h*x-v*y)/m+f};$r(e.edge,s,p,M),c.edge=Vr(s,n,null,M),e.edge=Vr(n,p,null,M),Fr(t),Fr(e)}}function Rr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,s=c-t;if(!s)return a;var l=a-r,f=1/i-1/s,h=l/s;return f?(-h+Math.sqrt(h*h-2*f*(l*l/(-2*s)-c+s/2+u-i/2)))/f+r:(r+a)/2}function Dr(n,t){var e=n.N;if(e)return Rr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Pr(n){this.site=n,this.edges=[]}function Ur(n){for(var t,e,r,u,i,o,a,c,s,l,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Xc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)l=a[o].end(),r=l.x,u=l.y,s=a[++o%c].start(),t=s.x,e=s.y,(oa(r-t)>Aa||oa(u-e)>Aa)&&(a.splice(o,0,new Br(Xr(i.site,l,oa(r-f)<Aa&&p-u>Aa?{x:f,y:oa(t-f)<Aa?e:p}:oa(u-p)<Aa&&h-r>Aa?{x:oa(e-p)<Aa?t:h,y:p}:oa(r-h)<Aa&&u-g>Aa?{x:h,y:oa(t-h)<Aa?e:g}:oa(u-g)<Aa&&r-f>Aa?{x:oa(e-g)<Aa?t:f,y:g}:null),i.site,null)),++c)}function jr(n,t){return t.angle-n.angle}function Hr(){Jr(this),this.x=this.y=this.arc=this.site=this.cy=null}function Fr(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,u=n.site,i=e.site;if(r!==i){var o=u.x,a=u.y,c=r.x-o,s=r.y-a,l=i.x-o,f=i.y-a,h=2*(c*f-s*l);if(!(h>=-Ca)){var g=c*c+s*s,p=l*l+f*f,v=(f*g-s*p)/h,d=(c*p-l*g)/h,f=d+a,m=Gc.pop()||new Hr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,x=Wc._;x;)if(m.y<x.y||m.y===x.y&&m.x<=x.x){if(!x.L){y=x.P;break}x=x.L}else{if(!x.R){y=x;break}x=x.R}Wc.insert(y,m),y||(Bc=m)}}}}function Or(n){var t=n.circle;t&&(t.P||(Bc=t.N),Wc.remove(t),Gc.push(t),Jr(t),n.circle=null)}function Yr(n){for(var t,e=Vc,r=De(n[0][0],n[0][1],n[1][0],n[1][1]),u=e.length;u--;)t=e[u],(!Ir(t,n)||!r(t)||oa(t.a.x-t.b.x)<Aa&&oa(t.a.y-t.b.y)<Aa)&&(t.a=t.b=null,e.splice(u,1))}function Ir(n,t){var e=n.b;if(e)return!0;var r,u,i=n.a,o=t[0][0],a=t[1][0],c=t[0][1],s=t[1][1],l=n.l,f=n.r,h=l.x,g=l.y,p=f.x,v=f.y,d=(h+p)/2,m=(g+v)/2;if(v===g){if(o>d||d>=a)return;if(h>p){if(i){if(i.y>=s)return}else i={x:d,y:c};e={x:d,y:s}}else{if(i){if(i.y<c)return}else i={x:d,y:s};e={x:d,y:c}}}else if(r=(h-p)/(v-g),u=m-r*d,-1>r||r>1)if(h>p){if(i){if(i.y>=s)return}else i={x:(c-u)/r,y:c};e={x:(s-u)/r,y:s}}else{if(i){if(i.y<c)return}else i={x:(s-u)/r,y:s};e={x:(c-u)/r,y:c}}else if(v>g){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.x<o)return}else i={x:a,y:r*a+u};e={x:o,y:r*o+u}}return n.a=i,n.b=e,!0}function Zr(n,t){this.l=n,this.r=t,this.a=this.b=null}function Vr(n,t,e,r){var u=new Zr(n,t);return Vc.push(u),e&&$r(u,n,t,e),r&&$r(u,t,n,r),Xc[n.i].edges.push(new Br(u,n,t)),Xc[t.i].edges.push(new Br(u,t,n)),u}function Xr(n,t,e){var r=new Zr(n,null);return r.a=t,r.b=e,Vc.push(r),r}function $r(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function Br(n,t,e){var r=n.a,u=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(u.x-r.x,r.y-u.y):Math.atan2(r.x-u.x,u.y-r.y)}function Wr(){this._=null}function Jr(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function Gr(n,t){var e=t,r=t.R,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function Kr(n,t){var e=t,r=t.L,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function Qr(n){for(;n.L;)n=n.L;return n}function nu(n,t){var e,r,u,i=n.sort(tu).pop();for(Vc=[],Xc=new Array(n.length),$c=new Wr,Wc=new Wr;;)if(u=Bc,i&&(!u||i.y<u.y||i.y===u.y&&i.x<u.x))(i.x!==e||i.y!==r)&&(Xc[i.i]=new Pr(i),zr(i),e=i.x,r=i.y),i=n.pop();else{if(!u)break;qr(u.arc)}t&&(Yr(t),Ur(t));var o={cells:Xc,edges:Vc};return $c=Wc=Vc=Xc=null,o}function tu(n,t){return t.y-n.y||t.x-n.x}function eu(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function ru(n){return n.x}function uu(n){return n.y}function iu(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function ou(n,t,e,r,u,i){if(!n(t,e,r,u,i)){var o=.5*(e+u),a=.5*(r+i),c=t.nodes;c[0]&&ou(n,c[0],e,r,o,a),c[1]&&ou(n,c[1],o,r,u,a),c[2]&&ou(n,c[2],e,a,o,i),c[3]&&ou(n,c[3],o,a,u,i)}}function au(n,t){n=Xo.rgb(n),t=Xo.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+vt(Math.round(e+i*n))+vt(Math.round(r+o*n))+vt(Math.round(u+a*n))}}function cu(n,t){var e,r={},u={};for(e in n)e in t?r[e]=fu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function su(n,t){return t-=n=+n,function(e){return n+t*e}}function lu(n,t){var e,r,u,i,o,a=0,c=0,s=[],l=[];for(n+="",t+="",Qc.lastIndex=0,r=0;e=Qc.exec(t);++r)e.index&&s.push(t.substring(a,c=e.index)),l.push({i:s.length,x:e[0]}),s.push(null),a=Qc.lastIndex;for(a<t.length&&s.push(t.substring(a)),r=0,i=l.length;(e=Qc.exec(n))&&i>r;++r)if(o=l[r],o.x==e[0]){if(o.i)if(null==s[o.i+1])for(s[o.i-1]+=o.x,s.splice(o.i,1),u=r+1;i>u;++u)l[u].i--;else for(s[o.i-1]+=o.x+s[o.i+1],s.splice(o.i,2),u=r+1;i>u;++u)l[u].i-=2;else if(null==s[o.i+1])s[o.i]=o.x;else for(s[o.i]=o.x+s[o.i+1],s.splice(o.i+1,1),u=r+1;i>u;++u)l[u].i--;l.splice(r,1),i--,r--}else o.x=su(parseFloat(e[0]),parseFloat(o.x));for(;i>r;)o=l.pop(),null==s[o.i+1]?s[o.i]=o.x:(s[o.i]=o.x+s[o.i+1],s.splice(o.i+1,1)),i--;return 1===s.length?null==s[0]?(o=l[0].x,function(n){return o(n)+""}):function(){return t}:function(n){for(r=0;i>r;++r)s[(o=l[r]).i]=o.x(n);return s.join("")}}function fu(n,t){for(var e,r=Xo.interpolators.length;--r>=0&&!(e=Xo.interpolators[r](n,t)););return e}function hu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(fu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function gu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function pu(n){return function(t){return 1-n(1-t)}}function vu(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function du(n){return n*n}function mu(n){return n*n*n}function yu(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function xu(n){return function(t){return Math.pow(t,n)}}function Mu(n){return 1-Math.cos(n*Ea)}function _u(n){return Math.pow(2,10*(n-1))}function bu(n){return 1-Math.sqrt(1-n*n)}function wu(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/ka*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*ka/t)}}function Su(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function ku(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Eu(n,t){n=Xo.hcl(n),t=Xo.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return rt(e+i*n,r+o*n,u+a*n)+""}}function Au(n,t){n=Xo.hsl(n),t=Xo.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return nt(e+i*n,r+o*n,u+a*n)+""}}function Cu(n,t){n=Xo.lab(n),t=Xo.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ot(e+i*n,r+o*n,u+a*n)+""}}function Nu(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Lu(n){var t=[n.a,n.b],e=[n.c,n.d],r=qu(t),u=Tu(t,e),i=qu(zu(e,t,-u))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,u*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*La,this.translate=[n.e,n.f],this.scale=[r,i],this.skew=i?Math.atan2(u,i)*La:0}function Tu(n,t){return n[0]*t[0]+n[1]*t[1]}function qu(n){var t=Math.sqrt(Tu(n,n));return t&&(n[0]/=t,n[1]/=t),t}function zu(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Ru(n,t){var e,r=[],u=[],i=Xo.transform(n),o=Xo.transform(t),a=i.translate,c=o.translate,s=i.rotate,l=o.rotate,f=i.skew,h=o.skew,g=i.scale,p=o.scale;return a[0]!=c[0]||a[1]!=c[1]?(r.push("translate(",null,",",null,")"),u.push({i:1,x:su(a[0],c[0])},{i:3,x:su(a[1],c[1])})):c[0]||c[1]?r.push("translate("+c+")"):r.push(""),s!=l?(s-l>180?l+=360:l-s>180&&(s+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:su(s,l)})):l&&r.push(r.pop()+"rotate("+l+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:su(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:su(g[0],p[0])},{i:e-2,x:su(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i<e;)r[(t=u[i]).i]=t.x(n);return r.join("")}}function Du(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return(e-n)*t}}function Pu(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return Math.max(0,Math.min(1,(e-n)*t))}}function Uu(n){for(var t=n.source,e=n.target,r=Hu(t,e),u=[t];t!==r;)t=t.parent,u.push(t);for(var i=u.length;e!==r;)u.splice(i,0,e),e=e.parent;return u}function ju(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Hu(n,t){if(n===t)return n;for(var e=ju(n),r=ju(t),u=e.pop(),i=r.pop(),o=null;u===i;)o=u,u=e.pop(),i=r.pop();return o}function Fu(n){n.fixed|=2}function Ou(n){n.fixed&=-7}function Yu(n){n.fixed|=4,n.px=n.x,n.py=n.y}function Iu(n){n.fixed&=-5}function Zu(n,t,e){var r=0,u=0;if(n.charge=0,!n.leaf)for(var i,o=n.nodes,a=o.length,c=-1;++c<a;)i=o[c],null!=i&&(Zu(i,t,e),n.charge+=i.charge,r+=i.charge*i.cx,u+=i.charge*i.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var s=t*e[n.point.index];n.charge+=n.pointCharge=s,r+=s*n.point.x,u+=s*n.point.y}n.cx=r/n.charge,n.cy=u/n.charge}function Vu(n,t){return Xo.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=Wu,n}function Xu(n){return n.children}function $u(n){return n.value}function Bu(n,t){return t.value-n.value}function Wu(n){return Xo.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function Ju(n){return n.x}function Gu(n){return n.y}function Ku(n,t,e){n.y0=t,n.y=e}function Qu(n){return Xo.range(n.length)}function ni(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function ti(n){for(var t,e=1,r=0,u=n[0][1],i=n.length;i>e;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function ei(n){return n.reduce(ri,0)}function ri(n,t){return n+t[1]}function ui(n,t){return ii(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function ii(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function oi(n){return[Xo.min(n),Xo.max(n)]}function ai(n,t){return n.parent==t.parent?1:2}function ci(n){var t=n.children;return t&&t.length?t[0]:n._tree.thread}function si(n){var t,e=n.children;return e&&(t=e.length)?e[t-1]:n._tree.thread}function li(n,t){var e=n.children;if(e&&(u=e.length))for(var r,u,i=-1;++i<u;)t(r=li(e[i],t),n)>0&&(n=r);return n}function fi(n,t){return n.x-t.x}function hi(n,t){return t.x-n.x}function gi(n,t){return n.depth-t.depth}function pi(n,t){function e(n,r){var u=n.children;if(u&&(o=u.length))for(var i,o,a=null,c=-1;++c<o;)i=u[c],e(i,a),a=i;t(n,r)}e(n,null)}function vi(n){for(var t,e=0,r=0,u=n.children,i=u.length;--i>=0;)t=u[i]._tree,t.prelim+=e,t.mod+=e,e+=t.shift+(r+=t.change)}function di(n,t,e){n=n._tree,t=t._tree;var r=e/(t.number-n.number);n.change+=r,t.change-=r,t.shift+=e,t.prelim+=e,t.mod+=e}function mi(n,t,e){return n._tree.ancestor.parent==t.parent?n._tree.ancestor:e}function yi(n,t){return n.value-t.value}function xi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function Mi(n,t){n._pack_next=t,t._pack_prev=n}function _i(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function bi(n){function t(n){l=Math.min(n.x-n.r,l),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(s=e.length)){var e,r,u,i,o,a,c,s,l=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(wi),r=e[0],r.x=-r.r,r.y=0,t(r),s>1&&(u=e[1],u.x=u.r,u.y=0,t(u),s>2))for(i=e[2],Ei(r,u,i),t(i),xi(r,i),r._pack_prev=i,xi(i,u),u=r._pack_next,o=3;s>o;o++){Ei(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(_i(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!_i(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.r<r.r?Mi(r,u=a):Mi(r=c,u),o--):(xi(r,i),u=i,t(i))}var m=(l+f)/2,y=(h+g)/2,x=0;for(o=0;s>o;o++)i=e[o],i.x-=m,i.y-=y,x=Math.max(x,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=x,e.forEach(Si)}}function wi(n){n._pack_next=n._pack_prev=n}function Si(n){delete n._pack_next,delete n._pack_prev}function ki(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i<o;)ki(u[i],t,e,r)}function Ei(n,t,e){var r=n.r+e.r,u=t.x-n.x,i=t.y-n.y;if(r&&(u||i)){var o=t.r+e.r,a=u*u+i*i;o*=o,r*=r;var c=.5+(r-o)/(2*a),s=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+c*u+s*i,e.y=n.y+c*i-s*u}else e.x=n.x+r,e.y=n.y}function Ai(n){return 1+Xo.max(n,function(n){return n.y})}function Ci(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Ni(n){var t=n.children;return t&&t.length?Ni(t[0]):n}function Li(n){var t,e=n.children;return e&&(t=e.length)?Li(e[t-1]):n}function Ti(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function qi(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function zi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ri(n){return n.rangeExtent?n.rangeExtent():zi(n.range())}function Di(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Pi(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Ui(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:ls}function ji(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)u.push(e(n[o-1],n[o])),i.push(r(t[o-1],t[o]));return function(t){var e=Xo.bisect(n,t,1,a)-1;return i[e](u[e](t))}}function Hi(n,t,e,r){function u(){var u=Math.min(n.length,t.length)>2?ji:Di,c=r?Pu:Du;return o=u(n,t,c,e),a=u(t,n,c,fu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Nu)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Ii(n,t)},i.tickFormat=function(t,e){return Zi(n,t,e)},i.nice=function(t){return Oi(n,t),u()},i.copy=function(){return Hi(n,t,e,r)},u()}function Fi(n,t){return Xo.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Oi(n,t){return Pi(n,Ui(Yi(n,t)[2]))}function Yi(n,t){null==t&&(t=10);var e=zi(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Ii(n,t){return Xo.range.apply(Xo,Yi(n,t))}function Zi(n,t,e){var r=Yi(n,t);return Xo.format(e?e.replace(Qa,function(n,t,e,u,i,o,a,c,s,l){return[t,e,u,i,o,a,c,s||"."+Xi(l,r),l].join("")}):",."+Vi(r[2])+"f")}function Vi(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Xi(n,t){var e=Vi(t[2]);return n in fs?Math.abs(e-Vi(Math.max(Math.abs(t[0]),Math.abs(t[1]))))+ +("e"!==n):e-2*("%"===n)}function $i(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Pi(r.map(u),e?Math:gs);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=zi(r),o=[],a=n[0],c=n[1],s=Math.floor(u(a)),l=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(l-s)){if(e){for(;l>s;s++)for(var h=1;f>h;h++)o.push(i(s)*h);o.push(i(s))}else for(o.push(i(s));s++<l;)for(var h=f-1;h>0;h--)o.push(i(s)*h);for(s=0;o[s]<a;s++);for(l=o.length;o[l-1]>c;l--);o=o.slice(s,l)}return o},o.tickFormat=function(n,t){if(!arguments.length)return hs;arguments.length<2?t=hs:"function"!=typeof t&&(t=Xo.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return $i(n.copy(),t,e,r)},Fi(o,n)}function Bi(n,t,e){function r(t){return n(u(t))}var u=Wi(t),i=Wi(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Ii(e,n)},r.tickFormat=function(n,t){return Zi(e,n,t)},r.nice=function(n){return r.domain(Oi(e,n))},r.exponent=function(o){return arguments.length?(u=Wi(t=o),i=Wi(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Bi(n.copy(),t,e)},Fi(r,n)}function Wi(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Ji(n,t){function e(e){return o[((i.get(e)||"range"===t.t&&i.set(e,n.push(e)))-1)%o.length]}function r(t,e){return Xo.range(n.length).map(function(n){return t+e*n})}var i,o,a;return e.domain=function(r){if(!arguments.length)return n;n=[],i=new u;for(var o,a=-1,c=r.length;++a<c;)i.has(o=r[a])||i.set(o,n.push(o));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(o=n,a=0,t={t:"range",a:arguments},e):o},e.rangePoints=function(u,i){arguments.length<2&&(i=0);var c=u[0],s=u[1],l=(s-c)/(Math.max(1,n.length-1)+i);return o=r(n.length<2?(c+s)/2:c+l*i/2,l),a=0,t={t:"rangePoints",a:arguments},e},e.rangeBands=function(u,i,c){arguments.length<2&&(i=0),arguments.length<3&&(c=i);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=(f-l)/(n.length-i+2*c);return o=r(l+h*c,h),s&&o.reverse(),a=h*(1-i),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(u,i,c){arguments.length<2&&(i=0),arguments.length<3&&(c=i);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=Math.floor((f-l)/(n.length-i+2*c)),g=f-l-(n.length-i)*h;return o=r(l+Math.round(g/2),h),s&&o.reverse(),a=Math.round(h*(1-i)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return a},e.rangeExtent=function(){return zi(t.a[0])},e.copy=function(){return Ji(n,t)},e.domain(n)}function Gi(n,t){function e(){var e=0,i=t.length;for(u=[];++e<i;)u[e-1]=Xo.quantile(n,e/i);return r}function r(n){return isNaN(n=+n)?void 0:t[Xo.bisect(u,n)]}var u;return r.domain=function(t){return arguments.length?(n=t.filter(function(n){return!isNaN(n)}).sort(Xo.ascending),e()):n},r.range=function(n){return arguments.length?(t=n,e()):t},r.quantiles=function(){return u},r.invertExtent=function(e){return e=t.indexOf(e),0>e?[0/0,0/0]:[e>0?u[e-1]:n[0],e<u.length?u[e]:n[n.length-1]]},r.copy=function(){return Gi(n,t)},e()}function Ki(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(i*(t-n))))]}function u(){return i=e.length/(t-n),o=e.length-1,r}var i,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],u()):[n,t]},r.range=function(n){return arguments.length?(e=n,u()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return Ki(n,t,e)},u()}function Qi(n,t){function e(e){return e>=e?t[Xo.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return Qi(n,t)},e}function no(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Ii(n,t)},t.tickFormat=function(t,e){return Zi(n,t,e)},t.copy=function(){return no(n)},t}function to(n){return n.innerRadius}function eo(n){return n.outerRadius}function ro(n){return n.startAngle}function uo(n){return n.endAngle}function io(n){function t(t){function o(){s.push("M",i(n(l),a))}for(var c,s=[],l=[],f=-1,h=t.length,g=_t(e),p=_t(r);++f<h;)u.call(this,c=t[f],f)?l.push([+g.call(this,c,f),+p.call(this,c,f)]):l.length&&(o(),l=[]);return l.length&&o(),s.length?s.join(""):null}var e=br,r=wr,u=be,i=oo,o=i.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(u=n,t):u},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?i=n:(i=Ms.get(n)||oo).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function oo(n){return n.join("L")}function ao(n){return oo(n)+"Z"}function co(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&u.push("H",r[0]),u.join("")}function so(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("V",(r=n[t])[1],"H",r[0]);return u.join("")}function lo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r=n[t])[0],"V",r[1]);return u.join("")}function fo(n,t){return n.length<4?oo(n):n[1]+po(n.slice(1,n.length-1),vo(n,t))}function ho(n,t){return n.length<3?oo(n):n[0]+po((n.push(n[0]),n),vo([n[n.length-2]].concat(n,[n[1]]),t))}function go(n,t){return n.length<3?oo(n):n[0]+po(n,vo(n,t))}function po(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return oo(n);var e=n.length!=t.length,r="",u=n[0],i=n[1],o=t[0],a=o,c=1;if(e&&(r+="Q"+(i[0]-2*o[0]/3)+","+(i[1]-2*o[1]/3)+","+i[0]+","+i[1],u=n[1],c=2),t.length>1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var s=2;s<t.length;s++,c++)i=n[c],a=t[s],r+="S"+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1]}if(e){var l=n[c];r+="Q"+(i[0]+2*a[0]/3)+","+(i[1]+2*a[1]/3)+","+l[0]+","+l[1]}return r}function vo(n,t){for(var e,r=[],u=(1-t)/2,i=n[0],o=n[1],a=1,c=n.length;++a<c;)e=i,i=o,o=n[a],r.push([u*(o[0]-e[0]),u*(o[1]-e[1])]);return r}function mo(n){if(n.length<3)return oo(n);var t=1,e=n.length,r=n[0],u=r[0],i=r[1],o=[u,u,u,(r=n[1])[0]],a=[i,i,i,r[1]],c=[u,",",i,"L",_o(ws,o),",",_o(ws,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),bo(c,o,a);return n.pop(),c.push("L",r),c.join("")}function yo(n){if(n.length<4)return oo(n);for(var t,e=[],r=-1,u=n.length,i=[0],o=[0];++r<3;)t=n[r],i.push(t[0]),o.push(t[1]);for(e.push(_o(ws,i)+","+_o(ws,o)),--r;++r<u;)t=n[r],i.shift(),i.push(t[0]),o.shift(),o.push(t[1]),bo(e,i,o);return e.join("")}function xo(n){for(var t,e,r=-1,u=n.length,i=u+4,o=[],a=[];++r<4;)e=n[r%u],o.push(e[0]),a.push(e[1]);for(t=[_o(ws,o),",",_o(ws,a)],--r;++r<i;)e=n[r%u],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),bo(t,o,a);return t.join("")}function Mo(n,t){var e=n.length-1;if(e)for(var r,u,i=n[0][0],o=n[0][1],a=n[e][0]-i,c=n[e][1]-o,s=-1;++s<=e;)r=n[s],u=s/e,r[0]=t*r[0]+(1-t)*(i+u*a),r[1]=t*r[1]+(1-t)*(o+u*c);return mo(n)}function _o(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function bo(n,t,e){n.push("C",_o(_s,t),",",_o(_s,e),",",_o(bs,t),",",_o(bs,e),",",_o(ws,t),",",_o(ws,e))}function wo(n,t){return(t[1]-n[1])/(t[0]-n[0])}function So(n){for(var t=0,e=n.length-1,r=[],u=n[0],i=n[1],o=r[0]=wo(u,i);++t<e;)r[t]=(o+(o=wo(u=i,i=n[t+1])))/2;return r[t]=o,r}function ko(n){for(var t,e,r,u,i=[],o=So(n),a=-1,c=n.length-1;++a<c;)t=wo(n[a],n[a+1]),oa(t)<Aa?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,u=e*e+r*r,u>9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function Eo(n){return n.length<3?oo(n):n[0]+po(n,ko(n))}function Ao(n){for(var t,e,r,u=-1,i=n.length;++u<i;)t=n[u],e=t[0],r=t[1]+ys,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Co(n){function t(t){function c(){v.push("M",a(n(m),f),l,s(n(d.reverse()),f),"Z")}for(var h,g,p,v=[],d=[],m=[],y=-1,x=t.length,M=_t(e),_=_t(u),b=e===r?function(){return g}:_t(r),w=u===i?function(){return p}:_t(i);++y<x;)o.call(this,h=t[y],y)?(d.push([g=+M.call(this,h,y),p=+_.call(this,h,y)]),m.push([+b.call(this,h,y),+w.call(this,h,y)])):d.length&&(c(),d=[],m=[]);return d.length&&c(),v.length?v.join(""):null}var e=br,r=br,u=0,i=wr,o=be,a=oo,c=a.key,s=a,l="L",f=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r},t.y=function(n){return arguments.length?(u=i=n,t):i},t.y0=function(n){return arguments.length?(u=n,t):u},t.y1=function(n){return arguments.length?(i=n,t):i},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(c="function"==typeof n?a=n:(a=Ms.get(n)||oo).key,s=a.reverse||a,l=a.closed?"M":"L",t):c},t.tension=function(n){return arguments.length?(f=n,t):f},t}function No(n){return n.radius}function Lo(n){return[n.x,n.y]}function To(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]+ys;return[e*Math.cos(r),e*Math.sin(r)]}}function qo(){return 64}function zo(){return"circle"}function Ro(n){var t=Math.sqrt(n/Sa);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function Do(n,t){return fa(n,Ns),n.id=t,n}function Po(n,t,e,r){var u=n.id;return R(n,"function"==typeof e?function(n,i,o){n.__transition__[u].tween.set(t,r(e.call(n,n.__data__,i,o)))}:(e=r(e),function(n){n.__transition__[u].tween.set(t,e)}))}function Uo(n){return null==n&&(n=""),function(){this.textContent=n}}function jo(n,t,e,r){var i=n.__transition__||(n.__transition__={active:0,count:0}),o=i[e];if(!o){var a=r.time;o=i[e]={tween:new u,time:a,ease:r.ease,delay:r.delay,duration:r.duration},++i.count,Xo.timer(function(r){function u(r){return i.active>e?s():(i.active=e,o.event&&o.event.start.call(n,l,t),o.tween.forEach(function(e,r){(r=r.call(n,l,t))&&v.push(r)}),Xo.timer(function(){return p.c=c(r||1)?be:c,1},0,a),void 0)}function c(r){if(i.active!==e)return s();for(var u=r/g,a=f(u),c=v.length;c>0;)v[--c].call(n,a);return u>=1?(o.event&&o.event.end.call(n,l,t),s()):void 0}function s(){return--i.count?delete i[e]:delete n.__transition__,1}var l=n.__data__,f=o.ease,h=o.delay,g=o.duration,p=Ja,v=[];return p.t=h+a,r>=h?u(r-h):(p.c=u,void 0)},0,a)}}function Ho(n,t){n.attr("transform",function(n){return"translate("+t(n)+",0)"})}function Fo(n,t){n.attr("transform",function(n){return"translate(0,"+t(n)+")"})}function Oo(n){return n.toISOString()}function Yo(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=Xo.bisect(js,u);return i==js.length?[t.year,Yi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/js[i-1]<js[i]/u?i-1:i]:[Os,Yi(n,e)[2]]}return r.invert=function(t){return Io(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(Io)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,Io(+e+1),t).length}var i=r.domain(),o=zi(i),a=null==n?u(o,10):"number"==typeof n&&u(o,n);return a&&(n=a[0],t=a[1]),r.domain(Pi(i,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=Io(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Io(+t+1);return t}}:n))},r.ticks=function(n,t){var e=zi(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Io(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Yo(n.copy(),t,e)},Fi(r,n)}function Io(n){return new Date(n)}function Zo(n){return JSON.parse(n.responseText)}function Vo(n){var t=Wo.createRange();return t.selectNode(Wo.body),t.createContextualFragment(n.responseText)}var Xo={version:"3.4.3"};Date.now||(Date.now=function(){return+new Date});var $o=[].slice,Bo=function(n){return $o.call(n)},Wo=document,Jo=Wo.documentElement,Go=window;try{Bo(Jo.childNodes)[0].nodeType}catch(Ko){Bo=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}try{Wo.createElement("div").style.setProperty("opacity",0,"")}catch(Qo){var na=Go.Element.prototype,ta=na.setAttribute,ea=na.setAttributeNS,ra=Go.CSSStyleDeclaration.prototype,ua=ra.setProperty;na.setAttribute=function(n,t){ta.call(this,n,t+"")},na.setAttributeNS=function(n,t,e){ea.call(this,n,t,e+"")},ra.setProperty=function(n,t,e){ua.call(this,n,t+"",e)}}Xo.ascending=function(n,t){return t>n?-1:n>t?1:n>=t?0:0/0},Xo.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},Xo.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&e>r&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&e>r&&(e=r)}return e},Xo.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&r>e&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&r>e&&(e=r)}return e},Xo.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i<o&&!(null!=(e=u=n[i])&&e>=e);)e=u=void 0;for(;++i<o;)null!=(r=n[i])&&(e>r&&(e=r),r>u&&(u=r))}else{for(;++i<o&&!(null!=(e=u=t.call(n,n[i],i))&&e>=e);)e=void 0;for(;++i<o;)null!=(r=t.call(n,n[i],i))&&(e>r&&(e=r),r>u&&(u=r))}return[e,u]},Xo.sum=function(n,t){var e,r=0,u=n.length,i=-1;if(1===arguments.length)for(;++i<u;)isNaN(e=+n[i])||(r+=e);else for(;++i<u;)isNaN(e=+t.call(n,n[i],i))||(r+=e);return r},Xo.mean=function(t,e){var r,u=t.length,i=0,o=-1,a=0;if(1===arguments.length)for(;++o<u;)n(r=t[o])&&(i+=(r-i)/++a);else for(;++o<u;)n(r=e.call(t,t[o],o))&&(i+=(r-i)/++a);return a?i:void 0},Xo.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),u=+n[r-1],i=e-r;return i?u+i*(n[r]-u):u},Xo.median=function(t,e){return arguments.length>1&&(t=t.map(e)),t=t.filter(n),t.length?Xo.quantile(t.sort(Xo.ascending),.5):void 0},Xo.bisector=function(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n.call(t,t[i],i)<e?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;e<n.call(t,t[i],i)?u=i:r=i+1}return r}}};var ia=Xo.bisector(function(n){return n});Xo.bisectLeft=ia.left,Xo.bisect=Xo.bisectRight=ia.right,Xo.shuffle=function(n){for(var t,e,r=n.length;r;)e=0|Math.random()*r--,t=n[r],n[r]=n[e],n[e]=t;return n},Xo.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},Xo.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},Xo.zip=function(){if(!(u=arguments.length))return[];for(var n=-1,e=Xo.min(arguments,t),r=new Array(e);++n<e;)for(var u,i=-1,o=r[n]=new Array(u);++i<u;)o[i]=arguments[i][n];return r},Xo.transpose=function(n){return Xo.zip.apply(Xo,n)},Xo.keys=function(n){var t=[];for(var e in n)t.push(e);return t},Xo.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},Xo.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},Xo.merge=function(n){for(var t,e,r,u=n.length,i=-1,o=0;++i<u;)o+=n[i].length;for(e=new Array(o);--u>=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var oa=Math.abs;Xo.range=function(n,t,r){if(arguments.length<3&&(r=1,arguments.length<2&&(t=n,n=0)),1/0===(t-n)/r)throw new Error("infinite range");var u,i=[],o=e(oa(r)),a=-1;if(n*=o,t*=o,r*=o,0>r)for(;(u=n+r*++a)>t;)i.push(u/o);else for(;(u=n+r*++a)<t;)i.push(u/o);return i},Xo.map=function(n){var t=new u;if(n instanceof u)n.forEach(function(n,e){t.set(n,e)});else for(var e in n)t.set(e,n[e]);return t},r(u,{has:i,get:function(n){return this[aa+n]},set:function(n,t){return this[aa+n]=t},remove:o,keys:a,values:function(){var n=[];return this.forEach(function(t,e){n.push(e)}),n},entries:function(){var n=[];return this.forEach(function(t,e){n.push({key:t,value:e})}),n},size:c,empty:s,forEach:function(n){for(var t in this)t.charCodeAt(0)===ca&&n.call(this,t.substring(1),this[t])}});var aa="\x00",ca=aa.charCodeAt(0);Xo.nest=function(){function n(t,a,c){if(c>=o.length)return r?r.call(i,a):e?a.sort(e):a;for(var s,l,f,h,g=-1,p=a.length,v=o[c++],d=new u;++g<p;)(h=d.get(s=v(l=a[g])))?h.push(l):d.set(s,[l]);return t?(l=t(),f=function(e,r){l.set(e,n(t,r,c))}):(l={},f=function(e,r){l[e]=n(t,r,c)}),d.forEach(f),l}function t(n,e){if(e>=o.length)return n;var r=[],u=a[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,i={},o=[],a=[];return i.map=function(t,e){return n(e,t,0)},i.entries=function(e){return t(n(Xo.map,e,0),0)},i.key=function(n){return o.push(n),i},i.sortKeys=function(n){return a[o.length-1]=n,i},i.sortValues=function(n){return e=n,i},i.rollup=function(n){return r=n,i},i},Xo.set=function(n){var t=new l;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},r(l,{has:i,add:function(n){return this[aa+n]=!0,n},remove:function(n){return n=aa+n,n in this&&delete this[n]},values:a,size:c,empty:s,forEach:function(n){for(var t in this)t.charCodeAt(0)===ca&&n.call(this,t.substring(1))}}),Xo.behavior={},Xo.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r<u;)n[e=arguments[r]]=f(n,t,t[e]);return n};var sa=["webkit","ms","moz","Moz","o","O"];Xo.dispatch=function(){for(var n=new p,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=v(n);return n},p.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.substring(e+1),n=n.substring(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},Xo.event=null,Xo.requote=function(n){return n.replace(la,"\\$&")};var la=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,fa={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},ha=function(n,t){return t.querySelector(n)},ga=function(n,t){return t.querySelectorAll(n)},pa=Jo[h(Jo,"matchesSelector")],va=function(n,t){return pa.call(n,t)};"function"==typeof Sizzle&&(ha=function(n,t){return Sizzle(n,t)[0]||null},ga=Sizzle,va=Sizzle.matchesSelector),Xo.selection=function(){return xa};var da=Xo.selection.prototype=[];da.select=function(n){var t,e,r,u,i=[];n=M(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var c=-1,s=r.length;++c<s;)(u=r[c])?(t.push(e=n.call(u,u.__data__,c,o)),e&&"__data__"in u&&(e.__data__=u.__data__)):t.push(null)}return x(i)},da.selectAll=function(n){var t,e,r=[];n=_(n);for(var u=-1,i=this.length;++u<i;)for(var o=this[u],a=-1,c=o.length;++a<c;)(e=o[a])&&(r.push(t=Bo(n.call(e,e.__data__,a,u))),t.parentNode=e);return x(r)};var ma={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};Xo.ns={prefix:ma,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&(e=n.substring(0,t),n=n.substring(t+1)),ma.hasOwnProperty(e)?{space:ma[e],local:n}:n}},da.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=Xo.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(b(t,n[t]));return this}return this.each(b(n,t))},da.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=k(n)).length,u=-1;if(t=e.classList){for(;++u<r;)if(!t.contains(n[u]))return!1}else for(t=e.getAttribute("class");++u<r;)if(!S(n[u]).test(t))return!1;return!0}for(t in n)this.each(E(t,n[t]));return this}return this.each(E(n,t))},da.style=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(C(e,n[e],t));return this}if(2>r)return Go.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(C(n,t,e))},da.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(N(t,n[t]));return this}return this.each(N(n,t))},da.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},da.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},da.append=function(n){return n=L(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},da.insert=function(n,t){return n=L(n),t=M(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},da.remove=function(){return this.each(function(){var n=this.parentNode;n&&n.removeChild(this)})},da.data=function(n,t){function e(n,e){var r,i,o,a=n.length,f=e.length,h=Math.min(a,f),g=new Array(f),p=new Array(f),v=new Array(a);if(t){var d,m=new u,y=new u,x=[];for(r=-1;++r<a;)d=t.call(i=n[r],i.__data__,r),m.has(d)?v[r]=i:m.set(d,i),x.push(d);for(r=-1;++r<f;)d=t.call(e,o=e[r],r),(i=m.get(d))?(g[r]=i,i.__data__=o):y.has(d)||(p[r]=T(o)),y.set(d,o),m.remove(d);for(r=-1;++r<a;)m.has(x[r])&&(v[r]=n[r])}else{for(r=-1;++r<h;)i=n[r],o=e[r],i?(i.__data__=o,g[r]=i):p[r]=T(o);for(;f>r;++r)p[r]=T(e[r]);for(;a>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,c.push(p),s.push(g),l.push(v)}var r,i,o=-1,a=this.length;if(!arguments.length){for(n=new Array(a=(r=this[0]).length);++o<a;)(i=r[o])&&(n[o]=i.__data__);return n}var c=D([]),s=x([]),l=x([]);if("function"==typeof n)for(;++o<a;)e(r=this[o],n.call(r,r.parentNode.__data__,o));else for(;++o<a;)e(r=this[o],n);return s.enter=function(){return c},s.exit=function(){return l},s},da.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},da.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=q(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return x(u)},da.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],u=r.length-1,i=r[u];--u>=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},da.sort=function(n){n=z.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},da.each=function(n){return R(this,function(t,e,r){n.call(t,t.__data__,e,r)})},da.call=function(n){var t=Bo(arguments);return n.apply(t[0]=this,t),this},da.empty=function(){return!this.node()},da.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},da.size=function(){var n=0;return this.each(function(){++n}),n};var ya=[];Xo.selection.enter=D,Xo.selection.enter.prototype=ya,ya.append=da.append,ya.empty=da.empty,ya.node=da.node,ya.call=da.call,ya.size=da.size,ya.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++a<c;){r=(u=this[a]).update,o.push(t=[]),t.parentNode=u.parentNode;for(var s=-1,l=u.length;++s<l;)(i=u[s])?(t.push(r[s]=e=n.call(u.parentNode,i.__data__,s,a)),e.__data__=i.__data__):t.push(null)}return x(o)},ya.insert=function(n,t){return arguments.length<2&&(t=P(this)),da.insert.call(this,n,t)},da.transition=function(){for(var n,t,e=ks||++Ls,r=[],u=Es||{time:Date.now(),ease:yu,delay:0,duration:250},i=-1,o=this.length;++i<o;){r.push(n=[]);for(var a=this[i],c=-1,s=a.length;++c<s;)(t=a[c])&&jo(t,c,e,u),n.push(t)}return Do(r,e)},da.interrupt=function(){return this.each(U)},Xo.select=function(n){var t=["string"==typeof n?ha(n,Wo):n];return t.parentNode=Jo,x([t])},Xo.selectAll=function(n){var t=Bo("string"==typeof n?ga(n,Wo):n);return t.parentNode=Jo,x([t])};var xa=Xo.select(Jo);da.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(j(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(j(n,t,e))};var Ma=Xo.map({mouseenter:"mouseover",mouseleave:"mouseout"});Ma.forEach(function(n){"on"+n in Wo&&Ma.remove(n)});var _a="onselectstart"in Wo?null:h(Jo.style,"userSelect"),ba=0;Xo.mouse=function(n){return Y(n,m())};var wa=/WebKit/.test(Go.navigator.userAgent)?-1:0;Xo.touches=function(n,t){return arguments.length<2&&(t=m().touches),t?Bo(t).map(function(t){var e=Y(n,t);return e.identifier=t.identifier,e}):[]},Xo.behavior.drag=function(){function n(){this.on("mousedown.drag",o).on("touchstart.drag",a)}function t(){return Xo.event.changedTouches[0].identifier}function e(n,t){return Xo.touches(n).filter(function(n){return n.identifier===t})[0]}function r(n,t,e,r){return function(){function o(){var n=t(l,g),e=n[0]-v[0],r=n[1]-v[1];d|=e|r,v=n,f({type:"drag",x:n[0]+c[0],y:n[1]+c[1],dx:e,dy:r})}function a(){m.on(e+"."+p,null).on(r+"."+p,null),y(d&&Xo.event.target===h),f({type:"dragend"})}var c,s=this,l=s.parentNode,f=u.of(s,arguments),h=Xo.event.target,g=n(),p=null==g?"drag":"drag-"+g,v=t(l,g),d=0,m=Xo.select(Go).on(e+"."+p,o).on(r+"."+p,a),y=O();i?(c=i.apply(s,arguments),c=[c.x-v[0],c.y-v[1]]):c=[0,0],f({type:"dragstart"})}}var u=y(n,"drag","dragstart","dragend"),i=null,o=r(g,Xo.mouse,"mousemove","mouseup"),a=r(t,e,"touchmove","touchend");return n.origin=function(t){return arguments.length?(i=t,n):i},Xo.rebind(n,u,"on")};var Sa=Math.PI,ka=2*Sa,Ea=Sa/2,Aa=1e-6,Ca=Aa*Aa,Na=Sa/180,La=180/Sa,Ta=Math.SQRT2,qa=2,za=4;Xo.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=B(v),o=i/(qa*h)*(e*W(Ta*t+v)-$(v));return[r+o*s,u+o*l,i*e/B(Ta*t+v)]}return[r+n*s,u+n*l,i*Math.exp(Ta*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],s=o-r,l=a-u,f=s*s+l*l,h=Math.sqrt(f),g=(c*c-i*i+za*f)/(2*i*qa*h),p=(c*c-i*i-za*f)/(2*c*qa*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Ta;return e.duration=1e3*y,e},Xo.behavior.zoom=function(){function n(n){n.on(A,s).on(Pa+".zoom",f).on(C,h).on("dblclick.zoom",g).on(L,l)}function t(n){return[(n[0]-S.x)/S.k,(n[1]-S.y)/S.k]}function e(n){return[n[0]*S.k+S.x,n[1]*S.k+S.y]}function r(n){S.k=Math.max(E[0],Math.min(E[1],n))}function u(n,t){t=e(t),S.x+=n[0]-t[0],S.y+=n[1]-t[1]}function i(){_&&_.domain(M.range().map(function(n){return(n-S.x)/S.k}).map(M.invert)),w&&w.domain(b.range().map(function(n){return(n-S.y)/S.k}).map(b.invert))}function o(n){n({type:"zoomstart"})}function a(n){i(),n({type:"zoom",scale:S.k,translate:[S.x,S.y]})}function c(n){n({type:"zoomend"})}function s(){function n(){l=1,u(Xo.mouse(r),g),a(i)}function e(){f.on(C,Go===r?h:null).on(N,null),p(l&&Xo.event.target===s),c(i)}var r=this,i=T.of(r,arguments),s=Xo.event.target,l=0,f=Xo.select(Go).on(C,n).on(N,e),g=t(Xo.mouse(r)),p=O();U.call(r),o(i)}function l(){function n(){var n=Xo.touches(g);return h=S.k,n.forEach(function(n){n.identifier in v&&(v[n.identifier]=t(n))}),n}function e(){for(var t=Xo.event.changedTouches,e=0,i=t.length;i>e;++e)v[t[e].identifier]=null;var o=n(),c=Date.now();if(1===o.length){if(500>c-x){var s=o[0],l=v[s.identifier];r(2*S.k),u(s,l),d(),a(p)}x=c}else if(o.length>1){var s=o[0],f=o[1],h=s[0]-f[0],g=s[1]-f[1];m=h*h+g*g}}function i(){for(var n,t,e,i,o=Xo.touches(g),c=0,s=o.length;s>c;++c,i=null)if(e=o[c],i=v[e.identifier]){if(t)break;n=e,t=i}if(i){var l=(l=e[0]-n[0])*l+(l=e[1]-n[1])*l,f=m&&Math.sqrt(l/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+i[0])/2,(t[1]+i[1])/2],r(f*h)}x=null,u(n,t),a(p)}function f(){if(Xo.event.touches.length){for(var t=Xo.event.changedTouches,e=0,r=t.length;r>e;++e)delete v[t[e].identifier];for(var u in v)return void n()}b.on(M,null).on(_,null),w.on(A,s).on(L,l),k(),c(p)}var h,g=this,p=T.of(g,arguments),v={},m=0,y=Xo.event.changedTouches[0].identifier,M="touchmove.zoom-"+y,_="touchend.zoom-"+y,b=Xo.select(Go).on(M,i).on(_,f),w=Xo.select(g).on(A,null).on(L,e),k=O();U.call(g),e(),o(p)}function f(){var n=T.of(this,arguments);m?clearTimeout(m):(U.call(this),o(n)),m=setTimeout(function(){m=null,c(n)},50),d();var e=v||Xo.mouse(this);p||(p=t(e)),r(Math.pow(2,.002*Ra())*S.k),u(e,p),a(n)}function h(){p=null}function g(){var n=T.of(this,arguments),e=Xo.mouse(this),i=t(e),s=Math.log(S.k)/Math.LN2;o(n),r(Math.pow(2,Xo.event.shiftKey?Math.ceil(s)-1:Math.floor(s)+1)),u(e,i),a(n),c(n)}var p,v,m,x,M,_,b,w,S={x:0,y:0,k:1},k=[960,500],E=Da,A="mousedown.zoom",C="mousemove.zoom",N="mouseup.zoom",L="touchstart.zoom",T=y(n,"zoomstart","zoom","zoomend");return n.event=function(n){n.each(function(){var n=T.of(this,arguments),t=S;ks?Xo.select(this).transition().each("start.zoom",function(){S=this.__chart__||{x:0,y:0,k:1},o(n)}).tween("zoom:zoom",function(){var e=k[0],r=k[1],u=e/2,i=r/2,o=Xo.interpolateZoom([(u-S.x)/S.k,(i-S.y)/S.k,e/S.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),c=e/r[2];this.__chart__=S={x:u-r[0]*c,y:i-r[1]*c,k:c},a(n)}}).each("end.zoom",function(){c(n)}):(this.__chart__=S,o(n),a(n),c(n))})},n.translate=function(t){return arguments.length?(S={x:+t[0],y:+t[1],k:S.k},i(),n):[S.x,S.y]},n.scale=function(t){return arguments.length?(S={x:S.x,y:S.y,k:+t},i(),n):S.k},n.scaleExtent=function(t){return arguments.length?(E=null==t?Da:[+t[0],+t[1]],n):E},n.center=function(t){return arguments.length?(v=t&&[+t[0],+t[1]],n):v},n.size=function(t){return arguments.length?(k=t&&[+t[0],+t[1]],n):k},n.x=function(t){return arguments.length?(_=t,M=t.copy(),S={x:0,y:0,k:1},n):_},n.y=function(t){return arguments.length?(w=t,b=t.copy(),S={x:0,y:0,k:1},n):w},Xo.rebind(n,T,"on")};var Ra,Da=[0,1/0],Pa="onwheel"in Wo?(Ra=function(){return-Xo.event.deltaY*(Xo.event.deltaMode?120:1)},"wheel"):"onmousewheel"in Wo?(Ra=function(){return Xo.event.wheelDelta},"mousewheel"):(Ra=function(){return-Xo.event.detail},"MozMousePixelScroll");G.prototype.toString=function(){return this.rgb()+""},Xo.hsl=function(n,t,e){return 1===arguments.length?n instanceof Q?K(n.h,n.s,n.l):dt(""+n,mt,K):K(+n,+t,+e)};var Ua=Q.prototype=new G;Ua.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),K(this.h,this.s,this.l/n)},Ua.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),K(this.h,this.s,n*this.l)},Ua.rgb=function(){return nt(this.h,this.s,this.l)},Xo.hcl=function(n,t,e){return 1===arguments.length?n instanceof et?tt(n.h,n.c,n.l):n instanceof it?at(n.l,n.a,n.b):at((n=yt((n=Xo.rgb(n)).r,n.g,n.b)).l,n.a,n.b):tt(+n,+t,+e)};var ja=et.prototype=new G;ja.brighter=function(n){return tt(this.h,this.c,Math.min(100,this.l+Ha*(arguments.length?n:1)))},ja.darker=function(n){return tt(this.h,this.c,Math.max(0,this.l-Ha*(arguments.length?n:1)))},ja.rgb=function(){return rt(this.h,this.c,this.l).rgb()},Xo.lab=function(n,t,e){return 1===arguments.length?n instanceof it?ut(n.l,n.a,n.b):n instanceof et?rt(n.l,n.c,n.h):yt((n=Xo.rgb(n)).r,n.g,n.b):ut(+n,+t,+e)};var Ha=18,Fa=.95047,Oa=1,Ya=1.08883,Ia=it.prototype=new G;Ia.brighter=function(n){return ut(Math.min(100,this.l+Ha*(arguments.length?n:1)),this.a,this.b)},Ia.darker=function(n){return ut(Math.max(0,this.l-Ha*(arguments.length?n:1)),this.a,this.b)},Ia.rgb=function(){return ot(this.l,this.a,this.b)},Xo.rgb=function(n,t,e){return 1===arguments.length?n instanceof pt?gt(n.r,n.g,n.b):dt(""+n,gt,nt):gt(~~n,~~t,~~e)};var Za=pt.prototype=new G;Za.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),gt(Math.min(255,~~(t/n)),Math.min(255,~~(e/n)),Math.min(255,~~(r/n)))):gt(u,u,u)},Za.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),gt(~~(n*this.r),~~(n*this.g),~~(n*this.b))},Za.hsl=function(){return mt(this.r,this.g,this.b)},Za.toString=function(){return"#"+vt(this.r)+vt(this.g)+vt(this.b)};var Va=Xo.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});Va.forEach(function(n,t){Va.set(n,ft(t))}),Xo.functor=_t,Xo.xhr=wt(bt),Xo.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=St(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(l>=s)return o;if(u)return u=!1,i;var t=l;if(34===n.charCodeAt(t)){for(var e=t;e++<s;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}l=e+2;var r=n.charCodeAt(e+1);return 13===r?(u=!0,10===n.charCodeAt(e+2)&&++l):10===r&&(u=!0),n.substring(t+1,e).replace(/""/g,'"')}for(;s>l;){var r=n.charCodeAt(l++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(l)&&(++l,++a);else if(r!==c)continue;return n.substring(t,l-a)}return n.substring(t)}for(var r,u,i={},o={},a=[],s=n.length,l=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();(!t||(h=t(h,f++)))&&a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new l,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},Xo.csv=Xo.dsv(",","text/csv"),Xo.tsv=Xo.dsv("	","text/tab-separated-values");var Xa,$a,Ba,Wa,Ja,Ga=Go[h(Go,"requestAnimationFrame")]||function(n){setTimeout(n,17)};Xo.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};$a?$a.n=i:Xa=i,$a=i,Ba||(Wa=clearTimeout(Wa),Ba=1,Ga(Et))},Xo.timer.flush=function(){At(),Ct()},Xo.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var Ka=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Lt);Xo.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=Xo.round(n,Nt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((0>=e?e+1:e-1)/3)))),Ka[8+e/3]};var Qa=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,nc=Xo.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=Xo.round(n,Nt(n,t))).toFixed(Math.max(0,Math.min(20,Nt(n*(1+1e-15),t))))}}),tc=Xo.time={},ec=Date;zt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){rc.setUTCDate.apply(this._,arguments)},setDay:function(){rc.setUTCDay.apply(this._,arguments)},setFullYear:function(){rc.setUTCFullYear.apply(this._,arguments)},setHours:function(){rc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){rc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){rc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){rc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){rc.setUTCSeconds.apply(this._,arguments)},setTime:function(){rc.setTime.apply(this._,arguments)}};var rc=Date.prototype;tc.year=Rt(function(n){return n=tc.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),tc.years=tc.year.range,tc.years.utc=tc.year.utc.range,tc.day=Rt(function(n){var t=new ec(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),tc.days=tc.day.range,tc.days.utc=tc.day.utc.range,tc.dayOfYear=function(n){var t=tc.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=tc[n]=Rt(function(n){return(n=tc.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=tc.year(n).getDay();return Math.floor((tc.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});tc[n+"s"]=e.range,tc[n+"s"].utc=e.utc.range,tc[n+"OfYear"]=function(n){var e=tc.year(n).getDay();return Math.floor((tc.dayOfYear(n)+(e+t)%7)/7)}}),tc.week=tc.sunday,tc.weeks=tc.sunday.range,tc.weeks.utc=tc.sunday.utc.range,tc.weekOfYear=tc.sundayOfYear;var uc={"-":"",_:" ",0:"0"},ic=/^\s*\d+/,oc=/^%/;Xo.locale=function(n){return{numberFormat:Tt(n),timeFormat:Pt(n)}};var ac=Xo.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});Xo.format=ac.numberFormat,Xo.geo={},re.prototype={s:0,t:0,add:function(n){ue(n,this.t,cc),ue(cc.s,this.s,this),this.s?this.t+=cc.t:this.s=cc.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var cc=new re;Xo.geo.stream=function(n,t){n&&sc.hasOwnProperty(n.type)?sc[n.type](n,t):ie(n,t)};var sc={Feature:function(n,t){ie(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++r<u;)ie(e[r].geometry,t)}},lc={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){oe(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)oe(e[r],t,0)},Polygon:function(n,t){ae(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)ae(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,u=e.length;++r<u;)ie(e[r],t)}};Xo.geo.area=function(n){return fc=0,Xo.geo.stream(n,gc),fc};var fc,hc=new re,gc={sphere:function(){fc+=4*Sa},point:g,lineStart:g,lineEnd:g,polygonStart:function(){hc.reset(),gc.lineStart=ce},polygonEnd:function(){var n=2*hc;fc+=0>n?4*Sa+n:n,gc.lineStart=gc.lineEnd=gc.point=g}};Xo.geo.bounds=function(){function n(n,t){x.push(M=[l=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=se([t*Na,e*Na]);if(m){var u=fe(m,r),i=[u[1],-u[0],0],o=fe(i,u);pe(o),o=ve(o);var c=t-p,s=c>0?1:-1,v=o[0]*La*s,d=oa(c)>180;if(d^(v>s*p&&s*t>v)){var y=o[1]*La;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>s*p&&s*t>v)){var y=-o[1]*La;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t):h>=l?(l>t&&(l=t),t>h&&(h=t)):t>p?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t)}else n(t,e);m=r,p=t}function e(){_.point=t}function r(){M[0]=l,M[1]=h,_.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=oa(r)>180?r+(r>0?360:-360):r}else v=n,d=e;gc.point(n,e),t(n,e)}function i(){gc.lineStart()}function o(){u(v,d),gc.lineEnd(),oa(y)>Aa&&(l=-(h=180)),M[0]=l,M[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function s(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var l,f,h,g,p,v,d,m,y,x,M,_={point:n,lineStart:e,lineEnd:r,polygonStart:function(){_.point=u,_.lineStart=i,_.lineEnd=o,y=0,gc.polygonStart()},polygonEnd:function(){gc.polygonEnd(),_.point=n,_.lineStart=e,_.lineEnd=r,0>hc?(l=-(h=180),f=-(g=90)):y>Aa?g=90:-Aa>y&&(f=-90),M[0]=l,M[1]=h}};return function(n){g=h=-(l=f=1/0),x=[],Xo.geo.stream(n,_);var t=x.length;if(t){x.sort(c);for(var e,r=1,u=x[0],i=[u];t>r;++r)e=x[r],s(e[0],u)||s(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,l=e[0],h=u[1])}return x=M=null,1/0===l||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[l,f],[h,g]]}}(),Xo.geo.centroid=function(n){pc=vc=dc=mc=yc=xc=Mc=_c=bc=wc=Sc=0,Xo.geo.stream(n,kc);var t=bc,e=wc,r=Sc,u=t*t+e*e+r*r;return Ca>u&&(t=xc,e=Mc,r=_c,Aa>vc&&(t=dc,e=mc,r=yc),u=t*t+e*e+r*r,Ca>u)?[0/0,0/0]:[Math.atan2(e,t)*La,X(r/Math.sqrt(u))*La]};var pc,vc,dc,mc,yc,xc,Mc,_c,bc,wc,Sc,kc={sphere:g,point:me,lineStart:xe,lineEnd:Me,polygonStart:function(){kc.lineStart=_e},polygonEnd:function(){kc.lineStart=xe}},Ec=Ee(be,Te,ze,[-Sa,-Sa/2]),Ac=1e9;Xo.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Pe(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(Xo.geo.conicEqualArea=function(){return je(He)}).raw=He,Xo.geo.albers=function(){return Xo.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},Xo.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=Xo.geo.albers(),o=Xo.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=Xo.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var s=i.scale(),l=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[l-.455*s,f-.238*s],[l+.455*s,f+.238*s]]).stream(c).point,r=o.translate([l-.307*s,f+.201*s]).clipExtent([[l-.425*s+Aa,f+.12*s+Aa],[l-.214*s-Aa,f+.234*s-Aa]]).stream(c).point,u=a.translate([l-.205*s,f+.212*s]).clipExtent([[l-.214*s+Aa,f+.166*s+Aa],[l-.115*s-Aa,f+.234*s-Aa]]).stream(c).point,n},n.scale(1070)};var Cc,Nc,Lc,Tc,qc,zc,Rc={point:g,lineStart:g,lineEnd:g,polygonStart:function(){Nc=0,Rc.lineStart=Fe},polygonEnd:function(){Rc.lineStart=Rc.lineEnd=Rc.point=g,Cc+=oa(Nc/2)}},Dc={point:Oe,lineStart:g,lineEnd:g,polygonStart:g,polygonEnd:g},Pc={point:Ze,lineStart:Ve,lineEnd:Xe,polygonStart:function(){Pc.lineStart=$e},polygonEnd:function(){Pc.point=Ze,Pc.lineStart=Ve,Pc.lineEnd=Xe}};Xo.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),Xo.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Cc=0,Xo.geo.stream(n,u(Rc)),Cc},n.centroid=function(n){return dc=mc=yc=xc=Mc=_c=bc=wc=Sc=0,Xo.geo.stream(n,u(Pc)),Sc?[bc/Sc,wc/Sc]:_c?[xc/_c,Mc/_c]:yc?[dc/yc,mc/yc]:[0/0,0/0]},n.bounds=function(n){return qc=zc=-(Lc=Tc=1/0),Xo.geo.stream(n,u(Dc)),[[Lc,Tc],[qc,zc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||Je(n):bt,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new Ye:new Be(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(Xo.geo.albersUsa()).context(null)},Xo.geo.transform=function(n){return{stream:function(t){var e=new Ge(t);for(var r in n)e[r]=n[r];return e}}},Ge.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},Xo.geo.projection=Qe,Xo.geo.projectionMutator=nr,(Xo.geo.equirectangular=function(){return Qe(er)}).raw=er.invert=er,Xo.geo.rotation=function(n){function t(t){return t=n(t[0]*Na,t[1]*Na),t[0]*=La,t[1]*=La,t}return n=ur(n[0]%360*Na,n[1]*Na,n.length>2?n[2]*Na:0),t.invert=function(t){return t=n.invert(t[0]*Na,t[1]*Na),t[0]*=La,t[1]*=La,t},t},rr.invert=er,Xo.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=ur(-n[0]*Na,-n[1]*Na,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=La,n[1]*=La}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=cr((t=+r)*Na,u*Na),n):t},n.precision=function(r){return arguments.length?(e=cr(t*Na,(u=+r)*Na),n):u},n.angle(90)},Xo.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Na,u=n[1]*Na,i=t[1]*Na,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),s=Math.cos(u),l=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=s*l-c*f*a)*e),c*l+s*f*a)},Xo.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return Xo.range(Math.ceil(i/d)*d,u,d).map(h).concat(Xo.range(Math.ceil(s/m)*m,c,m).map(g)).concat(Xo.range(Math.ceil(r/p)*p,e,p).filter(function(n){return oa(n%d)>Aa}).map(l)).concat(Xo.range(Math.ceil(a/v)*v,o,v).filter(function(n){return oa(n%m)>Aa}).map(f))}var e,r,u,i,o,a,c,s,l,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(s).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],s=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),s>c&&(t=s,s=c,c=t),n.precision(y)):[[i,s],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,l=lr(a,o,90),f=fr(r,e,y),h=lr(s,c,90),g=fr(i,u,y),n):y},n.majorExtent([[-180,-90+Aa],[180,90-Aa]]).minorExtent([[-180,-80-Aa],[180,80+Aa]])},Xo.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=hr,u=gr;return n.distance=function(){return Xo.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},Xo.geo.interpolate=function(n,t){return pr(n[0]*Na,n[1]*Na,t[0]*Na,t[1]*Na)},Xo.geo.length=function(n){return Uc=0,Xo.geo.stream(n,jc),Uc};var Uc,jc={sphere:g,point:g,lineStart:vr,lineEnd:g,polygonStart:g,polygonEnd:g},Hc=dr(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(Xo.geo.azimuthalEqualArea=function(){return Qe(Hc)}).raw=Hc;var Fc=dr(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},bt);(Xo.geo.azimuthalEquidistant=function(){return Qe(Fc)}).raw=Fc,(Xo.geo.conicConformal=function(){return je(mr)}).raw=mr,(Xo.geo.conicEquidistant=function(){return je(yr)}).raw=yr;var Oc=dr(function(n){return 1/n},Math.atan);(Xo.geo.gnomonic=function(){return Qe(Oc)}).raw=Oc,xr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Ea]},(Xo.geo.mercator=function(){return Mr(xr)}).raw=xr;var Yc=dr(function(){return 1},Math.asin);(Xo.geo.orthographic=function(){return Qe(Yc)}).raw=Yc;var Ic=dr(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(Xo.geo.stereographic=function(){return Qe(Ic)}).raw=Ic,_r.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Ea]},(Xo.geo.transverseMercator=function(){var n=Mr(_r),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[-n[1],n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},n.rotate([0,0])}).raw=_r,Xo.geom={},Xo.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=_t(e),i=_t(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(kr),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var s=Sr(a),l=Sr(c),f=l[0]===s[0],h=l[l.length-1]===s[s.length-1],g=[];for(t=s.length-1;t>=0;--t)g.push(n[a[s[t]][2]]);for(t=+f;t<l.length-h;++t)g.push(n[a[l[t]][2]]);return g}var e=br,r=wr;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},Xo.geom.polygon=function(n){return fa(n,Zc),n};var Zc=Xo.geom.polygon.prototype=[];Zc.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],u=0;++t<e;)n=r,r=this[t],u+=n[1]*r[0]-n[0]*r[1];return.5*u},Zc.centroid=function(n){var t,e,r=-1,u=this.length,i=0,o=0,a=this[u-1];for(arguments.length||(n=-1/(6*this.area()));++r<u;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],i+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[i*n,o*n]},Zc.clip=function(n){for(var t,e,r,u,i,o,a=Cr(n),c=-1,s=this.length-Cr(this),l=this[s-1];++c<s;){for(t=n.slice(),n.length=0,u=this[c],i=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],Er(o,l,u)?(Er(i,l,u)||n.push(Ar(i,o,l,u)),n.push(o)):Er(i,l,u)&&n.push(Ar(i,o,l,u)),i=o;a&&n.push(n[0]),l=u}return n};var Vc,Xc,$c,Bc,Wc,Jc=[],Gc=[];Pr.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(jr),t.length},Br.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},Wr.prototype={insert:function(n,t){var e,r,u;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=Qr(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(u=r.R,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.R&&(Gr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Kr(this,r))):(u=r.L,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.L&&(Kr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Gr(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,u=n.U,i=n.L,o=n.R;if(e=i?o?Qr(o):i:o,u?u.L===n?u.L=e:u.R=e:this._=e,i&&o?(r=e.C,e.C=n.C,e.L=i,i.U=e,e!==o?(u=e.U,e.U=n.U,n=e.R,u.L=n,e.R=o,o.U=e):(e.U=u,u=e,n=e.R)):(r=n.C,n=e),n&&(n.U=u),!r){if(n&&n.C)return n.C=!1,void 0;do{if(n===this._)break;if(n===u.L){if(t=u.R,t.C&&(t.C=!1,u.C=!0,Gr(this,u),t=u.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,Kr(this,t),t=u.R),t.C=u.C,u.C=t.R.C=!1,Gr(this,u),n=this._;break}}else if(t=u.L,t.C&&(t.C=!1,u.C=!0,Kr(this,u),t=u.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,Gr(this,t),t=u.L),t.C=u.C,u.C=t.L.C=!1,Kr(this,u),n=this._;break}t.C=!0,n=u,u=u.U}while(!n.C);n&&(n.C=!1)}}},Xo.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],u=a[0][1],i=a[1][0],o=a[1][1];return nu(e(n),a).cells.forEach(function(e,a){var c=e.edges,s=e.site,l=t[a]=c.length?c.map(function(n){var t=n.start();return[t.x,t.y]}):s.x>=r&&s.x<=i&&s.y>=u&&s.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];l.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Aa)*Aa,y:Math.round(o(n,t)/Aa)*Aa,i:t}})}var r=br,u=wr,i=r,o=u,a=Kc;return n?t(n):(t.links=function(n){return nu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return nu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(jr),c=-1,s=a.length,l=a[s-1].edge,f=l.l===o?l.r:l.l;++c<s;)u=l,i=f,l=a[c].edge,f=l.l===o?l.r:l.l,r<i.i&&r<f.i&&eu(o,i,f)<0&&t.push([n[r],n[i.i],n[f.i]])}),t},t.x=function(n){return arguments.length?(i=_t(r=n),t):r},t.y=function(n){return arguments.length?(o=_t(u=n),t):u},t.clipExtent=function(n){return arguments.length?(a=null==n?Kc:n,t):a===Kc?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===Kc?null:a&&a[1]},t)};var Kc=[[-1e6,-1e6],[1e6,1e6]];Xo.geom.delaunay=function(n){return Xo.geom.voronoi().triangles(n)},Xo.geom.quadtree=function(n,t,e,r,u){function i(n){function i(n,t,e,r,u,i,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var c=n.x,l=n.y;if(null!=c)if(oa(c-e)+oa(l-r)<.01)s(n,t,e,r,u,i,o,a);else{var f=n.point;n.x=n.y=n.point=null,s(n,f,c,l,u,i,o,a),s(n,t,e,r,u,i,o,a)}else n.x=e,n.y=r,n.point=t}else s(n,t,e,r,u,i,o,a)}function s(n,t,e,r,u,o,a,c){var s=.5*(u+a),l=.5*(o+c),f=e>=s,h=r>=l,g=(h<<1)+f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=iu()),f?u=s:a=s,h?o=l:c=l,i(n,t,e,r,u,o,a,c)}var l,f,h,g,p,v,d,m,y,x=_t(a),M=_t(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)l=n[g],l.x<v&&(v=l.x),l.y<d&&(d=l.y),l.x>m&&(m=l.x),l.y>y&&(y=l.y),f.push(l.x),h.push(l.y);else for(g=0;p>g;++g){var _=+x(l=n[g],g),b=+M(l,g);v>_&&(v=_),d>b&&(d=b),_>m&&(m=_),b>y&&(y=b),f.push(_),h.push(b)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=iu();if(k.add=function(n){i(k,n,+x(n,++g),+M(n,g),v,d,m,y)},k.visit=function(n){ou(n,k,v,d,m,y)},g=-1,null==t){for(;++g<p;)i(k,n[g],f[g],h[g],v,d,m,y);--g}else n.forEach(k.add);return f=h=n=l=null,k}var o,a=br,c=wr;return(o=arguments.length)?(a=ru,c=uu,3===o&&(u=e,r=t,e=t=0),i(n)):(i.x=function(n){return arguments.length?(a=n,i):a},i.y=function(n){return arguments.length?(c=n,i):c},i.extent=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],u=+n[1][1]),i):null==t?null:[[t,e],[r,u]]},i.size=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=e=0,r=+n[0],u=+n[1]),i):null==t?null:[r-t,u-e]},i)},Xo.interpolateRgb=au,Xo.interpolateObject=cu,Xo.interpolateNumber=su,Xo.interpolateString=lu;var Qc=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g;Xo.interpolate=fu,Xo.interpolators=[function(n,t){var e=typeof t;return("string"===e?Va.has(t)||/^(#|rgb\(|hsl\()/.test(t)?au:lu:t instanceof G?au:"object"===e?Array.isArray(t)?hu:cu:su)(n,t)}],Xo.interpolateArray=hu;var ns=function(){return bt},ts=Xo.map({linear:ns,poly:xu,quad:function(){return du},cubic:function(){return mu},sin:function(){return Mu},exp:function(){return _u},circle:function(){return bu},elastic:wu,back:Su,bounce:function(){return ku}}),es=Xo.map({"in":bt,out:pu,"in-out":vu,"out-in":function(n){return vu(pu(n))}});Xo.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.substring(0,t):n,r=t>=0?n.substring(t+1):"in";return e=ts.get(e)||ns,r=es.get(r)||bt,gu(r(e.apply(null,$o.call(arguments,1))))},Xo.interpolateHcl=Eu,Xo.interpolateHsl=Au,Xo.interpolateLab=Cu,Xo.interpolateRound=Nu,Xo.transform=function(n){var t=Wo.createElementNS(Xo.ns.prefix.svg,"g");return(Xo.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Lu(e?e.matrix:rs)})(n)},Lu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var rs={a:1,b:0,c:0,d:1,e:0,f:0};Xo.interpolateTransform=Ru,Xo.layout={},Xo.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(Uu(n[e]));return t}},Xo.layout.chord=function(){function n(){var n,s,f,h,g,p={},v=[],d=Xo.range(i),m=[];for(e=[],r=[],n=0,h=-1;++h<i;){for(s=0,g=-1;++g<i;)s+=u[h][g];v.push(s),m.push(Xo.range(i)),n+=s}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&m.forEach(function(n,t){n.sort(function(n,e){return a(u[t][n],u[t][e])})}),n=(ka-l*i)/n,s=0,h=-1;++h<i;){for(f=s,g=-1;++g<i;){var y=d[h],x=m[y][g],M=u[y][x],_=s,b=s+=M*n;p[y+"-"+x]={index:y,subindex:x,startAngle:_,endAngle:b,value:M}}r[y]={index:y,startAngle:f,endAngle:s,value:(s-f)/n},s+=l}for(h=-1;++h<i;)for(g=h-1;++g<i;){var w=p[h+"-"+g],S=p[g+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}c&&t()}function t(){e.sort(function(n,t){return c((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,u,i,o,a,c,s={},l=0;return s.matrix=function(n){return arguments.length?(i=(u=n)&&u.length,e=r=null,s):u},s.padding=function(n){return arguments.length?(l=n,e=r=null,s):l},s.sortGroups=function(n){return arguments.length?(o=n,e=r=null,s):o},s.sortSubgroups=function(n){return arguments.length?(a=n,e=null,s):a},s.sortChords=function(n){return arguments.length?(c=n,e&&t(),s):c},s.chords=function(){return e||n(),e},s.groups=function(){return r||n(),r},s},Xo.layout.force=function(){function n(n){return function(t,e,r,u){if(t.point!==n){var i=t.cx-n.x,o=t.cy-n.y,a=u-e,c=i*i+o*o;if(c>a*a/d){if(p>c){var s=t.charge/c;n.px-=i*s,n.py-=o*s}return!0}if(t.point&&c&&p>c){var s=t.pointCharge/c;n.px-=i*s,n.py-=o*s}}return!t.charge}}function t(n){n.px=Xo.event.x,n.py=Xo.event.y,a.resume()}var e,r,u,i,o,a={},c=Xo.dispatch("start","tick","end"),s=[1,1],l=.9,f=us,h=is,g=-30,p=os,v=.1,d=.64,m=[],y=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,x,M,_=m.length,b=y.length;for(e=0;b>e;++e)a=y[e],f=a.source,h=a.target,x=h.x-f.x,M=h.y-f.y,(p=x*x+M*M)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,x*=p,M*=p,h.x-=x*(d=f.weight/(h.weight+f.weight)),h.y-=M*d,f.x+=x*(d=1-d),f.y+=M*d);if((d=r*v)&&(x=s[0]/2,M=s[1]/2,e=-1,d))for(;++e<_;)a=m[e],a.x+=(x-a.x)*d,a.y+=(M-a.y)*d;if(g)for(Zu(t=Xo.geom.quadtree(m),r,o),e=-1;++e<_;)(a=m[e]).fixed||t.visit(n(a));for(e=-1;++e<_;)a=m[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*l,a.y-=(a.py-(a.py=a.y))*l);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(m=n,a):m},a.links=function(n){return arguments.length?(y=n,a):y},a.size=function(n){return arguments.length?(s=n,a):s},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(l=+n,a):l},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.chargeDistance=function(n){return arguments.length?(p=n*n,a):Math.sqrt(p)},a.gravity=function(n){return arguments.length?(v=+n,a):v},a.theta=function(n){return arguments.length?(d=n*n,a):Math.sqrt(d)},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),Xo.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=y[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,s=o.length;++a<s;)if(!isNaN(i=o[a][n]))return i;return Math.random()*r}var t,e,r,c=m.length,l=y.length,p=s[0],v=s[1];for(t=0;c>t;++t)(r=m[t]).index=t,r.weight=0;for(t=0;l>t;++t)r=y[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;l>t;++t)u[t]=+f.call(this,y[t],t);else for(t=0;l>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;l>t;++t)i[t]=+h.call(this,y[t],t);else for(t=0;l>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=Xo.behavior.drag().origin(bt).on("dragstart.force",Fu).on("drag.force",t).on("dragend.force",Ou)),arguments.length?(this.on("mouseover.force",Yu).on("mouseout.force",Iu).call(e),void 0):e},Xo.rebind(a,c,"on")};var us=20,is=1,os=1/0;Xo.layout.hierarchy=function(){function n(t,o,a){var c=u.call(e,t,o);if(t.depth=o,a.push(t),c&&(s=c.length)){for(var s,l,f=-1,h=t.children=new Array(s),g=0,p=o+1;++f<s;)l=h[f]=n(c[f],p,a),l.parent=t,g+=l.value;r&&h.sort(r),i&&(t.value=g)}else delete t.children,i&&(t.value=+i.call(e,t,o)||0);return t}function t(n,r){var u=n.children,o=0;if(u&&(a=u.length))for(var a,c=-1,s=r+1;++c<a;)o+=t(u[c],s);else i&&(o=+i.call(e,n,r)||0);return i&&(n.value=o),o}function e(t){var e=[];return n(t,0,e),e}var r=Bu,u=Xu,i=$u;return e.sort=function(n){return arguments.length?(r=n,e):r},e.children=function(n){return arguments.length?(u=n,e):u},e.value=function(n){return arguments.length?(i=n,e):i},e.revalue=function(n){return t(n,0),n},e},Xo.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,s=-1;for(r=t.value?r/t.value:0;++s<o;)n(a=i[s],e,c=a.value*r,u),e+=c}}function t(n){var e=n.children,r=0;if(e&&(u=e.length))for(var u,i=-1;++i<u;)r=Math.max(r,t(e[i]));return 1+r}function e(e,i){var o=r.call(this,e,i);return n(o[0],0,u[0],u[1]/t(o[0])),o}var r=Xo.layout.hierarchy(),u=[1,1];return e.size=function(n){return arguments.length?(u=n,e):u},Vu(e,r)},Xo.layout.pie=function(){function n(i){var o=i.map(function(e,r){return+t.call(n,e,r)}),a=+("function"==typeof r?r.apply(this,arguments):r),c=(("function"==typeof u?u.apply(this,arguments):u)-a)/Xo.sum(o),s=Xo.range(i.length);null!=e&&s.sort(e===as?function(n,t){return o[t]-o[n]}:function(n,t){return e(i[n],i[t])});var l=[];return s.forEach(function(n){var t;l[n]={data:i[n],value:t=o[n],startAngle:a,endAngle:a+=t*c}}),l}var t=Number,e=as,r=0,u=ka;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n};var as={};Xo.layout.stack=function(){function n(a,c){var s=a.map(function(e,r){return t.call(n,e,r)}),l=s.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,l,c);s=Xo.permute(s,f),l=Xo.permute(l,f);var h,g,p,v=r.call(n,l,c),d=s.length,m=s[0].length;for(g=0;m>g;++g)for(u.call(n,s[0][g],p=v[g],l[0][g][1]),h=1;d>h;++h)u.call(n,s[h][g],p+=l[h-1][g][1],l[h][g][1]);return a}var t=bt,e=Qu,r=ni,u=Ku,i=Ju,o=Gu;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:cs.get(t)||Qu,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:ss.get(t)||ni,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var cs=Xo.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(ti),i=n.map(ei),o=Xo.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,s=[],l=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],s.push(e)):(c+=i[e],l.push(e));return l.reverse().concat(s)},reverse:function(n){return Xo.range(n.length).reverse()},"default":Qu}),ss=Xo.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,s,l=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=s=0,e=1;h>e;++e){for(t=0,u=0;l>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];l>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,s>c&&(s=c)}for(e=0;h>e;++e)g[e]-=s;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ni});Xo.layout.histogram=function(){function n(n,i){for(var o,a,c=[],s=n.map(e,this),l=r.call(this,s,i),f=u.call(this,l,s,i),i=-1,h=s.length,g=f.length-1,p=t?1:1/h;++i<g;)o=c[i]=[],o.dx=f[i+1]-(o.x=f[i]),o.y=0;if(g>0)for(i=-1;++i<h;)a=s[i],a>=l[0]&&a<=l[1]&&(o=c[Xo.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=oi,u=ui;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=_t(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return ii(n,t)}:_t(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},Xo.layout.tree=function(){function n(n,i){function o(n,t){var r=n.children,u=n._tree;if(r&&(i=r.length)){for(var i,a,s,l=r[0],f=l,h=-1;++h<i;)s=r[h],o(s,a),f=c(s,a,f),a=s;vi(n);var g=.5*(l._tree.prelim+s._tree.prelim);t?(u.prelim=t._tree.prelim+e(n,t),u.mod=u.prelim-g):u.prelim=g}else t&&(u.prelim=t._tree.prelim+e(n,t))}function a(n,t){n.x=n._tree.prelim+t;var e=n.children;if(e&&(r=e.length)){var r,u=-1;for(t+=n._tree.mod;++u<r;)a(e[u],t)}}function c(n,t,r){if(t){for(var u,i=n,o=n,a=t,c=n.parent.children[0],s=i._tree.mod,l=o._tree.mod,f=a._tree.mod,h=c._tree.mod;a=si(a),i=ci(i),a&&i;)c=ci(c),o=si(o),o._tree.ancestor=n,u=a._tree.prelim+f-i._tree.prelim-s+e(a,i),u>0&&(di(mi(a,n,r),n,u),s+=u,l+=u),f+=a._tree.mod,s+=i._tree.mod,h+=c._tree.mod,l+=o._tree.mod;a&&!si(o)&&(o._tree.thread=a,o._tree.mod+=f-l),i&&!ci(c)&&(c._tree.thread=i,c._tree.mod+=s-h,r=n)}return r}var s=t.call(this,n,i),l=s[0];pi(l,function(n,t){n._tree={ancestor:n,prelim:0,mod:0,change:0,shift:0,number:t?t._tree.number+1:0}}),o(l),a(l,-l._tree.prelim);var f=li(l,hi),h=li(l,fi),g=li(l,gi),p=f.x-e(f,h)/2,v=h.x+e(h,f)/2,d=g.depth||1;return pi(l,u?function(n){n.x*=r[0],n.y=n.depth*r[1],delete n._tree}:function(n){n.x=(n.x-p)/(v-p)*r[0],n.y=n.depth/d*r[1],delete n._tree}),s}var t=Xo.layout.hierarchy().sort(null).value(null),e=ai,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Vu(n,t)},Xo.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],s=u[1],l=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,pi(a,function(n){n.r=+l(n.value)}),pi(a,bi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/s))/2;pi(a,function(n){n.r+=f}),pi(a,bi),pi(a,function(n){n.r-=f})}return ki(a,c/2,s/2,t?1:1/Math.max(2*a.r/c,2*a.r/s)),o}var t,e=Xo.layout.hierarchy().sort(yi),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Vu(n,e)},Xo.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],s=0;pi(c,function(n){var t=n.children;t&&t.length?(n.x=Ci(t),n.y=Ai(t)):(n.x=o?s+=e(n,o):0,n.y=0,o=n)});var l=Ni(c),f=Li(c),h=l.x-e(l,f)/2,g=f.x+e(f,l)/2;return pi(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=Xo.layout.hierarchy().sort(null).value(null),e=ai,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Vu(n,t)},Xo.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++u<i;)r=(e=n[u]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,s=f(e),l=[],h=i.slice(),p=1/0,v="slice"===g?s.dx:"dice"===g?s.dy:"slice-dice"===g?1&e.depth?s.dy:s.dx:Math.min(s.dx,s.dy);for(n(h,s.dx*s.dy/e.value),l.area=0;(c=h.length)>0;)l.push(o=h[c-1]),l.area+=o.area,"squarify"!==g||(a=r(l,v))<=p?(h.pop(),p=a):(l.area-=l.pop().area,u(l,v,s,!1),v=Math.min(s.dx,s.dy),l.length=l.area=0,p=1/0);l.length&&(u(l,v,s,!0),l.length=l.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(i>e&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,s=e.y,l=t?c(n.area/t):0;if(t==e.dx){for((r||l>e.dy)&&(l=e.dy);++i<o;)u=n[i],u.x=a,u.y=s,u.dy=l,a+=u.dx=Math.min(e.x+e.dx-a,l?c(u.area/l):0);u.z=!0,u.dx+=e.x+e.dx-a,e.y+=l,e.dy-=l}else{for((r||l>e.dx)&&(l=e.dx);++i<o;)u=n[i],u.x=a,u.y=s,u.dx=l,s+=u.dy=Math.min(e.y+e.dy-s,l?c(u.area/l):0);u.z=!1,u.dy+=e.y+e.dy-s,e.x+=l,e.dx-=l}}function i(r){var u=o||a(r),i=u[0];return i.x=0,i.y=0,i.dx=s[0],i.dy=s[1],o&&a.revalue(i),n([i],i.dx*i.dy/i.value),(o?e:t)(i),h&&(o=u),u}var o,a=Xo.layout.hierarchy(),c=Math.round,s=[1,1],l=null,f=Ti,h=!1,g="squarify",p=.5*(1+Math.sqrt(5));return i.size=function(n){return arguments.length?(s=n,i):s},i.padding=function(n){function t(t){var e=n.call(i,t,t.depth);return null==e?Ti(t):qi(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return qi(t,n)}if(!arguments.length)return l;var r;return f=null==(l=n)?Ti:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,i},i.round=function(n){return arguments.length?(c=n?Math.round:Number,i):c!=Number},i.sticky=function(n){return arguments.length?(h=n,o=null,i):h},i.ratio=function(n){return arguments.length?(p=n,i):p},i.mode=function(n){return arguments.length?(g=n+"",i):g},Vu(i,a)},Xo.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=Xo.random.normal.apply(Xo,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=Xo.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},Xo.scale={};var ls={floor:bt,ceil:bt};Xo.scale.linear=function(){return Hi([0,1],[0,1],fu,!1)};var fs={s:1,g:1,p:1,r:1,e:1};Xo.scale.log=function(){return $i(Xo.scale.linear().domain([0,1]),10,!0,[1,10])};var hs=Xo.format(".0e"),gs={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};Xo.scale.pow=function(){return Bi(Xo.scale.linear(),1,[0,1])},Xo.scale.sqrt=function(){return Xo.scale.pow().exponent(.5)},Xo.scale.ordinal=function(){return Ji([],{t:"range",a:[[]]})},Xo.scale.category10=function(){return Xo.scale.ordinal().range(ps)},Xo.scale.category20=function(){return Xo.scale.ordinal().range(vs)},Xo.scale.category20b=function(){return Xo.scale.ordinal().range(ds)},Xo.scale.category20c=function(){return Xo.scale.ordinal().range(ms)};var ps=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(ht),vs=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(ht),ds=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(ht),ms=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(ht);Xo.scale.quantile=function(){return Gi([],[])},Xo.scale.quantize=function(){return Ki(0,1,[0,1])},Xo.scale.threshold=function(){return Qi([.5],[0,1])},Xo.scale.identity=function(){return no([0,1])},Xo.svg={},Xo.svg.arc=function(){function n(){var n=t.apply(this,arguments),i=e.apply(this,arguments),o=r.apply(this,arguments)+ys,a=u.apply(this,arguments)+ys,c=(o>a&&(c=o,o=a,a=c),a-o),s=Sa>c?"0":"1",l=Math.cos(o),f=Math.sin(o),h=Math.cos(a),g=Math.sin(a);return c>=xs?n?"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"M0,"+n+"A"+n+","+n+" 0 1,0 0,"+-n+"A"+n+","+n+" 0 1,0 0,"+n+"Z":"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"Z":n?"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L"+n*h+","+n*g+"A"+n+","+n+" 0 "+s+",0 "+n*l+","+n*f+"Z":"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L0,0"+"Z"}var t=to,e=eo,r=ro,u=uo;return n.innerRadius=function(e){return arguments.length?(t=_t(e),n):t},n.outerRadius=function(t){return arguments.length?(e=_t(t),n):e},n.startAngle=function(t){return arguments.length?(r=_t(t),n):r},n.endAngle=function(t){return arguments.length?(u=_t(t),n):u},n.centroid=function(){var n=(t.apply(this,arguments)+e.apply(this,arguments))/2,i=(r.apply(this,arguments)+u.apply(this,arguments))/2+ys;return[Math.cos(i)*n,Math.sin(i)*n]},n};var ys=-Ea,xs=ka-Aa;Xo.svg.line=function(){return io(bt)};var Ms=Xo.map({linear:oo,"linear-closed":ao,step:co,"step-before":so,"step-after":lo,basis:mo,"basis-open":yo,"basis-closed":xo,bundle:Mo,cardinal:go,"cardinal-open":fo,"cardinal-closed":ho,monotone:Eo});Ms.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var _s=[0,2/3,1/3,0],bs=[0,1/3,2/3,0],ws=[0,1/6,2/3,1/6];Xo.svg.line.radial=function(){var n=io(Ao);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},so.reverse=lo,lo.reverse=so,Xo.svg.area=function(){return Co(bt)},Xo.svg.area.radial=function(){var n=Co(Ao);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},Xo.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),s=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,s)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,s.r,s.p0)+r(s.r,s.p1,s.a1-s.a0)+u(s.r,s.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)+ys,l=s.call(n,u,r)+ys;return{r:i,a0:o,a1:l,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(l),i*Math.sin(l)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Sa)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=hr,o=gr,a=No,c=ro,s=uo;return n.radius=function(t){return arguments.length?(a=_t(t),n):a},n.source=function(t){return arguments.length?(i=_t(t),n):i},n.target=function(t){return arguments.length?(o=_t(t),n):o},n.startAngle=function(t){return arguments.length?(c=_t(t),n):c},n.endAngle=function(t){return arguments.length?(s=_t(t),n):s},n},Xo.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=hr,e=gr,r=Lo;return n.source=function(e){return arguments.length?(t=_t(e),n):t},n.target=function(t){return arguments.length?(e=_t(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},Xo.svg.diagonal.radial=function(){var n=Xo.svg.diagonal(),t=Lo,e=n.projection;return n.projection=function(n){return arguments.length?e(To(t=n)):t},n},Xo.svg.symbol=function(){function n(n,r){return(Ss.get(t.call(this,n,r))||Ro)(e.call(this,n,r))}var t=zo,e=qo;return n.type=function(e){return arguments.length?(t=_t(e),n):t},n.size=function(t){return arguments.length?(e=_t(t),n):e},n};var Ss=Xo.map({circle:Ro,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Cs)),e=t*Cs;return"M0,"+-t+"L"+e+",0"+" 0,"+t+" "+-e+",0"+"Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/As),e=t*As/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/As),e=t*As/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});Xo.svg.symbolTypes=Ss.keys();var ks,Es,As=Math.sqrt(3),Cs=Math.tan(30*Na),Ns=[],Ls=0;Ns.call=da.call,Ns.empty=da.empty,Ns.node=da.node,Ns.size=da.size,Xo.transition=function(n){return arguments.length?ks?n.transition():n:xa.transition()},Xo.transition.prototype=Ns,Ns.select=function(n){var t,e,r,u=this.id,i=[];n=M(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]);for(var c=this[o],s=-1,l=c.length;++s<l;)(r=c[s])&&(e=n.call(r,r.__data__,s,o))?("__data__"in r&&(e.__data__=r.__data__),jo(e,s,u,r.__transition__[u]),t.push(e)):t.push(null)}return Do(i,u)},Ns.selectAll=function(n){var t,e,r,u,i,o=this.id,a=[];n=_(n);for(var c=-1,s=this.length;++c<s;)for(var l=this[c],f=-1,h=l.length;++f<h;)if(r=l[f]){i=r.__transition__[o],e=n.call(r,r.__data__,f,c),a.push(t=[]);for(var g=-1,p=e.length;++g<p;)(u=e[g])&&jo(u,g,o,i),t.push(u)}return Do(a,o)},Ns.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=q(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return Do(u,this.id)},Ns.tween=function(n,t){var e=this.id;return arguments.length<2?this.node().__transition__[e].tween.get(n):R(this,null==t?function(t){t.__transition__[e].tween.remove(n)}:function(r){r.__transition__[e].tween.set(n,t)})},Ns.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Ru:fu,a=Xo.ns.qualify(n);return Po(this,"attr."+n,t,a.local?i:u)},Ns.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=Xo.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Ns.style=function(n,t,e){function r(){this.style.removeProperty(n)}function u(t){return null==t?r:(t+="",function(){var r,u=Go.getComputedStyle(this,null).getPropertyValue(n);return u!==t&&(r=fu(u,t),function(t){this.style.setProperty(n,r(t),e)})})}var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(t="");for(e in n)this.style(e,n[e],t);return this}e=""}return Po(this,"style."+n,t,u)},Ns.styleTween=function(n,t,e){function r(r,u){var i=t.call(this,r,u,Go.getComputedStyle(this,null).getPropertyValue(n));return i&&function(t){this.style.setProperty(n,i(t),e)}}return arguments.length<3&&(e=""),this.tween("style."+n,r)},Ns.text=function(n){return Po(this,"text",n,Uo)},Ns.remove=function(){return this.each("end.transition",function(){var n;this.__transition__.count<2&&(n=this.parentNode)&&n.removeChild(this)})},Ns.ease=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].ease:("function"!=typeof n&&(n=Xo.ease.apply(Xo,arguments)),R(this,function(e){e.__transition__[t].ease=n}))},Ns.delay=function(n){var t=this.id;return R(this,"function"==typeof n?function(e,r,u){e.__transition__[t].delay=+n.call(e,e.__data__,r,u)}:(n=+n,function(e){e.__transition__[t].delay=n}))},Ns.duration=function(n){var t=this.id;return R(this,"function"==typeof n?function(e,r,u){e.__transition__[t].duration=Math.max(1,n.call(e,e.__data__,r,u))}:(n=Math.max(1,n),function(e){e.__transition__[t].duration=n}))},Ns.each=function(n,t){var e=this.id;if(arguments.length<2){var r=Es,u=ks;ks=e,R(this,function(t,r,u){Es=t.__transition__[e],n.call(t,t.__data__,r,u)}),Es=r,ks=u}else R(this,function(r){var u=r.__transition__[e];(u.event||(u.event=Xo.dispatch("start","end"))).on(n,t)});return this},Ns.transition=function(){for(var n,t,e,r,u=this.id,i=++Ls,o=[],a=0,c=this.length;c>a;a++){o.push(n=[]);for(var t=this[a],s=0,l=t.length;l>s;s++)(e=t[s])&&(r=Object.create(e.__transition__[u]),r.delay+=r.duration,jo(e,s,i,r)),n.push(e)}return Do(o,i)},Xo.svg.axis=function(){function n(n){n.each(function(){var n,s=Xo.select(this),l=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):bt:t,p=s.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Aa),d=Xo.transition(p.exit()).style("opacity",Aa).remove(),m=Xo.transition(p).style("opacity",1),y=Ri(f),x=s.selectAll(".domain").data([0]),M=(x.enter().append("path").attr("class","domain"),Xo.transition(x));v.append("line"),v.append("text");var _=v.select("line"),b=m.select("line"),w=p.select("text").text(g),S=v.select("text"),k=m.select("text");switch(r){case"bottom":n=Ho,_.attr("y2",u),S.attr("y",Math.max(u,0)+o),b.attr("x2",0).attr("y2",u),k.attr("x",0).attr("y",Math.max(u,0)+o),w.attr("dy",".71em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+i+"V0H"+y[1]+"V"+i);break;case"top":n=Ho,_.attr("y2",-u),S.attr("y",-(Math.max(u,0)+o)),b.attr("x2",0).attr("y2",-u),k.attr("x",0).attr("y",-(Math.max(u,0)+o)),w.attr("dy","0em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+-i+"V0H"+y[1]+"V"+-i);break;case"left":n=Fo,_.attr("x2",-u),S.attr("x",-(Math.max(u,0)+o)),b.attr("x2",-u).attr("y2",0),k.attr("x",-(Math.max(u,0)+o)).attr("y",0),w.attr("dy",".32em").style("text-anchor","end"),M.attr("d","M"+-i+","+y[0]+"H0V"+y[1]+"H"+-i);break;case"right":n=Fo,_.attr("x2",u),S.attr("x",Math.max(u,0)+o),b.attr("x2",u).attr("y2",0),k.attr("x",Math.max(u,0)+o).attr("y",0),w.attr("dy",".32em").style("text-anchor","start"),M.attr("d","M"+i+","+y[0]+"H0V"+y[1]+"H"+i)}if(f.rangeBand){var E=f,A=E.rangeBand()/2;l=f=function(n){return E(n)+A}}else l.rangeBand?l=f:d.call(n,f);v.call(n,l),m.call(n,f)})}var t,e=Xo.scale.linear(),r=Ts,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in qs?t+"":Ts,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Ts="bottom",qs={top:1,right:1,bottom:1,left:1};Xo.svg.brush=function(){function n(i){i.each(function(){var i=Xo.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=i.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),i.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=i.selectAll(".resize").data(p,bt);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return zs[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,f=Xo.transition(i),h=Xo.transition(o);c&&(l=Ri(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),e(f)),s&&(l=Ri(s),h.attr("y",l[0]).attr("height",l[1]-l[0]),r(f)),t(f)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+l[+/e$/.test(n)]+","+f[+/^s/.test(n)]+")"})}function e(n){n.select(".extent").attr("x",l[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",l[1]-l[0])}function r(n){n.select(".extent").attr("y",f[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",f[1]-f[0])}function u(){function u(){32==Xo.event.keyCode&&(C||(x=null,L[0]-=l[1],L[1]-=f[1],C=2),d())}function p(){32==Xo.event.keyCode&&2==C&&(L[0]+=l[1],L[1]+=f[1],C=0,d())}function v(){var n=Xo.mouse(_),u=!1;M&&(n[0]+=M[0],n[1]+=M[1]),C||(Xo.event.altKey?(x||(x=[(l[0]+l[1])/2,(f[0]+f[1])/2]),L[0]=l[+(n[0]<x[0])],L[1]=f[+(n[1]<x[1])]):x=null),E&&m(n,c,0)&&(e(S),u=!0),A&&m(n,s,1)&&(r(S),u=!0),u&&(t(S),w({type:"brush",mode:C?"move":"resize"}))}function m(n,t,e){var r,u,a=Ri(t),c=a[0],s=a[1],p=L[e],v=e?f:l,d=v[1]-v[0];return C&&(c-=p,s-=d+p),r=(e?g:h)?Math.max(c,Math.min(s,n[e])):n[e],C?u=(r+=p)+d:(x&&(p=Math.max(c,Math.min(s,2*x[e]-r))),r>p?(u=r,r=p):u=p),v[0]!=r||v[1]!=u?(e?o=null:i=null,v[0]=r,v[1]=u,!0):void 0}function y(){v(),S.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),Xo.select("body").style("cursor",null),T.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),N(),w({type:"brushend"})}var x,M,_=this,b=Xo.select(Xo.event.target),w=a.of(_,arguments),S=Xo.select(_),k=b.datum(),E=!/^(n|s)$/.test(k)&&c,A=!/^(e|w)$/.test(k)&&s,C=b.classed("extent"),N=O(),L=Xo.mouse(_),T=Xo.select(Go).on("keydown.brush",u).on("keyup.brush",p);if(Xo.event.changedTouches?T.on("touchmove.brush",v).on("touchend.brush",y):T.on("mousemove.brush",v).on("mouseup.brush",y),S.interrupt().selectAll("*").interrupt(),C)L[0]=l[0]-L[0],L[1]=f[0]-L[1];else if(k){var q=+/w$/.test(k),z=+/^n/.test(k);M=[l[1-q]-L[0],f[1-z]-L[1]],L[0]=l[q],L[1]=f[z]}else Xo.event.altKey&&(x=L.slice());S.style("pointer-events","none").selectAll(".resize").style("display",null),Xo.select("body").style("cursor",b.style("cursor")),w({type:"brushstart"}),v()}var i,o,a=y(n,"brushstart","brush","brushend"),c=null,s=null,l=[0,0],f=[0,0],h=!0,g=!0,p=Rs[0];return n.event=function(n){n.each(function(){var n=a.of(this,arguments),t={x:l,y:f,i:i,j:o},e=this.__chart__||t;this.__chart__=t,ks?Xo.select(this).transition().each("start.brush",function(){i=e.i,o=e.j,l=e.x,f=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=hu(l,t.x),r=hu(f,t.y);return i=o=null,function(u){l=t.x=e(u),f=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){i=t.i,o=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,p=Rs[!c<<1|!s],n):c},n.y=function(t){return arguments.length?(s=t,p=Rs[!c<<1|!s],n):s},n.clamp=function(t){return arguments.length?(c&&s?(h=!!t[0],g=!!t[1]):c?h=!!t:s&&(g=!!t),n):c&&s?[h,g]:c?h:s?g:null},n.extent=function(t){var e,r,u,a,h;return arguments.length?(c&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),i=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(h=e,e=r,r=h),(e!=l[0]||r!=l[1])&&(l=[e,r])),s&&(u=t[0],a=t[1],c&&(u=u[1],a=a[1]),o=[u,a],s.invert&&(u=s(u),a=s(a)),u>a&&(h=u,u=a,a=h),(u!=f[0]||a!=f[1])&&(f=[u,a])),n):(c&&(i?(e=i[0],r=i[1]):(e=l[0],r=l[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(h=e,e=r,r=h))),s&&(o?(u=o[0],a=o[1]):(u=f[0],a=f[1],s.invert&&(u=s.invert(u),a=s.invert(a)),u>a&&(h=u,u=a,a=h))),c&&s?[[e,u],[r,a]]:c?[e,r]:s&&[u,a])},n.clear=function(){return n.empty()||(l=[0,0],f=[0,0],i=o=null),n},n.empty=function(){return!!c&&l[0]==l[1]||!!s&&f[0]==f[1]},Xo.rebind(n,a,"on")};var zs={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Rs=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Ds=tc.format=ac.timeFormat,Ps=Ds.utc,Us=Ps("%Y-%m-%dT%H:%M:%S.%LZ");Ds.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Oo:Us,Oo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Oo.toString=Us.toString,tc.second=Rt(function(n){return new ec(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),tc.seconds=tc.second.range,tc.seconds.utc=tc.second.utc.range,tc.minute=Rt(function(n){return new ec(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),tc.minutes=tc.minute.range,tc.minutes.utc=tc.minute.utc.range,tc.hour=Rt(function(n){var t=n.getTimezoneOffset()/60;return new ec(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),tc.hours=tc.hour.range,tc.hours.utc=tc.hour.utc.range,tc.month=Rt(function(n){return n=tc.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),tc.months=tc.month.range,tc.months.utc=tc.month.utc.range;var js=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Hs=[[tc.second,1],[tc.second,5],[tc.second,15],[tc.second,30],[tc.minute,1],[tc.minute,5],[tc.minute,15],[tc.minute,30],[tc.hour,1],[tc.hour,3],[tc.hour,6],[tc.hour,12],[tc.day,1],[tc.day,2],[tc.week,1],[tc.month,1],[tc.month,3],[tc.year,1]],Fs=Ds.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",be]]),Os={range:function(n,t,e){return Xo.range(Math.ceil(n/e)*e,+t,e).map(Io)},floor:bt,ceil:bt};Hs.year=tc.year,tc.scale=function(){return Yo(Xo.scale.linear(),Hs,Fs)};var Ys=Hs.map(function(n){return[n[0].utc,n[1]]}),Is=Ps.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",be]]);Ys.year=tc.year.utc,tc.scale.utc=function(){return Yo(Xo.scale.linear(),Ys,Is)},Xo.text=wt(function(n){return n.responseText}),Xo.json=function(n,t){return St(n,"application/json",Zo,t)},Xo.html=function(n,t){return St(n,"text/html",Vo,t)},Xo.xml=wt(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(Xo):"object"==typeof module&&module.exports?module.exports=Xo:this.d3=Xo}();'use strict';(function(window){window.define=undefined;}).call(this,this);'use strict';tr.exportTo('tr.ui.b',function(){const DataSeriesEnableChangeEventType='data-series-enabled-change';const THIS_DOC=document.currentScript.ownerDocument;const svgNS='http://www.w3.org/2000/svg';const ColorScheme=tr.b.ColorScheme;function getColorOfKey(key,selected){let id=ColorScheme.getColorIdForGeneralPurposeString(key);if(selected){id+=ColorScheme.properties.brightenedOffsets[0];}
+return ColorScheme.colorsAsStrings[id];}
+function getSVGTextSize(parentNode,text,opt_callback,opt_this){const textNode=document.createElementNS('http://www.w3.org/2000/svg','text');textNode.setAttributeNS(null,'x',0);textNode.setAttributeNS(null,'y',0);textNode.setAttributeNS(null,'fill','black');textNode.appendChild(document.createTextNode(text));parentNode.appendChild(textNode);if(opt_callback){opt_callback.call(opt_this||parentNode,textNode);}
+const width=textNode.getComputedTextLength();const height=textNode.getBBox().height;parentNode.removeChild(textNode);return{width,height};}
+function DataSeries(key){this.key_=key;this.target_=undefined;this.title_='';this.optional_=false;this.enabled_=true;this.color_=getColorOfKey(key,false);this.highlightedColor_=getColorOfKey(key,true);}
+DataSeries.prototype={get key(){return this.key_;},get title(){return this.title_;},set title(t){this.title_=t;},get color(){return this.color_;},set color(c){this.color_=c;},get highlightedColor(){return this.highlightedColor_;},set highlightedColor(c){this.highlightedColor_=c;},get optional(){return this.optional_;},set optional(optional){this.optional_=optional;},get enabled(){return this.enabled_;},set enabled(enabled){if(!this.optional&&!enabled){this.optional=true;}
+this.enabled_=enabled;},get target(){return this.target_;},set target(t){this.target_=t;}};const ChartBase=tr.ui.b.define('svg',undefined,svgNS);ChartBase.prototype={__proto__:HTMLUnknownElement.prototype,getDataSeries(key){if(!this.seriesByKey_.has(key)){this.seriesByKey_.set(key,new DataSeries(key));}
+return this.seriesByKey_.get(key);},decorate(){Polymer.dom(this).classList.add('chart-base');this.setAttribute('style','cursor: default; user-select: none;');this.chartTitle_=undefined;this.seriesByKey_=new Map();this.graphWidth_=undefined;this.graphHeight_=undefined;this.margin={top:0,right:0,bottom:0,left:0,};this.hideLegend_=false;this.showTitleInLegend_=false;this.titleHeight_='16pt';const template=Polymer.dom(THIS_DOC).querySelector('#chart-base-template');const svgEl=Polymer.dom(template.content).querySelector('svg');for(let i=0;i<Polymer.dom(svgEl).children.length;i++){Polymer.dom(this).appendChild(Polymer.dom(svgEl.children[i]).cloneNode(true));}
+this.addEventListener(DataSeriesEnableChangeEventType,this.onDataSeriesEnableChange_.bind(this));},get hideLegend(){return this.hideLegend_;},set hideLegend(h){this.hideLegend_=h;this.updateContents_();},get showTitleInLegend(){return this.showTitleInLegend_;},set showTitleInLegend(s){this.showTitleInLegend_=s;this.updateContents_();},isSeriesEnabled(key){return this.getDataSeries(key).enabled;},onDataSeriesEnableChange_(event){this.getDataSeries(event.key).enabled=event.enabled;this.updateContents_();},get chartTitle(){return this.chartTitle_;},set chartTitle(chartTitle){this.chartTitle_=chartTitle;this.updateContents_();},get chartAreaElement(){return Polymer.dom(this).querySelector('#chart-area');},get graphWidth(){if(this.graphWidth_===undefined)return this.defaultGraphWidth;return this.graphWidth_;},set graphWidth(width){this.graphWidth_=width;this.updateContents_();},get defaultGraphWidth(){return 0;},get graphHeight(){if(this.graphHeight_===undefined)return this.defaultGraphHeight;return this.graphHeight_;},set graphHeight(height){this.graphHeight_=height;this.updateContents_();},get titleHeight(){return this.titleHeight_;},set titleHeight(height){this.titleHeight_=height;this.updateContents_();},get defaultGraphHeight(){return 0;},get totalWidth(){return this.margin.left+this.graphWidth+this.margin.right;},get totalHeight(){return this.margin.top+this.graphHeight+this.margin.bottom;},updateMargins_(){const legendSize=this.computeLegendSize_();this.margin.right=Math.max(this.margin.right,legendSize.width);this.margin.bottom=Math.max(this.margin.bottom,legendSize.height-this.graphHeight);if(this.chartTitle_){const titleSize=getSVGTextSize(this,this.chartTitle_,textNode=>{textNode.style.fontSize='16pt';});this.margin.top=Math.max(this.margin.top,titleSize.height+15);const horizontalOverhangPx=(titleSize.width-this.graphWidth)/2;this.margin.left=Math.max(this.margin.left,horizontalOverhangPx);this.margin.right=Math.max(this.margin.right,horizontalOverhangPx);}},computeLegendSize_(){let width=0;let height=0;if(this.hideLegend)return{width,height};let series=[...this.seriesByKey_.values()];if(this.showTitleInLegend){series=series.filter(series=>series.title!=='');}
+for(const seriesEntry of series){const legendText=this.showTitleInLegend?seriesEntry.title:seriesEntry.key;const textSize=getSVGTextSize(this,legendText);width=Math.max(width,textSize.width+30);height+=textSize.height;}
+return{width,height};},updateDimensions_(){const thisSel=d3.select(this);thisSel.attr('width',this.totalWidth);thisSel.attr('height',this.totalHeight);d3.select(this.chartAreaElement).attr('transform','translate('+this.margin.left+', '+this.margin.top+')');},updateContents_(){this.updateMargins_();this.updateDimensions_();this.updateTitle_();this.updateLegend_();},updateTitle_(){const titleSel=d3.select(this.chartAreaElement).select('#title');if(!this.chartTitle_){titleSel.style('display','none');return;}
+titleSel.attr('transform','translate('+this.graphWidth*0.5+',-15)').style('display',undefined).style('text-anchor','middle').style('font-size',this.titleHeight).attr('class','title').attr('width',this.graphWidth).text(this.chartTitle_);},updateLegend_(){const chartAreaSel=d3.select(this.chartAreaElement);chartAreaSel.selectAll('.legend').remove();if(this.hideLegend)return;let series;let seriesText;if(this.showTitleInLegend){series=[...this.seriesByKey_.values()].filter(series=>series.title!=='').filter(series=>series.color!=='transparent').reverse();seriesText=series=>series.title;}else{series=[...this.seriesByKey_.values()].filter(series=>series.color!=='transparent').reverse();seriesText=series=>series.key;}
+const legendEntriesSel=chartAreaSel.selectAll('.legend').data(series);legendEntriesSel.enter().append('foreignObject').attr('class','legend').attr('x',this.graphWidth+2).attr('width',this.margin.right).attr('height',18).attr('transform',(series,i)=>'translate(0,'+i*18+')').append('xhtml:body').style('margin',0).append('tr-ui-b-chart-legend-key').property('color',series=>((this.currentHighlightedLegendKey===series.key)?series.highlightedColor:series.color)).property('width',this.margin.right).property('target',series=>series.target).property('title',series=>series.title).property('optional',series=>series.optional).property('enabled',series=>series.enabled).text(seriesText);legendEntriesSel.exit().remove();},get highlightedLegendKey(){return this.highlightedLegendKey_;},set highlightedLegendKey(highlightedLegendKey){this.highlightedLegendKey_=highlightedLegendKey;this.updateHighlight_();},get currentHighlightedLegendKey(){if(this.tempHighlightedLegendKey_){return this.tempHighlightedLegendKey_;}
+return this.highlightedLegendKey_;},pushTempHighlightedLegendKey(key){if(this.tempHighlightedLegendKey_){throw new Error('push cannot nest');}
+this.tempHighlightedLegendKey_=key;this.updateHighlight_();},popTempHighlightedLegendKey(key){if(this.tempHighlightedLegendKey_!==key){throw new Error('pop cannot happen');}
+this.tempHighlightedLegendKey_=undefined;this.updateHighlight_();},updateHighlight_(){const chartAreaSel=d3.select(this.chartAreaElement);const legendEntriesSel=chartAreaSel.selectAll('.legend');const getDataSeries=chart.getDataSeries.bind(chart);const currentHighlightedLegendKey=chart.currentHighlightedLegendKey;legendEntriesSel.each(function(key){const dataSeries=getDataSeries(key);if(key===currentHighlightedLegendKey){this.style.fill=dataSeries.highlightedColor;this.style.fontWeight='bold';}else{this.style.fill=dataSeries.color;this.style.fontWeight='';}});}};return{ChartBase,DataSeriesEnableChangeEventType,getColorOfKey,getSVGTextSize,};});'use strict';tr.exportTo('tr.ui.b',function(){const D3_Y_AXIS_WIDTH_PX=9;const D3_X_AXIS_HEIGHT_PX=23;function sanitizePower(x,defaultValue){if(!isNaN(x)&&isFinite(x)&&(x!==0))return x;return defaultValue;}
+const ChartBase2D=tr.ui.b.define('chart-base-2d',tr.ui.b.ChartBase);ChartBase2D.prototype={__proto__:tr.ui.b.ChartBase.prototype,decorate(){super.decorate();Polymer.dom(this).classList.add('chart-base-2d');this.xScale_=d3.scale.linear();this.yScale_=d3.scale.linear();this.isYLogScale_=false;this.yLogScaleBase_=10;this.yLogScaleMin_=undefined;this.autoDataRange_=new tr.b.math.Range();this.overrideDataRange_=undefined;this.hideXAxis_=false;this.hideYAxis_=false;this.data_=[];this.xAxisLabel_='';this.yAxisLabel_='';this.textHeightPx_=0;this.unit_=undefined;d3.select(this.chartAreaElement).append('g').attr('id','brushes');d3.select(this.chartAreaElement).append('g').attr('id','series');this.addEventListener('mousedown',this.onMouseDown_.bind(this));},get yLogScaleBase(){return this.yLogScaleBase_;},set yLogScaleBase(b){this.yLogScaleBase_=b;},get unit(){return this.unit_;},set unit(unit){this.unit_=unit;this.updateContents_();},get xAxisLabel(){return this.xAxisLabel_;},set xAxisLabel(label){this.xAxisLabel_=label;},get yAxisLabel(){return this.yAxisLabel_;},set yAxisLabel(label){this.yAxisLabel_=label;},get hideXAxis(){return this.hideXAxis_;},set hideXAxis(h){this.hideXAxis_=h;this.updateContents_();},get hideYAxis(){return this.hideYAxis_;},set hideYAxis(h){this.hideYAxis_=h;this.updateContents_();},get data(){return this.data_;},set data(data){if(data===undefined){throw new Error('data must be an Array');}
+this.data_=data;this.updateSeriesKeys_();this.updateDataRange_();this.updateContents_();},set isYLogScale(logScale){if(logScale){this.yScale_=d3.scale.log().base(this.yLogScaleBase);}else{this.yScale_=d3.scale.linear();}
+this.isYLogScale_=logScale;},getYScaleMin_(){return this.isYLogScale_?this.yLogScaleMin_:0;},getYScaleDomain_(minValue,maxValue){if(this.overrideDataRange_!==undefined){return[this.dataRange.min,this.dataRange.max];}
+if(this.isYLogScale_){return[this.getYScaleMin_(),maxValue];}
+return[Math.min(minValue,this.getYScaleMin_()),maxValue];},getSampleWidth_(data,index,leftSide){let leftIndex;let rightIndex;if(leftSide){leftIndex=Math.max(index-1,0);rightIndex=index;}else{leftIndex=index;rightIndex=Math.min(index+1,data.length-1);}
+const leftWidth=this.getXForDatum_(data[index],index)-
+this.getXForDatum_(data[leftIndex],leftIndex);const rightWidth=this.getXForDatum_(data[rightIndex],rightIndex)-
+this.getXForDatum_(data[index],index);return tr.b.math.Statistics.mean([leftWidth,rightWidth]);},updateSeriesKeys_(){this.data_.forEach(function(datum){Object.keys(datum).forEach(function(key){if(this.isDatumFieldSeries_(key)){this.getDataSeries(key);}},this);},this);},isDatumFieldSeries_(fieldName){return fieldName!=='x';},getXForDatum_(datum,index){return datum.x;},updateMargins_(){this.margin.left=this.hideYAxis?0:this.yAxisWidth;this.margin.bottom=this.hideXAxis?0:this.xAxisHeight;if(this.hideXAxis&&!this.hideYAxis){this.margin.bottom=10;}
+if(this.hideYAxis&&!this.hideXAxis){this.margin.left=10;}
+this.margin.top=this.hideYAxis?0:10;if(this.yAxisLabel){this.margin.top+=this.textHeightPx_;}
+if(this.xAxisLabel){this.margin.right=Math.max(this.margin.right,16+tr.ui.b.getSVGTextSize(this,this.xAxisLabel).width);}
+super.updateMargins_();},get xAxisHeight(){return D3_X_AXIS_HEIGHT_PX;},computeScaleTickWidth_(scale){if(this.data.length===0)return 0;let tickValues=scale.ticks();let tickFormat=scale.tickFormat();if(this.isYLogScale_){const enclosingPowers=this.dataRange.enclosingPowers();tickValues=[];const maxPower=sanitizePower(enclosingPowers.max,this.yLogScaleBase);for(let power=sanitizePower(enclosingPowers.min,1);power<=maxPower;power*=this.yLogScaleBase){tickValues.push(power);}
+tickFormat=v=>v.toString();}
+if(this.unit){tickFormat=v=>this.unit.format(v);}
+let maxTickWidth=0;for(const tickValue of tickValues){maxTickWidth=Math.max(maxTickWidth,tr.ui.b.getSVGTextSize(this,tickFormat(tickValue)).width);}
+return D3_Y_AXIS_WIDTH_PX+maxTickWidth;},get yAxisWidth(){return this.computeScaleTickWidth_(this.yScale_);},updateScales_(){if(this.data_.length===0)return;this.xScale_.range([0,this.graphWidth]);this.xScale_.domain(d3.extent(this.data_,this.getXForDatum_.bind(this)));this.yScale_.range([this.graphHeight,0]);this.yScale_.domain([this.dataRange.min,this.dataRange.max]);},updateBrushContents_(brushSel){brushSel.selectAll('*').remove();},updateXAxis_(xAxis){xAxis.selectAll('*').remove();xAxis[0][0].style.opacity=0;if(this.hideXAxis)return;this.drawXAxis_(xAxis);const label=xAxis.append('text').attr('class','label');this.drawXAxisTicks_(xAxis);this.drawXAxisLabel_(label);xAxis[0][0].style.opacity=1;},drawXAxis_(xAxis){xAxis.attr('transform','translate(0,'+this.graphHeight+')').call(d3.svg.axis().scale(this.xScale_).orient('bottom'));},drawXAxisLabel_(label){label.attr('x',this.graphWidth+16).attr('y',8).text(this.xAxisLabel);},drawXAxisTicks_(xAxis){let previousRight=undefined;xAxis.selectAll('.tick')[0].forEach(function(tick){const currentLeft=tick.transform.baseVal[0].matrix.e;if((previousRight===undefined)||(currentLeft>(previousRight+3))){const currentWidth=tick.getBBox().width;previousRight=currentLeft+currentWidth;}else{tick.style.opacity=0;}});},set overrideDataRange(range){this.overrideDataRange_=range;},get dataRange(){if(this.overrideDataRange_!==undefined){return this.overrideDataRange_;}
+return this.autoDataRange_;},updateDataRange_(){if(this.overrideDataRange_!==undefined)return;const dataBySeriesKey=this.getDataBySeriesKey_();this.autoDataRange_.reset();for(const[series,values]of Object.entries(dataBySeriesKey)){for(let i=0;i<values.length;i++){this.autoDataRange_.addValue(values[i][series]);}}
+this.yLogScaleMin_=undefined;if(this.autoDataRange_.min!==undefined){let minValue=this.autoDataRange_.min;if(minValue===0){minValue=1;}
+const onePowerLess=tr.b.math.lesserPower(minValue/this.yLogScaleBase);this.yLogScaleMin_=onePowerLess;}},updateYAxis_(yAxis){yAxis.selectAll('*').remove();yAxis[0][0].style.opacity=0;if(this.hideYAxis)return;this.drawYAxis_(yAxis);this.drawYAxisTicks_(yAxis);const label=yAxis.append('text').attr('class','label');this.drawYAxisLabel_(label);},drawYAxis_(yAxis){let axisModifier=d3.svg.axis().scale(this.yScale_).orient('left');let tickFormat;if(this.isYLogScale_){if(this.yLogScaleMin_===undefined)return;const tickValues=[];const enclosingPowers=this.dataRange.enclosingPowers();const maxPower=sanitizePower(enclosingPowers.max,this.yLogScaleBase);for(let power=sanitizePower(enclosingPowers.min,1);power<=maxPower;power*=this.yLogScaleBase){tickValues.push(power);}
+axisModifier=axisModifier.tickValues(tickValues);tickFormat=v=>v.toString();}
+if(this.unit){tickFormat=v=>this.unit.format(v);}
+if(tickFormat){axisModifier=axisModifier.tickFormat(tickFormat);}
+yAxis.call(axisModifier);},drawYAxisLabel_(label){const labelWidthPx=Math.ceil(tr.ui.b.getSVGTextSize(this.chartAreaElement,this.yAxisLabel).width);label.attr('x',-labelWidthPx).attr('y',-8).text(this.yAxisLabel);},drawYAxisTicks_(yAxis){let previousTop=undefined;yAxis.selectAll('.tick')[0].forEach(function(tick){const bbox=tick.getBBox();const currentTop=tick.transform.baseVal[0].matrix.f;const currentBottom=currentTop+bbox.height;if((previousTop===undefined)||(previousTop>(currentBottom+3))){previousTop=currentTop;}else{tick.style.opacity=0;}});yAxis[0][0].style.opacity=1;},updateContents_(){if(this.textHeightPx_===0){this.textHeightPx_=tr.ui.b.getSVGTextSize(this,'Ay').height;}
+this.updateScales_();super.updateContents_();const chartAreaSel=d3.select(this.chartAreaElement);this.updateXAxis_(chartAreaSel.select('.x.axis'));this.updateYAxis_(chartAreaSel.select('.y.axis'));for(const child of this.querySelectorAll('.axis path, .axis line')){child.style.fill='none';child.style.shapeRendering='crispEdges';child.style.stroke='black';}
+this.updateBrushContents_(chartAreaSel.select('#brushes'));this.updateDataContents_(chartAreaSel.select('#series'));},updateDataContents_(seriesSel){throw new Error('Not implemented');},getDataBySeriesKey_(){const dataBySeriesKey={};for(const[key,series]of this.seriesByKey_){dataBySeriesKey[key]=[];}
+this.data_.forEach(function(multiSeriesDatum,index){const x=this.getXForDatum_(multiSeriesDatum,index);d3.keys(multiSeriesDatum).forEach(function(seriesKey){if(seriesKey==='x')return;if(multiSeriesDatum[seriesKey]===undefined)return;if(!this.isDatumFieldSeries_(seriesKey))return;const singleSeriesDatum={x};singleSeriesDatum[seriesKey]=multiSeriesDatum[seriesKey];dataBySeriesKey[seriesKey].push(singleSeriesDatum);},this);},this);return dataBySeriesKey;},getChartPointAtClientPoint_(clientPoint){const rect=this.getBoundingClientRect();return{x:clientPoint.x-rect.left-this.margin.left,y:clientPoint.y-rect.top-this.margin.top};},getDataPointAtChartPoint_(chartPoint){return{x:tr.b.math.clamp(this.xScale_.invert(chartPoint.x),this.xScale_.domain()[0],this.xScale_.domain()[1]),y:tr.b.math.clamp(this.yScale_.invert(chartPoint.y),this.yScale_.domain()[0],this.yScale_.domain()[1])};},getDataPointAtClientPoint_(clientX,clientY){const chartPoint=this.getChartPointAtClientPoint_({x:clientX,y:clientY});return this.getDataPointAtChartPoint_(chartPoint);},prepareDataEvent_(mouseEvent,dataEvent){const dataPoint=this.getDataPointAtClientPoint_(mouseEvent.clientX,mouseEvent.clientY);dataEvent.x=dataPoint.x;dataEvent.y=dataPoint.y;},onMouseDown_(mouseEvent){tr.ui.b.trackMouseMovesUntilMouseUp(this.onMouseMove_.bind(this,mouseEvent.button),this.onMouseUp_.bind(this,mouseEvent.button));mouseEvent.preventDefault();mouseEvent.stopPropagation();const dataEvent=new tr.b.Event('item-mousedown');dataEvent.button=mouseEvent.button;this.prepareDataEvent_(mouseEvent,dataEvent);this.dispatchEvent(dataEvent);for(const child of this.querySelector('#brushes').children){child.setAttribute('fill','rgb(103, 199, 165)');}},onMouseMove_(button,mouseEvent){if(mouseEvent.buttons!==undefined){mouseEvent.preventDefault();mouseEvent.stopPropagation();}
+const dataEvent=new tr.b.Event('item-mousemove');dataEvent.button=button;this.prepareDataEvent_(mouseEvent,dataEvent);this.dispatchEvent(dataEvent);for(const child of this.querySelector('#brushes').children){child.setAttribute('fill','rgb(103, 199, 165)');}},onMouseUp_(button,mouseEvent){mouseEvent.preventDefault();mouseEvent.stopPropagation();const dataEvent=new tr.b.Event('item-mouseup');dataEvent.button=button;this.prepareDataEvent_(mouseEvent,dataEvent);this.dispatchEvent(dataEvent);for(const child of this.querySelector('#brushes').children){child.setAttribute('fill','rgb(213, 236, 229)');}}};return{ChartBase2D,};});'use strict';tr.exportTo('tr.ui.b',function(){const ChartBase2D=tr.ui.b.ChartBase2D;const ChartBase2DBrushX=tr.ui.b.define('chart-base-2d-brush-1d',ChartBase2D);ChartBase2DBrushX.prototype={__proto__:ChartBase2D.prototype,decorate(){super.decorate();this.brushedRange_=new tr.b.math.Range();},set brushedRange(range){this.brushedRange_.reset();this.brushedRange_.addRange(range);this.updateContents_();},get brushedRange(){return tr.b.math.Range.fromDict(this.brushedRange_.toJSON());},computeBrushRangeFromIndices(indexA,indexB){indexA=tr.b.math.clamp(indexA,0,this.data_.length-1);indexB=tr.b.math.clamp(indexB,0,this.data_.length-1);const leftIndex=Math.min(indexA,indexB);const rightIndex=Math.max(indexA,indexB);const brushRange=new tr.b.math.Range();brushRange.addValue(this.getXForDatum_(this.data_[leftIndex],leftIndex)-
+this.getSampleWidth_(this.data_,leftIndex,true));brushRange.addValue(this.getXForDatum_(this.data_[rightIndex],rightIndex)+
+this.getSampleWidth_(this.data_,rightIndex,false));return brushRange;},getDataIndex_(dataX){if(this.data.length===0)return undefined;const bisect=d3.bisector(this.getXForDatum_.bind(this)).right;return bisect(this.data_,dataX)-1;},prepareDataEvent_(mouseEvent,dataEvent){ChartBase2D.prototype.prepareDataEvent_.call(this,mouseEvent,dataEvent);dataEvent.index=this.getDataIndex_(dataEvent.x);if(dataEvent.index!==undefined){dataEvent.data=this.data_[dataEvent.index];}},updateBrushContents_(brushSel){brushSel.selectAll('*').remove();const brushes=this.brushedRange_.isEmpty?[]:[this.brushedRange_];const brushRectsSel=brushSel.selectAll('rect').data(brushes);brushRectsSel.enter().append('rect');brushRectsSel.exit().remove();this.drawBrush_(brushRectsSel);},drawBrush_(brushRectsSel){brushRectsSel.attr('x',d=>this.xScale_(d.min)).attr('y',0).attr('width',d=>this.xScale_(d.max)-this.xScale_(d.min)).attr('height',this.graphHeight).attr('fill','rgb(213, 236, 229)');}};return{ChartBase2DBrushX,};});'use strict';tr.exportTo('tr.ui.b',function(){const ColumnChart=tr.ui.b.define('column-chart',tr.ui.b.ChartBase2DBrushX);ColumnChart.prototype={__proto__:tr.ui.b.ChartBase2DBrushX.prototype,decorate(){super.decorate();this.xCushion_=1;this.isStacked_=false;this.isGrouped_=false;this.enableHoverBox=true;this.displayXInHover=false;this.enableToolTip=false;this.toolTipCallBack_=()=>{};},set toolTipCallBack(callback){this.toolTipCallBack_=callback;},get toolTipCallBack(){return this.toolTipCallBack_;},set isGrouped(grouped){this.isGrouped_=grouped;if(grouped){this.getDataSeries('group').color='transparent';}
+this.updateContents_();},get isGrouped(){return this.isGrouped_;},set isStacked(stacked){this.isStacked_=true;this.updateContents_();},get isStacked(){return this.isStacked_;},get defaultGraphHeight(){return 100;},get defaultGraphWidth(){return 10*this.data_.length;},updateScales_(){if(this.data_.length===0)return;let xDifferences=0;let currentX=undefined;let previousX=undefined;this.data_.forEach(function(datum,index){previousX=currentX;currentX=this.getXForDatum_(datum,index);if(previousX!==undefined){xDifferences+=currentX-previousX;}},this);this.xScale_.range([0,this.graphWidth]);const domain=d3.extent(this.data_,this.getXForDatum_.bind(this));if(this.data_.length>1){this.xCushion_=xDifferences/(this.data_.length-1);}
+this.xScale_.domain([domain[0],domain[1]+this.xCushion_]);this.yScale_.range([this.graphHeight,0]);this.yScale_.domain(this.getYScaleDomain_(this.dataRange.min,this.dataRange.max));},updateDataRange_(){if(!this.isStacked){super.updateDataRange_();return;}
+this.autoDataRange_.reset();this.autoDataRange_.addValue(0);for(const datum of this.data_){let sum=0;for(const[key,series]of this.seriesByKey_){if(datum[key]===undefined){continue;}else if(this.isGrouped&&key==='group'){continue;}
+sum+=datum[key];}
+this.autoDataRange_.addValue(sum);}},getStackedRectsForDatum_(datum,index){const stacks=[];let bottom=this.yScale_.range()[0];let sum=0;for(const[key,series]of this.seriesByKey_){if(datum[key]===undefined||!this.isSeriesEnabled(key)){continue;}else if(this.isGrouped&&key==='group'){continue;}
+sum+=this.dataRange.clamp(datum[key]);const heightPx=bottom-this.yScale_(sum);bottom-=heightPx;stacks.push({key,value:datum[key],color:this.getDataSeries(key).color,heightPx,topPx:bottom,underflow:sum<this.dataRange.min,overflow:sum>this.dataRange.max,});}
+return stacks;},getRectsForDatum_(datum,index){if(this.isStacked){return this.getStackedRectsForDatum_(datum,index);}
+const stacks=[];for(const[key,series]of this.seriesByKey_){if(datum[key]===undefined||!this.isSeriesEnabled(key)){continue;}
+const clampedValue=this.dataRange.clamp(datum[key]);const topPx=this.yScale_(Math.max(clampedValue,this.getYScaleMin_()));stacks.push({key,value:datum[key],topPx,heightPx:this.yScale_.range()[0]-topPx,color:this.getDataSeries(key).color,underflow:datum[key]<this.dataRange.min,overflow:datum[key]>this.dataRange.max,});}
+stacks.sort(function(a,b){return b.topPx-a.topPx;});return stacks;},drawToolTip_(rect){if(!this.enableToolTip)return;const chartAreaSel=d3.select(this.chartAreaElement);chartAreaSel.selectAll('.tooltip').remove();const labelText='View Breakdown';const labelWidth=tr.ui.b.getSVGTextSize(this.chartAreaElement,labelText).width+5;const labelHeight=this.textHeightPx_;const toolTipLeftPx=rect.leftPx+(rect.widthPx/2);const toolTipTopPx=rect.topPx;chartAreaSel.append('rect').attr('class','tooltip').attr('fill','white').attr('opacity',0.8).attr('stroke','black').attr('x',toolTipLeftPx).attr('y',toolTipTopPx).attr('width',labelWidth+5).attr('height',labelHeight+10);chartAreaSel.append('text').style('cursor','pointer').attr('class','tooltip').on('mousedown',()=>this.toolTipCallBack_(rect)).attr('fill','blue').attr('x',toolTipLeftPx+4).attr('y',toolTipTopPx+labelHeight).attr('text-decoration','underline').text(labelText);},drawHoverValueBox_(rect){const rectHoverEvent=new tr.b.Event('rect-mouseenter');rectHoverEvent.rect=rect;this.dispatchEvent(rectHoverEvent);if(!this.enableHoverBox)return;const seriesKeys=[...this.seriesByKey_.keys()];const chartAreaSel=d3.select(this.chartAreaElement);chartAreaSel.selectAll('.hover').remove();let keyWidthPx=0;let keyHeightPx=0;if(seriesKeys.length>1&&!this.isGrouped){keyWidthPx=tr.ui.b.getSVGTextSize(this.chartAreaElement,rect.key).width+5;keyHeightPx=this.textHeightPx_;}
+let xLabelWidthPx=0;let xLabelHeightPx=0;if(this.displayXInHover){xLabelWidthPx=tr.ui.b.getSVGTextSize(this.chartAreaElement,rect.datum.x).width+5;xLabelHeightPx=this.textHeightPx_;}
+let groupWidthPx=0;let groupHeightPx=0;if(this.isGrouped&&rect.datum.group!==undefined){groupWidthPx=tr.ui.b.getSVGTextSize(this.chartAreaElement,rect.datum.group).width+5;groupHeightPx=this.textHeightPx_;}
+let value=rect.value;if(this.unit)value=this.unit.format(value);const valueWidthPx=tr.ui.b.getSVGTextSize(this.chartAreaElement,value).width+5;const valueHeightPx=this.textHeightPx_;const hoverWidthPx=Math.max(keyWidthPx,valueWidthPx,xLabelWidthPx,groupWidthPx);let hoverLeftPx=rect.leftPx+(rect.widthPx/2);hoverLeftPx=Math.max(hoverLeftPx-hoverWidthPx,-this.margin.left);const hoverHeightPx=keyHeightPx+valueHeightPx+
+xLabelHeightPx+groupHeightPx+2;const topOffSetPx=this.isGrouped?36:12;let hoverTopPx=rect.topPx;hoverTopPx=Math.min(hoverTopPx,this.getBoundingClientRect().height-
+hoverHeightPx-topOffSetPx);chartAreaSel.append('rect').attr('class','hover').on('mouseleave',()=>this.clearHoverValueBox_(rect)).on('mousedown',this.drawToolTip_.bind(this,rect)).attr('fill','white').attr('stroke','black').attr('x',hoverLeftPx).attr('y',hoverTopPx).attr('width',hoverWidthPx).attr('height',hoverHeightPx);if(seriesKeys.length>1&&!this.isGrouped){chartAreaSel.append('text').attr('class','hover').on('mouseleave',()=>this.clearHoverValueBox_(rect)).on('mousedown',this.drawToolTip_.bind(this,rect)).attr('fill',rect.color).attr('x',hoverLeftPx+2).attr('y',hoverTopPx+keyHeightPx-2).text(rect.key);}
+if(this.displayXInHover){chartAreaSel.append('text').attr('class','hover').on('mouseleave',()=>this.clearHoverValueBox_(rect)).on('mousedown',this.drawToolTip_.bind(this,rect)).attr('fill',rect.color).attr('x',hoverLeftPx+2).attr('y',hoverTopPx+keyHeightPx+xLabelHeightPx-2).text(rect.datum.x);}
+if(this.isGrouped&&rect.datum.group!==undefined){chartAreaSel.append('text').attr('class','hover').on('mouseleave',()=>this.clearHoverValueBox_(rect)).on('mousedown',this.drawToolTip_.bind(this,rect)).attr('fill',rect.color).attr('x',hoverLeftPx+2).attr('y',hoverTopPx+keyHeightPx+
+xLabelHeightPx+groupHeightPx-2).text(rect.datum.group);}
+chartAreaSel.append('text').attr('class','hover').on('mouseleave',()=>this.clearHoverValueBox_(rect)).on('mousedown',this.drawToolTip_.bind(this,rect)).attr('fill',rect.color).attr('x',hoverLeftPx+2).attr('y',hoverTopPx+hoverHeightPx-2).text(value);},clearHoverValueBox_(rect){const event=window.event;if(event.relatedTarget&&Array.from(event.relatedTarget.classList).includes('hover')){return;}
+const rectHoverEvent=new tr.b.Event('rect-mouseleave');rectHoverEvent.rect=rect;this.dispatchEvent(rectHoverEvent);d3.select(this.chartAreaElement).selectAll('.hover').remove();},drawRect_(rect,sel){sel=sel.data([rect]);sel.enter().append('rect').attr('fill',rect.color).attr('x',rect.leftPx).attr('y',rect.topPx).attr('width',rect.widthPx).attr('height',rect.heightPx).on('mousedown',this.drawToolTip_.bind(this,rect)).on('mouseenter',this.drawHoverValueBox_.bind(this,rect)).on('mouseleave',this.clearHoverValueBox_.bind(this,rect));sel.exit().remove();},drawUnderflow_(rect,sel){sel=sel.data([rect]);sel.enter().append('text').text('*').attr('fill',rect.color).attr('x',rect.leftPx+(rect.widthPx/2)).attr('y',this.graphHeight).on('mousedown',this.drawToolTip_.bind(this,rect)).on('mouseenter',this.drawHoverValueBox_.bind(this,rect)).on('mouseleave',this.clearHoverValueBox_.bind(this,rect));sel.exit().remove();},drawOverflow_(rect,sel){sel=sel.data([rect]);sel.enter().append('text').text('*').attr('fill',rect.color).attr('x',rect.leftPx+(rect.widthPx/2)).attr('y',0);sel.exit().remove();},updateDataContents_(dataSel){dataSel.selectAll('*').remove();const chartAreaSel=d3.select(this.chartAreaElement);const seriesKeys=[...this.seriesByKey_.keys()];const rectsSel=dataSel.selectAll('path');this.data_.forEach(function(datum,index){const currentX=this.getXForDatum_(datum,index);let width=undefined;if(index<(this.data_.length-1)){const nextX=this.getXForDatum_(this.data_[index+1],index+1);width=nextX-currentX;}else{width=this.xCushion_;}
+for(const rect of this.getRectsForDatum_(datum,index)){rect.datum=datum;rect.index=index;rect.leftPx=this.xScale_(currentX);rect.rightPx=this.xScale_(currentX+width);rect.widthPx=rect.rightPx-rect.leftPx;this.drawRect_(rect,rectsSel);if(rect.underflow){this.drawUnderflow_(rect,rectsSel);}
+if(rect.overflow){this.drawOverflow_(rect,rectsSel);}}},this);}};return{ColumnChart,};});'use strict';tr.exportTo('tr.ui.b',function(){const LineChart=tr.ui.b.define('line-chart',tr.ui.b.ChartBase2DBrushX);LineChart.prototype={__proto__:tr.ui.b.ChartBase2DBrushX.prototype,decorate(){super.decorate();this.enableHoverBox=true;this.displayXInHover=false;},get defaultGraphWidth(){return 20*this.data_.length;},get defaultGraphHeight(){return 100;},drawHoverValueBox_(circle){tr.ui.b.ColumnChart.prototype.drawHoverValueBox_.call(this,circle);},clearHoverValueBox_(circle){tr.ui.b.ColumnChart.prototype.clearHoverValueBox_.call(this,circle);},updateDataContents_(dataSel){dataSel.selectAll('*').remove();const dataBySeriesKey=this.getDataBySeriesKey_();const seriesKeys=[...this.seriesByKey_.keys()];const pathsSel=dataSel.selectAll('path').data(seriesKeys);pathsSel.enter().append('path').style('fill','none').style('stroke-width','1.5px').style('stroke',key=>this.getDataSeries(key).color).attr('d',key=>{const line=d3.svg.line().x(d=>this.xScale_(d.x)).y(d=>this.yScale_(this.dataRange.clamp(d[key])));return line(dataBySeriesKey[key]);});pathsSel.exit().remove();if(this.enableHoverBox){for(let index=0;index<this.data_.length;++index){const datum=this.data_[index];const x=this.getXForDatum_(datum,index);for(const[key,value]of Object.entries(datum)){if(key==='x')continue;if(value===undefined)continue;const color=this.getDataSeries(key).color;const circle=document.createElementNS('http://www.w3.org/2000/svg','circle');circle.setAttribute('cx',this.xScale_(x));circle.setAttribute('cy',this.yScale_(this.dataRange.clamp(value)));circle.setAttribute('r',5);circle.style.fill=color;circle.datum=datum;circle.key=key;circle.value=datum[key];circle.leftPx=this.xScale_(x);circle.widthPx=0;circle.color=color;circle.topPx=this.yScale_(this.dataRange.clamp(value));circle.heightPx=0;circle.addEventListener('mouseenter',()=>this.drawHoverValueBox_(circle));circle.addEventListener('mouseleave',()=>this.clearHoverValueBox_(circle));dataSel[0][0].appendChild(circle);}}}}};return{LineChart,};});'use strict';Polymer({is:'tr-ui-e-s-input-latency-side-panel',behaviors:[tr.ui.behaviors.SidePanel],ready(){this.rangeOfInterest_=new tr.b.math.Range();this.frametimeType_=tr.model.helpers.IMPL_FRAMETIME_TYPE;this.latencyChart_=undefined;this.frametimeChart_=undefined;this.selectedProcessId_=undefined;this.mouseDownIndex_=undefined;this.curMouseIndex_=undefined;},get model(){return this.model_;},set model(model){this.model_=model;if(this.model_){this.modelHelper_=this.model_.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);}else{this.modelHelper_=undefined;}
+this.updateToolbar_();this.updateContents_();},get frametimeType(){return this.frametimeType_;},set frametimeType(type){if(this.frametimeType_===type)return;this.frametimeType_=type;this.updateContents_();},get selectedProcessId(){return this.selectedProcessId_;},set selectedProcessId(process){if(this.selectedProcessId_===process)return;this.selectedProcessId_=process;this.updateContents_();},set selection(selection){if(this.latencyChart_===undefined)return;this.latencyChart_.brushedRange=selection.bounds;},setBrushedIndices(mouseDownIndex,curIndex){this.mouseDownIndex_=mouseDownIndex;this.curMouseIndex_=curIndex;this.updateBrushedRange_();},updateBrushedRange_(){if(this.latencyChart_===undefined)return;let r=new tr.b.math.Range();if(this.mouseDownIndex_===undefined){this.latencyChart_.brushedRange=r;return;}
+r=this.latencyChart_.computeBrushRangeFromIndices(this.mouseDownIndex_,this.curMouseIndex_);this.latencyChart_.brushedRange=r;let latencySlices=[];for(const thread of this.model_.getAllThreads()){for(const event of thread.getDescendantEvents()){if(event.title.indexOf('InputLatency:')===0){latencySlices.push(event);}}}
+latencySlices=tr.model.helpers.getSlicesIntersectingRange(r,latencySlices);const event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(latencySlices);this.latencyChart_.dispatchEvent(event);},registerMouseEventForLatencyChart_(){this.latencyChart_.addEventListener('item-mousedown',function(e){this.mouseDownIndex_=e.index;this.curMouseIndex_=e.index;this.updateBrushedRange_();}.bind(this));this.latencyChart_.addEventListener('item-mousemove',function(e){if(e.button===undefined)return;this.curMouseIndex_=e.index;this.updateBrushedRange_();}.bind(this));this.latencyChart_.addEventListener('item-mouseup',function(e){this.curMouseIndex=e.index;this.updateBrushedRange_();}.bind(this));},updateToolbar_(){const browserProcess=this.modelHelper_.browserProcess;const labels=[];if(browserProcess!==undefined){const labelStr='Browser: '+browserProcess.pid;labels.push({label:labelStr,value:browserProcess.pid});}
+for(const rendererHelper of
+Object.values(this.modelHelper_.rendererHelpers)){const rendererProcess=rendererHelper.process;const labelStr='Renderer: '+rendererProcess.userFriendlyName;labels.push({label:labelStr,value:rendererProcess.userFriendlyName});}
+if(labels.length===0)return;this.selectedProcessId_=labels[0].value;const toolbarEl=this.$.toolbar;Polymer.dom(toolbarEl).appendChild(tr.ui.b.createSelector(this,'frametimeType','inputLatencySidePanel.frametimeType',this.frametimeType_,[{label:'Main Thread Frame Times',value:tr.model.helpers.MAIN_FRAMETIME_TYPE},{label:'Impl Thread Frame Times',value:tr.model.helpers.IMPL_FRAMETIME_TYPE}]));Polymer.dom(toolbarEl).appendChild(tr.ui.b.createSelector(this,'selectedProcessId','inputLatencySidePanel.selectedProcessId',this.selectedProcessId_,labels));},get currentRangeOfInterest(){if(this.rangeOfInterest_.isEmpty){return this.model_.bounds;}
+return this.rangeOfInterest_;},createLatencyLineChart(data,title,parentNode){const chart=new tr.ui.b.LineChart();Polymer.dom(parentNode).appendChild(chart);let width=600;if(document.body.clientWidth!==undefined){width=document.body.clientWidth*0.5;}
+chart.graphWidth=width;chart.chartTitle=title;chart.data=data;return chart;},updateContents_(){const resultArea=this.$.result_area;this.latencyChart_=undefined;this.frametimeChart_=undefined;Polymer.dom(resultArea).textContent='';if(this.modelHelper_===undefined)return;const rangeOfInterest=this.currentRangeOfInterest;let chromeProcess;if(this.modelHelper_.rendererHelpers[this.selectedProcessId_]){chromeProcess=this.modelHelper_.rendererHelpers[this.selectedProcessId_];}else{chromeProcess=this.modelHelper_.browserHelper;}
+const frameEvents=chromeProcess.getFrameEventsInRange(this.frametimeType,rangeOfInterest);const frametimeData=tr.model.helpers.getFrametimeDataFromEvents(frameEvents);const averageFrametime=tr.b.math.Statistics.mean(frametimeData,d=>d.frametime);const latencyEvents=this.modelHelper_.browserHelper.getLatencyEventsInRange(rangeOfInterest);const latencyData=[];latencyEvents.forEach(function(event){if(event.inputLatency===undefined)return;latencyData.push({x:event.start,latency:event.inputLatency/1000});});const averageLatency=tr.b.math.Statistics.mean(latencyData,function(d){return d.latency;});const latencySummaryText=document.createElement('div');Polymer.dom(latencySummaryText).appendChild(tr.ui.b.createSpan({textContent:'Average Latency '+averageLatency+' ms',bold:true}));Polymer.dom(resultArea).appendChild(latencySummaryText);const frametimeSummaryText=document.createElement('div');Polymer.dom(frametimeSummaryText).appendChild(tr.ui.b.createSpan({textContent:'Average Frame Time '+averageFrametime+' ms',bold:true}));Polymer.dom(resultArea).appendChild(frametimeSummaryText);if(latencyData.length!==0){this.latencyChart_=this.createLatencyLineChart(latencyData,'Latency Over Time',resultArea);this.registerMouseEventForLatencyChart_();}
+if(frametimeData.length!==0){this.frametimeChart_=this.createLatencyLineChart(frametimeData,'Frame Times',resultArea);}},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(rangeOfInterest){this.rangeOfInterest_=rangeOfInterest;this.updateContents_();},supportsModel(m){if(m===undefined){return{supported:false,reason:'Unknown tracing model'};}
 if(!tr.model.helpers.ChromeModelHelper.supportsModel(m)){return{supported:false,reason:'No Chrome browser or renderer process found'};}
-var modelHelper=m.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(modelHelper.browserHelper&&modelHelper.browserHelper.hasLatencyEvents){return{supported:true};}
-return{supported:false,reason:'No InputLatency events trace. Consider enabling '+'benchmark" and "input" category when recording the trace'};},get textLabel(){return'Input Latency';}});'use strict';tr.exportTo('tr.ui.b',function(){var ChartBase=tr.ui.b.ChartBase;var getColorOfKey=tr.ui.b.getColorOfKey;var MIN_RADIUS=100;var PieChart=tr.ui.b.define('pie-chart',ChartBase);PieChart.prototype={__proto__:ChartBase.prototype,decorate:function(){ChartBase.prototype.decorate.call(this);this.classList.add('pie-chart');this.data_=undefined;this.seriesKeys_=undefined;var chartAreaSel=d3.select(this.chartAreaElement);var pieGroupSel=chartAreaSel.append('g').attr('class','pie-group');this.pieGroup_=pieGroupSel.node();this.pathsGroup_=pieGroupSel.append('g').attr('class','paths').node();this.labelsGroup_=pieGroupSel.append('g').attr('class','labels').node();this.linesGroup_=pieGroupSel.append('g').attr('class','lines').node();},get data(){return this.data_;},set data(data){if(data!==undefined){var seriesKeys=[];var seenSeriesKeys={};data.forEach(function(d){var k=d.label;if(seenSeriesKeys[k])
-throw new Error('Label '+k+' has been used already');seriesKeys.push(k);seenSeriesKeys[k]=true;},this);this.seriesKeys_=seriesKeys;}else{this.seriesKeys_=undefined;}
-this.data_=data;this.updateContents_();},get margin(){var margin={top:0,right:0,bottom:0,left:0};if(this.chartTitle_)
-margin.top+=40;return margin;},getMinSize:function(){this.updateContents_();var labelSel=d3.select(this.labelsGroup_).selectAll('.label');var maxLabelWidth=-Number.MAX_VALUE;var leftTextHeightSum=0;var rightTextHeightSum=0;labelSel.each(function(l){var r=this.getBoundingClientRect();maxLabelWidth=Math.max(maxLabelWidth,r.width+32);if(this.style.textAnchor=='end'){leftTextHeightSum+=r.height;}else{rightTextHeightSum+=r.height;}});var titleWidth=this.querySelector('#title').getBoundingClientRect().width;var margin=this.margin;var marginWidth=margin.left+margin.right;var marginHeight=margin.top+margin.bottom;return{width:Math.max(2*MIN_RADIUS+2*maxLabelWidth,titleWidth*1.1)+marginWidth,height:marginHeight+Math.max(2*MIN_RADIUS,leftTextHeightSum,rightTextHeightSum)*1.25};},getLegendKeys_:function(){return undefined;},updateScales_:function(width,height){if(this.data_===undefined)
-return;},updateContents_:function(){ChartBase.prototype.updateContents_.call(this);if(!this.data_)
-return;var width=this.chartAreaSize.width;var height=this.chartAreaSize.height;var radius=Math.max(MIN_RADIUS,Math.min(width,height*0.95)/2);d3.select(this.pieGroup_).attr('transform','translate('+width/2+','+height/2+')');var pieLayout=d3.layout.pie().value(function(d){return d.value;}).sort(null);var piePathsSel=d3.select(this.pathsGroup_).datum(this.data_).selectAll('path').data(pieLayout);function midAngle(d){return d.startAngle+(d.endAngle-d.startAngle)/2;}
-var pathsArc=d3.svg.arc().innerRadius(0).outerRadius(radius-30);var valueLabelArc=d3.svg.arc().innerRadius(radius-100).outerRadius(radius-30);var lineBeginArc=d3.svg.arc().innerRadius(radius-50).outerRadius(radius-50);var lineEndArc=d3.svg.arc().innerRadius(radius).outerRadius(radius);piePathsSel.enter().append('path').attr('class','arc').attr('fill',function(d,i){var origData=this.data_[i];var highlighted=(origData.label===this.currentHighlightedLegendKey);return getColorOfKey(origData.label,highlighted);}.bind(this)).attr('d',pathsArc).on('click',function(d,i){var origData=this.data_[i];var event=new tr.b.Event('item-click');event.data=origData;event.index=i;this.dispatchEvent(event);d3.event.stopPropagation();}.bind(this)).on('mouseenter',function(d,i){var origData=this.data_[i];this.pushTempHighlightedLegendKey(origData.label);}.bind(this)).on('mouseleave',function(d,i){var origData=this.data_[i];this.popTempHighlightedLegendKey(origData.label);}.bind(this));piePathsSel.enter().append('text').attr('class','arc-text').attr('transform',function(d){return'translate('+valueLabelArc.centroid(d)+')';}).attr('dy','.35em').style('text-anchor','middle').text(function(d,i){var origData=this.data_[i];if(origData.valueText===undefined)
-return'';if(d.endAngle-d.startAngle<0.4)
-return'';return origData.valueText;}.bind(this));piePathsSel.exit().remove();var labelSel=d3.select(this.labelsGroup_).selectAll('.label').data(pieLayout(this.data_));labelSel.enter().append('text').attr('class','label').attr('dy','.35em');labelSel.text(function(d){if(d.data.label.length>40)
-return d.data.label.substr(0,40)+'...';return d.data.label;});labelSel.attr('transform',function(d){var pos=lineEndArc.centroid(d);pos[0]=radius*(midAngle(d)<Math.PI?1:-1);return'translate('+pos+')';});labelSel.style('text-anchor',function(d){return midAngle(d)<Math.PI?'start':'end';});var lineSel=d3.select(this.linesGroup_).selectAll('.line').data(pieLayout(this.data_));lineSel.enter().append('polyline').attr('class','line').attr('dy','.35em');lineSel.attr('points',function(d){var pos=lineEndArc.centroid(d);pos[0]=radius*0.95*(midAngle(d)<Math.PI?1:-1);return[lineBeginArc.centroid(d),lineEndArc.centroid(d),pos];});},updateHighlight_:function(){ChartBase.prototype.updateHighlight_.call(this);var pathsGroupSel=d3.select(this.pathsGroup_);var that=this;pathsGroupSel.selectAll('.arc').each(function(d,i){var origData=that.data_[i];var highlighted=origData.label==that.currentHighlightedLegendKey;var color=getColorOfKey(origData.label,highlighted);this.style.fill=color;});}};return{PieChart:PieChart};});'use strict';(function(){var GROUP_BY_PROCESS_NAME='process';var GROUP_BY_THREAD_NAME='thread';var WALL_TIME_GROUPING_UNIT='Wall time';var CPU_TIME_GROUPING_UNIT='CPU time';function ResultsForGroup(model,name){this.model=model;this.name=name;this.topLevelSlices=[];this.allSlices=[];}
-ResultsForGroup.prototype={get wallTime(){var wallSum=tr.b.Statistics.sum(this.topLevelSlices,function(x){return x.duration;});return wallSum;},get cpuTime(){var cpuDuration=0;for(var i=0;i<this.topLevelSlices.length;i++){var x=this.topLevelSlices[i];if(x.cpuDuration===undefined){if(x.duration===undefined)
-continue;return 0;}
-cpuDuration+=x.cpuDuration;}
-return cpuDuration;},appendGroupContents:function(group){if(group.model!=this.model)
-throw new Error('Models must be the same');group.allSlices.forEach(function(slice){this.allSlices.push(slice);},this);group.topLevelSlices.forEach(function(slice){this.topLevelSlices.push(slice);},this);},appendThreadSlices:function(rangeOfInterest,thread){var tmp=this.getSlicesIntersectingRange(rangeOfInterest,thread.sliceGroup.slices);tmp.forEach(function(slice){this.allSlices.push(slice);},this);tmp=this.getSlicesIntersectingRange(rangeOfInterest,thread.sliceGroup.topLevelSlices);tmp.forEach(function(slice){this.topLevelSlices.push(slice);},this);},getSlicesIntersectingRange:function(rangeOfInterest,slices){var slicesInFilterRange=[];for(var i=0;i<slices.length;i++){var slice=slices[i];if(rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end))
-slicesInFilterRange.push(slice);}
-return slicesInFilterRange;}};Polymer('tr-ui-e-s-time-summary-side-panel',{ready:function(){this.rangeOfInterest_=new tr.b.Range();this.selection_=undefined;this.groupBy_=GROUP_BY_PROCESS_NAME;this.groupingUnit_=CPU_TIME_GROUPING_UNIT;this.showCpuIdleTime_=true;this.chart_=undefined;var toolbarEl=this.$.toolbar;this.groupBySelector_=tr.ui.b.createSelector(this,'groupBy','timeSummarySidePanel.groupBy',this.groupBy_,[{label:'Group by process',value:GROUP_BY_PROCESS_NAME},{label:'Group by thread',value:GROUP_BY_THREAD_NAME}]);toolbarEl.appendChild(this.groupBySelector_);this.groupingUnitSelector_=tr.ui.b.createSelector(this,'groupingUnit','timeSummarySidePanel.groupingUnit',this.groupingUnit_,[{label:'Wall time',value:WALL_TIME_GROUPING_UNIT},{label:'CPU time',value:CPU_TIME_GROUPING_UNIT}]);toolbarEl.appendChild(this.groupingUnitSelector_);this.showCpuIdleTimeCheckbox_=tr.ui.b.createCheckBox(this,'showCpuIdleTime','timeSummarySidePanel.showCpuIdleTime',this.showCpuIdleTime_,'Show CPU idle time');toolbarEl.appendChild(this.showCpuIdleTimeCheckbox_);this.updateShowCpuIdleTimeCheckboxVisibility_();},trimPieChartData:function(groups,otherGroup,getValue,opt_extraValue){groups=groups.filter(function(d){return getValue(d)!=0;});var sum=tr.b.Statistics.sum(groups,getValue);if(opt_extraValue!==undefined)
-sum+=opt_extraValue;function compareByValue(a,b){return getValue(a)-getValue(b);}
-groups.sort(compareByValue);var thresshold=0.1*sum;while(groups.length>1){var group=groups[0];if(getValue(group)>=thresshold)
-break;var v=getValue(group);if(v+getValue(otherGroup)>thresshold)
-break;groups.splice(0,1);otherGroup.appendGroupContents(group);}
-if(getValue(otherGroup)>0)
-groups.push(otherGroup);groups.sort(compareByValue);return groups;},generateResultsForGroup:function(model,name){return new ResultsForGroup(model,name);},createPieChartFromResultGroups:function(groups,title,getValue,opt_extraData){var chart=new tr.ui.b.PieChart();function pushDataForGroup(data,resultsForGroup,value){data.push({label:resultsForGroup.name,value:value,valueText:tr.v.Unit.byName.timeDurationInMs.format(value),resultsForGroup:resultsForGroup});}
-chart.addEventListener('item-click',function(clickEvent){var resultsForGroup=clickEvent.data.resultsForGroup;if(resultsForGroup===undefined)
-return;var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(resultsForGroup.allSlices);event.selection.timeSummaryGroupName=resultsForGroup.name;chart.dispatchEvent(event);});var data=[];groups.forEach(function(resultsForGroup){var value=getValue(resultsForGroup);if(value===0)
-return;pushDataForGroup(data,resultsForGroup,value);});if(opt_extraData)
-data.push.apply(data,opt_extraData);chart.chartTitle=title;chart.data=data;return chart;},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();},get groupBy(){return groupBy_;},set groupBy(groupBy){this.groupBy_=groupBy;if(this.groupBySelector_)
-this.groupBySelector_.selectedValue=groupBy;this.updateContents_();},get groupingUnit(){return groupingUnit_;},set groupingUnit(groupingUnit){this.groupingUnit_=groupingUnit;if(this.groupingUnitSelector_)
-this.groupingUnitSelector_.selectedValue=groupingUnit;this.updateShowCpuIdleTimeCheckboxVisibility_();this.updateContents_();},get showCpuIdleTime(){return this.showCpuIdleTime_;},set showCpuIdleTime(showCpuIdleTime){this.showCpuIdleTime_=showCpuIdleTime;if(this.showCpuIdleTimeCheckbox_)
-this.showCpuIdleTimeCheckbox_.checked=showCpuIdleTime;this.updateContents_();},updateShowCpuIdleTimeCheckboxVisibility_:function(){if(!this.showCpuIdleTimeCheckbox_)
-return;var visible=this.groupingUnit_==CPU_TIME_GROUPING_UNIT;if(visible)
-this.showCpuIdleTimeCheckbox_.style.display='';else
-this.showCpuIdleTimeCheckbox_.style.display='none';},getGroupNameForThread_:function(thread){if(this.groupBy_==GROUP_BY_THREAD_NAME)
-return thread.name?thread.name:thread.userFriendlyName;if(this.groupBy_==GROUP_BY_PROCESS_NAME)
-return thread.parent.userFriendlyName;},updateContents_:function(){var resultArea=this.$.result_area;this.chart_=undefined;resultArea.textContent='';if(this.model_===undefined)
-return;var rangeOfInterest;if(this.rangeOfInterest_.isEmpty)
-rangeOfInterest=this.model_.bounds;else
-rangeOfInterest=this.rangeOfInterest_;var allGroup=this.generateResultsForGroup(this.model_,'all');var resultsByGroupName={};this.model_.getAllThreads().forEach(function(thread){var groupName=this.getGroupNameForThread_(thread);if(resultsByGroupName[groupName]===undefined){resultsByGroupName[groupName]=this.generateResultsForGroup(this.model_,groupName);}
-resultsByGroupName[groupName].appendThreadSlices(rangeOfInterest,thread);allGroup.appendThreadSlices(rangeOfInterest,thread);},this);var getValueFromGroup=function(group){if(this.groupingUnit_==WALL_TIME_GROUPING_UNIT)
-return group.wallTime;return group.cpuTime;}.bind(this);var summaryText=document.createElement('div');summaryText.appendChild(tr.ui.b.createSpan({textContent:'Total '+this.groupingUnit_+': ',bold:true}));summaryText.appendChild(tr.v.ui.createScalarSpan(getValueFromGroup(allGroup),{unit:tr.v.Unit.byName.timeDurationInMs,ownerDocument:this.ownerDocument}));resultArea.appendChild(summaryText);var extraValue=0;var extraData=[];if(this.showCpuIdleTime_&&this.groupingUnit_===CPU_TIME_GROUPING_UNIT&&this.model.kernel.bestGuessAtCpuCount!==undefined){var maxCpuTime=rangeOfInterest.range*this.model.kernel.bestGuessAtCpuCount;var idleTime=Math.max(0,maxCpuTime-allGroup.cpuTime);extraData.push({label:'CPU Idle',value:idleTime,valueText:tr.v.Unit.byName.timeDurationInMs.format(idleTime)});extraValue+=idleTime;}
-var otherGroup=this.generateResultsForGroup(this.model_,'Other');var groups=this.trimPieChartData(tr.b.dictionaryValues(resultsByGroupName),otherGroup,getValueFromGroup,extraValue);if(groups.length==0){resultArea.appendChild(tr.ui.b.createSpan({textContent:'No data'}));return undefined;}
-this.chart_=this.createPieChartFromResultGroups(groups,this.groupingUnit_+' breakdown by '+this.groupBy_,getValueFromGroup,extraData);resultArea.appendChild(this.chart_);this.chart_.addEventListener('click',function(){var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.c.EventSet([]);this.dispatchEvent(event);});this.chart_.setSize(this.chart_.getMinSize());},get selection(){return selection_;},set selection(selection){this.selection_=selection;if(this.chart_===undefined)
-return;if(selection.timeSummaryGroupName)
-this.chart_.highlightedLegendKey=selection.timeSummaryGroupName;else
-this.chart_.highlightedLegendKey=undefined;},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(rangeOfInterest){this.rangeOfInterest_=rangeOfInterest;this.updateContents_();},supportsModel:function(model){return{supported:false};},get textLabel(){return'Time Summary';}});}());'use strict';tr.exportTo('tr.e.system_stats',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function SystemStatsSnapshot(objectInstance,ts,args){ObjectSnapshot.apply(this,arguments);this.objectInstance=objectInstance;this.ts=ts;this.args=args;this.stats=args;}
-SystemStatsSnapshot.prototype={__proto__:ObjectSnapshot.prototype,initialize:function(){if(this.args.length==0)
-throw new Error('No system stats snapshot data.');this.stats_=this.args;},getStats:function(){return this.stats_;},setStats:function(stats){this.stats_=stats;}};ObjectSnapshot.register(SystemStatsSnapshot,{typeName:'base::TraceEventSystemStatsMonitor::SystemStats'});return{SystemStatsSnapshot:SystemStatsSnapshot};});'use strict';tr.exportTo('tr.ui.e.system_stats',function(){var SystemStatsSnapshotView=tr.ui.b.define('tr-ui-e-system-stats-snapshot-view',tr.ui.analysis.ObjectSnapshotView);SystemStatsSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-system-stats-snapshot-view');},updateContents:function(){var snapshot=this.objectSnapshot_;if(!snapshot||!snapshot.getStats()){this.textContent='No system stats snapshot found.';return;}
-this.textContent='';var stats=snapshot.getStats();this.appendChild(this.buildList_(stats));},isFloat:function(n){return typeof n==='number'&&n%1!==0;},buildList_:function(stats){var statList=document.createElement('ul');for(var statName in stats){var statText=document.createElement('li');statText.textContent=''+statName+': ';statList.appendChild(statText);if(stats[statName]instanceof Object){statList.appendChild(this.buildList_(stats[statName]));}else{if(this.isFloat(stats[statName]))
-statText.textContent+=stats[statName].toFixed(2);else
-statText.textContent+=stats[statName];}}
-return statList;}};tr.ui.analysis.ObjectSnapshotView.register(SystemStatsSnapshotView,{typeName:'base::TraceEventSystemStatsMonitor::SystemStats'});return{SystemStatsSnapshotView:SystemStatsSnapshotView};});'use strict';tr.exportTo('tr.ui.b',function(){var constants={HEADING_WIDTH:250};return{constants:constants};});'use strict';Polymer('tr-ui-heading',{DOWN_ARROW:String.fromCharCode(0x25BE),RIGHT_ARROW:String.fromCharCode(0x25B8),ready:function(viewport){this.style.width=(tr.ui.b.constants.HEADING_WIDTH-6)+'px';this.heading_='';this.expanded_=true;this.arrowVisible_=false;this.selectionGenerator_=undefined;this.updateContents_();},get heading(){return this.heading_;},set heading(text){if(this.heading_===text)
-return;this.heading_=text;this.updateContents_();},set arrowVisible(val){if(this.arrowVisible_===val)
-return;this.arrowVisible_=!!val;this.updateContents_();},set tooltip(text){this.$.heading.title=text;},set selectionGenerator(generator){if(this.selectionGenerator_===generator)
-return;this.selectionGenerator_=generator;this.updateContents_();},get expanded(){return this.expanded_;},set expanded(expanded){if(this.expanded_===expanded)
-return;this.expanded_=!!expanded;this.updateContents_();},onHeadingDivClicked_:function(){this.dispatchEvent(new tr.b.Event('heading-clicked',{'bubbles':true}));},updateContents_:function(){if(this.arrowVisible_){this.$.arrow.style.display='';}else{this.$.arrow.style.display='none';this.$.heading.style.display=this.expanded_?'':'none';}
-if(this.arrowVisible_){this.$.arrow.textContent=this.expanded_?this.DOWN_ARROW:this.RIGHT_ARROW;}
-this.$.link.style.display='none';this.$.heading_content.style.display='none';if(this.selectionGenerator_){this.$.link.style.display='inline-block';this.$.link.selection=this.selectionGenerator_;this.$.link.textContent=this.heading_;}else{this.$.heading_content.style.display='inline-block';this.$.heading_content.textContent=this.heading_;}}});'use strict';tr.exportTo('tr.ui.tracks',function(){var Track=tr.ui.b.define('track',tr.ui.b.ContainerThatDecoratesItsChildren);Track.prototype={__proto__:tr.ui.b.ContainerThatDecoratesItsChildren.prototype,decorate:function(viewport){tr.ui.b.ContainerThatDecoratesItsChildren.prototype.decorate.call(this);if(viewport===undefined)
-throw new Error('viewport is required when creating a Track.');this.viewport_=viewport;this.classList.add('track');},get viewport(){return this.viewport_;},get drawingContainer(){var cur=this;while(cur){if(cur instanceof tr.ui.tracks.DrawingContainer)
-return cur;cur=cur.parentElement;}
-return undefined;},get eventContainer(){},invalidateDrawingContainer:function(){var dc=this.drawingContainer;if(dc)
-dc.invalidate();},context:function(){if(!this.parentNode)
-return undefined;if(!this.parentNode.context)
-throw new Error('Parent container does not support context() method.');return this.parentNode.context();},decorateChild_:function(childTrack){},undecorateChild_:function(childTrack){if(childTrack.detach)
-childTrack.detach();},updateContents_:function(){},drawTrack:function(type){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var canvasBounds=ctx.canvas.getBoundingClientRect();ctx.save();ctx.translate(0,pixelRatio*(bounds.top-canvasBounds.top));var dt=this.viewport.currentDisplayTransform;var viewLWorld=dt.xViewToWorld(0);var viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);this.draw(type,viewLWorld,viewRWorld);ctx.restore();},draw:function(type,viewLWorld,viewRWorld){},addEventsToTrackMap:function(eventToTrackMap){},addContainersToTrackMap:function(containerToTrackMap){},addIntersectingEventsInRangeToSelection:function(loVX,hiVX,loVY,hiVY,selection){var pixelRatio=window.devicePixelRatio||1;var dt=this.viewport.currentDisplayTransform;var viewPixWidthWorld=dt.xViewVectorToWorld(1);var loWX=dt.xViewToWorld(loVX*pixelRatio);var hiWX=dt.xViewToWorld(hiVX*pixelRatio);var clientRect=this.getBoundingClientRect();var a=Math.max(loVY,clientRect.top);var b=Math.min(hiVY,clientRect.bottom);if(a>b)
-return;this.addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){},addClosestInstantEventToSelection:function(instantEvents,worldX,worldMaxDist,selection){var instantEvent=tr.b.findClosestElementInSortedArray(instantEvents,function(x){return x.start;},worldX,worldMaxDist);if(!instantEvent)
-return;selection.push(instantEvent);}};return{Track:Track};});'use strict';tr.exportTo('tr.ui.tracks',function(){var StackedBarsTrack=tr.ui.b.define('stacked-bars-track',tr.ui.tracks.Track);StackedBarsTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('stacked-bars-track');this.objectInstance_=null;this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},addEventsToTrackMap:function(eventToTrackMap){var objectSnapshots=this.objectInstance_.snapshots;objectSnapshots.forEach(function(obj){eventToTrackMap.addEvent(obj,this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){function onSnapshot(snapshot){selection.push(snapshot);}
-var snapshots=this.objectInstance_.snapshots;var maxBounds=this.objectInstance_.parent.model.bounds.max;tr.b.iterateOverIntersectingIntervals(snapshots,function(x){return x.ts;},function(x,i){if(i==snapshots.length-1){if(snapshots.length==1)
-return maxBounds;return snapshots[i].ts-snapshots[i-1].ts;}
-return snapshots[i+1].ts-snapshots[i].ts;},loWX,hiWX,onSnapshot);},addEventNearToProvidedEventToSelection:function(event,offset,selection){if(!(event instanceof tr.model.ObjectSnapshot))
-throw new Error('Unrecognized event');var objectSnapshots=this.objectInstance_.snapshots;var index=objectSnapshots.indexOf(event);var newIndex=index+offset;if(newIndex>=0&&newIndex<objectSnapshots.length){selection.push(objectSnapshots[newIndex]);return true;}
-return false;},addAllEventsMatchingFilterToSelection:function(filter,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){var snapshot=tr.b.findClosestElementInSortedArray(this.objectInstance_.snapshots,function(x){return x.ts;},worldX,worldMaxDist);if(!snapshot)
-return;selection.push(snapshot);}};return{StackedBarsTrack:StackedBarsTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SelectionState=tr.model.SelectionState;var EventPresenter=tr.ui.b.EventPresenter;var ObjectInstanceTrack=tr.ui.b.define('object-instance-track',tr.ui.tracks.Track);ObjectInstanceTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('object-instance-track');this.objectInstances_=[];this.objectSnapshots_=[];this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},get objectInstances(){return this.objectInstances_;},set objectInstances(objectInstances){if(!objectInstances||objectInstances.length==0){this.heading='';this.objectInstances_=[];this.objectSnapshots_=[];return;}
-this.heading=objectInstances[0].typeName;this.objectInstances_=objectInstances;this.objectSnapshots_=[];this.objectInstances_.forEach(function(instance){this.objectSnapshots_.push.apply(this.objectSnapshots_,instance.snapshots);},this);this.objectSnapshots_.sort(function(a,b){return a.ts-b.ts;});},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},get snapshotRadiusView(){return 7*(window.devicePixelRatio||1);},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawLetterDots_(viewLWorld,viewRWorld);break;}},drawLetterDots_:function(viewLWorld,viewRWorld){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var height=bounds.height*pixelRatio;var halfHeight=height*0.5;var twoPi=Math.PI*2;var dt=this.viewport.currentDisplayTransform;var snapshotRadiusView=this.snapshotRadiusView;var snapshotRadiusWorld=dt.xViewVectorToWorld(height);var loI;ctx.save();dt.applyTransformToCanvas(ctx);var objectInstances=this.objectInstances_;var loI=tr.b.findLowIndexInSortedArray(objectInstances,function(instance){return instance.deletionTs;},viewLWorld);ctx.strokeStyle='rgb(0,0,0)';for(var i=loI;i<objectInstances.length;++i){var instance=objectInstances[i];var x=instance.creationTs;if(x>viewRWorld)
-break;var right=instance.deletionTs==Number.MAX_VALUE?viewRWorld:instance.deletionTs;ctx.fillStyle=EventPresenter.getObjectInstanceColor(instance);ctx.fillRect(x,pixelRatio,right-x,height-2*pixelRatio);}
-ctx.restore();var objectSnapshots=this.objectSnapshots_;loI=tr.b.findLowIndexInSortedArray(objectSnapshots,function(snapshot){return snapshot.ts+snapshotRadiusWorld;},viewLWorld);for(var i=loI;i<objectSnapshots.length;++i){var snapshot=objectSnapshots[i];var x=snapshot.ts;if(x-snapshotRadiusWorld>viewRWorld)
-break;var xView=dt.xWorldToView(x);ctx.fillStyle=EventPresenter.getObjectSnapshotColor(snapshot);ctx.beginPath();ctx.arc(xView,halfHeight,snapshotRadiusView,0,twoPi);ctx.fill();if(snapshot.selected){ctx.lineWidth=5;ctx.strokeStyle='rgb(100,100,0)';ctx.stroke();ctx.beginPath();ctx.arc(xView,halfHeight,snapshotRadiusView-1,0,twoPi);ctx.lineWidth=2;ctx.strokeStyle='rgb(255,255,0)';ctx.stroke();}else{ctx.lineWidth=1;ctx.strokeStyle='rgb(0,0,0)';ctx.stroke();}}
-ctx.lineWidth=1;var selectionState=SelectionState.NONE;if(objectInstances.length&&objectInstances[0].selectionState===SelectionState.DIMMED){selectionState=SelectionState.DIMMED;}
-if(selectionState===SelectionState.DIMMED){var width=bounds.width*pixelRatio;ctx.fillStyle='rgba(255,255,255,0.5)';ctx.fillRect(0,0,width,height);ctx.restore();}},addEventsToTrackMap:function(eventToTrackMap){if(this.objectInstance_!==undefined){this.objectInstance_.forEach(function(obj){eventToTrackMap.addEvent(obj,this);},this);}
-if(this.objectSnapshots_!==undefined){this.objectSnapshots_.forEach(function(obj){eventToTrackMap.addEvent(obj,this);},this);}},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){var foundSnapshot=false;function onSnapshot(snapshot){selection.push(snapshot);foundSnapshot=true;}
-var snapshotRadiusView=this.snapshotRadiusView;var snapshotRadiusWorld=viewPixWidthWorld*snapshotRadiusView;tr.b.iterateOverIntersectingIntervals(this.objectSnapshots_,function(x){return x.ts-snapshotRadiusWorld;},function(x){return 2*snapshotRadiusWorld;},loWX,hiWX,onSnapshot);if(foundSnapshot)
-return;tr.b.iterateOverIntersectingIntervals(this.objectInstances_,function(x){return x.creationTs;},function(x){return x.deletionTs-x.creationTs;},loWX,hiWX,selection.push.bind(selection));},addEventNearToProvidedEventToSelection:function(event,offset,selection){var events;if(event instanceof tr.model.ObjectSnapshot)
-events=this.objectSnapshots_;else if(event instanceof tr.model.ObjectInstance)
-events=this.objectInstances_;else
-throw new Error('Unrecognized event');var index=events.indexOf(event);var newIndex=index+offset;if(newIndex>=0&&newIndex<events.length){selection.push(events[newIndex]);return true;}
-return false;},addAllEventsMatchingFilterToSelection:function(filter,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){var snapshot=tr.b.findClosestElementInSortedArray(this.objectSnapshots_,function(x){return x.ts;},worldX,worldMaxDist);if(!snapshot)
-return;selection.push(snapshot);}};var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);tr.b.decorateExtensionRegistry(ObjectInstanceTrack,options);return{ObjectInstanceTrack:ObjectInstanceTrack};});'use strict';tr.exportTo('tr.ui.e.system_stats',function(){var EventPresenter=tr.ui.b.EventPresenter;var statCount;var excludedStats={'meminfo':{'pswpin':0,'pswpout':0,'pgmajfault':0},'diskinfo':{'io':0,'io_time':0,'read_time':0,'reads':0,'reads_merged':0,'sectors_read':0,'sectors_written':0,'weighted_io_time':0,'write_time':0,'writes':0,'writes_merged':0},'swapinfo':{}};var SystemStatsInstanceTrack=tr.ui.b.define('tr-ui-e-system-stats-instance-track',tr.ui.tracks.StackedBarsTrack);SystemStatsInstanceTrack.prototype={__proto__:tr.ui.tracks.StackedBarsTrack.prototype,decorate:function(viewport){tr.ui.tracks.StackedBarsTrack.prototype.decorate.call(this,viewport);this.classList.add('tr-ui-e-system-stats-instance-track');this.objectInstance_=null;},set objectInstances(objectInstances){if(!objectInstances){this.objectInstance_=[];return;}
-if(objectInstances.length!=1)
-throw new Error('Bad object instance count.');this.objectInstance_=objectInstances[0];if(this.objectInstance_!==null){this.computeRates_(this.objectInstance_.snapshots);this.maxStats_=this.computeMaxStats_(this.objectInstance_.snapshots);}},computeRates_:function(snapshots){for(var i=0;i<snapshots.length;i++){var snapshot=snapshots[i];var stats=snapshot.getStats();var prevSnapshot;var prevStats;if(i==0){prevSnapshot=snapshots[0];}else{prevSnapshot=snapshots[i-1];}
-prevStats=prevSnapshot.getStats();var timeIntervalSeconds=(snapshot.ts-prevSnapshot.ts)/1000;if(timeIntervalSeconds==0)
-timeIntervalSeconds=1;this.computeRatesRecursive_(prevStats,stats,timeIntervalSeconds);}},computeRatesRecursive_:function(prevStats,stats,timeIntervalSeconds){for(var statName in stats){if(stats[statName]instanceof Object){this.computeRatesRecursive_(prevStats[statName],stats[statName],timeIntervalSeconds);}else{if(statName=='sectors_read'){stats['bytes_read_per_sec']=(stats['sectors_read']-
-prevStats['sectors_read'])*512/timeIntervalSeconds;}
-if(statName=='sectors_written'){stats['bytes_written_per_sec']=(stats['sectors_written']-
-prevStats['sectors_written'])*512/timeIntervalSeconds;}
-if(statName=='pgmajfault'){stats['pgmajfault_per_sec']=(stats['pgmajfault']-
-prevStats['pgmajfault'])/timeIntervalSeconds;}
-if(statName=='pswpin'){stats['bytes_swpin_per_sec']=(stats['pswpin']-
-prevStats['pswpin'])*1000/timeIntervalSeconds;}
-if(statName=='pswpout'){stats['bytes_swpout_per_sec']=(stats['pswpout']-
-prevStats['pswpout'])*1000/timeIntervalSeconds;}}}},computeMaxStats_:function(snapshots){var maxStats=new Object();statCount=0;for(var i=0;i<snapshots.length;i++){var snapshot=snapshots[i];var stats=snapshot.getStats();this.computeMaxStatsRecursive_(stats,maxStats,excludedStats);}
-return maxStats;},computeMaxStatsRecursive_:function(stats,maxStats,excludedStats){for(var statName in stats){if(stats[statName]instanceof Object){if(!(statName in maxStats))
-maxStats[statName]=new Object();var excludedNested;if(excludedStats&&statName in excludedStats)
-excludedNested=excludedStats[statName];else
-excludedNested=null;this.computeMaxStatsRecursive_(stats[statName],maxStats[statName],excludedNested);}else{if(excludedStats&&statName in excludedStats)
-continue;if(!(statName in maxStats)){maxStats[statName]=0;statCount++;}
-if(stats[statName]>maxStats[statName])
-maxStats[statName]=stats[statName];}}},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawStatBars_(viewLWorld,viewRWorld);break;}},drawStatBars_:function(viewLWorld,viewRWorld){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var width=bounds.width*pixelRatio;var height=(bounds.height*pixelRatio)/statCount;var vp=this.viewport.currentDisplayTransform;var maxStats=this.maxStats_;var objectSnapshots=this.objectInstance_.snapshots;var lowIndex=tr.b.findLowIndexInSortedArray(objectSnapshots,function(snapshot){return snapshot.ts;},viewLWorld);if(lowIndex>0)
-lowIndex-=1;for(var i=lowIndex;i<objectSnapshots.length;++i){var snapshot=objectSnapshots[i];var trace=snapshot.getStats();var currentY=height;var left=snapshot.ts;if(left>viewRWorld)
-break;var leftView=vp.xWorldToView(left);if(leftView<0)
-leftView=0;var right;if(i!=objectSnapshots.length-1){right=objectSnapshots[i+1].ts;}else{if(objectSnapshots.length>1)
-right=objectSnapshots[i].ts+(objectSnapshots[i].ts-
-objectSnapshots[i-1].ts);else
-right=this.objectInstance_.parent.model.bounds.max;}
-var rightView=vp.xWorldToView(right);if(rightView>width)
-rightView=width;leftView=Math.floor(leftView);rightView=Math.floor(rightView);this.drawStatBarsRecursive_(snapshot,leftView,rightView,height,trace,maxStats,currentY);if(i==lowIndex)
-this.drawStatNames_(leftView,height,currentY,'',maxStats);}
-ctx.lineWidth=1;},drawStatBarsRecursive_:function(snapshot,leftView,rightView,height,stats,maxStats,currentY){var ctx=this.context();for(var statName in maxStats){if(stats[statName]instanceof Object){currentY=this.drawStatBarsRecursive_(snapshot,leftView,rightView,height,stats[statName],maxStats[statName],currentY);}else{var maxStat=maxStats[statName];ctx.fillStyle=EventPresenter.getBarSnapshotColor(snapshot,Math.round(currentY/height));var barHeight;if(maxStat>0){barHeight=height*Math.max(stats[statName],0)/maxStat;}else{barHeight=0;}
+const modelHelper=m.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(modelHelper.browserHelper&&modelHelper.browserHelper.hasLatencyEvents){return{supported:true};}
+return{supported:false,reason:'No InputLatency events trace. Consider enabling '+'benchmark" and "input" category when recording the trace'};},get textLabel(){return'Input Latency';}});tr.ui.side_panel.SidePanelRegistry.register(function(){return document.createElement('tr-ui-e-s-input-latency-side-panel');});'use strict';tr.exportTo('tr.e.system_stats',function(){const ObjectSnapshot=tr.model.ObjectSnapshot;function SystemStatsSnapshot(objectInstance,ts,args){ObjectSnapshot.apply(this,arguments);this.objectInstance=objectInstance;this.ts=ts;this.args=args;this.stats_=args;}
+SystemStatsSnapshot.prototype={__proto__:ObjectSnapshot.prototype,initialize(){if(this.args.length===0){throw new Error('No system stats snapshot data.');}
+this.stats_=this.args;},getStats(){return this.stats_;},setStats(stats){this.stats_=stats;}};ObjectSnapshot.subTypes.register(SystemStatsSnapshot,{typeName:'base::TraceEventSystemStatsMonitor::SystemStats'});return{SystemStatsSnapshot,};});'use strict';tr.exportTo('tr.ui.b',function(){const constants={HEADING_WIDTH:250};return{constants,};});'use strict';Polymer({is:'tr-ui-b-heading',DOWN_ARROW:String.fromCharCode(0x25BE),RIGHT_ARROW:String.fromCharCode(0x25B8),ready(viewport){this.style.width=(tr.ui.b.constants.HEADING_WIDTH-6)+'px';this.heading_='';this.expanded_=true;this.arrowVisible_=false;this.selectionGenerator_=undefined;this.updateContents_();},get heading(){return this.heading_;},set heading(text){if(this.heading_===text)return;this.heading_=text;this.updateContents_();},set arrowVisible(val){if(this.arrowVisible_===val)return;this.arrowVisible_=!!val;this.updateContents_();},set tooltip(text){this.$.heading.title=text;},set selectionGenerator(generator){if(this.selectionGenerator_===generator)return;this.selectionGenerator_=generator;this.updateContents_();},get expanded(){return this.expanded_;},set expanded(expanded){if(this.expanded_===expanded)return;this.expanded_=!!expanded;this.updateContents_();},onHeadingDivClicked_(){this.dispatchEvent(new tr.b.Event('heading-clicked',true));},updateContents_(){if(this.arrowVisible_){this.$.arrow.style.display='';}else{this.$.arrow.style.display='none';this.$.heading.style.display=this.expanded_?'':'none';}
+if(this.arrowVisible_){Polymer.dom(this.$.arrow).textContent=this.expanded_?this.DOWN_ARROW:this.RIGHT_ARROW;}
+this.$.link.style.display='none';this.$.heading_content.style.display='none';if(this.selectionGenerator_){this.$.link.style.display='inline-block';this.$.link.selection=this.selectionGenerator_;Polymer.dom(this.$.link).textContent=this.heading_;}else{this.$.heading_content.style.display='inline-block';Polymer.dom(this.$.heading_content).textContent=this.heading_;}}});'use strict';tr.exportTo('tr.ui.tracks',function(){const Track=tr.ui.b.define('track',tr.ui.b.ContainerThatDecoratesItsChildren);Track.prototype={__proto__:tr.ui.b.ContainerThatDecoratesItsChildren.prototype,decorate(viewport){tr.ui.b.ContainerThatDecoratesItsChildren.prototype.decorate.call(this);if(viewport===undefined){throw new Error('viewport is required when creating a Track.');}
+this.viewport_=viewport;Polymer.dom(this).classList.add('track');},get viewport(){return this.viewport_;},get drawingContainer(){if(this instanceof tr.ui.tracks.DrawingContainer)return this;let cur=this.parentElement;while(cur){if(cur instanceof tr.ui.tracks.DrawingContainer)return cur;cur=cur.parentElement;}
+return undefined;},get eventContainer(){},invalidateDrawingContainer(){const dc=this.drawingContainer;if(dc)dc.invalidate();},context(){if(!Polymer.dom(this).parentNode)return undefined;if(!Polymer.dom(this).parentNode.context){throw new Error('Parent container does not support context() method.');}
+return Polymer.dom(this).parentNode.context();},decorateChild_(childTrack){},undecorateChild_(childTrack){if(childTrack.detach){childTrack.detach();}},updateContents_(){},drawTrack(type){const ctx=this.context();const pixelRatio=window.devicePixelRatio||1;const bounds=this.getBoundingClientRect();const canvasBounds=ctx.canvas.getBoundingClientRect();ctx.save();ctx.translate(0,pixelRatio*(bounds.top-canvasBounds.top));const dt=this.viewport.currentDisplayTransform;const viewLWorld=dt.xViewToWorld(0);const viewRWorld=dt.xViewToWorld(canvasBounds.width*pixelRatio);const viewHeight=bounds.height*pixelRatio;this.draw(type,viewLWorld,viewRWorld,viewHeight);ctx.restore();},draw(type,viewLWorld,viewRWorld,viewHeight){},addEventsToTrackMap(eventToTrackMap){},addContainersToTrackMap(containerToTrackMap){},addIntersectingEventsInRangeToSelection(loVX,hiVX,loVY,hiVY,selection){const pixelRatio=window.devicePixelRatio||1;const dt=this.viewport.currentDisplayTransform;const viewPixWidthWorld=dt.xViewVectorToWorld(1);const loWX=dt.xViewToWorld(loVX*pixelRatio);const hiWX=dt.xViewToWorld(hiVX*pixelRatio);const clientRect=this.getBoundingClientRect();const a=Math.max(loVY,clientRect.top);const b=Math.min(hiVY,clientRect.bottom);if(a>b)return;this.addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection);},addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection){},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){},addClosestInstantEventToSelection(instantEvents,worldX,worldMaxDist,selection){const instantEvent=tr.b.findClosestElementInSortedArray(instantEvents,function(x){return x.start;},worldX,worldMaxDist);if(!instantEvent)return;selection.push(instantEvent);}};return{Track,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const SelectionState=tr.model.SelectionState;const EventPresenter=tr.ui.b.EventPresenter;const ObjectInstanceTrack=tr.ui.b.define('object-instance-track',tr.ui.tracks.Track);ObjectInstanceTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('object-instance-track');this.objectInstances_=[];this.objectSnapshots_=[];this.heading_=document.createElement('tr-ui-b-heading');Polymer.dom(this).appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},get objectInstances(){return this.objectInstances_;},set objectInstances(objectInstances){if(!objectInstances||objectInstances.length===0){this.heading='';this.objectInstances_=[];this.objectSnapshots_=[];return;}
+this.heading=objectInstances[0].baseTypeName;this.objectInstances_=objectInstances;this.objectSnapshots_=[];this.objectInstances_.forEach(function(instance){this.objectSnapshots_.push.apply(this.objectSnapshots_,instance.snapshots);},this);this.objectSnapshots_.sort(function(a,b){return a.ts-b.ts;});},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},get snapshotRadiusView(){return 7*(window.devicePixelRatio||1);},draw(type,viewLWorld,viewRWorld,viewHeight){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawObjectInstances_(viewLWorld,viewRWorld);break;}},drawObjectInstances_(viewLWorld,viewRWorld){const ctx=this.context();const pixelRatio=window.devicePixelRatio||1;const bounds=this.getBoundingClientRect();const height=bounds.height*pixelRatio;const halfHeight=height*0.5;const twoPi=Math.PI*2;const dt=this.viewport.currentDisplayTransform;const snapshotRadiusView=this.snapshotRadiusView;const snapshotRadiusWorld=dt.xViewVectorToWorld(height);const objectInstances=this.objectInstances_;let loI=tr.b.findLowIndexInSortedArray(objectInstances,function(instance){return instance.deletionTs;},viewLWorld);ctx.save();ctx.strokeStyle='rgb(0,0,0)';for(let i=loI;i<objectInstances.length;++i){const instance=objectInstances[i];const x=instance.creationTs;if(x>viewRWorld)break;const right=instance.deletionTs===Number.MAX_VALUE?viewRWorld:instance.deletionTs;const xView=dt.xWorldToView(x);const widthView=dt.xWorldVectorToView(right-x);ctx.fillStyle=EventPresenter.getObjectInstanceColor(instance);ctx.fillRect(xView,pixelRatio,widthView,height-2*pixelRatio);}
+ctx.restore();const objectSnapshots=this.objectSnapshots_;loI=tr.b.findLowIndexInSortedArray(objectSnapshots,function(snapshot){return snapshot.ts+snapshotRadiusWorld;},viewLWorld);for(let i=loI;i<objectSnapshots.length;++i){const snapshot=objectSnapshots[i];const x=snapshot.ts;if(x-snapshotRadiusWorld>viewRWorld)break;const xView=dt.xWorldToView(x);ctx.fillStyle=EventPresenter.getObjectSnapshotColor(snapshot);ctx.beginPath();ctx.arc(xView,halfHeight,snapshotRadiusView,0,twoPi);ctx.fill();if(snapshot.selected){ctx.lineWidth=5;ctx.strokeStyle='rgb(100,100,0)';ctx.stroke();ctx.beginPath();ctx.arc(xView,halfHeight,snapshotRadiusView-1,0,twoPi);ctx.lineWidth=2;ctx.strokeStyle='rgb(255,255,0)';ctx.stroke();}else{ctx.lineWidth=1;ctx.strokeStyle='rgb(0,0,0)';ctx.stroke();}}
+ctx.lineWidth=1;let selectionState=SelectionState.NONE;if(objectInstances.length&&objectInstances[0].selectionState===SelectionState.DIMMED){selectionState=SelectionState.DIMMED;}
+if(selectionState===SelectionState.DIMMED){const width=bounds.width*pixelRatio;ctx.fillStyle='rgba(255,255,255,0.5)';ctx.fillRect(0,0,width,height);ctx.restore();}},addEventsToTrackMap(eventToTrackMap){if(this.objectInstance_!==undefined){this.objectInstance_.forEach(function(obj){eventToTrackMap.addEvent(obj,this);},this);}
+if(this.objectSnapshots_!==undefined){this.objectSnapshots_.forEach(function(obj){eventToTrackMap.addEvent(obj,this);},this);}},addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection){let foundSnapshot=false;function onSnapshot(snapshot){selection.push(snapshot);foundSnapshot=true;}
+const snapshotRadiusView=this.snapshotRadiusView;const snapshotRadiusWorld=viewPixWidthWorld*snapshotRadiusView;tr.b.iterateOverIntersectingIntervals(this.objectSnapshots_,function(x){return x.ts-snapshotRadiusWorld;},function(x){return 2*snapshotRadiusWorld;},loWX,hiWX,onSnapshot);if(foundSnapshot)return;tr.b.iterateOverIntersectingIntervals(this.objectInstances_,function(x){return x.creationTs;},function(x){return x.deletionTs-x.creationTs;},loWX,hiWX,(value)=>{selection.push(value);});},addEventNearToProvidedEventToSelection(event,offset,selection){let events;if(event instanceof tr.model.ObjectSnapshot){events=this.objectSnapshots_;}else if(event instanceof tr.model.ObjectInstance){events=this.objectInstances_;}else{throw new Error('Unrecognized event');}
+const index=events.indexOf(event);const newIndex=index+offset;if(newIndex>=0&&newIndex<events.length){selection.push(events[newIndex]);return true;}
+return false;},addAllEventsMatchingFilterToSelection(filter,selection){},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){const snapshot=tr.b.findClosestElementInSortedArray(this.objectSnapshots_,function(x){return x.ts;},worldX,worldMaxDist);if(!snapshot)return;selection.push(snapshot);}};const options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);tr.b.decorateExtensionRegistry(ObjectInstanceTrack,options);return{ObjectInstanceTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const StackedBarsTrack=tr.ui.b.define('stacked-bars-track',tr.ui.tracks.Track);StackedBarsTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('stacked-bars-track');this.objectInstance_=null;this.heading_=document.createElement('tr-ui-b-heading');Polymer.dom(this).appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},addEventsToTrackMap(eventToTrackMap){const objectSnapshots=this.objectInstance_.snapshots;objectSnapshots.forEach(function(obj){eventToTrackMap.addEvent(obj,this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection){function onSnapshot(snapshot){selection.push(snapshot);}
+const snapshots=this.objectInstance_.snapshots;const maxBounds=this.objectInstance_.parent.model.bounds.max;tr.b.iterateOverIntersectingIntervals(snapshots,function(x){return x.ts;},function(x,i){if(i===snapshots.length-1){if(snapshots.length===1){return maxBounds;}
+return snapshots[i].ts-snapshots[i-1].ts;}
+return snapshots[i+1].ts-snapshots[i].ts;},loWX,hiWX,onSnapshot);},addEventNearToProvidedEventToSelection(event,offset,selection){if(!(event instanceof tr.model.ObjectSnapshot)){throw new Error('Unrecognized event');}
+const objectSnapshots=this.objectInstance_.snapshots;const index=objectSnapshots.indexOf(event);const newIndex=index+offset;if(newIndex>=0&&newIndex<objectSnapshots.length){selection.push(objectSnapshots[newIndex]);return true;}
+return false;},addAllEventsMatchingFilterToSelection(filter,selection){},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){const snapshot=tr.b.findClosestElementInSortedArray(this.objectInstance_.snapshots,function(x){return x.ts;},worldX,worldMaxDist);if(!snapshot)return;selection.push(snapshot);}};return{StackedBarsTrack,};});'use strict';tr.exportTo('tr.ui.e.system_stats',function(){const EventPresenter=tr.ui.b.EventPresenter;let statCount;const excludedStats={'meminfo':{'pswpin':0,'pswpout':0,'pgmajfault':0},'diskinfo':{'io':0,'io_time':0,'read_time':0,'reads':0,'reads_merged':0,'sectors_read':0,'sectors_written':0,'weighted_io_time':0,'write_time':0,'writes':0,'writes_merged':0},'swapinfo':{},'perfinfo':{'idle_time':0,'read_transfer_count':0,'write_transfer_count':0,'other_transfer_count':0,'read_operation_count':0,'write_operation_count':0,'other_operation_count':0,'pagefile_pages_written':0,'pagefile_pages_write_ios':0,'available_pages':0,'pages_read':0,'page_read_ios':0}};const SystemStatsInstanceTrack=tr.ui.b.define('tr-ui-e-system-stats-instance-track',tr.ui.tracks.StackedBarsTrack);const kPageSizeWindows=4096;SystemStatsInstanceTrack.prototype={__proto__:tr.ui.tracks.StackedBarsTrack.prototype,decorate(viewport){tr.ui.tracks.StackedBarsTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('tr-ui-e-system-stats-instance-track');this.objectInstance_=null;},set objectInstances(objectInstances){if(!objectInstances){this.objectInstance_=[];return;}
+if(objectInstances.length!==1){throw new Error('Bad object instance count.');}
+this.objectInstance_=objectInstances[0];if(this.objectInstance_!==null){this.computeRates_(this.objectInstance_.snapshots);this.maxStats_=this.computeMaxStats_(this.objectInstance_.snapshots);}},computeRates_(snapshots){for(let i=0;i<snapshots.length;i++){const snapshot=snapshots[i];const stats=snapshot.getStats();let prevSnapshot;if(i===0){prevSnapshot=snapshots[0];}else{prevSnapshot=snapshots[i-1];}
+const prevStats=prevSnapshot.getStats();let timeIntervalSeconds=(snapshot.ts-prevSnapshot.ts)/1000;if(timeIntervalSeconds===0){timeIntervalSeconds=1;}
+this.computeRatesRecursive_(prevStats,stats,timeIntervalSeconds);}},computeRatesRecursive_(prevStats,stats,timeIntervalSeconds){for(const statName in stats){if(stats[statName]instanceof Object){this.computeRatesRecursive_(prevStats[statName],stats[statName],timeIntervalSeconds);}else{if(statName==='sectors_read'){stats.bytes_read_per_sec=(stats.sectors_read-
+prevStats.sectors_read)*512/timeIntervalSeconds;}
+if(statName==='sectors_written'){stats.bytes_written_per_sec=(stats.sectors_written-
+prevStats.sectors_written)*512/timeIntervalSeconds;}
+if(statName==='pgmajfault'){stats.pgmajfault_per_sec=(stats.pgmajfault-
+prevStats.pgmajfault)/timeIntervalSeconds;}
+if(statName==='pswpin'){stats.bytes_swpin_per_sec=(stats.pswpin-
+prevStats.pswpin)*1000/timeIntervalSeconds;}
+if(statName==='pswpout'){stats.bytes_swpout_per_sec=(stats.pswpout-
+prevStats.pswpout)*1000/timeIntervalSeconds;}
+if(statName==='idle_time'){const units=tr.b.convertUnit(100.,tr.b.UnitScale.TIME.NANO_SEC,tr.b.UnitScale.TIME.SEC);const idleTile=(stats.idle_time-prevStats.idle_time)*units;stats.idle_time_per_sec=idleTile/timeIntervalSeconds;}
+if(statName==='read_transfer_count'){const bytesRead=stats.read_transfer_count-
+prevStats.read_transfer_count;stats.bytes_read_per_sec=bytesRead/timeIntervalSeconds;}
+if(statName==='write_transfer_count'){const bytesWritten=stats.write_transfer_count-
+prevStats.write_transfer_count;stats.bytes_written_per_sec=bytesWritten/timeIntervalSeconds;}
+if(statName==='other_transfer_count'){const bytesTransfer=stats.other_transfer_count-
+prevStats.other_transfer_count;stats.bytes_other_per_sec=bytesTransfer/timeIntervalSeconds;}
+if(statName==='read_operation_count'){const readOperation=stats.read_operation_count-
+prevStats.read_operation_count;stats.read_operation_per_sec=readOperation/timeIntervalSeconds;}
+if(statName==='write_operation_count'){const writeOperation=stats.write_operation_count-
+prevStats.write_operation_count;stats.write_operation_per_sec=writeOperation/timeIntervalSeconds;}
+if(statName==='other_operation_count'){const otherOperation=stats.other_operation_count-
+prevStats.other_operation_count;stats.other_operation_per_sec=otherOperation/timeIntervalSeconds;}
+if(statName==='pagefile_pages_written'){const pageFileBytesWritten=(stats.pagefile_pages_written-
+prevStats.pagefile_pages_written)*kPageSizeWindows;stats.pagefile_bytes_written_per_sec=pageFileBytesWritten/timeIntervalSeconds;}
+if(statName==='pagefile_pages_write_ios'){const pagefileWriteOperation=stats.pagefile_pages_write_ios-
+prevStats.pagefile_pages_write_ios;stats.pagefile_write_operation_per_sec=pagefileWriteOperation/timeIntervalSeconds;}
+if(statName==='available_pages'){stats.available_pages_in_bytes=stats.available_pages*kPageSizeWindows;}
+if(statName==='pages_read'){const pagesBytesRead=(stats.pages_read-prevStats.pages_read)*kPageSizeWindows;stats.bytes_read_per_sec=pagesBytesRead/timeIntervalSeconds;}
+if(statName==='page_read_ios'){const pagesBytesReadOperations=stats.page_read_ios-prevStats.page_read_ios;stats.pagefile_write_operation_per_sec=pagesBytesReadOperations/timeIntervalSeconds;}}}},computeMaxStats_(snapshots){const maxStats={};statCount=0;for(let i=0;i<snapshots.length;i++){const snapshot=snapshots[i];const stats=snapshot.getStats();this.computeMaxStatsRecursive_(stats,maxStats,excludedStats);}
+return maxStats;},computeMaxStatsRecursive_(stats,maxStats,excludedStats){for(const statName in stats){if(stats[statName]instanceof Object){if(!(statName in maxStats)){maxStats[statName]={};}
+let excludedNested;if(excludedStats&&statName in excludedStats){excludedNested=excludedStats[statName];}else{excludedNested=null;}
+this.computeMaxStatsRecursive_(stats[statName],maxStats[statName],excludedNested);}else{if(excludedStats&&statName in excludedStats){continue;}
+if(!(statName in maxStats)){maxStats[statName]=0;statCount++;}
+if(stats[statName]>maxStats[statName]){maxStats[statName]=stats[statName];}}}},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},draw(type,viewLWorld,viewRWorld,viewHeight){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawStatBars_(viewLWorld,viewRWorld);break;}},drawStatBars_(viewLWorld,viewRWorld){const ctx=this.context();const pixelRatio=window.devicePixelRatio||1;const bounds=this.getBoundingClientRect();const width=bounds.width*pixelRatio;const height=(bounds.height*pixelRatio)/statCount;const vp=this.viewport.currentDisplayTransform;const maxStats=this.maxStats_;const objectSnapshots=this.objectInstance_.snapshots;let lowIndex=tr.b.findLowIndexInSortedArray(objectSnapshots,function(snapshot){return snapshot.ts;},viewLWorld);if(lowIndex>0)lowIndex-=1;for(let i=lowIndex;i<objectSnapshots.length;++i){const snapshot=objectSnapshots[i];const trace=snapshot.getStats();const currentY=height;const left=snapshot.ts;if(left>viewRWorld)break;let leftView=vp.xWorldToView(left);if(leftView<0)leftView=0;let right;if(i!==objectSnapshots.length-1){right=objectSnapshots[i+1].ts;}else{if(objectSnapshots.length>1){right=objectSnapshots[i].ts+(objectSnapshots[i].ts-
+objectSnapshots[i-1].ts);}else{right=this.objectInstance_.parent.model.bounds.max;}}
+let rightView=vp.xWorldToView(right);if(rightView>width){rightView=width;}
+leftView=Math.floor(leftView);rightView=Math.floor(rightView);this.drawStatBarsRecursive_(snapshot,leftView,rightView,height,trace,maxStats,currentY);if(i===lowIndex){this.drawStatNames_(leftView,height,currentY,'',maxStats);}}
+ctx.lineWidth=1;},drawStatBarsRecursive_(snapshot,leftView,rightView,height,stats,maxStats,currentY){const ctx=this.context();for(const statName in maxStats){if(stats[statName]instanceof Object){currentY=this.drawStatBarsRecursive_(snapshot,leftView,rightView,height,stats[statName],maxStats[statName],currentY);}else{const maxStat=maxStats[statName];ctx.fillStyle=EventPresenter.getBarSnapshotColor(snapshot,Math.round(currentY/height));let barHeight;if(maxStat>0){barHeight=height*Math.max(stats[statName],0)/maxStat;}else{barHeight=0;}
 ctx.fillRect(leftView,currentY-barHeight,Math.max(rightView-leftView,1),barHeight);currentY+=height;}}
-return currentY;},drawStatNames_:function(leftView,height,currentY,prefix,maxStats){var ctx=this.context();ctx.textAlign='end';ctx.font='12px Arial';ctx.fillStyle='#000000';for(var statName in maxStats){if(maxStats[statName]instanceof Object){currentY=this.drawStatNames_(leftView,height,currentY,statName,maxStats[statName]);}else{var fullname=statName;if(prefix!='')
-fullname=prefix+' :: '+statName;ctx.fillText(fullname,leftView-10,currentY-height/4);currentY+=height;}}
-return currentY;}};tr.ui.tracks.ObjectInstanceTrack.register(SystemStatsInstanceTrack,{typeName:'base::TraceEventSystemStatsMonitor::SystemStats'});return{SystemStatsInstanceTrack:SystemStatsInstanceTrack};});'use strict';tr.exportTo('tr.c',function(){function ScriptingObject(){}
-ScriptingObject.prototype={onModelChanged:function(model){}};return{ScriptingObject:ScriptingObject};});'use strict';tr.exportTo('tr.c',function(){function ScriptingController(brushingStateController){this.brushingStateController_=brushingStateController;this.scriptObjectNames_=[];this.scriptObjectValues_=[];this.brushingStateController.addEventListener('model-changed',this.onModelChanged_.bind(this));var typeInfos=ScriptingObjectRegistry.getAllRegisteredTypeInfos();typeInfos.forEach(function(typeInfo){this.addScriptObject(typeInfo.metadata.name,typeInfo.constructor);global[typeInfo.metadata.name]=typeInfo.constructor;},this);}
+return currentY;},drawStatNames_(leftView,height,currentY,prefix,maxStats){const ctx=this.context();ctx.textAlign='end';ctx.font='12px Arial';ctx.fillStyle='#000000';for(const statName in maxStats){if(maxStats[statName]instanceof Object){currentY=this.drawStatNames_(leftView,height,currentY,statName,maxStats[statName]);}else{let fullname=statName;if(prefix!==''){fullname=prefix+' :: '+statName;}
+ctx.fillText(fullname,leftView-10,currentY-height/4);currentY+=height;}}
+return currentY;}};tr.ui.tracks.ObjectInstanceTrack.register(SystemStatsInstanceTrack,{typeName:'base::TraceEventSystemStatsMonitor::SystemStats'});return{SystemStatsInstanceTrack,};});'use strict';tr.exportTo('tr.ui.e.system_stats',function(){const SystemStatsSnapshotView=tr.ui.b.define('tr-ui-e-system-stats-snapshot-view',tr.ui.analysis.ObjectSnapshotView);SystemStatsSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate(){Polymer.dom(this).classList.add('tr-ui-e-system-stats-snapshot-view');},updateContents(){const snapshot=this.objectSnapshot_;if(!snapshot||!snapshot.getStats()){Polymer.dom(this).textContent='No system stats snapshot found.';return;}
+Polymer.dom(this).textContent='';const stats=snapshot.getStats();Polymer.dom(this).appendChild(this.buildList_(stats));},isFloat(n){return typeof n==='number'&&n%1!==0;},buildList_(stats){const statList=document.createElement('ul');for(const statName in stats){const statText=document.createElement('li');Polymer.dom(statText).textContent=''+statName+': ';Polymer.dom(statList).appendChild(statText);if(stats[statName]instanceof Object){Polymer.dom(statList).appendChild(this.buildList_(stats[statName]));}else{if(this.isFloat(stats[statName])){Polymer.dom(statText).textContent+=stats[statName].toFixed(2);}else{Polymer.dom(statText).textContent+=stats[statName];}}}
+return statList;}};tr.ui.analysis.ObjectSnapshotView.register(SystemStatsSnapshotView,{typeName:'base::TraceEventSystemStatsMonitor::SystemStats'});return{SystemStatsSnapshotView,};});'use strict';tr.exportTo('tr.ui.e.v8',function(){const IGNORED_ENTRIES={match:full=>full.startsWith('*CODE_AGE_')};const INSTANCE_TYPE_GROUPS={FIXED_ARRAY_TYPE:{match:full=>full.startsWith('*FIXED_ARRAY_'),realEntry:'FIXED_ARRAY_TYPE',keyToName:key=>key.slice('*FIXED_ARRAY_'.length).slice(0,-('_SUB_TYPE'.length)),nameToKey:name=>'*FIXED_ARRAY_'+name+'_SUB_TYPE'},CODE_TYPE:{match:full=>full.startsWith('*CODE_'),realEntry:'CODE_TYPE',keyToName:key=>key.slice('*CODE_'.length),nameToKey:name=>'*CODE_'+name},JS_OBJECTS:{match:full=>full.startsWith('JS_'),keyToName:key=>key,nameToKey:name=>name},Strings:{match:full=>full.endsWith('STRING_TYPE'),keyToName:key=>key,nameToKey:name=>name},Maps:{match:full=>full.startsWith('MAP_')&&full.endsWith('_TYPE'),keyToName:key=>key,nameToKey:name=>name},DescriptorArrays:{match:full=>full.endsWith('DESCRIPTOR_ARRAY_TYPE'),keyToName:key=>key,nameToKey:name=>name}};const DIFF_COLOR={GREEN:'#64DD17',RED:'#D50000'};function computePercentage(valueA,valueB){if(valueA===0)return 0;return valueA/valueB*100;}
+class DiffEntry{constructor(originalEntry,diffEntry){this.originalEntry_=originalEntry;this.diffEntry_=diffEntry;}
+get title(){return this.diffEntry_.title;}
+get overall(){return this.diffEntry_.overall;}
+get overAllocated(){return this.diffEntry_.overAllocated;}
+get count(){return this.diffEntry_.count;}
+get overallPercent(){return this.diffEntry_.overallPercent;}
+get overAllocatedPercent(){return this.diffEntry_.overAllocatedPercent;}
+get origin(){return this.originalEntry_;}
+get diff(){return this.diffEntry_;}
+get subRows(){return this.diffEntry_.subRows;}}
+class Entry{constructor(title,count,overall,overAllocated,histogram,overAllocatedHistogram){this.title_=title;this.overall_=overall;this.count_=count;this.overAllocated_=overAllocated;this.histogram_=histogram;this.overAllocatedHistogram_=overAllocatedHistogram;this.bucketSize_=this.histogram_.length;this.overallPercent_=100;this.overAllocatedPercent_=100;}
+get title(){return this.title_;}
+get overall(){return this.overall_;}
+get count(){return this.count_;}
+get overAllocated(){return this.overAllocated_;}
+get histogram(){return this.histogram_;}
+get overAllocatedHistogram(){return this.overAllocatedHistogram_;}
+get bucketSize(){return this.bucketSize_;}
+get overallPercent(){return this.overallPercent_;}
+set overallPercent(value){this.overallPercent_=value;}
+get overAllocatedPercent(){return this.overAllocatedPercent_;}
+set overAllocatedPercent(value){this.overAllocatedPercent_=value;}
+setFromObject(obj){this.count_=obj.count;this.overall_=obj.overall/1024;this.overAllocated_=obj.over_allocated/1024;this.histogram_=obj.histogram;this.overAllocatedHistogram_=obj.over_allocated_histogram;}
+diff(other){const entry=new Entry(this.title_,other.count_-this.count,other.overall_-this.overall,other.overAllocated_-this.overAllocated,[],[]);entry.overallPercent=computePercentage(entry.overall,this.overall);entry.overAllocatedPercent=computePercentage(entry.overAllocated,this.overAllocated);return new DiffEntry(this,entry);}}
+class GroupedEntry extends Entry{constructor(title,count,overall,overAllocated,histogram,overAllocatedHistogram){super(title,count,overall,overAllocated,histogram,overAllocatedHistogram);this.histogram_.fill(0);this.overAllocatedHistogram_.fill(0);this.entries_=new Map();}
+get title(){return this.title_;}
+set title(value){this.title_=value;}
+get subRows(){return Array.from(this.entries_.values());}
+getEntryFromTitle(title){return this.entries_.get(title);}
+add(entry){this.count_+=entry.count;this.overall_+=entry.overall;this.overAllocated_+=entry.overAllocated;if(this.bucketSize_===entry.bucketSize){for(let i=0;i<this.bucketSize_;++i){this.histogram_[i]+=entry.histogram[i];this.overAllocatedHistogram_[i]+=entry.overAllocatedHistogram[i];}}
+this.entries_.set(entry.title,entry);}
+accumulateUnknown(title){let unknownCount=this.count_;let unknownOverall=this.overall_;let unknownOverAllocated=this.overAllocated_;const unknownHistogram=tr.b.deepCopy(this.histogram_);const unknownOverAllocatedHistogram=tr.b.deepCopy(this.overAllocatedHistogram_);for(const entry of this.entries_.values()){unknownCount-=entry.count;unknownOverall-=entry.overall;unknownOverAllocated-=entry.overAllocated;for(let i=0;i<this.bucketSize_;++i){unknownHistogram[i]-=entry.histogram[i];unknownOverAllocatedHistogram[i]-=entry.overAllocatedHistogram[i];}}
+unknownOverAllocated=unknownOverAllocated<0?0:unknownOverAllocated;this.entries_.set(title,new Entry(title,unknownCount,unknownOverall,unknownOverAllocated,unknownHistogram,unknownOverAllocatedHistogram));}
+calculatePercentage(){for(const entry of this.entries_.values()){entry.overallPercent=computePercentage(entry.overall,this.overall_);entry.overAllocatedPercent=computePercentage(entry.overAllocated,this.overAllocated_);if(entry instanceof GroupedEntry)entry.calculatePercentage();}}
+diff(other){let newTitle='';if(this.title_.startsWith('Isolate')){newTitle='Total';}else{newTitle=this.title_;}
+const result=new GroupedEntry(newTitle,0,0,0,[],[]);for(const entry of this.entries_){const otherEntry=other.getEntryFromTitle(entry[0]);if(otherEntry===undefined)continue;result.add(entry[1].diff(otherEntry));}
+result.overallPercent=computePercentage(result.overall,this.overall);result.overAllocatedPercent=computePercentage(result.overAllocated,this.overAllocated);return new DiffEntry(this,result);}}
+function createSelector(targetEl,defaultValue,items,callback){const selectorEl=document.createElement('select');selectorEl.addEventListener('change',callback.bind(targetEl));const defaultOptionEl=document.createElement('option');for(let i=0;i<items.length;i++){const item=items[i];const optionEl=document.createElement('option');Polymer.dom(optionEl).textContent=item.label;optionEl.targetPropertyValue=item.value;optionEl.item=item;Polymer.dom(selectorEl).appendChild(optionEl);}
+selectorEl.__defineGetter__('selectedValue',function(v){if(selectorEl.children[selectorEl.selectedIndex]===undefined){return undefined;}
+return selectorEl.children[selectorEl.selectedIndex].targetPropertyValue;});selectorEl.__defineGetter__('selectedItem',function(v){if(selectorEl.children[selectorEl.selectedIndex]===undefined){return undefined;}
+return selectorEl.children[selectorEl.selectedIndex].item;});selectorEl.__defineSetter__('selectedValue',function(v){for(let i=0;i<selectorEl.children.length;i++){const value=selectorEl.children[i].targetPropertyValue;if(value===v){const changed=selectorEl.selectedIndex!==i;if(changed){selectorEl.selectedIndex=i;callback();}
+return;}}
+throw new Error('Not a valid value');});selectorEl.selectedIndex=-1;return selectorEl;}
+function plusMinus(value,toFixed=3){return(value>0?'+':'')+value.toFixed(toFixed);}
+function addArrow(value){if(value===0)return value;if(value===Number.NEGATIVE_INFINITY)return'\u2193\u221E';if(value===Number.POSITIVE_INFINITY)return'\u2191\u221E';return(value>0?'\u2191':'\u2193')+Math.abs(value.toFixed(3));}
+Polymer({is:'tr-ui-e-v8-gc-objects-stats-table',ready(){this.$.diffOption.style.display='none';this.isolateEntries_=[];this.selector1_=undefined;this.selector2_=undefined;},constructDiffTable_(table){this.$.diffTable.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;this.$.diffTable.tableColumns=[{title:'Component',value(row){const typeEl=document.createElement('span');typeEl.innerText=row.title;return typeEl;},showExpandButtons:true},{title:'Overall Memory(KB)',value(row){const spanEl=tr.ui.b.createSpan();spanEl.innerText=row.origin.overall.toFixed(3);return spanEl;},cmp(a,b){return a.origin.overall-b.origin.overall;}},{title:'diff(KB)',value(row){const spanEl=tr.ui.b.createSpan();spanEl.innerText=plusMinus(row.overall);if(row.overall>0){spanEl.style.color=DIFF_COLOR.RED;}else if(row.overall<0){spanEl.style.color=DIFF_COLOR.GREEN;}
+return spanEl;},cmp(a,b){return a.overall-b.overall;}},{title:'diff(%)',value(row){const spanEl=tr.ui.b.createSpan();spanEl.innerText=addArrow(row.overallPercent);if(row.overall>0){spanEl.style.color=DIFF_COLOR.RED;}else if(row.overall<0){spanEl.style.color=DIFF_COLOR.GREEN;}
+return spanEl;},cmp(a,b){return a.overall-b.overall;}},{title:'Over Allocated Memory(KB)',value(row){const spanEl=tr.ui.b.createSpan();spanEl.innerText=row.origin.overAllocated.toFixed(3);return spanEl;},cmp(a,b){return a.origin.overAllocated-b.origin.overAllocated;}},{title:'diff(KB)',value(row){const spanEl=tr.ui.b.createSpan();spanEl.innerText=plusMinus(row.overAllocated);if(row.overAllocated>0){spanEl.style.color=DIFF_COLOR.RED;}else if(row.overAllocated<0){spanEl.style.color=DIFF_COLOR.GREEN;}
+return spanEl;},cmp(a,b){return a.overAllocated-b.overAllocated;}},{title:'diff(%)',value(row){const spanEl=tr.ui.b.createSpan();spanEl.innerText=addArrow(row.overAllocatedPercent);if(row.overAllocated>0){spanEl.style.color=DIFF_COLOR.RED;}else if(row.overAllocated<0){spanEl.style.color=DIFF_COLOR.GREEN;}
+return spanEl;},cmp(a,b){return a.overAllocated-b.overAllocated;}},{title:'Count',value(row){const spanEl=tr.ui.b.createSpan();spanEl.innerText=row.origin.count;return spanEl;},cmp(a,b){return a.origin.count-b.origin.count;}},{title:'diff',value(row){const spanEl=tr.ui.b.createSpan();spanEl.innerText=plusMinus(row.count,0);if(row.count>0){spanEl.style.color=DIFF_COLOR.RED;}else if(row.count<0){spanEl.style.color=DIFF_COLOR.GREEN;}
+return spanEl;},cmp(a,b){return a.count-b.count;}},];},buildOptions_(){const items=[];for(const isolateEntry of this.isolateEntries_){items.push({label:isolateEntry.title,value:isolateEntry});}
+this.$.diffOption.style.display='inline-block';this.selector1_=createSelector(this,'',items,this.diffOptionChanged_);Polymer.dom(this.$.diffOption).appendChild(this.selector1_);const spanEl=tr.ui.b.createSpan();spanEl.innerText=' VS ';Polymer.dom(this.$.diffOption).appendChild(spanEl);this.selector2_=createSelector(this,'',items,this.diffOptionChanged_);Polymer.dom(this.$.diffOption).appendChild(this.selector2_);},diffOptionChanged_(){const isolateEntry1=this.selector1_.selectedValue;const isolateEntry2=this.selector2_.selectedValue;if(isolateEntry1===undefined||isolateEntry2===undefined){return;}
+if(isolateEntry1===isolateEntry2){this.$.diffTable.tableRows=[];this.$.diffTable.rebuild();return;}
+this.$.diffTable.tableRows=[isolateEntry1.diff(isolateEntry2)];this.$.diffTable.rebuild();},constructTable_(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;this.$.table.tableColumns=[{title:'Component',value(row){const typeEl=document.createElement('span');typeEl.innerText=row.title;return typeEl;},showExpandButtons:true},{title:'Overall Memory (KB)',value(row){const typeEl=document.createElement('span');typeEl.innerText=row.overall.toFixed(3);return typeEl;},cmp(a,b){return a.overall-b.overall;}},{title:'Over Allocated Memory (KB)',value(row){const typeEl=document.createElement('span');typeEl.innerText=row.overAllocated.toFixed(3);return typeEl;},cmp(a,b){return a.overAllocated-b.overAllocated;}},{title:'Overall Count',value(row){const typeEl=document.createElement('span');typeEl.innerText=row.count;return typeEl;},cmp(a,b){return a.count-b.count;}},{title:'Overall Memory Percent',value(row){const typeEl=document.createElement('span');typeEl.innerText=row.overallPercent.toFixed(3)+'%';return typeEl;},cmp(a,b){return a.overall-b.overall;}},{title:'Overall Allocated Memory Percent',value(row){const typeEl=document.createElement('span');typeEl.innerText=row.overAllocatedPercent.toFixed(3)+'%';return typeEl;},cmp(a,b){return a.overAllocated-b.overAllocated;}}];this.$.table.sortColumnIndex=1;this.$.table.sortDescending=true;},buildSubEntry_(objects,groupEntry,keyToName){const typeGroup=INSTANCE_TYPE_GROUPS[groupEntry.title];for(const instanceType of typeGroup){const e=objects[instanceType];if(e===undefined)continue;delete objects[instanceType];let title=instanceType;if(keyToName!==undefined)title=keyToName(title);groupEntry.add(new Entry(title,e.count,e.overall/1024,e.over_allocated/1024,e.histogram,e.over_allocated_histogram));}},buildUnGroupedEntries_(objects,objectEntry,bucketSize){for(const title of Object.getOwnPropertyNames(objects)){const obj=objects[title];const groupedEntry=new GroupedEntry(title,0,0,0,new Array(bucketSize),new Array(bucketSize));groupedEntry.setFromObject(obj);objectEntry.add(groupedEntry);}},createGroupEntries_(groupEntries,objects,bucketSize){for(const groupName of Object.getOwnPropertyNames(INSTANCE_TYPE_GROUPS)){const groupEntry=new GroupedEntry(groupName,0,0,0,new Array(bucketSize),new Array(bucketSize));if(INSTANCE_TYPE_GROUPS[groupName].realEntry!==undefined){groupEntry.savedRealEntry=objects[INSTANCE_TYPE_GROUPS[groupName].realEntry];delete objects[INSTANCE_TYPE_GROUPS[groupName].realEntry];}
+groupEntries[groupName]=groupEntry;}},buildGroupEntries_(groupEntries,objectEntry){for(const groupName of Object.getOwnPropertyNames(groupEntries)){const groupEntry=groupEntries[groupName];if(groupEntry.savedRealEntry!==undefined){groupEntry.setFromObject(groupEntry.savedRealEntry);groupEntry.accumulateUnknown('UNKNOWN');delete groupEntry.savedRealEntry;}
+objectEntry.add(groupEntry);}},buildSubEntriesForGroups_(groupEntries,objects){for(const instanceType of Object.getOwnPropertyNames(objects)){if(IGNORED_ENTRIES.match(instanceType)){delete objects[instanceType];continue;}
+const e=objects[instanceType];for(const name of Object.getOwnPropertyNames(INSTANCE_TYPE_GROUPS)){const group=INSTANCE_TYPE_GROUPS[name];if(group.match(instanceType)){groupEntries[name].add(new Entry(group.keyToName(instanceType),e.count,e.overall/1024,e.over_allocated/1024,e.histogram,e.over_allocated_histogram));delete objects[instanceType];}}}},build_(objects,objectEntry,bucketSize){delete objects.END;const groupEntries={};this.createGroupEntries_(groupEntries,objects,bucketSize);this.buildSubEntriesForGroups_(groupEntries,objects);this.buildGroupEntries_(groupEntries,objectEntry);this.buildUnGroupedEntries_(objects,objectEntry,bucketSize);},set selection(slices){slices.sortEvents(function(a,b){return b.start-a.start;});const previous=undefined;for(const slice of slices){if(!slice instanceof tr.e.v8.V8GCStatsThreadSlice)continue;const liveObjects=slice.liveObjects;const deadObjects=slice.deadObjects;const isolate=liveObjects.isolate;const isolateEntry=new GroupedEntry('Isolate_'+isolate+' at '+slice.start.toFixed(3)+' ms',0,0,0,[],[]);const liveEntry=new GroupedEntry('live objects',0,0,0,[],[]);const deadEntry=new GroupedEntry('dead objects',0,0,0,[],[]);const liveBucketSize=liveObjects.bucket_sizes.length;const deadBucketSize=deadObjects.bucket_sizes.length;this.build_(tr.b.deepCopy(liveObjects.type_data),liveEntry,liveBucketSize);isolateEntry.add(liveEntry);this.build_(tr.b.deepCopy(deadObjects.type_data),deadEntry,deadBucketSize);isolateEntry.add(deadEntry);isolateEntry.calculatePercentage();this.isolateEntries_.push(isolateEntry);}
+this.updateTable_();if(slices.length>1){this.buildOptions_();this.constructDiffTable_();}},updateTable_(){this.constructTable_();this.$.table.tableRows=this.isolateEntries_;this.$.table.rebuild();},});return{};});'use strict';Polymer({is:'tr-ui-e-multi-v8-gc-stats-thread-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){this.$.gcObjectsStats.selection=selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-e-multi-v8-gc-stats-thread-slice-sub-view',tr.e.v8.V8GCStatsThreadSlice,{multi:true,title:'V8 GC Stats slices'});'use strict';tr.exportTo('tr.e.v8',function(){const IC_STATS_PROPERTIES=['type','category','scriptName','filePosition','state','isNative','map','propertiesMode','numberOfOwnProperties','instanceType'];class ICStatsEntry{constructor(obj){this.type_=obj.type;if(this.type_.includes('Store')){this.category_='Store';}else if(this.type_.includes('Load')){this.category_='Load';}
+this.state_=obj.state;if(obj.functionName){this.functionName_=obj.optimized?'*':'~';this.functionName_+=obj.functionName.length===0?'(anonymous function)':obj.functionName;}
+this.offset_=obj.offset;this.scriptName_=obj.scriptName?obj.scriptName:'unknown';this.isNative_=obj.scriptName&&obj.scriptName.includes('native');this.lineNum_=obj.lineNum?obj.lineNum:'unknown';this.filePosition_=this.scriptName_+':'+this.lineNum_;if(this.functionName_){this.filePosition_+=' '+this.functionName_+'+'+this.offset_;}
+this.constructor_=obj.constructor?false:true;this.map_=obj.map;if(this.map_){this.propertiesMode_=obj.dict===1?'slow':'fast';}else{this.propertiesMode_='unknown';}
+this.numberOfOwnProperties_=obj.own;this.instanceType_=obj.instanceType;this.key_=obj.key;}
+get type(){return this.type_;}
+get category(){return this.category_;}
+get state(){return this.state_;}
+get functionName(){return this.functionName_;}
+get offset(){return this.offset_;}
+get scriptName(){return this.scriptName_;}
+get isNative(){return this.isNative_;}
+get lineNumber(){return this.lineNum_;}
+get isConstructor(){return this.constructor_;}
+get map(){return this.map_;}
+get propertiesMode(){return this.propertiesMode_;}
+get numberOfOwnProperties(){return this.numberOfOwnProperties_;}
+get instanceType(){return this.instanceType_;}
+get filePosition(){return this.filePosition_;}}
+class ICStatsEntryGroup{constructor(property,key){this.property_=property;this.key_=key;this.percentage_=0;this.entries_=[];this.subGroup_=undefined;}
+static groupBy(groups,entries,property){for(const entry of entries){const key=entry[property];let group=groups.get(key);if(!group){group=new ICStatsEntryGroup(property,key);groups.set(key,group);}
+group.add(entry);}
+for(const group of groups.values()){group.percentage=group.length/entries.length;}}
+add(entry){this.entries_.push(entry);}
+createSubGroup(){if(this.subGroup_)return this.subGroup_;this.subGroup_=new Map();for(const property of IC_STATS_PROPERTIES){if(property===this.property_)continue;const groups=new Map();this.subGroup_.set(property,groups);ICStatsEntryGroup.groupBy(groups,this.entries_,property);}
+return this.subGroup_;}
+get entries(){return this.entries_;}
+get key(){return this.key_;}
+get length(){return this.entries_.length;}
+get percentage(){return this.percentage_;}
+set percentage(value){this.percentage_=value;}}
+class ICStatsCollection{constructor(){this.entries_=[];this.groupedEntries_=new Map();}
+add(entry){this.entries_.push(entry);}
+groupBy(property){if(this.groupedEntries_.has(property)){return Array.from(this.groupedEntries_.get(property).values());}
+const groups=new Map();this.groupedEntries_.set(property,groups);ICStatsEntryGroup.groupBy(groups,this.entries_,property);return Array.from(groups.values());}
+get entries(){return this.entries_;}
+get length(){return this.entries_.length;}}
+return{IC_STATS_PROPERTIES,ICStatsEntry,ICStatsEntryGroup,ICStatsCollection,};});'use strict';tr.exportTo('tr.ui.e.v8',function(){const PROPERTIES=tr.e.v8.IC_STATS_PROPERTIES.map(x=>{return{label:x,value:x};});const ICStatsEntry=tr.e.v8.ICStatsEntry;const ICStatsEntryGroup=tr.e.v8.ICStatsEntryGroup;const ICStatsCollection=tr.e.v8.ICStatsCollection;Polymer({is:'tr-ui-e-v8-ic-stats-table',ready(){this.icStatsCollection_=new ICStatsCollection();this.groupKey_=PROPERTIES[0].value;this.selector_=tr.ui.b.createSelector(this,'groupKey','v8ICStatsGroupKey',this.groupKey_,PROPERTIES);Polymer.dom(this.$.groupOption).appendChild(this.selector_);},get groupKey(){return this.groupKey_;},set groupKey(key){this.groupKey_=key;if(this.icStatsCollection_.length===0)return;this.updateTable_(this.groupKey_);},constructTable_(table,groupKey){table.tableColumns=[{title:'',value:row=>{let expanded=false;const buttonEl=tr.ui.b.createButton('details',function(){const previousSibling=Polymer.dom(this).parentNode.parentNode;const parentNode=previousSibling.parentNode;if(expanded){const trEls=parentNode.getElementsByClassName('subTable');Array.from(trEls).map(x=>x.parentNode.removeChild(x));expanded=false;return;}
+expanded=true;const subGroups=row.createSubGroup();const tr=document.createElement('tr');tr.classList.add('subTable');tr.appendChild(document.createElement('td'));const td=document.createElement('td');td.colSpan=3;for(const subGroup of subGroups){const property=subGroup[0];const all=Array.from(subGroup[1].values());const group=all.slice(0,20);const divEl=document.createElement('div');const spanEl=document.createElement('span');const subTableEl=document.createElement('tr-ui-b-table');spanEl.innerText=`Top 20 out of ${all.length}`;spanEl.style.fontWeight='bold';spanEl.style.fontSize='14px';divEl.appendChild(spanEl);this.constructTable_(subTableEl,property);subTableEl.tableRows=group;subTableEl.rebuild();divEl.appendChild(subTableEl);td.appendChild(divEl);}
+tr.appendChild(td);parentNode.insertBefore(tr,previousSibling.nextSibling);});return buttonEl;}},{title:'Percentage',value(row){const spanEl=document.createElement('span');spanEl.innerText=(row.percentage*100).toFixed(3)+'%';return spanEl;},cmp:(a,b)=>a.percentage-b.percentage},{title:'Count',value(row){const spanEl=document.createElement('span');spanEl.innerText=row.length;return spanEl;},cmp:(a,b)=>a.length-b.length},{title:groupKey,value(row){const spanEl=document.createElement('span');spanEl.innerText=row.key?row.key:'';return spanEl;}}];table.sortColumnIndex=1;table.sortDescending=true;},updateTable_(groupKey){this.constructTable_(this.$.table,groupKey);this.$.table.tableRows=this.icStatsCollection_.groupBy(groupKey);this.$.table.rebuild();},set selection(slices){for(const slice of slices){for(const icStatsObj of slice.icStats){const entry=new ICStatsEntry(icStatsObj);this.icStatsCollection_.add(entry);}}
+this.$.total.innerText='Total items: '+this.icStatsCollection_.length;this.updateTable_(this.selector_.selectedValue);}});return{};});'use strict';Polymer({is:'tr-ui-e-multi-v8-ic-stats-thread-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){this.$.table.selection=selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-e-multi-v8-ic-stats-thread-slice-sub-view',tr.e.v8.V8ICStatsThreadSlice,{multi:true,title:'V8 IC stats slices'});'use strict';tr.exportTo('tr.e.v8',function(){class RuntimeStatsEntry{constructor(name,count,time){this.name_=name;this.count_=count;this.time_=time;}
+get name(){return this.name_;}
+get count(){return this.count_;}
+get time(){return this.time_;}
+addSample(count,time){this.count_+=count;this.time_+=time;}}
+class RuntimeStatsGroup extends RuntimeStatsEntry{constructor(name,matchRegex){super(name,0,0);this.regex_=matchRegex;this.entries_=new Map();}
+match(name){return this.regex_&&name.match(this.regex_);}
+add(entry){const value=this.entries_.get(entry.name);if(value!==undefined){value.addSample(entry.count,entry.time);}else{this.entries_.set(entry.name,entry);}
+this.count_+=entry.count;this.time_+=entry.time;}
+get values(){return Array.from(this.entries_.values());}}
+class RuntimeStatsGroupCollection{constructor(){this.blink_cpp_group_=new RuntimeStatsGroup('Blink C++',/.*Callback.*/);this.api_group_=new RuntimeStatsGroup('API',/.*API.*/);this.groups_=[new RuntimeStatsGroup('Total'),new RuntimeStatsGroup('IC',/.*IC_.*/),new RuntimeStatsGroup('Optimize-Background',/(.*OptimizeConcurrent.*)|RecompileConcurrent.*/),new RuntimeStatsGroup('Optimize',/StackGuard|.*Optimize.*|.*Deoptimize.*|Recompile.*/),new RuntimeStatsGroup('Compile-Background',/(.*CompileBackground.*)/),new RuntimeStatsGroup('Compile',/(^Compile.*)|(.*_Compile.*)/),new RuntimeStatsGroup('Parse-Background',/.*ParseBackground.*/),new RuntimeStatsGroup('Parse',/.*Parse.*/),this.blink_cpp_group_,this.api_group_,new RuntimeStatsGroup('GC-Background-Marking',/.*GC.MC.BACKGROUND.*MARKING.*/),new RuntimeStatsGroup('GC-Background-Sweeping',/.*GC.MC.BACKGROUND.*SWEEPING.*/),new RuntimeStatsGroup('GC-Background-Scavenger',/.*GC.SCAVENGER.BACKGROUND.*/),new RuntimeStatsGroup('GC-Background-MinorMC',/.*GC.MINOR_MC.BACKGROUND.*/),new RuntimeStatsGroup('GC-Background-MajorMC',/.*GC.MC.BACKGROUND.*/),new RuntimeStatsGroup('GC-Background-Other',/.*GC.*BACKGROUND.*/),new RuntimeStatsGroup('GC',/GC|AllocateInTargetSpace/),new RuntimeStatsGroup('JavaScript',/JS_Execution/),new RuntimeStatsGroup('V8 C++',/.*/)];this.blink_group_collection_=null;}
+addSlices(slices){const blinkEntries=[];for(const slice of slices){if(!(slice instanceof tr.e.v8.V8ThreadSlice))return;let runtimeCallStats;try{runtimeCallStats=JSON.parse(slice.runtimeCallStats);}catch(e){runtimeCallStats=slice.runtimeCallStats;}
+if(runtimeCallStats===undefined)continue;for(const[name,stat]of Object.entries(runtimeCallStats)){if(name.match(/Blink_.*/)){if(name==='Blink_V8')continue;const entry=new RuntimeStatsEntry(name,stat[0],stat[1]);blinkEntries.push(entry);continue;}
+for(let i=1;i<this.groups_.length;++i){if(this.groups_[i].match(name)){if(stat.length!==2)break;const entry=new RuntimeStatsEntry(name,stat[0],stat[1]);this.groups_[0].addSample(stat[0],stat[1]);this.groups_[i].add(entry);break;}}}}
+this.blink_group_collection_=new BlinkRuntimeStatsGroupCollection(blinkEntries);}
+get totalTime(){return this.groups_[0].time;}
+get totalCount(){return this.groups_[0].count;}
+get runtimeGroups(){return this.groups_;}
+get blinkRCSGroupCollection(){return this.blink_group_collection_;}
+get blinkCppTotalTime(){return this.blink_cpp_group_.time+this.api_group_.time;}}
+class BlinkRuntimeStatsGroupCollection{constructor(entries){this.groups_=[new RuntimeStatsGroup('Blink_Bindings',/^Blink_Bindings_(.*)/),new RuntimeStatsGroup('Blink_GC',/^Blink_GC_(.*)/),new RuntimeStatsGroup('Blink_Layout',/^Blink_Layout_(.*)/),new RuntimeStatsGroup('Blink_Parsing',/^Blink_Parsing_(.*)/),new RuntimeStatsGroup('Blink_Style',/^Blink_Style_(.*)/),new RuntimeStatsGroup('Blink_Callbacks',/^Blink_(.*)/)];this.total_group_=new RuntimeStatsGroup('Blink_Total',/.*/);for(const entry of entries){for(const group of this.groups_){if(group.match(entry.name)){const newEntry=new RuntimeStatsEntry('Blink_'+group.match(entry.name)[1],entry.count,entry.time);group.add(newEntry);this.total_group_.addSample(entry.count,entry.time);break;}}}}
+get runtimeGroups(){return this.groups_.concat(this.total_group_);}
+get values(){return this.groups_.reduce((values,group)=>values.concat(group.values),[]);}
+get totalTime(){return this.total_group_.time;}
+get totalCount(){return this.total_group_.count;}}
+return{BlinkRuntimeStatsGroupCollection,RuntimeStatsEntry,RuntimeStatsGroup,RuntimeStatsGroupCollection,};});'use strict';tr.exportTo('tr.ui.e.v8',function(){const codeSearchURL_='https://cs.chromium.org/search/?sq=package:chromium&type=cs&q=';function removeBlinkPrefix_(name){if(name.startsWith('Blink_'))name=name.substring(6);return name;}
+function handleCodeSearchForV8_(event){if(event.target.parentNode===undefined)return;let name=event.target.parentNode.entryName;if(name.startsWith('API_'))name=name.substring(4);const url=codeSearchURL_+encodeURIComponent(name)+'+file:src/v8/src';window.open(url,'_blank');}
+function handleCodeSearchForBlink_(event){if(event.target.parentNode===undefined)return;const name=event.target.parentNode.entryName;const url=codeSearchURL_+
+encodeURIComponent('RuntimeCallStats::CounterId::k'+name)+'+file:src/third_party/WebKit/|src/out/Debug/';window.open(url,'_blank');}
+function createCodeSearchEl_(handleCodeSearch){const codeSearchEl=document.createElement('span');codeSearchEl.innerText='?';codeSearchEl.style.float='right';codeSearchEl.style.borderRadius='5px';codeSearchEl.style.backgroundColor='#EEE';codeSearchEl.addEventListener('click',handleCodeSearch.bind(this));return codeSearchEl;}
+const timeColumn_={title:'Time',value(row){const typeEl=document.createElement('span');typeEl.innerText=(row.time/1000.0).toFixed(3)+' ms';return typeEl;},width:'100px',cmp(a,b){return a.time-b.time;}};const countColumn_={title:'Count',value(row){const typeEl=document.createElement('span');typeEl.innerText=row.count;return typeEl;},width:'100px',cmp(a,b){return a.count-b.count;}};function percentColumn_(title,totalTime){return{title,value(row){const typeEl=document.createElement('span');typeEl.innerText=(row.time/totalTime*100).toFixed(3)+'%';return typeEl;},width:'100px',cmp(a,b){return a.time-b.time;}};}
+function nameColumn_(handleCodeSearch,modifyName){return{title:'Name',value(row){const typeEl=document.createElement('span');let name=row.name;if(modifyName)name=modifyName(name);typeEl.innerText=name;if(!(row instanceof tr.e.v8.RuntimeStatsGroup)){typeEl.title='click ? for code search';typeEl.entryName=name;const codeSearchEl=createCodeSearchEl_(handleCodeSearch);typeEl.appendChild(codeSearchEl);}
+return typeEl;},width:'200px',showExpandButtons:true};}
+function initializeCommonOptions_(table){table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;table.sortColumnIndex=1;table.sortDescending=true;table.subRowsPropertyName='values';}
+Polymer({is:'tr-ui-e-v8-runtime-call-stats-table',ready(){this.table_=this.$.table;this.blink_rcs_table_=this.$.blink_rcs_table;this.totalTime_=0;},constructV8RCSTable_(totalTime){this.table_.tableColumns=[nameColumn_(handleCodeSearchForV8_),timeColumn_,countColumn_,percentColumn_('Percent',totalTime)];initializeCommonOptions_(this.table_);},constructBlinkRCSTable_(blinkCppTotalTime){this.blink_rcs_table_.tableColumns=[nameColumn_(handleCodeSearchForBlink_,removeBlinkPrefix_),timeColumn_,countColumn_,percentColumn_('Percent (of \'Blink C++\' + \'API\')',blinkCppTotalTime)];initializeCommonOptions_(this.blink_rcs_table_);},set slices(slices){const runtimeGroupCollection=new tr.e.v8.RuntimeStatsGroupCollection();runtimeGroupCollection.addSlices(slices);if(runtimeGroupCollection.totalTime>0){this.$.v8_rcs_heading.textContent='V8 Runtime Call Stats';this.constructV8RCSTable_(runtimeGroupCollection.totalTime);this.table_.tableRows=runtimeGroupCollection.runtimeGroups;this.table_.rebuild();}
+const blinkRCSGroupCollection=runtimeGroupCollection.blinkRCSGroupCollection;if(runtimeGroupCollection.blinkCppTotalTime>0&&blinkRCSGroupCollection.totalTime>0){this.$.blink_rcs_heading.textContent='Blink Runtime Call Stats';this.constructBlinkRCSTable_(runtimeGroupCollection.blinkCppTotalTime);this.blink_rcs_table_.tableRows=blinkRCSGroupCollection.runtimeGroups;this.blink_rcs_table_.rebuild();}}});return{};});'use strict';Polymer({is:'tr-ui-e-multi-v8-thread-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){this.$.runtimeCallStats.slices=selection;this.$.content.selection=selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-e-multi-v8-thread-slice-sub-view',tr.e.v8.V8ThreadSlice,{multi:true,title:'V8 slices'});'use strict';Polymer({is:'tr-ui-e-single-v8-gc-stats-thread-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){this.$.content.selection=selection;this.$.gcObjectsStats.selection=selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-e-single-v8-gc-stats-thread-slice-sub-view',tr.e.v8.V8GCStatsThreadSlice,{multi:false,title:'V8 GC stats slice'});'use strict';Polymer({is:'tr-ui-e-single-v8-ic-stats-thread-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){this.$.table.selection=selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-e-single-v8-ic-stats-thread-slice-sub-view',tr.e.v8.V8ICStatsThreadSlice,{multi:false,title:'V8 IC stats slice'});'use strict';Polymer({is:'tr-ui-e-single-v8-thread-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){this.$.runtimeCallStats.slices=selection;this.$.content.selection=selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-e-single-v8-thread-slice-sub-view',tr.e.v8.V8ThreadSlice,{multi:false,title:'V8 slice'});'use strict';tr.exportTo('tr.c',function(){function ScriptingObject(){}
+ScriptingObject.prototype={onModelChanged(model){}};return{ScriptingObject,};});'use strict';tr.exportTo('tr.c',function(){function ScriptingController(brushingStateController){this.brushingStateController_=brushingStateController;this.scriptObjectNames_=[];this.scriptObjectValues_=[];this.brushingStateController.addEventListener('model-changed',this.onModelChanged_.bind(this));const typeInfos=ScriptingObjectRegistry.getAllRegisteredTypeInfos();typeInfos.forEach(function(typeInfo){this.addScriptObject(typeInfo.metadata.name,typeInfo.constructor);global[typeInfo.metadata.name]=typeInfo.constructor;},this);}
 function ScriptingObjectRegistry(){}
-var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(ScriptingObjectRegistry,options);ScriptingController.prototype={get brushingStateController(){return this.brushingStateController_;},onModelChanged_:function(){this.scriptObjectValues_.forEach(function(v){if(v.onModelChanged)
-v.onModelChanged(this.brushingStateController.model);},this);},addScriptObject:function(name,value){this.scriptObjectNames_.push(name);this.scriptObjectValues_.push(value);},executeCommand:function(command){var f=new Function(this.scriptObjectNames_,'return eval('+command+')');return f.apply(null,this.scriptObjectValues_);}};return{ScriptingController:ScriptingController,ScriptingObjectRegistry:ScriptingObjectRegistry};});'use strict';tr.exportTo('tr.metrics',function(){function MetricRegistry(){}
-var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Function;tr.b.decorateExtensionRegistry(MetricRegistry,options);return{MetricRegistry:MetricRegistry};});'use strict';tr.exportTo('tr.v',function(){function Value(canonicalUrl,name,opt_options,opt_groupingKeys,opt_diagnostics){if(typeof(name)!=='string')
-throw new Error('Expected value_name grouping key to be provided');this.groupingKeys=opt_groupingKeys||{};this.groupingKeys.name=name;this.diagnostics=opt_diagnostics||{};this.diagnostics.canonical_url=canonicalUrl;var options=opt_options||{};this.description=options.description;this.important=options.important!==undefined?options.important:false;}
-Value.fromDict=function(d){if(d.type==='numeric')
-return NumericValue.fromDict(d);if(d.type==='dict')
-return DictValue.fromDict(d);if(d.type=='failure')
-return FailureValue.fromDict(d);if(d.type==='skip')
-return SkipValue.fromDict(d);throw new Error('Not implemented');};Value.prototype={get name(){return this.groupingKeys.name;},get canonicalUrl(){return this.diagnostics.canonical_url;},addGroupingKey:function(keyName,key){if(this.groupingKeys.hasOwnProperty(keyName))
-throw new Error('Tried to redefine grouping key '+keyName);this.groupingKeys[keyName]=key;},asDict:function(){return this.asJSON();},asJSON:function(){var d={grouping_keys:this.groupingKeys,description:this.description,important:this.important,diagnostics:this.diagnostics};this._asDictInto(d);if(d.type===undefined)
-throw new Error('_asDictInto must set type field');return d;},_asDictInto:function(d){throw new Error('Not implemented');}};function NumericValue(canonicalUrl,name,numeric,opt_options,opt_groupingKeys,opt_diagnostics){if(!(numeric instanceof tr.v.NumericBase))
-throw new Error('Expected numeric to be instance of tr.v.NumericBase');Value.call(this,canonicalUrl,name,opt_options,opt_groupingKeys,opt_diagnostics);this.numeric=numeric;}
-NumericValue.fromDict=function(d){if(d.numeric===undefined)
-throw new Error('Expected numeric to be provided');var numeric=tr.v.NumericBase.fromDict(d.numeric);return new NumericValue(d.diagnostics.canonical_url,d.grouping_keys.name,numeric,d,d.grouping_keys,d.diagnostics);};NumericValue.prototype={__proto__:Value.prototype,_asDictInto:function(d){d.type='numeric';d.numeric=this.numeric.asDict();}};function DictValue(canonicalUrl,name,value,opt_options,opt_groupingKeys,opt_diagnostics){Value.call(this,canonicalUrl,name,opt_options,opt_groupingKeys,opt_diagnostics);this.value=value;}
-DictValue.fromDict=function(d){if(d.units!==undefined)
-throw new Error('Expected units to be undefined');if(d.value===undefined)
-throw new Error('Expected value to be provided');return new DictValue(d.diagnostics.canonical_url,d.grouping_keys.name,d.value,d,d.groupingKeys,d.diagnostics);};DictValue.prototype={__proto__:Value.prototype,_asDictInto:function(d){d.type='dict';d.value=this.value;}};function FailureValue(canonicalUrl,name,opt_options,opt_groupingKeys,opt_diagnostics){var options=opt_options||{};var stack;if(options.stack===undefined){if(options.stack_str===undefined){throw new Error('Expected stack_str or stack to be provided');}else{stack=options.stack_str;}}else{stack=options.stack;}
-if(typeof stack!=='string')
-throw new Error('stack must be provided as a string');if(canonicalUrl===undefined){throw new Error('FailureValue must provide canonicalUrl');}
-Value.call(this,canonicalUrl,name,options,opt_groupingKeys,opt_diagnostics);this.stack=stack;}
-FailureValue.fromError=function(canonicalUrl,e){var ex=tr.b.normalizeException(e);return new FailureValue(canonicalUrl,ex.typeName,{description:ex.message,stack:ex.stack});};FailureValue.fromDict=function(d){if(d.units!==undefined)
-throw new Error('Expected units to be undefined');if(d.stack_str===undefined)
-throw new Error('Expected stack_str to be provided');return new FailureValue(d.diagnostics.canonical_url,d.grouping_keys.name,d,d.grouping_keys,d.diagnostics);};FailureValue.prototype={__proto__:Value.prototype,_asDictInto:function(d){d.type='failure';d.stack_str=this.stack;}};function SkipValue(canonicalUrl,name,opt_options,opt_groupingKeys,opt_diagnostics){Value.call(this,canonicalUrl,name,opt_options,opt_groupingKeys,opt_diagnostics);}
-SkipValue.fromDict=function(d){if(d.units!==undefined)
-throw new Error('Expected units to be undefined');return new SkipValue(d.diagnostics.canonical_url,d.grouping_keys.name,d,d.grouping_keys,d.diagnostics);};SkipValue.prototype={__proto__:Value.prototype,_asDictInto:function(d){d.type='skip';}};return{Value:Value,NumericValue:NumericValue,DictValue:DictValue,FailureValue:FailureValue,SkipValue:SkipValue};});'use strict';tr.exportTo('tr.metrics',function(){function sampleMetric(valueList,model){var unit=tr.v.Unit.byName.sizeInBytes_smallerIsBetter;var n1=new tr.v.ScalarNumeric(unit,1);var n2=new tr.v.ScalarNumeric(unit,2);valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'foo',n1));valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'bar',n2));}
-sampleMetric.prototype={__proto__:Function.prototype};tr.metrics.MetricRegistry.register(sampleMetric);return{sampleMetric:sampleMetric};});'use strict';tr.exportTo('tr.metrics.sh',function(){function perceptualBlend(ir,index,score){return Math.exp(1-score);}
-function filterExpectationsByRange(irs,opt_range){var filteredExpectations=[];irs.forEach(function(ir){if(!(ir instanceof tr.model.um.UserExpectation))
-return;if(!opt_range||opt_range.intersectsExplicitRangeExclusive(ir.start,ir.end))
-filteredExpectations.push(ir);});return filteredExpectations;}
-return{perceptualBlend:perceptualBlend,filterExpectationsByRange:filterExpectationsByRange};});'use strict';tr.exportTo('tr.metrics.sh',function(){var UNIT=tr.v.Unit.byName.normalizedPercentage_biggerIsBetter;var DESCRIPTION='Normalized CPU budget consumption';function EfficiencyMetric(valueList,model){var scores=[];model.userModel.expectations.forEach(function(ue){var options={};options.description=DESCRIPTION;var groupingKeys={};groupingKeys.userExpectationStableId=ue.stableId;groupingKeys.userExpectationStageTitle=ue.stageTitle;groupingKeys.userExpectationInitiatorTitle=ue.initiatorTitle;var score=undefined;if((ue.totalCpuMs===undefined)||(ue.totalCpuMs==0))
-return;var cpuFractionBudget=tr.b.Range.fromExplicitRange(0.5,1.5);if(ue instanceof tr.model.um.IdleExpectation){cpuFractionBudget=tr.b.Range.fromExplicitRange(0.1,1);}else if(ue instanceof tr.model.um.AnimationExpectation){cpuFractionBudget=tr.b.Range.fromExplicitRange(1,2);}
-var cpuMsBudget=tr.b.Range.fromExplicitRange(ue.duration*cpuFractionBudget.min,ue.duration*cpuFractionBudget.max);var normalizedCpu=tr.b.normalize(ue.totalCpuMs,cpuMsBudget.min,cpuMsBudget.max);score=1-tr.b.clamp(normalizedCpu,0,1);scores.push(score);valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'efficiency',new tr.v.ScalarNumeric(UNIT,score),options,groupingKeys));});var options={};options.description=DESCRIPTION;var groupingKeys={};var overallScore=tr.b.Statistics.weightedMean(scores,tr.metrics.sh.perceptualBlend);if(overallScore===undefined)
-return;valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'efficiency',new tr.v.ScalarNumeric(UNIT,overallScore),options,groupingKeys));}
-EfficiencyMetric.prototype={__proto__:Function.prototype};tr.metrics.MetricRegistry.register(EfficiencyMetric);return{EfficiencyMetric:EfficiencyMetric};});'use strict';tr.exportTo('tr.metrics.sh',function(){var MIN_DISCREPANCY=0.05;var MAX_DISCREPANCY=0.3;var UNIT=tr.v.Unit.byName.normalizedPercentage_biggerIsBetter;var DESCRIPTION='Mean Opinion Score for Animation smoothness';function AnimationSmoothnessMetric(valueList,model){model.userModel.expectations.forEach(function(ue){if(!(ue instanceof tr.model.um.AnimationExpectation))
-return;if(ue.frameEvents===undefined||ue.frameEvents.length===0)
-throw new Error('Animation missing frameEvents '+ue.stableId);var options={};options.description=DESCRIPTION;var groupingKeys={};groupingKeys.userExpectationStableId=ue.stableId;groupingKeys.userExpectationStageTitle=ue.stageTitle;groupingKeys.userExpectationInitiatorTitle=ue.initiatorTitle;var frameTimestamps=ue.frameEvents.toArray().map(function(event){return event.start;});var absolute=false;var discrepancy=tr.b.Statistics.timestampsDiscrepancy(frameTimestamps,absolute);var smoothness=1-tr.b.normalize(discrepancy,MIN_DISCREPANCY,MAX_DISCREPANCY);var score=tr.b.clamp(smoothness,0,1);valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'smoothness',new tr.v.ScalarNumeric(UNIT,score),options,groupingKeys));});}
-AnimationSmoothnessMetric.prototype={__proto__:Function.prototype};tr.metrics.MetricRegistry.register(AnimationSmoothnessMetric);return{AnimationSmoothnessMetric:AnimationSmoothnessMetric};});'use strict';tr.exportTo('tr.metrics.sh',function(){var MAX_FPS=60;var MIN_FPS=10;var UNIT=tr.v.Unit.byName.normalizedPercentage_biggerIsBetter;var DESCRIPTION='Mean Opinion Score for Animation throughput';function AnimationThroughputMetric(valueList,model){model.userModel.expectations.forEach(function(ue){if(!(ue instanceof tr.model.um.AnimationExpectation))
-return;if(ue.frameEvents===undefined||ue.frameEvents.length===0)
-throw new Error('Animation missing frameEvents '+ue.stableId);var options={};options.description=DESCRIPTION;var groupingKeys={};groupingKeys.userExpectationStableId=ue.stableId;groupingKeys.userExpectationStageTitle=ue.stageTitle;groupingKeys.userExpectationInitiatorTitle=ue.initiatorTitle;var durationSeconds=ue.duration/1000;var avgSpf=durationSeconds/ue.frameEvents.length;var throughput=1-tr.b.normalize(avgSpf,1/MAX_FPS,1/MIN_FPS);var score=tr.b.clamp(throughput,0,1);valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'throughput',new tr.v.ScalarNumeric(UNIT,score),options,groupingKeys));});}
-AnimationThroughputMetric.prototype={__proto__:Function.prototype};tr.metrics.MetricRegistry.register(AnimationThroughputMetric);return{AnimationThroughputMetric:AnimationThroughputMetric};});'use strict';tr.exportTo('tr.metrics.sh',function(){var RESPONSE_HISTOGRAM=tr.v.Numeric.fromDict({unit:'unitless',min:150,max:5000,centralBinWidth:485,underflowBin:{min:-Number.MAX_VALUE,max:150,count:1000},centralBins:[{min:150,max:635,count:708},{min:635,max:1120,count:223},{min:1120,max:1605,count:50},{min:1605,max:2090,count:33},{min:2090,max:2575,count:23},{min:2575,max:3060,count:17},{min:3060,max:3545,count:12},{min:3545,max:4030,count:8},{min:4030,max:4515,count:4},{min:4515,max:5000,count:1}],overflowBin:{min:5000,max:Number.MAX_VALUE,count:0}});var FAST_RESPONSE_HISTOGRAM=tr.v.Numeric.fromDict({unit:'unitless',min:66,max:2200,centralBinWidth:214,underflowBin:{min:-Number.MAX_VALUE,max:66,count:1000},centralBins:[{min:66,max:280,count:708},{min:280,max:493,count:223},{min:493,max:706,count:50},{min:706,max:920,count:33},{min:920,max:1133,count:23},{min:1133,max:1346,count:17},{min:1346,max:1560,count:12},{min:1560,max:1773,count:8},{min:1773,max:1987,count:4},{min:1987,max:2200,count:1}],overflowBin:{min:2200,max:Number.MAX_VALUE,count:0}});var LOAD_HISTOGRAM=tr.v.Numeric.fromDict({unit:'unitless',min:1000,max:60000,centralBinWidth:5900,underflowBin:{min:-Number.MAX_VALUE,max:1000,count:1000},centralBins:[{min:1000,max:6900,count:901},{min:6900,max:12800,count:574},{min:12800,max:18700,count:298},{min:18700,max:24600,count:65},{min:24600,max:30500,count:35},{min:30500,max:36400,count:23},{min:36400,max:42300,count:16},{min:42300,max:48200,count:10},{min:48200,max:54100,count:5},{min:54100,max:60000,count:2}],overflowBin:{min:60000,max:Number.MAX_VALUE,count:0}});var UNIT=tr.v.Unit.byName.normalizedPercentage_biggerIsBetter;var DESCRIPTION=('For Load and Response, Mean Opinion Score of completion time; '+'For Animation, perceptual blend of Mean Opinion Scores of '+'throughput and smoothness');function getDurationScore(histogram,duration){return histogram.getInterpolatedCountAt(duration)/histogram.maxCount;}
-function ResponsivenessMetric(valueList,model){tr.metrics.sh.AnimationThroughputMetric(valueList,model);tr.metrics.sh.AnimationSmoothnessMetric(valueList,model);var throughputForAnimation={};var smoothnessForAnimation={};valueList.valueDicts.forEach(function(value){if((value.type!=='numeric')||(value.numeric.type!=='scalar'))
-return;var ue=value.grouping_keys.userExpectationStableId;if(value.grouping_keys.name==='throughput')
-throughputForAnimation[ue]=value.numeric.value;if(value.grouping_keys.name==='smoothness')
-smoothnessForAnimation[ue]=value.numeric.value;});var scores=[];model.userModel.expectations.forEach(function(ue){var score=undefined;if(ue instanceof tr.model.um.IdleExpectation){return;}else if(ue instanceof tr.model.um.LoadExpectation){score=getDurationScore(LOAD_HISTOGRAM,ue.duration);}else if(ue instanceof tr.model.um.ResponseExpectation){var histogram=RESPONSE_HISTOGRAM;if(ue.isAnimationBegin)
-histogram=FAST_RESPONSE_HISTOGRAM;score=getDurationScore(histogram,ue.duration);}else if(ue instanceof tr.model.um.AnimationExpectation){var throughput=throughputForAnimation[ue.stableId];var smoothness=smoothnessForAnimation[ue.stableId];if(throughput===undefined)
-throw new Error('Missing throughput for '+ue.stableId);if(smoothness===undefined)
-throw new Error('Missing smoothness for '+ue.stableId);score=tr.b.Statistics.weightedMean([throughput,smoothness],tr.metrics.sh.perceptualBlend);}else{throw new Error('Unrecognized stage for '+ue.stableId);}
-if(score===undefined)
-throw new Error('Failed to compute responsiveness for '+ue.stableId);scores.push(score);var options={};options.description=DESCRIPTION;var groupingKeys={};groupingKeys.userExpectationStableId=ue.stableId;groupingKeys.userExpectationStageTitle=ue.stageTitle;groupingKeys.userExpectationInitiatorTitle=ue.initiatorTitle;valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'responsiveness',new tr.v.ScalarNumeric(UNIT,score),options,groupingKeys));});var options={};options.description=DESCRIPTION;var groupingKeys={};var overallScore=tr.b.Statistics.weightedMean(scores,tr.metrics.sh.perceptualBlend);if(overallScore===undefined)
-return;valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'responsiveness',new tr.v.ScalarNumeric(UNIT,overallScore),options,groupingKeys));}
-ResponsivenessMetric.prototype={__proto__:Function.prototype};tr.metrics.MetricRegistry.register(ResponsivenessMetric);return{ResponsivenessMetric:ResponsivenessMetric};});'use strict';tr.exportTo('tr.metrics.sh',function(){function SystemHealthMetrics(valueList,model){tr.metrics.sh.ResponsivenessMetric(valueList,model);tr.metrics.sh.EfficiencyMetric(valueList,model);}
-SystemHealthMetrics.prototype={__proto__:Function.prototype};tr.metrics.MetricRegistry.register(SystemHealthMetrics);return{SystemHealthMetrics:SystemHealthMetrics};});'use strict';tr.exportTo('tr.metrics',function(){function tracingMetric(valueList,model){if(!model.stats.hasEventSizesinBytes){throw new Error('Model stats does not have event size information. '+'Please enable ImportOptions.trackDetailedModelStats.');}
-var eventStats=model.stats.allTraceEventStatsInTimeIntervals;eventStats.sort(function(a,b){return a.timeInterval-b.timeInterval;});var maxEventCountPerSec=0;var maxEventBytesPerSec=0;var totalTraceBytes=0;var WINDOW_SIZE=Math.floor(1000/model.stats.TIME_INTERVAL_SIZE_IN_MS);var runningEventNumPerSec=0;var runningEventBytesPerSec=0;var start=0;var end=0;while(end<eventStats.length){var startEventStats=eventStats[start];var endEventStats=eventStats[end];var timeWindow=endEventStats.timeInterval-startEventStats.timeInterval;if(timeWindow>=WINDOW_SIZE){runningEventNumPerSec-=startEventStats.numEvents;runningEventBytesPerSec-=startEventStats.totalEventSizeinBytes;start++;continue;}
-runningEventNumPerSec+=endEventStats.numEvents;if(maxEventCountPerSec<runningEventNumPerSec)
-maxEventCountPerSec=runningEventNumPerSec;runningEventBytesPerSec+=endEventStats.totalEventSizeinBytes;if(maxEventBytesPerSec<runningEventBytesPerSec)
-maxEventBytesPerSec=runningEventBytesPerSec;totalTraceBytes+=endEventStats.totalEventSizeinBytes;end++;}
-var stats=model.stats.allTraceEventStats;var categoryStatsMap=new Map();var categoryStats=[];for(var i=0;i<stats.length;i++){var categoryStat=categoryStatsMap.get(stats[i].category);if(categoryStat===undefined){categoryStat={category:stats[i].category,totalEventSizeinBytes:0};categoryStatsMap.set(stats[i].category,categoryStat);categoryStats.push(categoryStat);}
-categoryStat.totalEventSizeinBytes+=stats[i].totalEventSizeinBytes;}
-var maxCategoryStats=categoryStats.reduce(function(a,b){return a.totalEventSizeinBytes<b.totalEventSizeinBytes?b:a;});var maxEventBytesPerCategory=maxCategoryStats.totalEventSizeinBytes;var maxCategoryName=maxCategoryStats.category;var maxEventCountPerSecValue=new tr.v.ScalarNumeric(tr.v.Unit.byName.unitlessNumber_smallerIsBetter,maxEventCountPerSec);var maxEventBytesPerSecValue=new tr.v.ScalarNumeric(tr.v.Unit.byName.sizeInBytes_smallerIsBetter,maxEventBytesPerSec);var totalTraceBytesValue=new tr.v.ScalarNumeric(tr.v.Unit.byName.sizeInBytes_smallerIsBetter,totalTraceBytes);var diagnostics={category_with_max_event_size:{name:maxCategoryName,size_in_bytes:maxEventBytesPerCategory}};valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'Total trace size in bytes',totalTraceBytesValue,undefined,undefined,diagnostics));valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'Max number of events per second',maxEventCountPerSecValue,undefined,undefined,diagnostics));valueList.addValue(new tr.v.NumericValue(model.canonicalUrl,'Max event size in bytes per second',maxEventBytesPerSecValue,undefined,undefined,diagnostics));}
-tracingMetric.prototype={__proto__:Function.prototype};tr.metrics.MetricRegistry.register(tracingMetric);return{tracingMetric:tracingMetric};});'use strict';Polymer('tr-ui-a-alert-sub-view',{ready:function(){this.currentSelection_=undefined;this.$.table.tableColumns=[{title:'Label',value:function(row){return row.name;},width:'150px'},{title:'Value',width:'100%',value:function(row){return row.value;}}];this.$.table.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},getRowsForSingleAlert_:function(alert){var rows=[];for(var argName in alert.args){var argView=document.createElement('tr-ui-a-generic-object-view');argView.object=alert.args[argName];rows.push({name:argName,value:argView});}
-if(alert.associatedEvents.length){alert.associatedEvents.forEach(function(event,i){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return event;},event.title);var valueString='';if(event instanceof tr.model.TimedEvent)
-valueString='took '+event.duration.toFixed(2)+'ms';rows.push({name:linkEl,value:valueString});});}
-var descriptionEl=tr.ui.b.createDiv({textContent:alert.info.description,maxWidth:'300px'});rows.push({name:'Description',value:descriptionEl});if(alert.info.docLinks){alert.info.docLinks.forEach(function(linkObject){var linkEl=document.createElement('a');linkEl.target='_blank';linkEl.href=linkObject.href;linkEl.textContent=linkObject.textContent;rows.push({name:linkObject.label,value:linkEl});});}
-return rows;},getRowsForAlerts_:function(alerts){if(alerts.length==1){var rows=[{name:'Alert',value:alerts[0].title}];var detailRows=this.getRowsForSingleAlert_(alerts[0]);rows.push.apply(rows,detailRows);return rows;}else{return alerts.map(function(alert){return{name:'Alert',value:alert.title,isExpanded:alerts.size<10,subRows:this.getRowsForSingleAlert_(alert)};},this);}},updateContents_:function(){if(this.currentSelection_===undefined){this.$.table.rows=[];this.$.table.rebuild();return;}
-var alerts=this.currentSelection_;this.$.table.tableRows=this.getRowsForAlerts_(alerts);this.$.table.rebuild();},get relatedEventsToHighlight(){if(!this.currentSelection_)
-return undefined;return this.currentSelection_[0].associatedEvents;}});'use strict';tr.exportTo('tr.b',function(){function MultiDimensionalViewNode(title,isLowerBound){this.title=title;var dimensions=title.length;this.children=new Array(dimensions);for(var i=0;i<dimensions;i++)
-this.children[i]=new Map();this.total=0;this.self=0;this.isLowerBound=!!isLowerBound;}
-MultiDimensionalViewNode.prototype={get subRows(){return tr.b.mapValues(this.children[0]);}};var MultiDimensionalViewType={TOP_DOWN_TREE_VIEW:0,TOP_DOWN_HEAVY_VIEW:1,BOTTOM_UP_HEAVY_VIEW:2};function MultiDimensionalViewBuilder(dimensions){if(dimensions<0)
-throw new Error('Dimensions must be non-negative');this.dimensions_=dimensions;this.buildRoot_=this.createRootNode_();this.topDownTreeViewRoot_=undefined;this.topDownHeavyViewRoot_=undefined;this.bottomUpHeavyViewNode_=undefined;this.maxDimensionDepths_=new Array(dimensions);for(var d=0;d<dimensions;d++)
-this.maxDimensionDepths_[d]=0;}
-MultiDimensionalViewBuilder.ValueKind={SELF:0,TOTAL:1};MultiDimensionalViewBuilder.prototype={addPath:function(path,value,valueKind){if(this.buildRoot_===undefined){throw new Error('Paths cannot be added after either view has been built');}
-if(path.length!==this.dimensions_)
-throw new Error('Path must be '+this.dimensions_+'-dimensional');var node=this.buildRoot_;for(var d=0;d<path.length;d++){var singleDimensionPath=path[d];var singleDimensionPathLength=singleDimensionPath.length;this.maxDimensionDepths_[d]=Math.max(this.maxDimensionDepths_[d],singleDimensionPathLength);for(var i=0;i<singleDimensionPathLength;i++)
-node=this.getOrCreateChildNode_(node,d,singleDimensionPath[i]);}
-switch(valueKind){case MultiDimensionalViewBuilder.ValueKind.SELF:node.self+=value;break;case MultiDimensionalViewBuilder.ValueKind.TOTAL:node.total+=value;break;default:throw new Error('Invalid value kind: '+valueKind);}
-node.isLowerBound=false;},buildView:function(viewType){switch(viewType){case MultiDimensionalViewType.TOP_DOWN_TREE_VIEW:return this.buildTopDownTreeView();case MultiDimensionalViewType.TOP_DOWN_HEAVY_VIEW:return this.buildTopDownHeavyView();case MultiDimensionalViewType.BOTTOM_UP_HEAVY_VIEW:return this.buildBottomUpHeavyView();default:throw new Error('Unknown multi-dimensional view type: '+viewType);}},buildTopDownTreeView:function(){if(this.topDownTreeViewRoot_===undefined){var treeViewRoot=this.buildRoot_;this.buildRoot_=undefined;this.setUpMissingChildRelationships_(treeViewRoot,0);this.finalizeTotalValues_(treeViewRoot,0,new WeakMap());this.topDownTreeViewRoot_=treeViewRoot;}
-return this.topDownTreeViewRoot_;},buildTopDownHeavyView:function(){if(this.topDownHeavyViewRoot_===undefined){this.topDownHeavyViewRoot_=this.buildGenericHeavyView_(this.addDimensionToTopDownHeavyViewNode_.bind(this));}
-return this.topDownHeavyViewRoot_;},buildBottomUpHeavyView:function(){if(this.bottomUpHeavyViewNode_===undefined){this.bottomUpHeavyViewNode_=this.buildGenericHeavyView_(this.addDimensionToBottomUpHeavyViewNode_.bind(this));}
-return this.bottomUpHeavyViewNode_;},createRootNode_:function(){return new MultiDimensionalViewNode(new Array(this.dimensions_),true);},getOrCreateChildNode_:function(parentNode,dimension,childDimensionTitle){if(dimension<0||dimension>=this.dimensions_)
-throw new Error('Invalid dimension');var dimensionChildren=parentNode.children[dimension];var childNode=dimensionChildren.get(childDimensionTitle);if(childNode!==undefined)
-return childNode;var childTitle=parentNode.title.slice();childTitle[dimension]=childDimensionTitle;childNode=new MultiDimensionalViewNode(childTitle,true);dimensionChildren.set(childDimensionTitle,childNode);return childNode;},setUpMissingChildRelationships_:function(node,firstDimensionToSetUp){for(var d=firstDimensionToSetUp;d<this.dimensions_;d++){var currentDimensionChildTitles=new Set(node.children[d].keys());for(var i=0;i<d;i++){for(var previousDimensionChildNode of node.children[i].values()){for(var previousDimensionGrandChildTitle of
+const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(ScriptingObjectRegistry,options);ScriptingController.prototype={get brushingStateController(){return this.brushingStateController_;},onModelChanged_(){this.scriptObjectValues_.forEach(function(v){if(v.onModelChanged){v.onModelChanged(this.brushingStateController.model);}},this);},addScriptObject(name,value){this.scriptObjectNames_.push(name);this.scriptObjectValues_.push(value);},executeCommand(command){const f=new Function(this.scriptObjectNames_,'return eval('+command+')');return f.apply(null,this.scriptObjectValues_);}};return{ScriptingController,ScriptingObjectRegistry,};});'use strict';tr.exportTo('tr.metrics',function(){function MetricRegistry(){}
+const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};tr.b.decorateExtensionRegistry(MetricRegistry,options);function camelCaseToHackerString(camelCase){let hackerString='';for(const c of camelCase){const lowered=c.toLocaleLowerCase();if(lowered===c){hackerString+=c;}else{hackerString+='_'+lowered;}}
+return hackerString;}
+function getCallStack(){try{throw new Error();}catch(error){return error.stack;}}
+function getPathsFromStack(stack){return stack.split('\n').map(line=>{line=line.replace(/^ */,'').split(':');if(line.length<4)return'';return line[line.length-3].split('/');}).filter(x=>x);}
+MetricRegistry.checkFilename=function(metricName,opt_metricPathForTest){if(metricName==='runtimeStatsTotalMetric'||metricName==='v8AndMemoryMetrics'){return;}
+const expectedFilename=camelCaseToHackerString(metricName)+'.html';const stack=getCallStack();let metricPath=opt_metricPathForTest;if(metricPath===undefined){const paths=getPathsFromStack(stack);const METRIC_STACK_INDEX=5;if(paths.length<=METRIC_STACK_INDEX||paths[METRIC_STACK_INDEX].join('/')===paths[0].join('/')){return;}
+metricPath=paths[METRIC_STACK_INDEX].slice(paths[METRIC_STACK_INDEX].length-2);}
+if(!metricPath[1].endsWith('_test.html')&&!metricPath[1].endsWith('_test.html.js')&&metricPath[1]!==expectedFilename&&metricPath[1]!==expectedFilename+'.js'&&metricPath.join('_')!==expectedFilename&&metricPath.join('_')!==expectedFilename+'.js'){throw new Error('Expected '+metricName+' to be in a file named '+
+expectedFilename+'; actual: '+metricPath.join('/')+'; stack: '+stack.replace(/\n/g,'\n  '));}};MetricRegistry.addEventListener('will-register',function(e){const metric=e.typeInfo.constructor;if(!(metric instanceof Function)){throw new Error('Metrics must be functions.');}
+if(!metric.name.endsWith('Metric')&&!metric.name.endsWith('Metrics')){throw new Error('Metric names must end with "Metric" or "Metrics".');}
+if(metric.length<2){throw new Error('Metrics take a HistogramSet and a Model and '+'optionally an options dictionary.');}
+MetricRegistry.checkFilename(metric.name);});return{MetricRegistry,};});'use strict';tr.exportTo('tr.metrics',function(){function accessibilityMetric(histograms,model){const browserAccessibilityEventsHist=new tr.v.Histogram('browser_accessibility_events',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);browserAccessibilityEventsHist.description='Browser accessibility events time';const renderAccessibilityEventsHist=new tr.v.Histogram('render_accessibility_events',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);renderAccessibilityEventsHist.description='Render accessibility events time';const renderAccessibilityLocationsHist=new tr.v.Histogram('render_accessibility_locations',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);renderAccessibilityLocationsHist.description='Render accessibility locations time';const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(chromeHelper===undefined)return;for(const rendererHelper of Object.values(chromeHelper.rendererHelpers)){const mainThread=rendererHelper.mainThread;if(mainThread===undefined)continue;for(const slice of mainThread.getDescendantEvents()){if(!(slice instanceof tr.model.ThreadSlice))continue;if(slice.title==='RenderAccessibilityImpl::SendPendingAccessibilityEvents'){renderAccessibilityEventsHist.addSample(slice.duration,{event:new tr.v.d.RelatedEventSet(slice)});}
+if(slice.title==='RenderAccessibilityImpl::SendLocationChanges'){renderAccessibilityLocationsHist.addSample(slice.duration,{event:new tr.v.d.RelatedEventSet(slice)});}}}
+for(const browserHelper of Object.values(chromeHelper.browserHelpers)){const mainThread=browserHelper.mainThread;if(mainThread===undefined)continue;for(const slice of mainThread.getDescendantEvents()){if(slice.title==='BrowserAccessibilityManager::OnAccessibilityEvents'){browserAccessibilityEventsHist.addSample(slice.duration,{event:new tr.v.d.RelatedEventSet(slice)});}}}
+histograms.addHistogram(browserAccessibilityEventsHist);histograms.addHistogram(renderAccessibilityEventsHist);histograms.addHistogram(renderAccessibilityLocationsHist);}
+tr.metrics.MetricRegistry.register(accessibilityMetric);return{accessibilityMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const MESSAGE_LOOP_EVENT_NAME='Startup.BrowserMessageLoopStartTimeFromMainEntry3';const CONTENT_START_EVENT_NAME='content::Start';const NAVIGATION_EVENT_NAME='Navigation StartToCommit';const FIRST_CONTENTFUL_PAINT_EVENT_NAME='firstContentfulPaint';function androidStartupMetric(histograms,model){let messageLoopStartEvents=[];let navigationEvents=[];const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(!chromeHelper)return;for(const helper of chromeHelper.browserHelpers){for(const ev of helper.mainThread.asyncSliceGroup.childEvents()){if(ev.title===MESSAGE_LOOP_EVENT_NAME){messageLoopStartEvents.push(ev);}else if(ev.title===NAVIGATION_EVENT_NAME){navigationEvents.push(ev);}}}
+let contentStartEvents=[];let firstContentfulPaintEvents=[];const rendererHelpers=chromeHelper.rendererHelpers;const pids=Object.keys(rendererHelpers);for(const rendererHelper of Object.values(chromeHelper.rendererHelpers)){if(!rendererHelper.mainThread)continue;for(const ev of rendererHelper.mainThread.sliceGroup.childEvents()){if(ev.title===FIRST_CONTENTFUL_PAINT_EVENT_NAME){firstContentfulPaintEvents.push(ev);break;}else if(ev.title===CONTENT_START_EVENT_NAME){contentStartEvents.push(ev);}}}
+let totalBrowserStarts=messageLoopStartEvents.length;let totalContentStartEvents=contentStartEvents.length;let totalFcpEvents=firstContentfulPaintEvents.length;let totalNavigations=navigationEvents.length;if(totalFcpEvents!==totalBrowserStarts||totalNavigations!==totalBrowserStarts||totalContentStartEvents!==totalBrowserStarts||totalBrowserStarts===0){messageLoopStartEvents=[];contentStartEvents=[];navigationEvents=[];firstContentfulPaintEvents=[];for(const proc of Object.values(model.processes)){for(const ev of proc.getDescendantEvents()){if(ev.title===MESSAGE_LOOP_EVENT_NAME){messageLoopStartEvents.push(ev);}else if(ev.title===NAVIGATION_EVENT_NAME){navigationEvents.push(ev);}else if(ev.title===CONTENT_START_EVENT_NAME){contentStartEvents.push(ev);}}
+for(const ev of proc.getDescendantEvents()){if(ev.title===FIRST_CONTENTFUL_PAINT_EVENT_NAME){firstContentfulPaintEvents.push(ev);break;}}}
+totalBrowserStarts=messageLoopStartEvents.length;totalContentStartEvents=contentStartEvents.length;totalNavigations=navigationEvents.length;totalFcpEvents=firstContentfulPaintEvents.length;}
+function orderEvents(event1,event2){return event1.start-event2.start;}
+messageLoopStartEvents.sort(orderEvents);contentStartEvents.sort(orderEvents);navigationEvents.sort(orderEvents);firstContentfulPaintEvents.sort(orderEvents);if(totalFcpEvents<totalBrowserStarts){throw new Error('Found fewer FCP events ('+totalFcpEvents+') than browser starts ('+totalBrowserStarts+')');}
+const messageLoopStartHistogram=histograms.createHistogram('messageloop_start_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[]);const contentStartHistogram=histograms.createHistogram('experimental_content_start_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[]);const navigationStartHistogram=histograms.createHistogram('experimental_navigation_start_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[]);const navigationCommitHistogram=histograms.createHistogram('navigation_commit_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[]);const firstContentfulPaintHistogram=histograms.createHistogram('first_contentful_paint_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[]);let contentIndex=0;let navIndex=0;let fcpIndex=0;for(let loopStartIndex=0;loopStartIndex<totalBrowserStarts;){const startEvent=messageLoopStartEvents[loopStartIndex];if(fcpIndex===totalFcpEvents){break;}
+const contentStartEvent=contentIndex<contentStartEvents.length?contentStartEvents[contentIndex]:null;if(contentStartEvent&&contentStartEvent.start<startEvent.start){contentIndex++;continue;}
+const navEvent=navIndex<navigationEvents.length?navigationEvents[navIndex]:null;if(navEvent&&navEvent.start<startEvent.start){navIndex++;continue;}
+const fcpEvent=firstContentfulPaintEvents[fcpIndex];if(fcpEvent.start<startEvent.start){fcpIndex++;continue;}
+loopStartIndex++;if(fcpIndex<2){continue;}
+messageLoopStartHistogram.addSample(startEvent.duration,{events:new tr.v.d.RelatedEventSet([startEvent])});if(contentStartEvent){contentStartHistogram.addSample(contentStartEvent.start-startEvent.start,{events:new tr.v.d.RelatedEventSet([startEvent,contentStartEvent])});}
+if(navEvent){navigationStartHistogram.addSample(navEvent.start-startEvent.start,{events:new tr.v.d.RelatedEventSet([startEvent,navEvent])});navigationCommitHistogram.addSample(navEvent.end-startEvent.start,{events:new tr.v.d.RelatedEventSet([startEvent,navEvent])});}
+firstContentfulPaintHistogram.addSample(fcpEvent.end-startEvent.start,{events:new tr.v.d.RelatedEventSet([startEvent,fcpEvent])});}}
+tr.metrics.MetricRegistry.register(androidStartupMetric);return{androidStartupMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const MAX_INPUT_EVENT_TO_STARTUP_DELAY_IN_MS=2000;const MIN_DRAW_DELAY_IN_MS=80;const MAX_DRAW_DELAY_IN_MS=2000;function findProcess(processName,model){for(const pid in model.processes){const process=model.processes[pid];if(process.name===processName){return process;}}
+return undefined;}
+function findThreads(process,threadPrefix){if(process===undefined)return undefined;const threads=[];for(const tid in process.threads){const thread=process.threads[tid];if(thread.name.startsWith(threadPrefix)){threads.push(thread);}}
+return threads;}
+function findUIThread(process){if(process===undefined)return undefined;const threads=findThreads(process,'UI Thread');if(threads!==undefined&&threads.length===1){return threads[0];}
+return process.threads[process.pid];}
+function findLaunchSlices(model){const launches=[];const binders=findThreads(findProcess('system_server',model),'Binder');for(const binderId in binders){const binder=binders[binderId];for(const sliceId in binder.asyncSliceGroup.slices){const slice=binder.asyncSliceGroup.slices[sliceId];if(slice.title.startsWith('launching:')){launches.push(slice);}}}
+return launches;}
+function findDrawSlice(appName,startNotBefore,model){let drawSlice=undefined;const thread=findUIThread(findProcess(appName,model));if(thread===undefined)return undefined;for(const sliceId in thread.sliceGroup.slices){const slice=thread.sliceGroup.slices[sliceId];if(slice.start<startNotBefore+MIN_DRAW_DELAY_IN_MS||slice.start>startNotBefore+MAX_DRAW_DELAY_IN_MS)continue;if(slice.title!=='draw')continue;if(drawSlice===undefined||slice.start<drawSlice.start){drawSlice=slice;}}
+return drawSlice;}
+function findInputEventSlice(endNotAfter,model){const endNotBefore=endNotAfter-MAX_INPUT_EVENT_TO_STARTUP_DELAY_IN_MS;let inputSlice=undefined;const systemUi=findUIThread(findProcess('com.android.systemui',model));if(systemUi===undefined)return undefined;for(const sliceId in systemUi.asyncSliceGroup.slices){const slice=systemUi.asyncSliceGroup.slices[sliceId];if(slice.end>endNotAfter||slice.end<endNotBefore)continue;if(slice.title!=='deliverInputEvent')continue;if(inputSlice===undefined||slice.end>inputSlice.end){inputSlice=slice;}}
+return inputSlice;}
+function computeStartupTimeInMs(appName,launchSlice,model){let startupStart=launchSlice.start;let startupEnd=launchSlice.end;const drawSlice=findDrawSlice(appName,launchSlice.end,model);if(drawSlice!==undefined){startupEnd=drawSlice.end;}
+const inputSlice=findInputEventSlice(launchSlice.start,model);if(inputSlice!==undefined){startupStart=inputSlice.start;}
+return startupEnd-startupStart;}
+function measureStartup(histograms,model){const launches=findLaunchSlices(model);for(const sliceId in launches){const launchSlice=launches[sliceId];const appName=launchSlice.title.split(': ')[1];const startupMs=computeStartupTimeInMs(appName,launchSlice,model);histograms.createHistogram(`android:systrace:startup:${appName}`,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,startupMs);}}
+function measureThreadStates(histograms,model,rangeOfInterest){for(const pid in model.processes){const process=model.processes[pid];if(process.name===undefined)continue;let hasSlices=false;let timeRunning=0;let timeRunnable=0;let timeSleeping=0;let timeUninterruptible=0;let timeBlockIO=0;let timeUnknown=0;for(const tid in process.threads){const thread=process.threads[tid];if(thread.timeSlices===undefined)continue;for(const sliceId in thread.timeSlices){const slice=thread.timeSlices[sliceId];const sliceRange=tr.b.math.Range.fromExplicitRange(slice.start,slice.end);const intersection=rangeOfInterest.findIntersection(sliceRange);const duration=intersection.duration;if(duration===0)continue;hasSlices=true;if(slice.title==='Running'){timeRunning+=duration;}else if(slice.title==='Runnable'){timeRunnable+=duration;}else if(slice.title==='Sleeping'){timeSleeping+=duration;}else if(slice.title.startsWith('Uninterruptible')){timeUninterruptible+=duration;if(slice.title.includes('Block I/O'))timeBlockIO+=duration;}else{timeUnknown+=duration;}}}
+if(hasSlices){const wall=rangeOfInterest.max-rangeOfInterest.min;histograms.createHistogram(`android:systrace:threadtime:${process.name}:running`,tr.b.Unit.byName.normalizedPercentage,timeRunning/wall);histograms.createHistogram(`android:systrace:threadtime:${process.name}:runnable`,tr.b.Unit.byName.normalizedPercentage,timeRunnable/wall);histograms.createHistogram(`android:systrace:threadtime:${process.name}:sleeping`,tr.b.Unit.byName.normalizedPercentage,timeSleeping/wall);histograms.createHistogram(`android:systrace:threadtime:${process.name}:blockio`,tr.b.Unit.byName.normalizedPercentage,timeBlockIO/wall);histograms.createHistogram(`android:systrace:threadtime:${process.name}:uninterruptible`,tr.b.Unit.byName.normalizedPercentage,timeUninterruptible/wall);if(timeUnknown>0){histograms.createHistogram(`android:systrace:threadtime:${process.name}:unknown`,tr.b.Unit.byName.normalizedPercentage,timeUnknown/wall);}}}}
+function androidSystraceMetric(histograms,model,options){let rangeOfInterest=model.bounds;if(options!==undefined&&options.rangeOfInterest!==undefined){rangeOfInterest=options.rangeOfInterest;}
+measureStartup(histograms,model);measureThreadStates(histograms,model,rangeOfInterest);}
+tr.metrics.MetricRegistry.register(androidSystraceMetric,{supportsRangeOfInterest:true});return{androidSystraceMetric,};});'use strict';tr.exportTo('tr.b.math',function(){const PERCENTILE_PRECISION=1e-7;function PiecewiseLinearFunction(){this.pieces=[];}
+PiecewiseLinearFunction.prototype={push(x1,y1,x2,y2){if(x1>=x2){throw new Error('Invalid segment');}
+if(this.pieces.length>0&&this.pieces[this.pieces.length-1].x2>x1){throw new Error('Potentially overlapping segments');}
+if(x1<x2){this.pieces.push(new Piece(x1,y1,x2,y2));}},partBelow(y){return this.pieces.reduce((acc,p)=>(acc+p.partBelow(y)),0);},get min(){return this.pieces.reduce((acc,p)=>Math.min(acc,p.min),Infinity);},get max(){return this.pieces.reduce((acc,p)=>Math.max(acc,p.max),-Infinity);},get average(){let weightedSum=0;let totalWeight=0;this.pieces.forEach(function(piece){weightedSum+=piece.width*piece.average;totalWeight+=piece.width;});if(totalWeight===0)return 0;return weightedSum/totalWeight;},percentile(percent){if(!(percent>=0&&percent<=1)){throw new Error('percent must be [0,1]');}
+let lower=this.min;let upper=this.max;const total=this.partBelow(upper);if(total===0)return 0;while(upper-lower>PERCENTILE_PRECISION){const middle=(lower+upper)/2;const below=this.partBelow(middle);if(below/total<percent){lower=middle;}else{upper=middle;}}
+return(lower+upper)/2;}};function Piece(x1,y1,x2,y2){this.x1=x1;this.y1=y1;this.x2=x2;this.y2=y2;}
+Piece.prototype={partBelow(y){const width=this.width;if(width===0)return 0;const minY=this.min;const maxY=this.max;if(y>=maxY)return width;if(y<minY)return 0;return(y-minY)/(maxY-minY)*width;},get min(){return Math.min(this.y1,this.y2);},get max(){return Math.max(this.y1,this.y2);},get average(){return(this.y1+this.y2)/2;},get width(){return this.x2-this.x1;}};return{PiecewiseLinearFunction,};});'use strict';tr.exportTo('tr.metrics.v8.utils',function(){const IDLE_TASK_EVENT='SingleThreadIdleTaskRunner::RunTask';const V8_EXECUTE='V8.Execute';const GC_EVENT_PREFIX='V8.GC';const FULL_GC_EVENT='V8.GCCompactor';const LOW_MEMORY_EVENT='V8.GCLowMemoryNotification';const MAJOR_GC_EVENT='MajorGC';const MINOR_GC_EVENT='MinorGC';const TOP_GC_EVENTS={'V8.GCCompactor':'v8-gc-full-mark-compactor','V8.GCFinalizeMC':'v8-gc-latency-mark-compactor','V8.GCFinalizeMCReduceMemory':'v8-gc-memory-mark-compactor','V8.GCIncrementalMarking':'v8-gc-incremental-step','V8.GCIncrementalMarkingFinalize':'v8-gc-incremental-finalize','V8.GCIncrementalMarkingStart':'v8-gc-incremental-start','V8.GCPhantomHandleProcessingCallback':'v8-gc-phantom-handle-callback','V8.GCScavenger':'v8-gc-scavenger'};const MARK_COMPACTOR_EVENTS=new Set(['V8.GCCompactor','V8.GCFinalizeMC','V8.GCFinalizeMCReduceMemory','V8.GCIncrementalMarking','V8.GCIncrementalMarkingFinalize','V8.GCIncrementalMarkingStart','V8.GCPhantomHandleProcessingCallback']);const LOW_MEMORY_MARK_COMPACTOR='v8-gc-low-memory-mark-compactor';function findParent(event,predicate){let parent=event.parentSlice;while(parent){if(predicate(parent)){return parent;}
+parent=parent.parentSlice;}
+return null;}
+function isIdleTask(event){return event.title===IDLE_TASK_EVENT;}
+function isLowMemoryEvent(event){return event.title===LOW_MEMORY_EVENT;}
+function isV8Event(event){return event.title.startsWith('V8.');}
+function isV8ExecuteEvent(event){return event.title===V8_EXECUTE;}
+function isTopV8ExecuteEvent(event){return isV8ExecuteEvent(event)&&findParent(isV8ExecuteEvent)===null;}
+function isGarbageCollectionEvent(event){return event.title&&event.title.startsWith(GC_EVENT_PREFIX)&&event.title!==LOW_MEMORY_EVENT;}
+function isTopGarbageCollectionEvent(event){return event.title in TOP_GC_EVENTS;}
+function isForcedGarbageCollectionEvent(event){return findParent(event,isLowMemoryEvent)!==null;}
+function isSubGarbageCollectionEvent(event){return isGarbageCollectionEvent(event)&&event.parentSlice&&(isTopGarbageCollectionEvent(event.parentSlice)||event.parentSlice.title===MAJOR_GC_EVENT||event.parentSlice.title===MINOR_GC_EVENT);}
+function isNotForcedTopGarbageCollectionEvent(event){return tr.metrics.v8.utils.isTopGarbageCollectionEvent(event)&&!tr.metrics.v8.utils.isForcedGarbageCollectionEvent(event);}
+function isNotForcedSubGarbageCollectionEvent(event){return tr.metrics.v8.utils.isSubGarbageCollectionEvent(event)&&!tr.metrics.v8.utils.isForcedGarbageCollectionEvent(event);}
+function isFullMarkCompactorEvent(event){return event.title==='V8.GCCompactor';}
+function isMarkCompactorSummaryEvent(event){return event.title==='V8.GCMarkCompactorSummary';}
+function isMarkCompactorMarkingSummaryEvent(event){return event.title==='V8.GCMarkCompactorMarkingSummary';}
+function isIncrementalMarkingEvent(event){return event.title.startsWith('V8.GCIncrementalMarking');}
+function isLatencyMarkCompactorEvent(event){return event.title==='V8.GCFinalizeMC';}
+function isMemoryMarkCompactorEvent(event){return event.title==='V8.GCFinalizeMCReduceMemory';}
+function isScavengerEvent(event){return event.title==='V8.GCScavenger';}
+function isCompileOptimizeRCSCategory(name){return name==='Optimize';}
+function isCompileUnoptimizeRCSCategory(name){return name==='Compile';}
+function isCompileParseRCSCategory(name){return name==='Parse';}
+function isCompileRCSCategory(name){return name==='Compile'||name==='Optimize'||name==='Parse';}
+function isV8RCSEvent(event){return event instanceof tr.e.v8.V8ThreadSlice;}
+function isMarkCompactorEvent(event){return MARK_COMPACTOR_EVENTS.has(event.title);}
+function isNotForcedMarkCompactorEvent(event){return!isForcedGarbageCollectionEvent(event)&&isMarkCompactorEvent(event);}
+function forcedGCEventName(){return LOW_MEMORY_EVENT;}
+function topGarbageCollectionEventName(event){if(event.title===FULL_GC_EVENT){if(findParent(event,isLowMemoryEvent)){return LOW_MEMORY_MARK_COMPACTOR;}}
+return TOP_GC_EVENTS[event.title];}
+function subGarbageCollectionEventName(event){const topEvent=findParent(event,isTopGarbageCollectionEvent);const prefix=topEvent?topGarbageCollectionEventName(topEvent):'unknown';const name=event.title.replace('V8.GC_MC_','').replace('V8.GC_SCAVENGER_','').replace('V8.GC_','').replace(/_/g,'-').toLowerCase();return prefix+'-'+name;}
+function jsExecutionThreads(model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);let threads=[];for(const rendererHelper of Object.values(chromeHelper.rendererHelpers)){if(rendererHelper.isChromeTracingUI)continue;threads.push(rendererHelper.mainThread);threads=threads.concat(rendererHelper.dedicatedWorkerThreads);threads=threads.concat(rendererHelper.foregroundWorkerThreads);}
+return threads;}
+function groupAndProcessEvents(model,filterCallback,groupCallback,processCallback){const groupToEvents={};const threads=jsExecutionThreads(model);for(const thread of threads){for(const event of thread.sliceGroup.childEvents()){if(!filterCallback(event))continue;const group=groupCallback(event);groupToEvents[group]=groupToEvents[group]||[];groupToEvents[group].push(event);}}
+for(const[group,events]of Object.entries(groupToEvents)){processCallback(group,events);}}
+function unionOfIntervals(intervals){if(intervals.length===0)return[];return tr.b.math.mergeRanges(intervals.map(x=>{return{min:x.start,max:x.end};}),1e-6,function(ranges){return{start:ranges.reduce((acc,x)=>Math.min(acc,x.min),ranges[0].min),end:ranges.reduce((acc,x)=>Math.max(acc,x.max),ranges[0].max)};});}
+function hasV8Stats(globalMemoryDump){let v8stats=undefined;globalMemoryDump.iterateContainerDumps(function(dump){v8stats=v8stats||dump.getMemoryAllocatorDumpByFullName('v8');});return!!v8stats;}
+function rangeForMemoryDumps(model){const startOfFirstDumpWithV8=model.globalMemoryDumps.filter(hasV8Stats).reduce((start,dump)=>Math.min(start,dump.start),Infinity);if(startOfFirstDumpWithV8===Infinity)return new tr.b.math.Range();return tr.b.math.Range.fromExplicitRange(startOfFirstDumpWithV8,Infinity);}
+class WindowEndpoint{constructor(start,points){this.points=points;this.lastIndex=-1;this.position=start;this.distanceUntilNextPoint=points[0].position-start;this.cummulativePause=0;this.stackDepth=0;}
+advance(delta){if(delta<this.distanceUntilNextPoint){this.position+=delta;this.cummulativePause+=this.stackDepth>0?delta:0;this.distanceUntilNextPoint=this.points[this.lastIndex+1].position-this.position;}else{this.position+=this.distanceUntilNextPoint;this.cummulativePause+=this.stackDepth>0?this.distanceUntilNextPoint:0;this.distanceUntilNextPoint=0;this.lastIndex++;if(this.lastIndex<this.points.length){this.stackDepth+=this.points[this.lastIndex].delta;if(this.lastIndex+1<this.points.length){this.distanceUntilNextPoint=this.points[this.lastIndex+1].position-this.position;}}}}}
+function mutatorUtilization(start,end,timeWindow,intervals){const mu=new tr.b.math.PiecewiseLinearFunction();if(end-start<=timeWindow){return mu;}
+if(intervals.length===0){mu.push(start,1.0,end-timeWindow,1.0);return mu;}
+intervals=unionOfIntervals(intervals);const points=[];for(const interval of intervals){points.push({position:interval.start,delta:1});points.push({position:interval.end,delta:-1});}
+points.sort((a,b)=>a.position-b.position);points.push({position:end,delta:0});const left=new WindowEndpoint(start,points);const right=new WindowEndpoint(start,points);const EPSILON=1e-6;while(right.position-left.position<timeWindow-EPSILON){right.advance(timeWindow-(right.position-left.position));}
+while(right.lastIndex<points.length){const distanceUntilNextPoint=Math.min(left.distanceUntilNextPoint,right.distanceUntilNextPoint);const position1=left.position;const value1=right.cummulativePause-left.cummulativePause;left.advance(distanceUntilNextPoint);right.advance(distanceUntilNextPoint);if(distanceUntilNextPoint>0){const position2=left.position;const value2=right.cummulativePause-left.cummulativePause;mu.push(position1,1.0-value1/timeWindow,position2,1.0-value2/timeWindow);}}
+return mu;}
+function addMutatorUtilization(metricName,eventFilter,timeWindows,rendererHelpers,histograms){const histogramMap=new Map();for(const timeWindow of timeWindows){const summaryOptions={avg:false,count:false,max:false,min:true,std:false,sum:false};const description=`The minimum mutator utilization in ${timeWindow}ms time window`;const histogram=histograms.createHistogram(`${metricName}-${timeWindow}ms_window`,tr.b.Unit.byName.normalizedPercentage_biggerIsBetter,[],{summaryOptions,description});histogramMap.set(timeWindow,histogram);}
+for(const rendererHelper of rendererHelpers){if(rendererHelper.isChromeTracingUI)continue;const pauses=[];for(const event of rendererHelper.mainThread.sliceGroup.childEvents()){if(eventFilter(event)&&event.end>event.start){pauses.push({start:event.start,end:event.end});}}
+pauses.sort((a,b)=>a.start-b.start);const start=rendererHelper.mainThread.bounds.min;const end=rendererHelper.mainThread.bounds.max;for(const timeWindow of timeWindows){const mu=mutatorUtilization(start,end,timeWindow,pauses);histogramMap.get(timeWindow).addSample(mu.min);}}}
+return{addMutatorUtilization,findParent,forcedGCEventName,groupAndProcessEvents,isForcedGarbageCollectionEvent,isFullMarkCompactorEvent,isGarbageCollectionEvent,isIdleTask,isIncrementalMarkingEvent,isLatencyMarkCompactorEvent,isLowMemoryEvent,isMarkCompactorSummaryEvent,isMarkCompactorMarkingSummaryEvent,isMemoryMarkCompactorEvent,isNotForcedMarkCompactorEvent,isNotForcedTopGarbageCollectionEvent,isNotForcedSubGarbageCollectionEvent,isScavengerEvent,isSubGarbageCollectionEvent,isTopGarbageCollectionEvent,isTopV8ExecuteEvent,isV8Event,isV8ExecuteEvent,isV8RCSEvent,isCompileRCSCategory,isCompileOptimizeRCSCategory,isCompileUnoptimizeRCSCategory,isCompileParseRCSCategory,mutatorUtilization,rangeForMemoryDumps,subGarbageCollectionEventName,topGarbageCollectionEventName,unionOfIntervals,};});'use strict';tr.exportTo('tr.metrics.blink',function(){const BLINK_TOP_GC_FOREGROUND_SWEEPING_EVENTS={'BlinkGC.CompleteSweep':'blink-gc-complete-sweep','BlinkGC.LazySweepInIdle':'blink-gc-sweep-task-foreground','BlinkGC.LazySweepOnAllocation':'blink-gc-sweep-allocation'};const BLINK_TOP_GC_BACKGROUND_SWEEPING_EVENTS={'BlinkGC.ConcurrentSweep':'blink-gc-sweep-task-background'};const BLINK_TOP_GC_EVENTS=Object.assign({'BlinkGC.AtomicPauseMarkEpilogue':'blink-gc-atomic-pause-mark-epilogue','BlinkGC.AtomicPauseMarkPrologue':'blink-gc-atomic-pause-mark-prologue','BlinkGC.AtomicPauseMarkRoots':'blink-gc-atomic-pause-mark-roots','BlinkGC.AtomicPauseMarkTransitiveClosure':'blink-gc-atomic-pause-mark-transitive-closure','BlinkGC.AtomicPauseSweepAndCompact':'blink-gc-atomic-pause-sweep-and-compact','BlinkGC.IncrementalMarkingStartMarking':'blink-gc-incremental-start','BlinkGC.IncrementalMarkingStep':'blink-gc-incremental-step'},BLINK_TOP_GC_FOREGROUND_SWEEPING_EVENTS);const ATOMIC_PAUSE_EVENTS=['BlinkGC.AtomicPauseMarkEpilogue','BlinkGC.AtomicPauseMarkPrologue','BlinkGC.AtomicPauseMarkRoots','BlinkGC.AtomicPauseMarkTransitiveClosure','BlinkGC.AtomicPauseSweepAndCompact'];function blinkGarbageCollectionEventName(event){return BLINK_TOP_GC_EVENTS[event.title];}
+function isNonForcedEvent(event){return(!event.args||!event.args.forced)&&!tr.metrics.v8.utils.isForcedGarbageCollectionEvent(event);}
+function isNonForcedBlinkGarbageCollectionEvent(event){return event.title in BLINK_TOP_GC_EVENTS&&isNonForcedEvent(event);}
+function isNonForcedBlinkGarbageCollectionAtomicPauseEvent(event){return ATOMIC_PAUSE_EVENTS.includes(event.title)&&isNonForcedEvent(event);}
+function isNonForcedBlinkGarbageCollectionForegroundSweepingEvent(event){return event.title in BLINK_TOP_GC_FOREGROUND_SWEEPING_EVENTS&&isNonForcedEvent(event);}
+function isNonForcedBlinkGarbageCollectionBackgroundSweepingEvent(event){return event.title in BLINK_TOP_GC_BACKGROUND_SWEEPING_EVENTS&&isNonForcedEvent(event);}
+function isNonNestedNonForcedBlinkGarbageCollectionEvent(event){return isNonForcedBlinkGarbageCollectionEvent(event)&&!tr.metrics.v8.utils.findParent(event,tr.metrics.v8.utils.isGarbageCollectionEvent);}
+function blinkGcMetric(histograms,model){addDurationOfTopEvents(histograms,model);addDurationOfAtomicPause(histograms,model);addTotalDurationOfTopEvents(histograms,model);addTotalDurationOfBlinkAndV8TopEvents(histograms,model);addTotalDurationOfForegroundSweeping(histograms,model);addTotalDurationOfBackgroundSweeping(histograms,model);}
+tr.metrics.MetricRegistry.register(blinkGcMetric);const timeDurationInMs_smallerIsBetter=tr.b.Unit.byName.timeDurationInMs_smallerIsBetter;const CUSTOM_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(0,20,200).addExponentialBins(200,100);function createNumericForTopEventTime(name){const n=new tr.v.Histogram(name,timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);n.customizeSummaryOptions({avg:true,count:true,max:true,min:false,std:true,sum:true,percentile:[0.90]});return n;}
+function createNumericForTotalEventTime(name){const n=new tr.v.Histogram(name,timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);n.customizeSummaryOptions({avg:false,count:true,max:false,min:false,std:false,sum:true,percentile:[0.90]});return n;}
+function createNumericForUnifiedEventTime(name){const n=new tr.v.Histogram(name,timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);n.customizeSummaryOptions({avg:false,count:true,max:true,min:false,std:false,sum:true,percentile:[0.90]});return n;}
+function addDurationOfTopEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNonForcedBlinkGarbageCollectionEvent,blinkGarbageCollectionEventName,function(name,events){const cpuDuration=createNumericForTopEventTime(name);for(const event of events){cpuDuration.addSample(event.cpuDuration);}
+histograms.addHistogram(cpuDuration);});}
+function addDurationOfAtomicPause(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNonForcedBlinkGarbageCollectionAtomicPauseEvent,event=>event.args.epoch,function(group,events){const cpuDuration=createNumericForTopEventTime('blink-gc-atomic-pause');cpuDuration.addSample(events.reduce((acc,current)=>acc+current.cpuDuration,0));histograms.addHistogram(cpuDuration);});}
+function addTotalDurationOfTopEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNonForcedBlinkGarbageCollectionEvent,event=>'blink-gc-total',function(name,events){const cpuDuration=createNumericForTotalEventTime(name);for(const event of events){cpuDuration.addSample(event.cpuDuration);}
+histograms.addHistogram(cpuDuration);});}
+function addTotalDurationOfForegroundSweeping(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNonForcedBlinkGarbageCollectionForegroundSweepingEvent,event=>'blink-gc-sweep-foreground',function(name,events){const cpuDuration=createNumericForTotalEventTime(name);for(const event of events){cpuDuration.addSample(event.cpuDuration);}
+histograms.addHistogram(cpuDuration);});}
+function addTotalDurationOfBackgroundSweeping(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNonForcedBlinkGarbageCollectionBackgroundSweepingEvent,event=>'blink-gc-sweep-background',function(name,events){const cpuDuration=createNumericForTotalEventTime(name);for(const event of events){cpuDuration.addSample(event.cpuDuration);}
+histograms.addHistogram(cpuDuration);});}
+function isV8OrBlinkTopLevelGarbageCollectionEvent(event){return tr.metrics.v8.utils.isNotForcedTopGarbageCollectionEvent(event)||isNonNestedNonForcedBlinkGarbageCollectionEvent(event);}
+function addTotalDurationOfBlinkAndV8TopEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isV8OrBlinkTopLevelGarbageCollectionEvent,event=>'unified-gc-total',function(name,events){const cpuDuration=createNumericForUnifiedEventTime(name);for(const event of events){cpuDuration.addSample(event.cpuDuration);}
+histograms.addHistogram(cpuDuration);});}
+return{blinkGcMetric,};});'use strict';tr.exportTo('tr.metrics.blink',function(){function leakDetectionMetric(histograms,model){const modelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(modelHelper===undefined){throw new Error('Chrome is not present.');}
+const rendererHelpers=modelHelper.rendererHelpers;if(Object.keys(rendererHelpers).length===0){throw new Error('Renderer process is not present.');}
+const pids=Object.keys(rendererHelpers);const chromeDumps=tr.metrics.sh.splitGlobalDumpsByBrowserName(model,undefined).get('chrome');const sumCounter=new Map();for(const pid of pids){for(const[key,count]of countLeakedBlinkObjects(chromeDumps,pid)){sumCounter.set(key,(sumCounter.get(key)||0)+count);}}
+for(const[key,count]of sumCounter){histograms.createHistogram('Leaked '+key,tr.b.Unit.byName.count_smallerIsBetter,count);}
+for(const[key,count]of sumCounter){if(count>0){throw new Error('Memory leak is found.');}}}
+tr.metrics.MetricRegistry.register(leakDetectionMetric);function countLeakedBlinkObjects(dumps,pid){if(dumps===undefined||dumps.length<2){throw new Error('Expected at least two memory dumps.');}
+const firstCounter=countBlinkObjects(dumps[0],pid);const lastCounter=countBlinkObjects(dumps[dumps.length-1],pid);const diffCounter=new Map();for(const[key,lastCount]of lastCounter){diffCounter.set(key,lastCount-firstCounter.get(key));}
+return diffCounter;}
+function countBlinkObjects(dump,pid){const counter=new Map();const processesMemoryDumps=dump.processMemoryDumps;if(processesMemoryDumps[pid]===undefined)return counter;const blinkObjectsDump=processesMemoryDumps[pid].memoryAllocatorDumps.find(dump=>dump.fullName==='blink_objects');for(const v of blinkObjectsDump.children){counter.set(v.name,v.numerics.object_count.value);}
+return counter;}
+return{leakDetectionMetric,};});'use strict';tr.exportTo('tr.metrics.console',function(){const COUNT_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(1,1e4,30);const SUMMARY_OPTIONS=tr.v.Histogram.AVERAGE_ONLY_SUMMARY_OPTIONS;const SOURCES=['all','js','network'];function consoleErrorMetric(histograms,model){const counts={};for(const source of SOURCES){counts[source]=0;}
+for(const slice of model.getDescendantEvents()){if(slice.category==='blink.console'&&slice.title==='ConsoleMessage::Error'){const source=slice.args.source.toLowerCase();counts.all++;if(source in counts){counts[source]++;}}
+if(slice.category==='v8.console'&&(slice.title==='V8ConsoleMessage::Exception'||slice.title==='V8ConsoleMessage::Error'||slice.title==='V8ConsoleMessage::Assert')){counts.all++;counts.js++;}}
+for(const source of SOURCES){histograms.createHistogram(`console:error:${source}`,tr.b.Unit.byName.count_smallerIsBetter,counts[source],{description:`Number of ${source} console error messages`,summaryOptions:SUMMARY_OPTIONS});}}
+tr.metrics.MetricRegistry.register(consoleErrorMetric);return{consoleErrorMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){function getCpuSnapshotsFromModel(model){const snapshots=[];for(const pid in model.processes){const snapshotInstances=model.processes[pid].objects.getAllInstancesNamed('CPUSnapshots');if(!snapshotInstances)continue;for(const object of snapshotInstances[0].snapshots){snapshots.push(object.args.processes);}}
+return snapshots;}
+function getProcessSumsFromSnapshot(snapshot){const processSums=new Map();for(const processData of snapshot){const processName=processData.name;if(!(processSums.has(processName))){processSums.set(processName,{sum:0.0,paths:new Set()});}
+processSums.get(processName).sum+=parseFloat(processData.pCpu);if(processData.path){processSums.get(processName).paths.add(processData.path);}}
+return processSums;}
+function buildNumericsFromSnapshots(snapshots){const processNumerics=new Map();for(const snapshot of snapshots){const processSums=getProcessSumsFromSnapshot(snapshot);for(const[processName,processData]of processSums.entries()){if(!(processNumerics.has(processName))){processNumerics.set(processName,{numeric:new tr.v.Histogram('cpu:percent:'+processName,tr.b.Unit.byName.normalizedPercentage_smallerIsBetter),paths:new Set()});}
+processNumerics.get(processName).numeric.addSample(processData.sum/100.0);for(const path of processData.paths){processNumerics.get(processName).paths.add(path);}}}
+return processNumerics;}
+function cpuProcessMetric(histograms,model){const snapshots=getCpuSnapshotsFromModel(model);const processNumerics=buildNumericsFromSnapshots(snapshots);for(const[processName,processData]of processNumerics){const numeric=processData.numeric;const missingSnapshotCount=snapshots.length-numeric.numValues;for(let i=0;i<missingSnapshotCount;i++){numeric.addSample(0);}
+numeric.diagnostics.set('paths',new
+tr.v.d.GenericSet([...processData.paths]));histograms.addHistogram(numeric);}}
+tr.metrics.MetricRegistry.register(cpuProcessMetric);return{cpuProcessMetric,};});'use strict';tr.exportTo('tr.metrics',function(){function mediaMetric(histograms,model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(chromeHelper===undefined)return;for(const rendererHelper of Object.values(chromeHelper.rendererHelpers)){const mainThread=rendererHelper.mainThread;if(mainThread===undefined)continue;const videoThreads=rendererHelper.process.findAllThreadsMatching(thread=>(thread.name?thread.name.startsWith('ThreadPoolSingleThreadSharedForegroundBlocking'):false));const compositorThread=rendererHelper.compositorThread;if(compositorThread!==undefined){videoThreads.push(compositorThread);}
+const audioThreads=rendererHelper.process.findAllThreadsNamed('AudioOutputDevice');if(audioThreads.length===0&&videoThreads.length===0)continue;const processData=new PerProcessData();processData.recordPlayStarts(mainThread);if(!processData.hasPlaybacks)continue;if(videoThreads.length!==0){processData.calculateTimeToVideoPlays(videoThreads);processData.calculateDroppedFrameCounts(videoThreads);}
+if(audioThreads.length!==0){processData.calculateTimeToAudioPlays(audioThreads);}
+processData.calculateSeekTimes(mainThread);processData.calculateBufferingTimes(mainThread);processData.addMetricToHistograms(histograms);}}
+class PerProcessData{constructor(){this.playbackIdToDataMap_=new Map();}
+recordPlayStarts(mainThread){for(const event of mainThread.sliceGroup.getDescendantEvents()){if(event.title==='WebMediaPlayerImpl::DoLoad'){const id=event.args.id;if(this.playbackIdToDataMap_.has(id)){throw new Error('Unexpected multiple initialization of a media playback');}
+this.playbackIdToDataMap_.set(id,new PerPlaybackData(event.start));}}}
+get hasPlaybacks(){return this.playbackIdToDataMap_.size>0;}
+calculateTimeToVideoPlays(videoThreads){for(const thread of videoThreads){for(const event of thread.sliceGroup.getDescendantEvents()){if(event.title==='VideoRendererImpl::Render'){this.getPerPlaybackObject_(event.args.id).processVideoRenderTime(event.start);}}}}
+calculateTimeToAudioPlays(audioThreads){for(const audioThread of audioThreads){for(const event of audioThread.sliceGroup.getDescendantEvents()){if(event.title==='AudioRendererImpl::Render'){this.getPerPlaybackObject_(event.args.id).processAudioRenderTime(event.start);}}}}
+calculateSeekTimes(mainThread){for(const event of mainThread.sliceGroup.getDescendantEvents()){if(event.title==='WebMediaPlayerImpl::DoSeek'){this.getPerPlaybackObject_(event.args.id).processDoSeek(event.args.target,event.start);}else if(event.title==='WebMediaPlayerImpl::OnPipelineSeeked'){this.getPerPlaybackObject_(event.args.id).processOnPipelineSeeked(event.args.target,event.start);}else if(event.title==='WebMediaPlayerImpl::BufferingHaveEnough'){this.getPerPlaybackObject_(event.args.id).processBufferingHaveEnough(event.start);}}}
+calculateBufferingTimes(mainThread){for(const event of mainThread.sliceGroup.getDescendantEvents()){if(event.title==='WebMediaPlayerImpl::OnEnded'){this.getPerPlaybackObject_(event.args.id).processOnEnded(event.start,event.args.duration);}}}
+calculateDroppedFrameCounts(videoThreads){for(const thread of videoThreads){for(const event of thread.sliceGroup.getDescendantEvents()){if(event.title==='VideoFramesDropped'){this.getPerPlaybackObject_(event.args.id).processVideoFramesDropped(event.args.count);}}}}
+addMetricToHistograms(histograms){for(const[id,playbackData]of this.playbackIdToDataMap_){playbackData.addMetricToHistograms(histograms);}}
+getPerPlaybackObject_(playbackId){let perPlaybackObject=this.playbackIdToDataMap_.get(playbackId);if(perPlaybackObject===undefined){perPlaybackObject=new PerPlaybackData(undefined);this.playbackIdToDataMap_.set(playbackId,perPlaybackObject);}
+return perPlaybackObject;}}
+class PerPlaybackData{constructor(playStartTime){this.playStart_=playStartTime;this.timeToVideoPlay_=undefined;this.timeToAudioPlay_=undefined;this.bufferingTime_=undefined;this.droppedFrameCount_=0;this.seekError_=false;this.seekTimes_=new Map();this.currentSeek_=undefined;}
+get timeToVideoPlay(){return this.timeToVideoPlay_;}
+get timeToAudioPlay(){return this.timeToAudioPlay_;}
+get bufferingTime(){return this.bufferingTime_;}
+get droppedFrameCount(){return(this.timeToVideoPlay_!==undefined)?this.droppedFrameCount_:undefined;}
+get seekTimes(){if(this.seekError_||this.currentSeek_!==undefined)return new Map();return this.seekTimes_;}
+processVideoRenderTime(videoRenderTime){if(this.playStart_!==undefined&&this.timeToVideoPlay_===undefined){this.timeToVideoPlay_=videoRenderTime-this.playStart_;}}
+processAudioRenderTime(audioRenderTime){if(this.playStart_!==undefined&&this.timeToAudioPlay_===undefined){this.timeToAudioPlay_=audioRenderTime-this.playStart_;}}
+processVideoFramesDropped(count){this.droppedFrameCount_+=count;}
+processDoSeek(target,startTime){if(this.currentSeek_!==undefined){this.seekError_=true;return;}
+this.currentSeek_={target,startTime};this.seekTimes_.set(target,this.currentSeek_);}
+processOnPipelineSeeked(target,time){if(this.seekError_)return;const currentSeek=this.currentSeek_;if(currentSeek===undefined){return;}
+if(currentSeek.target!==target){this.seekError_=true;return;}
+if(currentSeek.pipelineSeekTime!==undefined){this.seekError_=true;return;}
+currentSeek.pipelineSeekTime=time-currentSeek.startTime;}
+processBufferingHaveEnough(time){if(this.seekError_)return;const currentSeek=this.currentSeek_;if(currentSeek===undefined){return;}
+if(currentSeek.pipelineSeekTime===undefined){return;}
+currentSeek.seekTime=time-currentSeek.startTime;this.currentSeek_=undefined;}
+processOnEnded(playEndTime,duration){if(this.playStart_===undefined)return;if(this.seekTimes_.size!==0||this.seekError_)return;if(this.bufferingTime_!==undefined)return;duration=tr.b.convertUnit(duration,tr.b.UnitPrefixScale.METRIC.NONE,tr.b.UnitPrefixScale.METRIC.MILLI);const playTime=playEndTime-this.playStart_;if(this.timeToVideoPlay_!==undefined){this.bufferingTime_=playTime-duration-this.timeToVideoPlay_;}else if(this.timeToAudioPlay!==undefined){this.bufferingTime_=playTime-duration-this.timeToAudioPlay_;}}
+addMetricToHistograms(histograms){this.addSample_(histograms,'time_to_video_play',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,this.timeToVideoPlay);this.addSample_(histograms,'time_to_audio_play',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,this.timeToAudioPlay);this.addSample_(histograms,'dropped_frame_count',tr.b.Unit.byName.count_smallerIsBetter,this.droppedFrameCount);for(const[key,value]of this.seekTimes.entries()){const keyString=key.toString().replace('.','_');this.addSample_(histograms,'pipeline_seek_time_'+keyString,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,value.pipelineSeekTime);this.addSample_(histograms,'seek_time_'+keyString,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,value.seekTime);}
+this.addSample_(histograms,'buffering_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,this.bufferingTime);}
+addSample_(histograms,name,unit,sample){if(sample===undefined)return;const histogram=histograms.getHistogramNamed(name);if(histogram===undefined){histograms.createHistogram(name,unit,sample);}else{histogram.addSample(sample);}}}
+tr.metrics.MetricRegistry.register(mediaMetric);return{mediaMetric,};});'use strict';tr.exportTo('tr.metrics.rendering',function(){const UNKNOWN_THREAD_NAME='Unknown';const CATEGORY_THREAD_MAP=new Map();CATEGORY_THREAD_MAP.set('total_all',[/.*/]);CATEGORY_THREAD_MAP.set('browser',[/^Browser Compositor$/,/^CrBrowserMain$/]);CATEGORY_THREAD_MAP.set('display_compositor',[/^VizCompositorThread$/]);CATEGORY_THREAD_MAP.set('GPU',[/^Chrome_InProcGpuThread$/,/^CrGpuMain$/]);CATEGORY_THREAD_MAP.set('IO',[/IOThread/]);CATEGORY_THREAD_MAP.set('raster',[/CompositorTileWorker/]);CATEGORY_THREAD_MAP.set('renderer_compositor',[/^Compositor$/]);CATEGORY_THREAD_MAP.set('renderer_main',[/^CrRendererMain$/]);CATEGORY_THREAD_MAP.set('total_rendering',[/^Browser Compositor$/,/^Chrome_InProcGpuThread$/,/^Compositor$/,/CompositorTileWorker/,/^CrBrowserMain$/,/^CrGpuMain$/,/^CrRendererMain$/,/IOThread/,/^VizCompositorThread$/]);const ALL_CATEGORIES=[...CATEGORY_THREAD_MAP.keys(),'other'];function addValueToMap_(map,key,value){const oldValue=map.get(key)||0;map.set(key,oldValue+value);}
+function categoryShouldHaveBreakdown(category){return category==='total_all'||category==='total_rendering';}
+function*getCategories_(threadName){let isOther=true;for(const[category,regexps]of CATEGORY_THREAD_MAP){for(const regexp of regexps){if(regexp.test(threadName)){if(category!=='total_all')isOther=false;yield category;break;}}}
+if(isOther)yield'other';}
+function isSubset_(regexps1,regexps2){for(const r1 of regexps1){if(regexps2.find(r2=>r2.toString()===r1.toString())===undefined){return false;}}
+return true;}
+function addCpuUtilizationHistograms(histograms,model,segments,shouldNormalize,segmentCostFunc,histogramNameFunc,description,unit){if(!unit)unit=tr.b.Unit.byName.unitlessNumber;const histogramMap=new Map();for(const category of ALL_CATEGORIES){const histogram=histograms.createHistogram(histogramNameFunc(category),unit,[],{binBoundaries:tr.v.HistogramBinBoundaries.createExponential(1,50,20),description,summaryOptions:tr.metrics.rendering.SUMMARY_OPTIONS,});histogramMap.set(category,histogram);}
+for(const[category,regexps]of CATEGORY_THREAD_MAP){const relatedCategories=new tr.v.d.RelatedNameMap();const histogram=histogramMap.get(category);for(const[otherCategory,otherRegexps]of CATEGORY_THREAD_MAP){if(otherCategory===category)continue;if(category!=='all'&&!isSubset_(otherRegexps,regexps))continue;const otherHistogram=histogramMap.get(otherCategory);relatedCategories.set(otherCategory,otherHistogram.name);}
+if([...relatedCategories.values()].length>0){histogram.diagnostics.set('breakdown',relatedCategories);}}
+for(const segment of segments){const threadValues=new Map();for(const thread of model.getAllThreads()){addValueToMap_(threadValues,thread.name||UNKNOWN_THREAD_NAME,segmentCostFunc(thread,segment));}
+const categoryValues=new Map();const breakdowns=new Map();for(const[threadName,coresPerSec]of threadValues){for(const category of getCategories_(threadName)){addValueToMap_(categoryValues,category,coresPerSec);if(!categoryShouldHaveBreakdown(category))continue;if(!breakdowns.has(category)){breakdowns.set(category,new tr.v.d.Breakdown());}
+breakdowns.get(category).set(threadName,coresPerSec);}}
+for(const category of ALL_CATEGORIES){let value=categoryValues.get(category)||0;if(shouldNormalize)value/=segment.duration;const diagnostics=new tr.v.d.DiagnosticMap();const breakdown=breakdowns.get(category);if(breakdown)diagnostics.set('breakdown',breakdown);const histogram=histogramMap.get(category);histogram.addSample(value,diagnostics);}}}
+const SUMMARY_OPTIONS={percentile:[0.90,0.95],ci:[0.95],};return{addCpuUtilizationHistograms,SUMMARY_OPTIONS,};});'use strict';tr.exportTo('tr.metrics.rendering',function(){const PRESENT_EVENT='Display::FrameDisplayed';const DISPLAY_EVENT='BenchmarkInstrumentation::DisplayRenderingStats';const DRM_EVENT='DrmEventFlipComplete';const SURFACE_FLINGER_EVENT='vsync_before';const COMPOSITOR_FRAME_PRESENTED_EVENT='FramePresented';const MIN_FRAME_LENGTH=0.5;const MIN_FRAME_COUNT=10;const PAUSE_THRESHOLD=20;const ASH_ENVIRONMENT='ash';const BROWSER_ENVIRONMENT='browser';class FrameEvent{constructor(event){this.event_=event;}
+get eventStart(){return this.event_.start;}
+get frameStart(){if(this.event_.title!==DRM_EVENT)return this.event_.start;const data=this.event_.args.data;const TIME=tr.b.UnitScale.TIME;return tr.b.convertUnit(data['vblank.tv_sec'],TIME.SEC,TIME.MILLI_SEC)+
+tr.b.convertUnit(data['vblank.tv_usec'],TIME.MICRO_SEC,TIME.MILLI_SEC);}
+get event(){return this.event_;}}
+class FrameSegment{constructor(frameEvent,duration){this.frameEvent_=frameEvent;this.duration_=duration;this.segment_=new tr.model.um.Segment(frameEvent.eventStart,duration);this.length_=undefined;}
+updateLength(refreshPeriod){this.length_=this.duration_/refreshPeriod;}
+get segment(){return this.segment_;}
+get boundsRange(){return this.segment_.boundsRange;}
+get length(){return this.length_;}
+get duration(){return this.duration_;}
+get event(){return this.frameEvent_.event;}}
+function getDisplayCompositorPresentationEventsExp_(modelHelper){if(!modelHelper)return[];function findEventsFromProcess(process){const events=[];for(const event of process.findTopmostSlicesNamed(PRESENT_EVENT)){events.push(event);}
+return events;}
+if(modelHelper.gpuHelper){const events=findEventsFromProcess(modelHelper.gpuHelper.process);if(events.length>0)return events;}
+if(!modelHelper.browserProcess)return[];return findEventsFromProcess(modelHelper.browserProcess);}
+function getDisplayCompositorPresentationEvents_(modelHelper){if(!modelHelper||!modelHelper.browserProcess)return[];let events=[];if(modelHelper.surfaceFlingerProcess){events=[...modelHelper.surfaceFlingerProcess.findTopmostSlicesNamed(SURFACE_FLINGER_EVENT)];if(events.length>0)return events;}
+if(modelHelper.gpuHelper){const gpuProcess=modelHelper.gpuHelper.process;events=[...gpuProcess.findTopmostSlicesNamed(DRM_EVENT)];if(events.length>0)return events;events=[...gpuProcess.findTopmostSlicesNamed(DISPLAY_EVENT)];if(events.length>0)return events;}
+return[...modelHelper.browserProcess.findTopmostSlicesNamed(DISPLAY_EVENT)];}
+function getUIPresentationEvents_(modelHelper){if(!modelHelper||!modelHelper.browserProcess)return[];const legacyEvents=[];const eventsByEnvironment={};eventsByEnvironment[ASH_ENVIRONMENT]=[];eventsByEnvironment[BROWSER_ENVIRONMENT]=[];for(const event of modelHelper.browserProcess.findTopmostSlicesNamed(COMPOSITOR_FRAME_PRESENTED_EVENT)){if(!('environment'in event.args)){legacyEvents.push(event);}else{eventsByEnvironment[event.args.environment].push(event);}}
+if(eventsByEnvironment[ASH_ENVIRONMENT].length>0){return eventsByEnvironment[ASH_ENVIRONMENT];}
+if(eventsByEnvironment[BROWSER_ENVIRONMENT].length>0){return eventsByEnvironment[BROWSER_ENVIRONMENT];}
+return legacyEvents;}
+function computeFrameSegments_(events,segments,opt_minFrameCount){const minFrameCount=opt_minFrameCount||MIN_FRAME_COUNT;const frameEvents=events.map(e=>new FrameEvent(e));const frameSegments=[];for(const segment of segments){const filtered=segment.boundsRange.filterArray(frameEvents,x=>x.eventStart);if(filtered.length<minFrameCount)continue;for(let i=1;i<filtered.length;i++){const duration=filtered[i].frameStart-filtered[i-1].frameStart;frameSegments.push(new FrameSegment(filtered[i-1],duration));}}
+return frameSegments;}
+function addBasicFrameTimeHistograms_(histograms,frameSegments,prefix){const frameTimes=(frameSegments.length===0)?[0]:frameSegments.map(x=>x.duration);histograms.createHistogram(`${prefix}frame_times`,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,frameTimes,{binBoundaries:tr.v.HistogramBinBoundaries.createLinear(0,50,20),description:'Raw frame times.',summaryOptions:tr.metrics.rendering.SUMMARY_OPTIONS,});histograms.createHistogram(`${prefix}percentage_smooth`,tr.b.Unit.byName.unitlessNumber_biggerIsBetter,100*tr.b.math.Statistics.sum(frameTimes,(x=>(x<17?1:0)))/frameTimes.length,{description:'Percentage of frames that were hitting 60 FPS.',summaryOptions:{},});}
+function addFrameTimeHistograms(histograms,model,segments,opt_minFrameCount){const minFrameCount=opt_minFrameCount||MIN_FRAME_COUNT;const modelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const events=getDisplayCompositorPresentationEvents_(modelHelper);if(!events)return;addFrameTimeHistogramsHelper(histograms,model,segments,events,'',true,minFrameCount);const eventsExp=getDisplayCompositorPresentationEventsExp_(modelHelper);if(eventsExp&&eventsExp.length>0){addFrameTimeHistogramsHelper(histograms,model,segments,eventsExp,'exp_',minFrameCount);}}
+function addFrameTimeHistogramsHelper(histograms,model,segments,events,prefix,addCpuMetrics,minFrameCount){const frameSegments=computeFrameSegments_(events,segments,minFrameCount);addBasicFrameTimeHistograms_(histograms,frameSegments,prefix+'');if(addCpuMetrics){tr.metrics.rendering.addCpuUtilizationHistograms(histograms,model,frameSegments,false,(thread,segment)=>thread.getCpuTimeForRange(segment.boundsRange),category=>`thread_${category}_cpu_time_per_frame`,'CPU cores of a thread group per frame',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);tr.metrics.rendering.addCpuUtilizationHistograms(histograms,model,frameSegments,false,(thread,segment)=>thread.getNumToplevelSlicesForRange(segment.boundsRange),category=>`tasks_per_frame_${category}`,'Number of tasks of a thread group per frame',tr.b.Unit.byName.unitlessNumber_smallerIsBetter);}
+const refreshPeriod=getRefreshPeriod(model,frameSegments.map(fs=>fs.boundsRange));frameSegments.forEach(fs=>fs.updateLength(refreshPeriod));const validFrames=frameSegments.filter(fs=>fs.length>=MIN_FRAME_LENGTH);const totalFrameDuration=tr.b.math.Statistics.sum(frameSegments,fs=>fs.duration);addJankCountHistograms(histograms,validFrames,prefix);const frameLengths=validFrames.map(frame=>frame.length);histograms.createHistogram(prefix+'frame_lengths',tr.b.Unit.byName.unitlessNumber_smallerIsBetter,frameLengths,{binBoundaries:tr.v.HistogramBinBoundaries.createLinear(0,5,20),summaryOptions:tr.metrics.rendering.SUMMARY_OPTIONS,description:'Frame times in vsyncs.'});histograms.createHistogram(prefix+'avg_surface_fps',tr.b.Unit.byName.unitlessNumber_biggerIsBetter,frameLengths.length/tr.b.convertUnit(totalFrameDuration,tr.b.UnitScale.TIME.MILLI_SEC,tr.b.UnitScale.TIME.SEC),{description:'Average frames per second.',summaryOptions:{},});}
+function addUIFrameTimeHistograms(histograms,model,segments,opt_minFrameCount){const minFrameCount=opt_minFrameCount||MIN_FRAME_COUNT;const events=getUIPresentationEvents_(model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper));if(events.length===0)return;const frameSegments=computeFrameSegments_(events,segments,minFrameCount);addBasicFrameTimeHistograms_(histograms,frameSegments,'ui_');}
+function addJankCountHistograms(histograms,validFrames,prefix){const jankEvents=[];for(let i=1;i<validFrames.length;i++){const change=Math.round((validFrames[i].length-validFrames[i-1].length));if(change>0&&change<PAUSE_THRESHOLD){jankEvents.push(validFrames[i].event);}}
+const jankCount=jankEvents.length;const diagnostics=new tr.v.d.DiagnosticMap();diagnostics.set('events',new tr.v.d.RelatedEventSet(jankEvents));diagnostics.set('timestamps',new tr.v.d.GenericSet(jankEvents.map(e=>e.start)));const histogram=histograms.createHistogram(prefix+'jank_count',tr.b.Unit.byName.count_smallerIsBetter,{value:jankCount,diagnostics},{description:'Number of changes in frame rate.',summaryOptions:{},});}
+function getRefreshPeriod(model,ranges){for(const metadata of model.metadata){if(metadata.value&&metadata.value.surface_flinger){return metadata.value.surface_flinger.refresh_period;}}
+const FRAME_LENGTH=1000.0/60;const BEGIN_FRAME_ARGS='Scheduler::BeginFrame';const FRAME_INTERVAL='interval_us';const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);for(const rendererHelper of Object.values(chromeHelper.rendererHelpers)){if(rendererHelper.compositorThread===undefined)continue;const slices=rendererHelper.compositorThread.sliceGroup;for(const slice of slices.getDescendantEventsInSortedRanges(ranges)){if(slice.title!==BEGIN_FRAME_ARGS)continue;const data=slice.args.args;if(!(FRAME_INTERVAL in data)){throw new Error(`${FRAME_INTERVAL} is missing`);}
+return tr.b.convertUnit(data[FRAME_INTERVAL],tr.b.UnitScale.TIME.MICRO_SEC,tr.b.UnitScale.TIME.MILLI_SEC);}}
+return FRAME_LENGTH;}
+return{addFrameTimeHistograms,addUIFrameTimeHistograms,};});'use strict';tr.exportTo('tr.metrics.rendering',function(){const RGB_DECODE_EVENT='ImageFrameGenerator::decode';const YUV_DECODE_EVENT='ImageFrameGenerator::decodeToYUV';const BLINK_GPU_RASTER_DECODE_EVENT='GpuImageDecodeCache::DecodeImage';const BLINK_SOFTWARE_RASTER_DECODE_EVENT='SoftwareImageDecodeCache::'+'DecodeImageInTask';function getImageDecodingEvents_(modelHelper,ranges){if(!modelHelper||!modelHelper.rendererHelpers)return[];const events=[];for(const renderer of Object.values(modelHelper.rendererHelpers)){for(const thread of renderer.rasterWorkerThreads){const slices=thread.sliceGroup;for(const slice of slices.getDescendantEventsInSortedRanges(ranges)){if(slice.title===RGB_DECODE_EVENT||slice.title===YUV_DECODE_EVENT||slice.title===BLINK_GPU_RASTER_DECODE_EVENT||slice.title===BLINK_SOFTWARE_RASTER_DECODE_EVENT){events.push(slice);}}}}
+return events;}
+function addImageDecodeTimeHistograms(histograms,model,segments){const modelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const decodeEvents=getImageDecodingEvents_(modelHelper,segments.map(s=>s.boundsRange));if(!decodeEvents)return;histograms.createHistogram('rgb_decode_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,decodeEvents.filter(slice=>slice.title===RGB_DECODE_EVENT).map(slice=>slice.cpuDuration),{description:'Duration of the Blink RGB decoding path for a chunk '+'of image data (possibly the whole image).',summaryOptions:tr.metrics.rendering.SUMMARY_OPTIONS,});histograms.createHistogram('yuv_decode_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,decodeEvents.filter(slice=>slice.title===YUV_DECODE_EVENT).map(slice=>slice.cpuDuration),{description:'Duration of the Blink YUV decoding path for a '+'chunk of image data (possibly the whole image).',summaryOptions:tr.metrics.rendering.SUMMARY_OPTIONS,});histograms.createHistogram('blink_decode_time_gpu_rasterization',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,decodeEvents.filter(slice=>slice.title===BLINK_GPU_RASTER_DECODE_EVENT).map(slice=>slice.cpuDuration),{description:'Duration of decoding and scaling within the '+'GpuImageDecodeCache for a chunk of image data '+'(possibly the whole image)',summaryOptions:tr.metrics.rendering.SUMMARY_OPTIONS,});histograms.createHistogram('blink_decode_time_software_rasterization',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,decodeEvents.filter(slice=>slice.title===BLINK_SOFTWARE_RASTER_DECODE_EVENT).map(slice=>slice.cpuDuration),{description:'Duration of decoding and scaling within the '+'SoftwareImageDecodeCache for a chunk of image data '+'(possibly the whole image)',summaryOptions:tr.metrics.rendering.SUMMARY_OPTIONS,});}
+return{addImageDecodeTimeHistograms};});'use strict';tr.exportTo('tr.metrics.rendering',function(){const BEGIN_SCROLL_UPDATE_COMP_NAME='LATENCY_BEGIN_SCROLL_LISTENER_UPDATE_MAIN_COMPONENT';const END_COMP_NAME='INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT';function*iterAsyncEvents_(processHelpers,ranges,processEventFn){for(const processHelper of processHelpers){const process=processHelper.process;for(const event of process.getDescendantEventsInSortedRanges(ranges,container=>container instanceof tr.model.AsyncSliceGroup)){yield*processEventFn(event);}}}
+function*processLatencyEvent(event){if(event.title!=='Latency::ScrollUpdate'||!('data'in event.args)||!(END_COMP_NAME in event.args.data)){return;}
+const data=event.args.data;const endTime=data[END_COMP_NAME].time;if(BEGIN_SCROLL_UPDATE_COMP_NAME in data){yield tr.b.Unit.timestampFromUs(endTime-data[BEGIN_SCROLL_UPDATE_COMP_NAME].time);}else{throw new Error('LatencyInfo has no begin component');}}
+function addLatencyHistograms(histograms,model,segments){const modelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(!modelHelper)return;const ranges=segments.map(s=>s.boundsRange);const mainThreadScrollLatencies=[...iterAsyncEvents_(Object.values(modelHelper.rendererHelpers),ranges,processLatencyEvent)];histograms.createHistogram('main_thread_scroll_latency',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,mainThreadScrollLatencies,{binBoundaries:tr.v.HistogramBinBoundaries.createLinear(0,50,50),summaryOptions:tr.metrics.rendering.SUMMARY_OPTIONS,description:'Main thread scroll latencies.'});}
+return{addLatencyHistograms,};});'use strict';tr.exportTo('tr.metrics.rendering',function(){function eventIsValidGraphicsEvent_(event,eventMap){if(event.title!=='Graphics.Pipeline'||!event.bindId||!event.args||!event.args.step){return false;}
+const bindId=event.bindId;if(eventMap.has(bindId)&&event.args.step in eventMap.get(bindId)){if(event.args.step==='IssueBeginFrame'||event.args.step==='ReceiveBeginFrame'){throw new Error('Unexpected duplicate step: '+event.args.step);}
+return false;}
+return true;}
+function generateBreakdownForCompositorPipelineInClient_(flow){const breakdown=new tr.v.d.Breakdown();breakdown.set('time before GenerateRenderPass',flow.GenerateRenderPass.start-flow.ReceiveBeginFrame.start);breakdown.set('GenerateRenderPass duration',flow.GenerateRenderPass.duration);breakdown.set('GenerateCompositorFrame duration',flow.GenerateCompositorFrame.duration);breakdown.set('SubmitCompositorFrame duration',flow.SubmitCompositorFrame.duration);return breakdown;}
+function generateBreakdownForCompositorPipelineInService_(flow){const breakdown=new tr.v.d.Breakdown();breakdown.set('Processing CompositorFrame on reception',flow.ReceiveCompositorFrame.duration);breakdown.set('Delay before SurfaceAggregation',flow.SurfaceAggregation.start-flow.ReceiveCompositorFrame.end);breakdown.set('SurfaceAggregation duration',flow.SurfaceAggregation.duration);return breakdown;}
+function generateBreakdownForDraw_(drawEvent){const breakdown=new tr.v.d.Breakdown();for(const slice of drawEvent.subSlices){breakdown.set(slice.title,slice.duration);}
+return breakdown;}
+function getDisplayCompositorThread_(model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const gpuHelper=chromeHelper.gpuHelper;if(gpuHelper){const thread=gpuHelper.process.findAtMostOneThreadNamed('VizCompositorThread');if(thread){return thread;}}
+if(!chromeHelper.browserProcess)return null;return chromeHelper.browserProcess.findAtMostOneThreadNamed('CrBrowserMain');}
+function getRasterTaskTimes(sourceFrameNumber,model){const modelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const renderers=modelHelper.telemetryHelper.renderersWithIR;if(renderers.length===0)return;const rasterThreads=renderers[0].rasterWorkerThreads;let earliestStart=undefined;let lastEnd=undefined;for(const rasterThread of rasterThreads){for(const slice of[...rasterThread.findTopmostSlicesNamed('TaskGraphRunner::RunTask')]){if(slice.args&&slice.args.source_frame_number_&&slice.args.source_frame_number_===sourceFrameNumber){if(earliestStart===undefined||slice.start<earliestStart){earliestStart=slice.start;}
+if(lastEnd===undefined||slice.end>lastEnd){lastEnd=slice.end;}}}}
+return{start:earliestStart,end:lastEnd};}
+function addPipelineHistograms(histograms,model,segments){const ranges=segments.map(s=>s.boundsRange);const bindEvents=new Map();for(const thread of model.getAllThreads()){for(const event of thread.sliceGroup.childEvents()){if(!eventIsValidGraphicsEvent_(event,bindEvents))continue;for(const range of ranges){if(range.containsExplicitRangeInclusive(event.start,event.end)){if(!bindEvents.has(event.bindId))bindEvents.set(event.bindId,{});break;}}
+if(bindEvents.has(event.bindId)){bindEvents.get(event.bindId)[event.args.step]=event;}}}
+const dcThread=getDisplayCompositorThread_(model);const drawEvents={};if(dcThread){const events=[...dcThread.findTopmostSlicesNamed('Graphics.Pipeline.DrawAndSwap')];for(const segment of segments){const filteredEvents=segment.boundsRange.filterArray(events,evt=>evt.start);for(const event of filteredEvents){if((event.args&&event.args.status==='canceled')||!event.id.startsWith(':ptr:')){continue;}
+const id=parseInt(event.id.substring(5),16);if(id in drawEvents){throw new Error('Duplicate draw events: '+id);}
+drawEvents[id]=event;}}}
+const issueToReceipt=histograms.createHistogram('pipeline:begin_frame_transport',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[],{description:'Latency of begin-frame message from the display '+'compositor to the client, including the IPC latency and task-'+'queue time in the client.',summaryOptions:tr.metrics.rendering.SUMMARY_OPTIONS,});const issueToRasterStart=histograms.createHistogram('pipeline:begin_frame_to_raster_start',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[],{description:'Latency between begin-frame message and '+'the beginning of the first CompositorTask run in the compositor.',summaryOptions:tr.metrics.rendering.SUMMARY_OPTIONS,});const issueToRasterEnd=histograms.createHistogram('pipeline:begin_frame_to_raster_end',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[],{description:'Latency between begin-frame message and '+'the end of the last CompositorTask run in the compositor.',summaryOptions:tr.metrics.rendering.SUMMARY_OPTIONS,});const receiptToSubmit=histograms.createHistogram('pipeline:begin_frame_to_frame_submission',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[],{description:'Latency between begin-frame reception and '+'CompositorFrame submission in the renderer.',summaryOptions:tr.metrics.rendering.SUMMARY_OPTIONS,});const submitToAggregate=histograms.createHistogram('pipeline:frame_submission_to_display',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[],{description:'Latency between CompositorFrame submission in the '+'renderer to display in the display-compositor, including IPC '+'latency, task-queue time in the display-compositor, and '+'additional processing (e.g. surface-sync etc.)',summaryOptions:tr.metrics.rendering.SUMMARY_OPTIONS,});const aggregateToDraw=histograms.createHistogram('pipeline:draw',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[],{description:'How long it takes for the gpu-swap step.',summaryOptions:tr.metrics.rendering.SUMMARY_OPTIONS,});for(const flow of bindEvents.values()){if(!flow.IssueBeginFrame||!flow.ReceiveBeginFrame||!flow.SubmitCompositorFrame||!flow.SurfaceAggregation){continue;}
+issueToReceipt.addSample(flow.ReceiveBeginFrame.start-
+flow.IssueBeginFrame.start);receiptToSubmit.addSample(flow.SubmitCompositorFrame.end-flow.ReceiveBeginFrame.start,{breakdown:generateBreakdownForCompositorPipelineInClient_(flow)});submitToAggregate.addSample(flow.SurfaceAggregation.end-flow.SubmitCompositorFrame.end,{breakdown:generateBreakdownForCompositorPipelineInService_(flow)});if(flow.SubmitCompositorFrame.parentSlice){const sourceFrameNumber=flow.SubmitCompositorFrame.parentSlice.args.source_frame_number_;const rasterDuration=getRasterTaskTimes(sourceFrameNumber,model);if(rasterDuration&&rasterDuration.start&&rasterDuration.end){const receiveToStart=rasterDuration.start-
+flow.ReceiveBeginFrame.start;const receiveToEnd=rasterDuration.end-flow.ReceiveBeginFrame.end;if(receiveToEnd>0){issueToRasterStart.addSample(receiveToStart>0?receiveToStart:0);issueToRasterEnd.addSample(receiveToEnd);}}}
+if(flow.SurfaceAggregation.args&&flow.SurfaceAggregation.args.display_trace){const displayTrace=flow.SurfaceAggregation.args.display_trace;if(!(displayTrace in drawEvents))continue;const drawEvent=drawEvents[displayTrace];aggregateToDraw.addSample(drawEvent.duration,{breakdown:generateBreakdownForDraw_(drawEvent)});}}}
+return{addPipelineHistograms,};});'use strict';tr.exportTo('tr.metrics.rendering',function(){const IMPL_THREAD_RENDERING_STATS_EVENT='BenchmarkInstrumentation::ImplThreadRenderingStats';const VISIBLE_CONTENT_DATA='visible_content_area';const APPROXIMATED_VISIBLE_CONTENT_DATA='approximated_visible_content_area';const CHECKERBOARDED_VISIBLE_CONTENT_DATA='checkerboarded_visible_content_area';function addPixelsHistograms(histograms,model,segments){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(!chromeHelper)return;const approximatedPixelPercentages=[];const checkerboardedPixelPercentages=[];const ranges=segments.map(s=>s.boundsRange);for(const rendererHelper of Object.values(chromeHelper.rendererHelpers)){if(rendererHelper.compositorThread===undefined)continue;const slices=rendererHelper.compositorThread.sliceGroup;for(const slice of slices.getDescendantEventsInSortedRanges(ranges)){if(slice.title!==IMPL_THREAD_RENDERING_STATS_EVENT)continue;const data=slice.args.data;if(!(VISIBLE_CONTENT_DATA in data)){throw new Error(`${VISIBLE_CONTENT_DATA} is missing`);}
+const visibleContentArea=data[VISIBLE_CONTENT_DATA];if(visibleContentArea===0){continue;}
+if(APPROXIMATED_VISIBLE_CONTENT_DATA in data){approximatedPixelPercentages.push(data[APPROXIMATED_VISIBLE_CONTENT_DATA]/visibleContentArea);}
+if(CHECKERBOARDED_VISIBLE_CONTENT_DATA in data){checkerboardedPixelPercentages.push(data[CHECKERBOARDED_VISIBLE_CONTENT_DATA]/visibleContentArea);}}}
+histograms.createHistogram('mean_pixels_approximated',tr.b.Unit.byName.normalizedPercentage_smallerIsBetter,100*tr.b.math.Statistics.mean(approximatedPixelPercentages),{description:'Percentage of pixels that were approximated '+'(checkerboarding, low-resolution tiles, etc.).',summaryOptions:{},});histograms.createHistogram('mean_pixels_checkerboarded',tr.b.Unit.byName.normalizedPercentage_smallerIsBetter,100*tr.b.math.Statistics.mean(checkerboardedPixelPercentages),{description:'Percentage of pixels that were checkerboarded.',summaryOptions:{},});}
+return{addPixelsHistograms,};});'use strict';tr.exportTo('tr.metrics.rendering',function(){const BEGIN_MAIN_FRAME_EVENT='ThreadProxy::BeginMainFrame';const SEND_BEGIN_FRAME_EVENT='ThreadProxy::ScheduledActionSendBeginMainFrame';function getEventTimesByBeginFrameId_(thread,title,ranges){const out=new Map();const slices=thread.sliceGroup;for(const slice of slices.getDescendantEventsInSortedRanges(ranges)){if(slice.title!==title)continue;const id=slice.args.begin_frame_id;if(id===undefined)throw new Error('Event is missing begin_frame_id');if(out.has(id))throw new Error(`There must be exactly one ${title}`);out.set(id,slice.start);}
+return out;}
+function addQueueingDurationHistograms(histograms,model,segments){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(!chromeHelper)return;let targetRenderers=chromeHelper.telemetryHelper.renderersWithIR;if(targetRenderers.length===0){targetRenderers=Object.values(chromeHelper.rendererHelpers);}
+const queueingDurations=[];const ranges=segments.map(s=>s.boundsRange);for(const rendererHelper of targetRenderers){const mainThread=rendererHelper.mainThread;const compositorThread=rendererHelper.compositorThread;if(mainThread===undefined||compositorThread===undefined)continue;const beginMainFrameTimes=getEventTimesByBeginFrameId_(mainThread,BEGIN_MAIN_FRAME_EVENT,ranges);const sendBeginFrameTimes=getEventTimesByBeginFrameId_(compositorThread,SEND_BEGIN_FRAME_EVENT,ranges);for(const[id,time]of sendBeginFrameTimes){queueingDurations.push(beginMainFrameTimes.get(id)-time);}}
+histograms.createHistogram('queueing_durations',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,queueingDurations,{binBoundaries:tr.v.HistogramBinBoundaries.createExponential(0.01,2,20),summaryOptions:tr.metrics.rendering.SUMMARY_OPTIONS,description:'Time between ScheduledActionSendBeginMainFrame in '+'the compositor thread and the corresponding '+'BeginMainFrame in the main thread.'});}
+return{addQueueingDurationHistograms,};});'use strict';tr.exportTo('tr.metrics.rendering',function(){const GESTURE_EVENT='SyntheticGestureController::running';function renderingMetric(histograms,model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(!chromeHelper)return;let segments=chromeHelper.telemetryHelper.irSegments;if(segments.length===0){segments=chromeHelper.telemetryHelper.animationSegments;}
+if(segments.length>0){tr.metrics.rendering.addFrameTimeHistograms(histograms,model,segments);tr.metrics.rendering.addImageDecodeTimeHistograms(histograms,model,segments);tr.metrics.rendering.addLatencyHistograms(histograms,model,segments);tr.metrics.rendering.addPipelineHistograms(histograms,model,segments);tr.metrics.rendering.addPixelsHistograms(histograms,model,segments);tr.metrics.rendering.addQueueingDurationHistograms(histograms,model,segments);}
+const uiSegments=chromeHelper.telemetryHelper.uiSegments;if(uiSegments.length>0){tr.metrics.rendering.addUIFrameTimeHistograms(histograms,model,chromeHelper.telemetryHelper.uiSegments);}}
+tr.metrics.MetricRegistry.register(renderingMetric,{requiredCategories:['benchmark','toplevel'],});return{renderingMetric,};});'use strict';tr.exportTo('tr.metrics',function(){function sampleExceptionMetric(histograms,model){const hist=new tr.v.Histogram('foo',tr.b.Unit.byName.sizeInBytes_smallerIsBetter);hist.addSample(9);hist.addSample(91,{bar:new tr.v.d.GenericSet([{hello:42}])});for(const expectation of model.userModel.expectations){if(expectation instanceof tr.model.um.ResponseExpectation){}else if(expectation instanceof tr.model.um.AnimationExpectation){}else if(expectation instanceof tr.model.um.IdleExpectation){}else if(expectation instanceof tr.model.um.LoadExpectation){}}
+const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);for(const[pid,process]of Object.entries(model.processes)){}
+histograms.addHistogram(hist);throw new Error('There was an error');}
+tr.metrics.MetricRegistry.register(sampleExceptionMetric);return{sampleExceptionMetric,};});'use strict';tr.exportTo('tr.metrics',function(){function sampleMetric(histograms,model){const hist=new tr.v.Histogram('foo',tr.b.Unit.byName.sizeInBytes_smallerIsBetter);hist.addSample(9);hist.addSample(91,{bar:new tr.v.d.GenericSet([{hello:42}])});for(const expectation of model.userModel.expectations){if(expectation instanceof tr.model.um.ResponseExpectation){}else if(expectation instanceof tr.model.um.AnimationExpectation){}else if(expectation instanceof tr.model.um.IdleExpectation){}else if(expectation instanceof tr.model.um.LoadExpectation){}}
+const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);for(const[pid,process]of Object.entries(model.processes)){}
+histograms.addHistogram(hist);}
+tr.metrics.MetricRegistry.register(sampleMetric);return{sampleMetric,};});'use strict';tr.exportTo('tr.metrics',function(){const HANDLE_INPUT_EVENT_TITLE='WebViewImpl::handleInputEvent';function findPrecedingEvents_(eventsA,eventsB){const events=new Map();let eventsBIndex=0;for(const eventA of eventsA){for(;eventsBIndex<eventsB.length;eventsBIndex++){if(eventsB[eventsBIndex].start>eventA.start)break;}
+if(eventsBIndex>0){events.set(eventA,eventsB[eventsBIndex-1]);}}
+return events;}
+function findFollowingEvents_(eventsA,eventsB){const events=new Map();let eventsBIndex=0;for(const eventA of eventsA){for(;eventsBIndex<eventsB.length;eventsBIndex++){if(eventsB[eventsBIndex].start>=eventA.start)break;}
+if(eventsBIndex>=0&&eventsBIndex<eventsB.length){events.set(eventA,eventsB[eventsBIndex]);}}
+return events;}
+function getSpaNavigationStartCandidates_(rendererHelper,browserHelper){const isNavStartEvent=e=>{if(e.title===HANDLE_INPUT_EVENT_TITLE&&e.args.type==='MouseUp'){return true;}
+return e.title==='NavigationControllerImpl::GoToIndex';};return[...rendererHelper.mainThread.sliceGroup.getDescendantEvents(),...browserHelper.mainThread.sliceGroup.getDescendantEvents()].filter(isNavStartEvent);}
+function getSpaNavigationEvents_(rendererHelper){const isNavEvent=e=>e.category==='blink'&&e.title==='FrameLoader::updateForSameDocumentNavigation';return[...rendererHelper.mainThread.sliceGroup.getDescendantEvents()].filter(isNavEvent);}
+function getInputLatencyEvents_(browserHelper){const isInputLatencyEvent=e=>e.title==='InputLatency::MouseUp';return browserHelper.getAllAsyncSlicesMatching(isInputLatencyEvent);}
+function getInputLatencyEventByBindIdMap_(browserHelper){const inputLatencyEventByBindIdMap=new Map();for(const event of getInputLatencyEvents_(browserHelper)){inputLatencyEventByBindIdMap.set(event.args.data.trace_id,event);}
+return inputLatencyEventByBindIdMap;}
+function getSpaNavigationEventToNavigationStartMap_(rendererHelper,browserHelper){const mainThread=rendererHelper.mainThread;const spaNavEvents=getSpaNavigationEvents_(rendererHelper);const navStartCandidates=getSpaNavigationStartCandidates_(rendererHelper,browserHelper).sort(tr.importer.compareEvents);const spaNavEventToNavStartCandidateMap=findPrecedingEvents_(spaNavEvents,navStartCandidates);const inputLatencyEventByBindIdMap=getInputLatencyEventByBindIdMap_(browserHelper);const spaNavEventToNavStartEventMap=new Map();for(const[spaNavEvent,navStartCandidate]of
+spaNavEventToNavStartCandidateMap){if(navStartCandidate.title===HANDLE_INPUT_EVENT_TITLE){const inputLatencySlice=inputLatencyEventByBindIdMap.get(Number(navStartCandidate.parentSlice.bindId));if(inputLatencySlice){spaNavEventToNavStartEventMap.set(spaNavEvent,inputLatencySlice);}}else{spaNavEventToNavStartEventMap.set(spaNavEvent,navStartCandidate);}}
+return spaNavEventToNavStartEventMap;}
+function getFirstPaintEvents_(rendererHelper){const isFirstPaintEvent=e=>e.category==='blink'&&e.title==='PaintLayerCompositor::updateIfNeededRecursive';return[...rendererHelper.mainThread.sliceGroup.getDescendantEvents()].filter(isFirstPaintEvent);}
+function getSpaNavigationEventToFirstPaintEventMap_(rendererHelper){const spaNavEvents=getSpaNavigationEvents_(rendererHelper).sort(tr.importer.compareEvents);const firstPaintEvents=getFirstPaintEvents_(rendererHelper).sort(tr.importer.compareEvents);return findFollowingEvents_(spaNavEvents,firstPaintEvents);}
+function findSpaNavigationsOnRenderer(rendererHelper,browserHelper){const spaNavEventToNavStartMap=getSpaNavigationEventToNavigationStartMap_(rendererHelper,browserHelper);const spaNavEventToFirstPaintEventMap=getSpaNavigationEventToFirstPaintEventMap_(rendererHelper);const spaNavigations=[];for(const[spaNavEvent,navStartEvent]of
+spaNavEventToNavStartMap){if(spaNavEventToFirstPaintEventMap.has(spaNavEvent)){const firstPaintEvent=spaNavEventToFirstPaintEventMap.get(spaNavEvent);const isNavStartAsyncSlice=navStartEvent instanceof tr.model.AsyncSlice;spaNavigations.push({navStartCandidates:{inputLatencyAsyncSlice:isNavStartAsyncSlice?navStartEvent:undefined,goToIndexSlice:isNavStartAsyncSlice?undefined:navStartEvent},firstPaintEvent,url:spaNavEvent.args.url});}}
+return spaNavigations;}
+return{findSpaNavigationsOnRenderer,};});'use strict';tr.exportTo('tr.metrics.sh',function(){function getWallClockSelfTime_(event,rangeOfInterest){if(event.duration===0)return 0;const selfTimeRanges=[rangeOfInterest.findIntersection(event.range)];for(const subSlice of event.subSlices){if(selfTimeRanges.length===0)return 0;const lastRange=selfTimeRanges.pop();selfTimeRanges.push(...tr.b.math.Range.findDifference(lastRange,subSlice.range));}
+return tr.b.math.Statistics.sum(selfTimeRanges,r=>r.duration);}
+function getCPUSelfTime_(event,rangeOfInterest){if(event.duration===0||event.selfTime===0)return 0;if(event.cpuSelfTime===undefined)return 0;const cpuTimeDensity=event.cpuSelfTime/event.selfTime;return getWallClockSelfTime_(event,rangeOfInterest)*cpuTimeDensity;}
+function generateTimeBreakdownTree(mainThread,rangeOfInterest,getEventSelfTime){if(mainThread===null)return;const breakdownTree={};for(const title of
+tr.e.chrome.ChromeUserFriendlyCategoryDriver.ALL_TITLES){breakdownTree[title]={total:0,events:{}};}
+for(const event of mainThread.sliceGroup.childEvents()){if(!rangeOfInterest.intersectsRangeExclusive(event.range))continue;const eventSelfTime=getEventSelfTime(event,rangeOfInterest);const title=tr.e.chrome.ChromeUserFriendlyCategoryDriver.fromEvent(event);breakdownTree[title].total+=eventSelfTime;if(breakdownTree[title].events[event.title]===undefined){breakdownTree[title].events[event.title]=0;}
+breakdownTree[title].events[event.title]+=eventSelfTime;let timeIntersectionRatio=0;if(event.duration>0){timeIntersectionRatio=rangeOfInterest.findExplicitIntersectionDuration(event.start,event.end)/event.duration;}
+const v8Runtime=event.args['runtime-call-stat'];if(v8Runtime!==undefined){const v8RuntimeObject=JSON.parse(v8Runtime);for(const runtimeCall in v8RuntimeObject){if(v8RuntimeObject[runtimeCall].length===2){if(breakdownTree.v8_runtime.events[runtimeCall]===undefined){breakdownTree.v8_runtime.events[runtimeCall]=0;}
+const runtimeTime=tr.b.Unit.timestampFromUs(v8RuntimeObject[runtimeCall][1]*timeIntersectionRatio);breakdownTree.v8_runtime.total+=runtimeTime;breakdownTree.v8_runtime.events[runtimeCall]+=runtimeTime;}}}}
+return breakdownTree;}
+function addIdleAndBlockByNetworkBreakdown_(breakdownTree,mainThreadEvents,networkEvents,rangeOfInterest){const mainThreadEventRanges=tr.b.math.convertEventsToRanges(mainThreadEvents);const networkEventRanges=tr.b.math.convertEventsToRanges(networkEvents);const eventRanges=mainThreadEventRanges.concat(networkEventRanges);const idleRanges=tr.b.math.findEmptyRangesBetweenRanges(eventRanges,rangeOfInterest);const totalFreeDuration=tr.b.math.Statistics.sum(idleRanges,range=>range.duration);breakdownTree.idle={total:totalFreeDuration,events:{}};let totalBlockedDuration=rangeOfInterest.duration;for(const[title,component]of Object.entries(breakdownTree)){if(title==='v8_runtime')continue;totalBlockedDuration-=component.total;}
+breakdownTree.blocked_on_network={total:Math.max(totalBlockedDuration,0),events:{}};}
+function generateWallClockTimeBreakdownTree(mainThread,networkEvents,rangeOfInterest){const breakdownTree=generateTimeBreakdownTree(mainThread,rangeOfInterest,getWallClockSelfTime_);const mainThreadEventsInRange=tr.model.helpers.getSlicesIntersectingRange(rangeOfInterest,mainThread.sliceGroup.topLevelSlices);addIdleAndBlockByNetworkBreakdown_(breakdownTree,mainThreadEventsInRange,networkEvents,rangeOfInterest);return breakdownTree;}
+function generateCpuTimeBreakdownTree(mainThread,rangeOfInterest){return generateTimeBreakdownTree(mainThread,rangeOfInterest,getCPUSelfTime_);}
+return{generateTimeBreakdownTree,generateWallClockTimeBreakdownTree,generateCpuTimeBreakdownTree,};});'use strict';tr.exportTo('tr.e.chrome',function(){const LCP_CANDIDATE_EVENT_TITLE='NavStartToLargestContentfulPaint::Candidate::AllFrames::UKM';const LCP_INVALIDATE_EVENT_TITLE='NavStartToLargestContentfulPaint::Invalidate::AllFrames::UKM';class LcpEvent{constructor(event){if(!LcpInvalidateEvent.isLcpInvalidateEvent(event)&&!LcpCandidateEvent.isLcpCandidateEvent(event)){throw new Error('The LCP event should be either a candidate event or'+'an invalidate event.');}
+if(event.start===undefined||event.args.main_frame_tree_node_id===undefined){throw new Error('The LCP event is in unexpected format.');}
+this.start=event.start;this.mainFrameTreeNodeId=event.args.main_frame_tree_node_id;}}
+class LcpCandidateEvent extends LcpEvent{constructor(event){super(event);const{durationInMilliseconds,size,type,inMainFrame}=event.args.data;if(durationInMilliseconds===undefined||size===undefined||type===undefined||inMainFrame===undefined||event.args.main_frame_tree_node_id===undefined||!LcpCandidateEvent.isLcpCandidateEvent(event)){throw new Error('The LCP candidate event is in unexpected format.');}
+this.durationInMilliseconds=durationInMilliseconds;this.size=size;this.type=type;this.inMainFrame=inMainFrame;}
+static isLcpCandidateEvent(event){return event.title===LCP_CANDIDATE_EVENT_TITLE;}}
+class LcpInvalidateEvent extends LcpEvent{constructor(event){super(event);if(!LcpInvalidateEvent.isLcpInvalidateEvent(event)){throw new Error('The LCP invalidate event is in unexpected format.');}}
+static isLcpInvalidateEvent(event){return event.title===LCP_INVALIDATE_EVENT_TITLE;}}
+class LargestContentfulPaint{constructor(allBrowserEvents){this.allBrowserEvents=allBrowserEvents;}
+findCandidates(){const finalLcpEvents=this.findFinalLcpEventOfEachNavigation(this.allBrowserEvents);const finalCandidates=finalLcpEvents.filter(finalLcpEvent=>!LcpInvalidateEvent.isLcpInvalidateEvent(finalLcpEvent));return finalCandidates;}
+findFinalLcpEventOfEachNavigation(allBrowserEvents){const lcpEvents=[];for(const lcpEvent of allBrowserEvents){if(LcpCandidateEvent.isLcpCandidateEvent(lcpEvent)){lcpEvents.push(new LcpCandidateEvent(lcpEvent));}else if(LcpInvalidateEvent.isLcpInvalidateEvent(lcpEvent)){lcpEvents.push(new LcpInvalidateEvent(lcpEvent));}}
+const lcpEventsGroupedByNavigation=new Map();for(const e of lcpEvents){const key=e.mainFrameTreeNodeId;if(!lcpEventsGroupedByNavigation.has(key)){lcpEventsGroupedByNavigation[key]=[];}
+lcpEventsGroupedByNavigation[key].push(e);}
+const finalLcpEventOfEachNaivgation=[];for(const lcpEventList of Object.values(lcpEventsGroupedByNavigation)){lcpEventList.sort((a,b)=>a.start-b.start);finalLcpEventOfEachNaivgation.push(lcpEventList[lcpEventList.length-1]);}
+return finalLcpEventOfEachNaivgation;}}
+return{LCP_CANDIDATE_EVENT_TITLE,LCP_INVALIDATE_EVENT_TITLE,LargestContentfulPaint,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const LONG_TASK_THRESHOLD_MS=50;const timeDurationInMs_smallerIsBetter=tr.b.Unit.byName.timeDurationInMs_smallerIsBetter;const unitlessNumber_smallerIsBetter=tr.b.Unit.byName.unitlessNumber_smallerIsBetter;const RelatedEventSet=tr.v.d.RelatedEventSet;const hasCategoryAndName=tr.metrics.sh.hasCategoryAndName;const EventFinderUtils=tr.e.chrome.EventFinderUtils;function createBreakdownDiagnostic(breakdownTree){const breakdownDiagnostic=new tr.v.d.Breakdown();breakdownDiagnostic.colorScheme=tr.v.d.COLOR_SCHEME_CHROME_USER_FRIENDLY_CATEGORY_DRIVER;for(const label in breakdownTree){breakdownDiagnostic.set(label,breakdownTree[label].total);}
+return breakdownDiagnostic;}
+const LOADING_METRIC_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(0,1e3,20).addLinearBins(3e3,20).addExponentialBins(20e3,20);const TIME_TO_INTERACTIVE_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(1,40e3,35).addExponentialBins(80e3,15);const LAYOUT_SHIFT_SCORE_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(0,50,25);const SUMMARY_OPTIONS={avg:true,count:false,max:true,min:true,std:true,sum:false,};function findFrameLoaderSnapshotAt(rendererHelper,frameIdRef,ts){const objects=rendererHelper.process.objects;const frameLoaderInstances=objects.instancesByTypeName_.FrameLoader;if(frameLoaderInstances===undefined)return undefined;let snapshot;for(const instance of frameLoaderInstances){if(!instance.isAliveAt(ts))continue;const maybeSnapshot=instance.getSnapshotAt(ts);if(frameIdRef!==maybeSnapshot.args.frame.id_ref)continue;snapshot=maybeSnapshot;}
+return snapshot;}
+function findAllEvents(rendererHelper,category,title){const targetEvents=[];for(const ev of rendererHelper.process.getDescendantEvents()){if(!hasCategoryAndName(ev,category,title))continue;targetEvents.push(ev);}
+return targetEvents;}
+function getMostRecentValidEvent(rendererHelper,category,title){const targetEvents=findAllEvents(rendererHelper,category,title);let validEvent;for(const targetEvent of targetEvents){if(rendererHelper.isTelemetryInternalEvent(targetEvent))continue;if(validEvent===undefined){validEvent=targetEvent;}else{if(validEvent.start<targetEvent.start){validEvent=targetEvent;}}}
+return validEvent;}
+function getFirstViewportReadySamples(rendererHelper,navIdToNavStartEvents){const samples=[];const pcEvent=getMostRecentValidEvent(rendererHelper,'blink.user_timing','pc');if(pcEvent===undefined)return samples;if(rendererHelper.isTelemetryInternalEvent(pcEvent))return samples;const navigationStartEvent=navIdToNavStartEvents.get(pcEvent.args.data.navigationId);if(navigationStartEvent===undefined)return samples;const navStartToEventRange=tr.b.math.Range.fromExplicitRange(navigationStartEvent.start,pcEvent.start);const networkEvents=EventFinderUtils.getNetworkEventsInRange(rendererHelper.process,navStartToEventRange);const breakdownTree=tr.metrics.sh.generateWallClockTimeBreakdownTree(rendererHelper.mainThread,networkEvents,navStartToEventRange);samples.push({value:navStartToEventRange.duration,breakdownTree,diagnostics:{breakdown:createBreakdownDiagnostic(breakdownTree),Start:new RelatedEventSet(navigationStartEvent),End:new RelatedEventSet(pcEvent)}});return samples;}
+function getAboveTheFoldLoadedToVisibleSamples(rendererHelper){const samples=[];const pcEvent=getMostRecentValidEvent(rendererHelper,'blink.user_timing','pc');const visibleEvent=getMostRecentValidEvent(rendererHelper,'blink.user_timing','visible');if(pcEvent!==undefined&&visibleEvent!==undefined){samples.push({value:Math.max(0.0,pcEvent.start-visibleEvent.start),diagnostics:{Start:new RelatedEventSet(visibleEvent),End:new RelatedEventSet(pcEvent)}});}
+return samples;}
+function findTimeToXEntries(category,eventName,rendererHelper,frameToNavStartEvents,navIdToNavStartEvents){const targetEvents=findAllEvents(rendererHelper,category,eventName);const entries=[];for(const targetEvent of targetEvents){if(rendererHelper.isTelemetryInternalEvent(targetEvent))continue;const frameIdRef=targetEvent.args.frame;const snapshot=findFrameLoaderSnapshotAt(rendererHelper,frameIdRef,targetEvent.start);if(snapshot===undefined||!snapshot.args.isLoadingMainFrame)continue;const url=snapshot.args.documentLoaderURL;if(tr.e.chrome.CHROME_INTERNAL_URLS.includes(url))continue;let navigationStartEvent;if(targetEvent.args.data===undefined||targetEvent.args.data.navigationId===undefined){navigationStartEvent=EventFinderUtils.findLastEventStartingOnOrBeforeTimestamp(frameToNavStartEvents.get(frameIdRef)||[],targetEvent.start);}else{navigationStartEvent=navIdToNavStartEvents.get(targetEvent.args.data.navigationId);}
+if(navigationStartEvent===undefined)continue;entries.push({navigationStartEvent,targetEvent,url,});}
+return entries;}
+function collectTimeToEvent(rendererHelper,timeToXEntries){const samples=[];for(const{targetEvent,navigationStartEvent,url}of timeToXEntries){const navStartToEventRange=tr.b.math.Range.fromExplicitRange(navigationStartEvent.start,targetEvent.start);const networkEvents=EventFinderUtils.getNetworkEventsInRange(rendererHelper.process,navStartToEventRange);const breakdownTree=tr.metrics.sh.generateWallClockTimeBreakdownTree(rendererHelper.mainThread,networkEvents,navStartToEventRange);samples.push({value:navStartToEventRange.duration,breakdownTree,diagnostics:{breakdown:createBreakdownDiagnostic(breakdownTree),url:new tr.v.d.GenericSet([url]),Start:new RelatedEventSet(navigationStartEvent),End:new RelatedEventSet(targetEvent)}});}
+return samples;}
+function collectTimeToEventInCpuTime(rendererHelper,timeToXEntries){const samples=[];for(const{targetEvent,navigationStartEvent,url}of timeToXEntries){const navStartToEventRange=tr.b.math.Range.fromExplicitRange(navigationStartEvent.start,targetEvent.start);const mainThreadCpuTime=rendererHelper.mainThread.getCpuTimeForRange(navStartToEventRange);const breakdownTree=tr.metrics.sh.generateCpuTimeBreakdownTree(rendererHelper.mainThread,navStartToEventRange);samples.push({value:mainThreadCpuTime,breakdownTree,diagnostics:{breakdown:createBreakdownDiagnostic(breakdownTree),start:new RelatedEventSet(navigationStartEvent),end:new RelatedEventSet(targetEvent),infos:new tr.v.d.GenericSet([{pid:rendererHelper.pid,start:navigationStartEvent.start,event:targetEvent.start,}]),}});}
+return samples;}
+function findLayoutShiftSamples(rendererHelper){let sample;EventFinderUtils.getSortedMainThreadEventsByFrame(rendererHelper,'LayoutShift','loading').forEach((events)=>{const evData=events.pop().args.data;if(evData.is_main_frame){sample={value:evData.cumulative_score};}});return sample?[sample]:[];}
+function lineSweep(lineSweepRects,viewport){const verticalSweepRects=[];const horizontalSweepRects=[];for(let i=0;i<lineSweepRects.length;i++){const rect=lineSweepRects[i];let left=rect.left;let right=rect.right;let top=rect.top;let bottom=rect.bottom;if(left>viewport.x+viewport.width)continue;if(right<viewport.x)continue;if(top>viewport.y+viewport.height)continue;if(bottom<viewport.y)continue;left=Math.max(left,viewport.y);right=Math.min(right,viewport.y+viewport.width);top=Math.max(top,viewport.y);bottom=Math.min(bottom,viewport.y+viewport.height);verticalSweepRects.push({id:i,value:left,type:'left'},{id:i,value:right,type:'right'});horizontalSweepRects.push({id:i,value:top,type:'top'},{id:i,value:bottom,type:'bottom'});}
+verticalSweepRects.sort((a,b)=>a.value-b.value);horizontalSweepRects.sort((a,b)=>a.value-b.value);const active=new Array(lineSweepRects.length).fill(0);let area=0;active[verticalSweepRects[0].id]=1;for(let i=1;i<verticalSweepRects.length;i++){const currentLine=verticalSweepRects[i];const previousLine=verticalSweepRects[i-1];const deltaX=currentLine.value-previousLine.value;if(deltaX===0)continue;let count=0;let firstRect;for(let j=0;j<horizontalSweepRects.length;j++){if(active[horizontalSweepRects[j].id]===1){if(horizontalSweepRects[j].type==='top'){if(count===0){firstRect=j;count++;}}else{if(count===1){const deltaY=horizontalSweepRects[j].value-
+horizontalSweepRects[firstRect].value;area+=deltaX*deltaY;count--;}}}}
+active[currentLine.id]=(currentLine.type==='left');}
+return area;}
+function addVisuallyCompleteBeforeSomeTimeSample(samples,rendererHelper,navigationStart,loadDuration,frameID){const someTime=2000;if(loadDuration<someTime)return;let viewport;for(const event of EventFinderUtils.getMainThreadEvents(rendererHelper,'viewport','loading')){if(event.args.data.frameID===frameID&&event.start>navigationStart&&event.start<navigationStart+loadDuration){viewport=event.args.data;break;}}
+if(!viewport)return;const ccDisplayItemListObjects=rendererHelper.process.objects.getAllInstancesNamed('cc::DisplayItemList');if(!ccDisplayItemListObjects||!ccDisplayItemListObjects.length)return;const RectsUpdatedAfterSomeTime=[];for(let i=0;i<ccDisplayItemListObjects.length;i++){const displayItemListSnapshots=ccDisplayItemListObjects[i].snapshots;for(let j=0;j<displayItemListSnapshots.length;j++){const snapshot=displayItemListSnapshots[j];const timestamp=snapshot.ts;if(timestamp<navigationStart||timestamp>navigationStart+loadDuration){continue;}
+if(timestamp-navigationStart>someTime){RectsUpdatedAfterSomeTime.push(snapshot.args.params.layerRect);}}}
+const areaUpdatedAfterSomeTime=RectsUpdatedAfterSomeTime.length?lineSweep(RectsUpdatedAfterSomeTime,viewport):0;const pixelsLastUpdatedBeforeSomeTime=1-
+areaUpdatedAfterSomeTime/(viewport.width*viewport.height);samples.push({value:pixelsLastUpdatedBeforeSomeTime});}
+function addSpeedIndexSample(rendererHelper){const rects=[];let totalArea=0;for(const event of EventFinderUtils.getMainThreadEvents(rendererHelper,'PaintTracker::LayoutObjectPainted','loading')){const rect=event.args.data.visible_new_visual_rect;if(!rect)continue;const area=areaOfQuad(rect);if(!area)continue;rects.push({rect,ts:event.start});totalArea+=area;}
+const sample=[];if(!totalArea)return sample;let areaSoFar=0;const progress=new Array(rects.length);for(let i=0;i<rects.length;i++){const area=areaOfQuad(rects[i].rect);areaSoFar+=(area/totalArea);progress[i]={value:areaSoFar,ts:rects[i].ts};}
+sample.push({value:calculateSpeedIndex(progress)});return sample;}
+function areaOfQuad(quad){const width=Math.max(Math.abs(quad[0]-quad[2]),Math.abs(quad[2]-quad[4]));const height=Math.max(Math.abs(quad[1]-quad[3]),Math.abs(quad[3]-quad[5]));return width*height;}
+function calculateSpeedIndex(progress){let lastMs=0;let lastProgress=0;let speedIndex=0;for(let i=0;i<progress.length;i++){const elapsed=progress[i].ts-lastMs;speedIndex+=elapsed*(1.0-lastProgress);lastMs=progress[i].ts;lastProgress=progress[i].value;}
+return speedIndex;}
+function addFirstMeaningfulPaintSample(samples,rendererHelper,navigationStart,fmpMarkerEvent,url){const navStartToFMPRange=tr.b.math.Range.fromExplicitRange(navigationStart.start,fmpMarkerEvent.start);const networkEvents=EventFinderUtils.getNetworkEventsInRange(rendererHelper.process,navStartToFMPRange);const timeToFirstMeaningfulPaint=navStartToFMPRange.duration;const breakdownTree=tr.metrics.sh.generateWallClockTimeBreakdownTree(rendererHelper.mainThread,networkEvents,navStartToFMPRange);samples.push({value:timeToFirstMeaningfulPaint,breakdownTree,diagnostics:{breakdown:createBreakdownDiagnostic(breakdownTree),start:new RelatedEventSet(navigationStart),end:new RelatedEventSet(fmpMarkerEvent),infos:new tr.v.d.GenericSet([{url,pid:rendererHelper.pid,start:navigationStart.start,fmp:fmpMarkerEvent.start,}]),}});}
+function addFirstMeaningfulPaintCpuTimeSample(samples,rendererHelper,navigationStart,fmpMarkerEvent,url){const navStartToFMPRange=tr.b.math.Range.fromExplicitRange(navigationStart.start,fmpMarkerEvent.start);const mainThreadCpuTime=rendererHelper.mainThread.getCpuTimeForRange(navStartToFMPRange);const breakdownTree=tr.metrics.sh.generateCpuTimeBreakdownTree(rendererHelper.mainThread,navStartToFMPRange);samples.push({value:mainThreadCpuTime,breakdownTree,diagnostics:{breakdown:createBreakdownDiagnostic(breakdownTree),start:new RelatedEventSet(navigationStart),end:new RelatedEventSet(fmpMarkerEvent),infos:new tr.v.d.GenericSet([{url,pid:rendererHelper.pid,start:navigationStart.start,fmp:fmpMarkerEvent.start,}]),}});}
+function decorateInteractivitySampleWithDiagnostics_(rendererHelper,eventTimestamp,navigationStartEvent,firstMeaningfulPaintTime,domContentLoadedEndTime,url){if(eventTimestamp===undefined)return undefined;const navigationStartTime=navigationStartEvent.start;const navStartToEventTimeRange=tr.b.math.Range.fromExplicitRange(navigationStartTime,eventTimestamp);const networkEvents=EventFinderUtils.getNetworkEventsInRange(rendererHelper.process,navStartToEventTimeRange);const breakdownTree=tr.metrics.sh.generateWallClockTimeBreakdownTree(rendererHelper.mainThread,networkEvents,navStartToEventTimeRange);const breakdownDiagnostic=createBreakdownDiagnostic(breakdownTree);return{value:navStartToEventTimeRange.duration,diagnostics:tr.v.d.DiagnosticMap.fromObject({'Start':new RelatedEventSet(navigationStartEvent),'Navigation infos':new tr.v.d.GenericSet([{url,pid:rendererHelper.pid,navigationStartTime,firstMeaningfulPaintTime,domContentLoadedEndTime,eventTimestamp,}]),'Breakdown of [navStart, eventTimestamp]':breakdownDiagnostic,}),};}
+function getCandidateIndex(entry){return entry.targetEvent.args.data.candidateIndex;}
+function findLastCandidateForEachNavigation(timeToXEntries){const entryMap=new Map();for(const e of timeToXEntries){const navStartEvent=e.navigationStartEvent;if(!entryMap.has(navStartEvent)){entryMap.set(navStartEvent,[]);}
+entryMap.get(navStartEvent).push(e);}
+const lastCandidates=[];for(const timeToXEntriesByNavigation of entryMap.values()){let lastCandidate=timeToXEntriesByNavigation.shift();for(const entry of timeToXEntriesByNavigation){if(getCandidateIndex(entry)>getCandidateIndex(lastCandidate)){lastCandidate=entry;}}
+lastCandidates.push(lastCandidate);}
+return lastCandidates;}
+function findLargestTextPaintSamples(rendererHelper,frameToNavStartEvents,navIdToNavStartEvents){const timeToPaintEntries=findTimeToXEntries('loading','LargestTextPaint::Candidate',rendererHelper,frameToNavStartEvents,navIdToNavStartEvents);const timeToPaintBlockingEntries=findTimeToXEntries('loading','LargestTextPaint::NoCandidate',rendererHelper,frameToNavStartEvents,navIdToNavStartEvents);const lastCandidateEvents=findLastCandidateForEachNavigation(timeToPaintEntries.concat(timeToPaintBlockingEntries)).filter(event=>event.targetEvent.title!=='LargestTextPaint::NoCandidate');return collectTimeToEvent(rendererHelper,lastCandidateEvents);}
+function findLargestImagePaintSamples(rendererHelper,frameToNavStartEvents,navIdToNavStartEvents){const timeToPaintEntries=findTimeToXEntries('loading','LargestImagePaint::Candidate',rendererHelper,frameToNavStartEvents,navIdToNavStartEvents);const timeToPaintBlockingEntries=findTimeToXEntries('loading','LargestImagePaint::NoCandidate',rendererHelper,frameToNavStartEvents,navIdToNavStartEvents);const lastCandidateEvents=findLastCandidateForEachNavigation(timeToPaintEntries.concat(timeToPaintBlockingEntries)).filter(event=>event.targetEvent.title!=='LargestImagePaint::NoCandidate');return collectTimeToEvent(rendererHelper,lastCandidateEvents);}
+function findLargestContentfulPaintHistogramSamples(allBrowserEvents){const lcp=new tr.e.chrome.LargestContentfulPaint(allBrowserEvents);const lcpSamples=lcp.findCandidates().map(candidate=>{const{durationInMilliseconds,size,type,inMainFrame,mainFrameTreeNodeId}=candidate;return{value:durationInMilliseconds,diagnostics:{size:new tr.v.d.GenericSet([size]),type:new tr.v.d.GenericSet([type]),inMainFrame:new tr.v.d.GenericSet([inMainFrame]),mainFrameTreeNodeId:new tr.v.d.GenericSet([mainFrameTreeNodeId]),},};});return lcpSamples;}
+function collectLoadingMetricsForRenderer(rendererHelper){const frameToNavStartEvents=EventFinderUtils.getSortedMainThreadEventsByFrame(rendererHelper,'navigationStart','blink.user_timing');const navIdToNavStartEvents=EventFinderUtils.getSortedMainThreadEventsByNavId(rendererHelper,'navigationStart','blink.user_timing');const firstPaintSamples=collectTimeToEvent(rendererHelper,findTimeToXEntries('loading','firstPaint',rendererHelper,frameToNavStartEvents,navIdToNavStartEvents));const timeToFCPEntries=findTimeToXEntries('loading','firstContentfulPaint',rendererHelper,frameToNavStartEvents,navIdToNavStartEvents);const firstContentfulPaintSamples=collectTimeToEvent(rendererHelper,timeToFCPEntries);const firstContentfulPaintCpuTimeSamples=collectTimeToEventInCpuTime(rendererHelper,timeToFCPEntries);const onLoadSamples=collectTimeToEvent(rendererHelper,findTimeToXEntries('blink.user_timing','loadEventStart',rendererHelper,frameToNavStartEvents,navIdToNavStartEvents));const aboveTheFoldLoadedToVisibleSamples=getAboveTheFoldLoadedToVisibleSamples(rendererHelper);const firstViewportReadySamples=getFirstViewportReadySamples(rendererHelper,navIdToNavStartEvents);const largestImagePaintSamples=findLargestImagePaintSamples(rendererHelper,frameToNavStartEvents,navIdToNavStartEvents);const largestTextPaintSamples=findLargestTextPaintSamples(rendererHelper,frameToNavStartEvents,navIdToNavStartEvents);const layoutShiftSamples=findLayoutShiftSamples(rendererHelper);const speedIndexSamples=addSpeedIndexSample(rendererHelper);return{frameToNavStartEvents,firstPaintSamples,firstContentfulPaintSamples,firstContentfulPaintCpuTimeSamples,onLoadSamples,aboveTheFoldLoadedToVisibleSamples,firstViewportReadySamples,largestImagePaintSamples,largestTextPaintSamples,layoutShiftSamples,speedIndexSamples};}
+function collectMetricsFromLoadExpectations(model,chromeHelper){const interactiveSamples=[];const firstCpuIdleSamples=[];const firstMeaningfulPaintSamples=[];const firstMeaningfulPaintCpuTimeSamples=[];const visuallyCompleteBeforeSomeTimeSamples=[];for(const expectation of model.userModel.expectations){if(!(expectation instanceof tr.model.um.LoadExpectation))continue;if(tr.e.chrome.CHROME_INTERNAL_URLS.includes(expectation.url)){continue;}
+const rendererHelper=chromeHelper.rendererHelpers[expectation.renderProcess.pid];addVisuallyCompleteBeforeSomeTimeSample(visuallyCompleteBeforeSomeTimeSamples,rendererHelper,expectation.navigationStart.start,expectation.duration,expectation.navigationStart.args.frame);if(expectation.fmpEvent!==undefined){addFirstMeaningfulPaintSample(firstMeaningfulPaintSamples,rendererHelper,expectation.navigationStart,expectation.fmpEvent,expectation.url);addFirstMeaningfulPaintCpuTimeSample(firstMeaningfulPaintCpuTimeSamples,rendererHelper,expectation.navigationStart,expectation.fmpEvent,expectation.url);}
+if(expectation.firstCpuIdleTime!==undefined){firstCpuIdleSamples.push(decorateInteractivitySampleWithDiagnostics_(rendererHelper,expectation.firstCpuIdleTime,expectation.navigationStart,expectation.fmpEvent.start,expectation.domContentLoadedEndEvent.start,expectation.url));}
+if(expectation.timeToInteractive!==undefined){interactiveSamples.push(decorateInteractivitySampleWithDiagnostics_(rendererHelper,expectation.timeToInteractive,expectation.navigationStart,expectation.fmpEvent.start,expectation.domContentLoadedEndEvent.start,expectation.url));}}
+return{firstMeaningfulPaintSamples,firstMeaningfulPaintCpuTimeSamples,firstCpuIdleSamples,interactiveSamples,visuallyCompleteBeforeSomeTimeSamples,};}
+function addSamplesToHistogram(samples,histogram,histograms){for(const sample of samples){histogram.addSample(sample.value,sample.diagnostics);if(histogram.name!=='timeToFirstContentfulPaint')continue;if(!sample.breakdownTree)continue;for(const[category,breakdown]of Object.entries(sample.breakdownTree)){const relatedName=`${histogram.name}:${category}`;let relatedHist=histograms.getHistogramsNamed(relatedName)[0];if(!relatedHist){relatedHist=histograms.createHistogram(relatedName,histogram.unit,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,summaryOptions:{count:false,max:false,min:false,sum:false,},});let relatedNames=histogram.diagnostics.get('breakdown');if(!relatedNames){relatedNames=new tr.v.d.RelatedNameMap();histogram.diagnostics.set('breakdown',relatedNames);}
+relatedNames.set(category,relatedName);}
+relatedHist.addSample(breakdown.total,{breakdown:tr.v.d.Breakdown.fromEntries(Object.entries(breakdown.events)),});}}}
+function loadingMetric(histograms,model){const firstPaintHistogram=histograms.createHistogram('timeToFirstPaint',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'time to first paint',summaryOptions:SUMMARY_OPTIONS,});const firstContentfulPaintHistogram=histograms.createHistogram('timeToFirstContentfulPaint',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'time to first contentful paint',summaryOptions:SUMMARY_OPTIONS,});const firstContentfulPaintCpuTimeHistogram=histograms.createHistogram('cpuTimeToFirstContentfulPaint',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'CPU time to first contentful paint',summaryOptions:SUMMARY_OPTIONS,});const onLoadHistogram=histograms.createHistogram('timeToOnload',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'time to onload. '+'This is temporary metric used for PCv1/v2 sanity checking',summaryOptions:SUMMARY_OPTIONS,});const firstMeaningfulPaintHistogram=histograms.createHistogram('timeToFirstMeaningfulPaint',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'time to first meaningful paint',summaryOptions:SUMMARY_OPTIONS,});const firstMeaningfulPaintCpuTimeHistogram=histograms.createHistogram('cpuTimeToFirstMeaningfulPaint',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'CPU time to first meaningful paint',summaryOptions:SUMMARY_OPTIONS,});const timeToInteractiveHistogram=histograms.createHistogram('timeToInteractive',timeDurationInMs_smallerIsBetter,[],{binBoundaries:TIME_TO_INTERACTIVE_BOUNDARIES,description:'Time to Interactive',summaryOptions:SUMMARY_OPTIONS,});const timeToFirstCpuIdleHistogram=histograms.createHistogram('timeToFirstCpuIdle',timeDurationInMs_smallerIsBetter,[],{binBoundaries:TIME_TO_INTERACTIVE_BOUNDARIES,description:'Time to First CPU Idle',summaryOptions:SUMMARY_OPTIONS,});const aboveTheFoldLoadedToVisibleHistogram=histograms.createHistogram('aboveTheFoldLoadedToVisible',timeDurationInMs_smallerIsBetter,[],{binBoundaries:TIME_TO_INTERACTIVE_BOUNDARIES,description:'Time from first visible to load for AMP pages only.',summaryOptions:SUMMARY_OPTIONS,});const firstViewportReadyHistogram=histograms.createHistogram('timeToFirstViewportReady',timeDurationInMs_smallerIsBetter,[],{binBoundaries:TIME_TO_INTERACTIVE_BOUNDARIES,description:'Time from navigation to load for AMP pages only. ',summaryOptions:SUMMARY_OPTIONS,});const largestImagePaintHistogram=histograms.createHistogram('largestImagePaint',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'Time to Largest Image Paint',summaryOptions:SUMMARY_OPTIONS,});const largestTextPaintHistogram=histograms.createHistogram('largestTextPaint',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'Time to Largest Text Paint',summaryOptions:SUMMARY_OPTIONS,});const largestContentfulPaintHistogram=histograms.createHistogram('largestContentfulPaint',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'Time to Largest Contentful Paint',summaryOptions:SUMMARY_OPTIONS,});const layoutShiftHistogram=histograms.createHistogram('mainFrameCumulativeLayoutShift',unitlessNumber_smallerIsBetter,[],{binBoundaries:LAYOUT_SHIFT_SCORE_BOUNDARIES,description:'Main Frame Document Cumulative Layout Shift Score',summaryOptions:SUMMARY_OPTIONS,});const visuallyCompleteBeforeSomeTimeHistogram=histograms.createHistogram('visuallyCompleteBeforeSomeTime',unitlessNumber_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'Fraction of pixels in the initial viewport reaching '+'final value within some time interval after navigation start.',summaryOptions:SUMMARY_OPTIONS,});const speedIndexHistogram=histograms.createHistogram('speedIndex',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:' the average time at which visible parts of the'+' page are displayed (in ms).',summaryOptions:SUMMARY_OPTIONS,});const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);for(const pid in chromeHelper.rendererHelpers){const rendererHelper=chromeHelper.rendererHelpers[pid];if(rendererHelper.isChromeTracingUI)continue;const samplesSet=collectLoadingMetricsForRenderer(rendererHelper);const lcpSamples=findLargestContentfulPaintHistogramSamples(chromeHelper.browserHelper.mainThread.sliceGroup.slices);addSamplesToHistogram(lcpSamples,largestContentfulPaintHistogram,histograms);addSamplesToHistogram(samplesSet.firstPaintSamples,firstPaintHistogram,histograms);addSamplesToHistogram(samplesSet.firstContentfulPaintSamples,firstContentfulPaintHistogram,histograms);addSamplesToHistogram(samplesSet.firstContentfulPaintCpuTimeSamples,firstContentfulPaintCpuTimeHistogram,histograms);addSamplesToHistogram(samplesSet.onLoadSamples,onLoadHistogram,histograms);addSamplesToHistogram(samplesSet.aboveTheFoldLoadedToVisibleSamples,aboveTheFoldLoadedToVisibleHistogram,histograms);addSamplesToHistogram(samplesSet.firstViewportReadySamples,firstViewportReadyHistogram,histograms);addSamplesToHistogram(samplesSet.largestImagePaintSamples,largestImagePaintHistogram,histograms);addSamplesToHistogram(samplesSet.largestTextPaintSamples,largestTextPaintHistogram,histograms);addSamplesToHistogram(samplesSet.layoutShiftSamples,layoutShiftHistogram,histograms);addSamplesToHistogram(samplesSet.speedIndexSamples,speedIndexHistogram,histograms);}
+const samplesSet=collectMetricsFromLoadExpectations(model,chromeHelper);addSamplesToHistogram(samplesSet.firstMeaningfulPaintSamples,firstMeaningfulPaintHistogram,histograms);addSamplesToHistogram(samplesSet.firstMeaningfulPaintCpuTimeSamples,firstMeaningfulPaintCpuTimeHistogram,histograms);addSamplesToHistogram(samplesSet.interactiveSamples,timeToInteractiveHistogram,histograms);addSamplesToHistogram(samplesSet.firstCpuIdleSamples,timeToFirstCpuIdleHistogram,histograms);addSamplesToHistogram(samplesSet.visuallyCompleteBeforeSomeTimeSamples,visuallyCompleteBeforeSomeTimeHistogram,histograms);}
+tr.metrics.MetricRegistry.register(loadingMetric);return{loadingMetric,createBreakdownDiagnostic};});'use strict';tr.exportTo('tr.metrics',function(){const SPA_NAVIGATION_START_TO_FIRST_PAINT_DURATION_BIN_BOUNDARY=tr.v.HistogramBinBoundaries.createExponential(1,1000,50);function spaNavigationMetric(histograms,model){const histogram=new tr.v.Histogram('spaNavigationStartToFpDuration',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,SPA_NAVIGATION_START_TO_FIRST_PAINT_DURATION_BIN_BOUNDARY);histogram.description='Latency between the input event causing'+' a SPA navigation and the first paint event after it';histogram.customizeSummaryOptions({count:false,sum:false,});const modelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(!modelHelper){return;}
+const rendererHelpers=modelHelper.rendererHelpers;if(!rendererHelpers){return;}
+const browserHelper=modelHelper.browserHelper;for(const rendererHelper of Object.values(rendererHelpers)){const spaNavigations=tr.metrics.findSpaNavigationsOnRenderer(rendererHelper,browserHelper);for(const spaNav of spaNavigations){let beginTs=0;if(spaNav.navStartCandidates.inputLatencyAsyncSlice){const beginData=spaNav.navStartCandidates.inputLatencyAsyncSlice.args.data;beginTs=model.convertTimestampToModelTime('traceEventClock',beginData.INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT.time);}else{beginTs=spaNav.navStartCandidates.goToIndexSlice.start;}
+const rangeOfInterest=tr.b.math.Range.fromExplicitRange(beginTs,spaNav.firstPaintEvent.start);const networkEvents=tr.e.chrome.EventFinderUtils.getNetworkEventsInRange(rendererHelper.process,rangeOfInterest);const breakdownDict=tr.metrics.sh.generateWallClockTimeBreakdownTree(rendererHelper.mainThread,networkEvents,rangeOfInterest);const breakdownDiagnostic=new tr.v.d.Breakdown();breakdownDiagnostic.colorScheme=tr.v.d.COLOR_SCHEME_CHROME_USER_FRIENDLY_CATEGORY_DRIVER;for(const label in breakdownDict){breakdownDiagnostic.set(label,parseInt(breakdownDict[label].total*1e3)/1e3);}
+histogram.addSample(rangeOfInterest.duration,{'Breakdown of [navStart, firstPaint]':breakdownDiagnostic,'Start':new tr.v.d.RelatedEventSet(spaNav.navigationStart),'End':new tr.v.d.RelatedEventSet(spaNav.firstPaintEvent),'Navigation infos':new tr.v.d.GenericSet([{url:spaNav.url,pid:rendererHelper.pid,navStart:beginTs,firstPaint:spaNav.firstPaintEvent.start}]),});}}
+histograms.addHistogram(histogram);}
+tr.metrics.MetricRegistry.register(spaNavigationMetric);return{spaNavigationMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const LATENCY_BOUNDS=tr.v.HistogramBinBoundaries.createLinear(0,20,100);function clockSyncLatencyMetric(values,model){const domains=Array.from(model.clockSyncManager.domainsSeen).sort();for(let i=0;i<domains.length;i++){for(let j=i+1;j<domains.length;j++){const latency=model.clockSyncManager.getTimeTransformerError(domains[i],domains[j]);const hist=new tr.v.Histogram('clock_sync_latency_'+
+domains[i].toLowerCase()+'_to_'+domains[j].toLowerCase(),tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,LATENCY_BOUNDS);hist.customizeSummaryOptions({avg:true,count:false,max:false,min:false,std:false,sum:false,});hist.description='Clock sync latency for domain '+domains[i]+' to domain '+domains[j];hist.addSample(latency);values.addHistogram(hist);}}}
+tr.metrics.MetricRegistry.register(clockSyncLatencyMetric);return{clockSyncLatencyMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const CPU_TIME_PERCENTAGE_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(0.01,50,200);function cpuTimeMetric(histograms,model,opt_options){let rangeOfInterest=model.bounds;if(opt_options&&opt_options.rangeOfInterest){rangeOfInterest=opt_options.rangeOfInterest;}else{const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(chromeHelper){const chromeBounds=chromeHelper.chromeBounds;if(chromeBounds){rangeOfInterest=chromeBounds;}}}
+let allProcessCpuTime=0;for(const pid in model.processes){const process=model.processes[pid];if(tr.model.helpers.ChromeRendererHelper.isTracingProcess(process)){continue;}
+let processCpuTime=0;for(const tid in process.threads){const thread=process.threads[tid];processCpuTime+=thread.getCpuTimeForRange(rangeOfInterest);}
+allProcessCpuTime+=processCpuTime;}
+let normalizedAllProcessCpuTime=0;if(rangeOfInterest.duration>0){normalizedAllProcessCpuTime=allProcessCpuTime/rangeOfInterest.duration;}
+const unit=tr.b.Unit.byName.normalizedPercentage_smallerIsBetter;const cpuTimeHist=new tr.v.Histogram('cpu_time_percentage',unit,CPU_TIME_PERCENTAGE_BOUNDARIES);cpuTimeHist.description='Percent CPU utilization, normalized against a single core. Can be '+'greater than 100% if machine has multiple cores.';cpuTimeHist.customizeSummaryOptions({avg:true,count:false,max:false,min:false,std:false,sum:false});cpuTimeHist.addSample(normalizedAllProcessCpuTime);histograms.addHistogram(cpuTimeHist);}
+tr.metrics.MetricRegistry.register(cpuTimeMetric,{supportsRangeOfInterest:true});return{cpuTimeMetric,};});'use strict';tr.exportTo('tr.v',function(){class HistogramDeserializer{static deserialize(data){const deserializer=new HistogramDeserializer(data[0],data[1]);return data.slice(2).map(datum=>tr.v.Histogram.deserialize(datum,deserializer));}
+constructor(objects,diagnostics){this.objects_=objects;this.diagnostics_=[];for(const[type,diagnosticsByName]of Object.entries(diagnostics||{})){for(const[name,diagnosticsById]of Object.entries(diagnosticsByName)){for(const[id,data]of Object.entries(diagnosticsById)){const diagnostic=tr.v.d.Diagnostic.deserialize(type,data,this);this.diagnostics_[parseInt(id)]={name,diagnostic};}}}}
+getObject(id){return this.objects_[id];}
+getDiagnostic(id){return this.diagnostics_[parseInt(id)];}}
+return{HistogramDeserializer};});'use strict';tr.exportTo('tr.v',function(){class HistogramGrouping{constructor(key,callback){this.key_=key;this.callback_=callback;HistogramGrouping.BY_KEY.set(key,this);}
+get key(){return this.key_;}
+get callback(){return this.callback_;}
+get label(){return this.key;}
+static buildFromTags(tags,diagnosticName){const booleanTags=new Set();const keyValueTags=new Set();for(const tag of tags){if(tag.includes(':')){const key=tag.split(':')[0];if(booleanTags.has(key)){throw new Error(`Tag "${key}" cannot be both boolean and key-value`);}
+keyValueTags.add(key);}else{if(keyValueTags.has(tag)){throw new Error(`Tag "${tag}" cannot be both boolean and key-value`);}
+booleanTags.add(tag);}}
+const groupings=[];for(const tag of booleanTags){groupings.push(HistogramGrouping.buildBooleanTagGrouping_(tag,diagnosticName));}
+for(const tag of keyValueTags){groupings.push(HistogramGrouping.buildKeyValueTagGrouping_(tag,diagnosticName));}
+return groupings;}
+static buildBooleanTagGrouping_(tag,diagnosticName){return new HistogramGrouping(`${tag}Tag`,h=>{const tags=h.diagnostics.get(diagnosticName);if(tags===undefined||!tags.has(tag))return`~${tag}`;return tag;});}
+static buildKeyValueTagGrouping_(tag,diagnosticName){return new HistogramGrouping(`${tag}Tag`,h=>{const tags=h.diagnostics.get(diagnosticName);if(tags===undefined)return`~${tag}`;const values=new Set();for(const value of tags){const kvp=value.split(':');if(kvp.length<2||kvp[0]!==tag)continue;values.add(kvp[1]);}
+if(values.size===0)return`~${tag}`;const sortedValues=Array.from(values);sortedValues.sort();return sortedValues.join(',');},`${tag} tag`);}}
+HistogramGrouping.BY_KEY=new Map();HistogramGrouping.HISTOGRAM_NAME=new HistogramGrouping('name',h=>h.name);HistogramGrouping.DISPLAY_LABEL=new HistogramGrouping('displayLabel',hist=>{const labels=hist.diagnostics.get(tr.v.d.RESERVED_NAMES.LABELS);if(labels!==undefined&&labels.size>0){return Array.from(labels).join(',');}
+const benchmarks=hist.diagnostics.get(tr.v.d.RESERVED_NAMES.BENCHMARKS);const start=hist.diagnostics.get(tr.v.d.RESERVED_NAMES.BENCHMARK_START);if(benchmarks===undefined){if(start===undefined)return'Value';return start.toString();}
+const benchmarksStr=Array.from(benchmarks).join('\n');if(start===undefined)return benchmarksStr;return benchmarksStr+'\n'+start.toString();});class GenericSetGrouping extends HistogramGrouping{constructor(name){super(name,undefined);this.callback_=this.compute_.bind(this);}
+compute_(hist){const diag=hist.diagnostics.get(this.key);if(diag===undefined)return'';const parts=Array.from(diag);parts.sort();return parts.join(',');}}
+GenericSetGrouping.NAMES=[tr.v.d.RESERVED_NAMES.ARCHITECTURES,tr.v.d.RESERVED_NAMES.BENCHMARKS,tr.v.d.RESERVED_NAMES.BOTS,tr.v.d.RESERVED_NAMES.BUILDS,tr.v.d.RESERVED_NAMES.DEVICE_IDS,tr.v.d.RESERVED_NAMES.MASTERS,tr.v.d.RESERVED_NAMES.MEMORY_AMOUNTS,tr.v.d.RESERVED_NAMES.OS_NAMES,tr.v.d.RESERVED_NAMES.OS_VERSIONS,tr.v.d.RESERVED_NAMES.PRODUCT_VERSIONS,tr.v.d.RESERVED_NAMES.STORIES,tr.v.d.RESERVED_NAMES.STORYSET_REPEATS,tr.v.d.RESERVED_NAMES.STORY_TAGS,tr.v.d.RESERVED_NAMES.TEST_PATH,];for(const name of GenericSetGrouping.NAMES){new GenericSetGrouping(name);}
+class DateRangeGrouping extends HistogramGrouping{constructor(name){super(name,undefined);this.callback_=this.compute_.bind(this);}
+compute_(hist){const diag=hist.diagnostics.get(this.key);if(diag===undefined)return'';return diag.toString();}}
+DateRangeGrouping.NAMES=[tr.v.d.RESERVED_NAMES.BENCHMARK_START,tr.v.d.RESERVED_NAMES.TRACE_START,];for(const name of DateRangeGrouping.NAMES){new DateRangeGrouping(name);}
+return{HistogramGrouping,GenericSetGrouping,DateRangeGrouping,};});'use strict';tr.exportTo('tr.v',function(){class HistogramSet{constructor(opt_histograms){this.histograms_=new Set();this.sharedDiagnosticsByGuid_=new Map();if(opt_histograms!==undefined){for(const hist of opt_histograms){this.addHistogram(hist);}}}
+has(hist){return this.histograms_.has(hist);}
+createHistogram(name,unit,samples,opt_options){const hist=tr.v.Histogram.create(name,unit,samples,opt_options);this.addHistogram(hist);return hist;}
+addHistogram(hist,opt_diagnostics){if(this.has(hist)){throw new Error('Cannot add same Histogram twice');}
+if(opt_diagnostics!==undefined){if(!(opt_diagnostics instanceof Map)){opt_diagnostics=Object.entries(opt_diagnostics);}
+for(const[name,diagnostic]of opt_diagnostics){hist.diagnostics.set(name,diagnostic);}}
+this.histograms_.add(hist);}
+addSharedDiagnosticToAllHistograms(name,diagnostic){this.addSharedDiagnostic(diagnostic);for(const hist of this){hist.diagnostics.set(name,diagnostic);}}
+addSharedDiagnostic(diagnostic){this.sharedDiagnosticsByGuid_.set(diagnostic.guid,diagnostic);}
+get length(){return this.histograms_.size;}*[Symbol.iterator](){for(const hist of this.histograms_){yield hist;}}
+getHistogramsNamed(name){return[...this].filter(h=>h.name===name);}
+getHistogramNamed(name){const histograms=this.getHistogramsNamed(name);if(histograms.length===0)return undefined;if(histograms.length>1){throw new Error(`Unexpectedly found multiple histograms named "${name}"`);}
+return histograms[0];}
+lookupDiagnostic(guid){return this.sharedDiagnosticsByGuid_.get(guid);}
+deserialize(data){for(const hist of tr.v.HistogramDeserializer.deserialize(data)){this.addHistogram(hist);}}
+importDicts(dicts){if((dicts instanceof Array)&&(dicts.length>2)&&(dicts[0]instanceof Array)){this.deserialize(dicts);return;}
+for(const dict of dicts){this.importLegacyDict(dict);}}
+importLegacyDict(dict){if(dict.type!==undefined){if(dict.type==='TagMap')return;if(!tr.v.d.Diagnostic.findTypeInfoWithName(dict.type)){throw new Error('Unrecognized shared diagnostic type '+dict.type);}
+this.sharedDiagnosticsByGuid_.set(dict.guid,tr.v.d.Diagnostic.fromDict(dict));}else{const hist=tr.v.Histogram.fromDict(dict);this.addHistogram(hist);hist.diagnostics.resolveSharedDiagnostics(this,true);}}
+asDicts(){const dicts=[];for(const diagnostic of this.sharedDiagnosticsByGuid_.values()){dicts.push(diagnostic.asDict());}
+for(const hist of this){dicts.push(hist.asDict());}
+return dicts;}
+get sourceHistograms(){const diagnosticNames=new Set();for(const hist of this){for(const diagnostic of hist.diagnostics.values()){if(!(diagnostic instanceof tr.v.d.RelatedNameMap))continue;for(const name of diagnostic.values()){diagnosticNames.add(name);}}}
+const sourceHistograms=new HistogramSet;for(const hist of this){if(!diagnosticNames.has(hist.name)){sourceHistograms.addHistogram(hist);}}
+return sourceHistograms;}
+groupHistogramsRecursively(groupings,opt_skipGroupingCallback){function recurse(histograms,level){if(level===groupings.length){return histograms;}
+const grouping=groupings[level];const groupedHistograms=tr.b.groupIntoMap(histograms,grouping.callback);if(opt_skipGroupingCallback&&opt_skipGroupingCallback(grouping,groupedHistograms)){return recurse(histograms,level+1);}
+for(const[key,group]of groupedHistograms){groupedHistograms.set(key,recurse(group,level+1));}
+return groupedHistograms;}
+return recurse([...this],0);}
+deduplicateDiagnostics(){const namesToCandidates=new Map();const diagnosticsToHistograms=new Map();const keysToDiagnostics=new Map();for(const hist of this){for(const[name,candidate]of hist.diagnostics){if(candidate.equals===undefined){this.sharedDiagnosticsByGuid_.set(candidate.guid,candidate);continue;}
+const hashKey=candidate.hashKey;if(candidate.hashKey!==undefined){if(keysToDiagnostics.has(hashKey)){hist.diagnostics.set(name,keysToDiagnostics.get(hashKey));}else{keysToDiagnostics.set(hashKey,candidate);this.sharedDiagnosticsByGuid_.set(candidate.guid,candidate);}
+continue;}
+if(diagnosticsToHistograms.get(candidate)===undefined){diagnosticsToHistograms.set(candidate,[hist]);}else{diagnosticsToHistograms.get(candidate).push(hist);}
+if(!namesToCandidates.has(name)){namesToCandidates.set(name,new Set());}
+namesToCandidates.get(name).add(candidate);}}
+for(const[name,candidates]of namesToCandidates){const deduplicatedDiagnostics=new Set();for(const candidate of candidates){let found=false;for(const test of deduplicatedDiagnostics){if(candidate.equals(test)){const hists=diagnosticsToHistograms.get(candidate);for(const hist of hists){hist.diagnostics.set(name,test);}
+found=true;break;}}
+if(!found){deduplicatedDiagnostics.add(candidate);}
+for(const diagnostic of deduplicatedDiagnostics){this.sharedDiagnosticsByGuid_.set(diagnostic.guid,diagnostic);}}}}
+buildGroupingsFromTags(names){const tags=new Map();for(const hist of this){for(const name of names){if(!hist.diagnostics.has(name))continue;if(!tags.has(name))tags.set(name,new Set());for(const tag of hist.diagnostics.get(name)){tags.get(name).add(tag);}}}
+const groupings=[];for(const[name,values]of tags){const built=tr.v.HistogramGrouping.buildFromTags(values,name);for(const grouping of built){groupings.push(grouping);}}
+return groupings;}}
+return{HistogramSet};});'use strict';tr.exportTo('tr.e.chrome',function(){function hasTitleAndCategory(event,title,category){return event.title===title&&event.category&&tr.b.getCategoryParts(event.category).includes(category);}
+function getNavStartTimestamps(rendererHelper){const navStartTimestamps=[];for(const e of rendererHelper.mainThread.sliceGroup.childEvents()){if(hasTitleAndCategory(e,'navigationStart','blink.user_timing')){navStartTimestamps.push(e.start);}}
+return navStartTimestamps;}
+function getInteractiveTimestamps(model){const interactiveTimestampsMap=new Map();const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);for(const rendererHelper of Object.values(chromeHelper.rendererHelpers)){const timestamps=[];interactiveTimestampsMap.set(rendererHelper.pid,timestamps);}
+for(const expectation of model.userModel.expectations){if(!(expectation instanceof tr.model.um.LoadExpectation))continue;if(tr.e.chrome.CHROME_INTERNAL_URLS.includes(expectation.url)){continue;}
+if(expectation.timeToInteractive===undefined)continue;if(interactiveTimestampsMap.get(expectation.renderProcess.pid)===undefined){interactiveTimestampsMap.set(expectation.renderProcess.pid,[]);}
+interactiveTimestampsMap.get(expectation.renderProcess.pid).push(expectation.timeToInteractive);}
+return interactiveTimestampsMap;}
+function getPostInteractiveTaskWindows(interactiveTimestamps,navStartTimestamps,traceEndTimestamp){let navStartTsIndex=0;let lastTaskWindowEndTs=undefined;const taskWindows=[];for(const currTTI of interactiveTimestamps){while(navStartTsIndex<navStartTimestamps.length&&navStartTimestamps[navStartTsIndex]<currTTI){navStartTsIndex++;}
+const taskWindowEndTs=navStartTsIndex<navStartTimestamps.length?navStartTimestamps[navStartTsIndex]:traceEndTimestamp;if(taskWindowEndTs===lastTaskWindowEndTs){throw Error('Encountered two consecutive interactive timestamps '+'with no navigationStart between them. '+'PostInteractiveTaskWindow is not well defined in this case.');}
+taskWindows.push(tr.b.math.Range.fromExplicitRange(currTTI,taskWindowEndTs));lastTaskWindowEndTs=taskWindowEndTs;}
+return taskWindows;}
+function contributionToEQT(window,task){const startInWindow=Math.max(window.min,task.start);const endInWindow=Math.min(window.max,task.end);const durationInWindow=endInWindow-startInWindow;if(durationInWindow<=0)return 0;const probabilityOfTask=durationInWindow/(window.max-window.min);const minQueueingTime=task.end-endInWindow;const maxQueueingTime=task.end-startInWindow;const expectedQueueingTimeDueToTask=(maxQueueingTime+minQueueingTime)/2;return probabilityOfTask*expectedQueueingTimeDueToTask;}
+function weightedExpectedQueueingTime(window,weightedTasks){let result=0;for(const task of weightedTasks){result+=contributionToEQT(window,task)*task.weight;}
+return result;}
+function expectedQueueingTime(window,tasks){return weightedExpectedQueueingTime(window,tasks.map(function(task){return{start:task.start,end:task.end,weight:1};}));}
+class SlidingWindow{constructor(startTime,windowSize,sortedTasks){this.windowSize_=windowSize;this.sortedTasks_=sortedTasks;this.range_=tr.b.math.Range.fromExplicitRange(startTime,startTime+windowSize);this.firstTaskIndex_=sortedTasks.findIndex(task=>startTime<task.end);if(this.firstTaskIndex_===-1){this.firstTaskIndex_=sortedTasks.length;}
+this.lastTaskIndex_=-1;while(this.lastTaskIndex_+1<sortedTasks.length&&sortedTasks[this.lastTaskIndex_+1].start<startTime+windowSize){this.lastTaskIndex_++;}
+this.innerEQT_=0;for(let i=this.firstTaskIndex_+1;i<this.lastTaskIndex_;i++){this.innerEQT_+=contributionToEQT(this.range_,sortedTasks[i]);}}
+get getEQT(){let firstTaskEQT=0;if(this.firstTaskIndex_<this.sortedTasks_.length){firstTaskEQT=contributionToEQT(this.range_,this.sortedTasks_[this.firstTaskIndex_]);}
+let lastTaskEQT=0;if(this.firstTaskIndex_<this.lastTaskIndex_){lastTaskEQT=contributionToEQT(this.range_,this.sortedTasks_[this.lastTaskIndex_]);}
+return firstTaskEQT+this.innerEQT_+lastTaskEQT;}
+slide(t){this.range_=tr.b.math.Range.fromExplicitRange(t,t+this.windowSize_);if(this.firstTaskIndex_<this.sortedTasks_.length&&this.sortedTasks_[this.firstTaskIndex_].end<=t){this.firstTaskIndex_++;if(this.firstTaskIndex_<this.lastTaskIndex_){this.innerEQT_-=contributionToEQT(this.range_,this.sortedTasks_[this.firstTaskIndex_]);}}
+if(this.lastTaskIndex_+1<this.sortedTasks_.length&&this.sortedTasks_[this.lastTaskIndex_+1].start<t+this.windowSize_){if(this.firstTaskIndex_<this.lastTaskIndex_){this.innerEQT_+=contributionToEQT(this.range_,this.sortedTasks_[this.lastTaskIndex_]);}
+this.lastTaskIndex_++;}}}
+function maxExpectedQueueingTimeInSlidingWindow(startTime,endTime,windowSize,tasks){if(windowSize<=0){throw Error('The window size must be positive number');}
+if(startTime+windowSize>endTime){throw Error('The sliding window must fit in the specified time range');}
+const sortedTasks=tasks.slice().sort((a,b)=>a.start-b.start);for(let i=1;i<sortedTasks.length;i++){if(sortedTasks[i-1].end>sortedTasks[i].start){const midpoint=(sortedTasks[i-1].end+sortedTasks[i].start)/2;sortedTasks[i-1].end=midpoint;sortedTasks[i].start=midpoint;}}
+let endpoints=[];endpoints.push(startTime);endpoints.push(endTime-windowSize);for(const task of tasks){endpoints.push(task.start-windowSize);endpoints.push(task.start);endpoints.push(task.end-windowSize);endpoints.push(task.end);}
+endpoints=endpoints.filter(x=>(startTime<=x&&x+windowSize<=endTime));endpoints.sort((a,b)=>a-b);const slidingWindow=new SlidingWindow(endpoints[0],windowSize,sortedTasks);let maxEQT=0;for(const t of endpoints){slidingWindow.slide(t);maxEQT=Math.max(maxEQT,slidingWindow.getEQT);}
+return maxEQT;}
+return{getPostInteractiveTaskWindows,getNavStartTimestamps,getInteractiveTimestamps,expectedQueueingTime,maxExpectedQueueingTimeInSlidingWindow,weightedExpectedQueueingTime};});'use strict';tr.exportTo('tr.metrics.sh',function(){const WINDOW_SIZE_MS=500;const EQT_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(0.01,WINDOW_SIZE_MS,50);function containsForcedGC_(slice){return slice.findTopmostSlicesRelativeToThisSlice(tr.metrics.v8.utils.isForcedGarbageCollectionEvent).length>0;}
+function getOrCreateHistogram_(histograms,name,description){return histograms.getHistogramNamed(name)||histograms.createHistogram(name,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[],{binBoundaries:EQT_BOUNDARIES,description,summaryOptions:{avg:false,count:false,max:true,min:false,std:false,sum:false,},});}
+function expectedQueueingTimeMetric(histograms,model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const rendererHelpers=Object.values(chromeHelper.rendererHelpers);addExpectedQueueingTimeMetric_('renderer_eqt',event=>{return{start:event.start,duration:event.duration};},false,rendererHelpers,histograms,model);}
+function addExpectedQueueingTimeMetric_(eqtName,getEventTimes,isCpuTime,rendererHelpers,histograms,model){function getTasks(rendererHelper){const tasks=[];for(const slice of
+tr.e.chrome.EventFinderUtils.findToplevelSchedulerTasks(rendererHelper.mainThread)){const times=getEventTimes(slice);if(times.duration>0&&!containsForcedGC_(slice)){tasks.push({start:times.start,end:times.start+times.duration});}}
+return tasks;}
+const totalHistogram=getOrCreateHistogram_(histograms,`total:${WINDOW_SIZE_MS}ms_window:${eqtName}`,`The maximum EQT in a ${WINDOW_SIZE_MS}ms sliding window`+' for a given renderer');for(const rendererHelper of rendererHelpers){if(rendererHelper.isChromeTracingUI)continue;if(rendererHelper.mainThread.bounds.duration<WINDOW_SIZE_MS)continue;const tasks=getTasks(rendererHelper);const totalBreakdown=getV8Contribution_(eqtName,getEventTimes,isCpuTime,totalHistogram,histograms,rendererHelper,model);totalHistogram.addSample(tr.e.chrome.maxExpectedQueueingTimeInSlidingWindow(rendererHelper.mainThread.bounds.min,rendererHelper.mainThread.bounds.max,WINDOW_SIZE_MS,tasks),{v8:totalBreakdown});}}
+function getV8Contribution_(eqtName,getEventTimes,isCpuTime,totalEqtHistogram,histograms,rendererHelper,model){if(!model.categories.includes('v8'))return null;const totalBreakdown=new tr.v.d.Breakdown();const eventNamesWithTaskExtractors=getV8EventNamesWithTaskExtractors_(getEventTimes);if(!isCpuTime){const taskExtractorsUsingRCS=getV8EventNamesWithTaskExtractorsUsingRCS_(getEventTimes);for(const[eventName,getTasks]of taskExtractorsUsingRCS){eventNamesWithTaskExtractors.set(eventName,getTasks);}}
+let totalNames=totalEqtHistogram.diagnostics.get('v8');if(!totalNames){totalNames=new tr.v.d.RelatedNameMap();totalEqtHistogram.diagnostics.set('v8',totalNames);}
+for(const[eventName,getTasks]of eventNamesWithTaskExtractors){const totalHistogram=getOrCreateHistogram_(histograms,`total:${WINDOW_SIZE_MS}ms_window:${eqtName}:${eventName}`,`Contribution to the expected queueing time by ${eventName}`+' for a given renderer. It is computed as the maximum EQT in'+` a ${WINDOW_SIZE_MS}ms sliding window after shrinking top-level`+` tasks to contain only ${eventName} subevents`);const tasks=getTasks(rendererHelper);const totalSample=tr.e.chrome.maxExpectedQueueingTimeInSlidingWindow(rendererHelper.mainThread.bounds.min,rendererHelper.mainThread.bounds.max,WINDOW_SIZE_MS,tasks);totalHistogram.addSample(totalSample);totalBreakdown.set(eventName,totalSample);totalNames.set(eventName,totalHistogram.name);}
+return totalBreakdown;}
+function getV8EventNamesWithTaskExtractors_(getEventTimes,cpuMetrics){function durationOfTopmostSubSlices(slice,predicate,excludePredicate){let duration=0;for(const sub of slice.findTopmostSlicesRelativeToThisSlice(predicate)){duration+=getEventTimes(sub).duration;if(excludePredicate!==null&&excludePredicate!==undefined){duration-=durationOfTopmostSubSlices(sub,excludePredicate);}}
+return duration;}
+function taskExtractor(predicate,excludePredicate){return function(rendererHelper){const slices=tr.e.chrome.EventFinderUtils.findToplevelSchedulerTasks(rendererHelper.mainThread);const result=[];for(const slice of slices){const times=getEventTimes(slice);if(times.duration>0&&!containsForcedGC_(slice)){const duration=durationOfTopmostSubSlices(slice,predicate,excludePredicate);result.push({start:times.start,end:times.start+duration});}}
+return result;};}
+return new Map([['v8',taskExtractor(tr.metrics.v8.utils.isV8Event)],['v8:execute',taskExtractor(tr.metrics.v8.utils.isV8ExecuteEvent)],['v8:gc',taskExtractor(tr.metrics.v8.utils.isGarbageCollectionEvent)]]);}
+function extractTaskRCS(getEventTimes,predicate,rendererHelper){const result=[];for(const topSlice of
+rendererHelper.mainThread.sliceGroup.topLevelSlices){const times=getEventTimes(topSlice);if(times.duration<=0||containsForcedGC_(topSlice)){continue;}
+const v8ThreadSlices=[];for(const slice of topSlice.descendentSlices){if(tr.metrics.v8.utils.isV8RCSEvent(slice)){v8ThreadSlices.push(slice);}}
+const runtimeGroupCollection=new tr.e.v8.RuntimeStatsGroupCollection();runtimeGroupCollection.addSlices(v8ThreadSlices);let duration=0;for(const runtimeGroup of runtimeGroupCollection.runtimeGroups){if(predicate(runtimeGroup.name)){duration+=runtimeGroup.time;}}
+duration=tr.b.convertUnit(duration,tr.b.UnitPrefixScale.METRIC.MICRO,tr.b.UnitPrefixScale.METRIC.MILLI);result.push({start:times.start,end:times.start+duration});}
+return result;}
+function getV8EventNamesWithTaskExtractorsUsingRCS_(getEventTimes){const extractors=new Map();extractors.set('v8:compile_rcs',rendererHelper=>extractTaskRCS(getEventTimes,tr.metrics.v8.utils.isCompileRCSCategory,rendererHelper));extractors.set('v8:compile:optimize_rcs',rendererHelper=>extractTaskRCS(getEventTimes,tr.metrics.v8.utils.isCompileOptimizeRCSCategory,rendererHelper));return extractors;}
+tr.metrics.MetricRegistry.register(expectedQueueingTimeMetric);return{expectedQueueingTimeMetric,};});'use strict';tr.exportTo('tr.b',function(){function MultiDimensionalViewNode(title,valueCount){this.title=title;const dimensions=title.length;this.children=new Array(dimensions);for(let i=0;i<dimensions;i++){this.children[i]=new Map();}
+this.values=new Array(valueCount);for(let v=0;v<valueCount;v++){this.values[v]={self:0,total:0,totalState:NOT_PROVIDED};}}
+MultiDimensionalViewNode.TotalState={NOT_PROVIDED:0,LOWER_BOUND:1,EXACT:2};const NOT_PROVIDED=MultiDimensionalViewNode.TotalState.NOT_PROVIDED;const LOWER_BOUND=MultiDimensionalViewNode.TotalState.LOWER_BOUND;const EXACT=MultiDimensionalViewNode.TotalState.EXACT;MultiDimensionalViewNode.prototype={get subRows(){return Array.from(this.children[0].values());}};function MultiDimensionalViewBuilder(dimensions,valueCount){if(typeof(dimensions)!=='number'||dimensions<0){throw new Error('Dimensions must be a non-negative number');}
+this.dimensions_=dimensions;if(typeof(valueCount)!=='number'||valueCount<0){throw new Error('Number of values must be a non-negative number');}
+this.valueCount_=valueCount;this.buildRoot_=this.createRootNode_();this.topDownTreeViewRoot_=undefined;this.topDownHeavyViewRoot_=undefined;this.bottomUpHeavyViewNode_=undefined;this.complete_=false;this.maxDimensionDepths_=new Array(dimensions);for(let d=0;d<dimensions;d++){this.maxDimensionDepths_[d]=0;}}
+MultiDimensionalViewBuilder.ValueKind={SELF:0,TOTAL:1};MultiDimensionalViewBuilder.ViewType={TOP_DOWN_TREE_VIEW:0,TOP_DOWN_HEAVY_VIEW:1,BOTTOM_UP_HEAVY_VIEW:2};MultiDimensionalViewBuilder.prototype={addPath(path,values,valueKind){if(this.buildRoot_===undefined){throw new Error('Paths cannot be added after either view has been built');}
+if(path.length!==this.dimensions_){throw new Error('Path must be '+this.dimensions_+'-dimensional');}
+if(values.length!==this.valueCount_){throw new Error('Must provide '+this.valueCount_+' values');}
+let isTotal;switch(valueKind){case MultiDimensionalViewBuilder.ValueKind.SELF:isTotal=false;break;case MultiDimensionalViewBuilder.ValueKind.TOTAL:isTotal=true;break;default:throw new Error('Invalid value kind: '+valueKind);}
+let node=this.buildRoot_;for(let d=0;d<path.length;d++){const singleDimensionPath=path[d];const singleDimensionPathLength=singleDimensionPath.length;this.maxDimensionDepths_[d]=Math.max(this.maxDimensionDepths_[d],singleDimensionPathLength);for(let i=0;i<singleDimensionPathLength;i++){node=this.getOrCreateChildNode_(node,d,singleDimensionPath[i]);}}
+for(let v=0;v<this.valueCount_;v++){const addedValue=values[v];if(addedValue===undefined)continue;const nodeValue=node.values[v];if(isTotal){nodeValue.total+=addedValue;nodeValue.totalState=EXACT;}else{nodeValue.self+=addedValue;nodeValue.totalState=Math.max(nodeValue.totalState,LOWER_BOUND);}}},get complete(){return this.complete_;},set complete(isComplete){if(this.buildRoot_===undefined){throw new Error('Can\'t set complete after any view has been built.');}
+this.complete_=isComplete;},buildView(viewType){switch(viewType){case MultiDimensionalViewBuilder.ViewType.TOP_DOWN_TREE_VIEW:return this.buildTopDownTreeView();case MultiDimensionalViewBuilder.ViewType.TOP_DOWN_HEAVY_VIEW:return this.buildTopDownHeavyView();case MultiDimensionalViewBuilder.ViewType.BOTTOM_UP_HEAVY_VIEW:return this.buildBottomUpHeavyView();default:throw new Error('Unknown multi-dimensional view type: '+viewType);}},buildTopDownTreeView(){if(this.topDownTreeViewRoot_===undefined){const treeViewRoot=this.buildRoot_;this.buildRoot_=undefined;this.setUpMissingChildRelationships_(treeViewRoot,0);this.finalizeTotalValues_(treeViewRoot,0,new WeakMap());this.topDownTreeViewRoot_=treeViewRoot;}
+return this.topDownTreeViewRoot_;},buildTopDownHeavyView(){if(this.topDownHeavyViewRoot_===undefined){this.topDownHeavyViewRoot_=this.buildGenericHeavyView_(this.addDimensionToTopDownHeavyViewNode_.bind(this));}
+return this.topDownHeavyViewRoot_;},buildBottomUpHeavyView(){if(this.bottomUpHeavyViewNode_===undefined){this.bottomUpHeavyViewNode_=this.buildGenericHeavyView_(this.addDimensionToBottomUpHeavyViewNode_.bind(this));}
+return this.bottomUpHeavyViewNode_;},createRootNode_(){return new MultiDimensionalViewNode(new Array(this.dimensions_),this.valueCount_);},getOrCreateChildNode_(parentNode,dimension,childDimensionTitle){if(dimension<0||dimension>=this.dimensions_){throw new Error('Invalid dimension');}
+const dimensionChildren=parentNode.children[dimension];let childNode=dimensionChildren.get(childDimensionTitle);if(childNode!==undefined){return childNode;}
+const childTitle=parentNode.title.slice();childTitle[dimension]=childDimensionTitle;childNode=new MultiDimensionalViewNode(childTitle,this.valueCount_);dimensionChildren.set(childDimensionTitle,childNode);return childNode;},setUpMissingChildRelationships_(node,firstDimensionToSetUp){for(let d=firstDimensionToSetUp;d<this.dimensions_;d++){const currentDimensionChildTitles=new Set(node.children[d].keys());for(let i=0;i<d;i++){for(const previousDimensionChildNode of node.children[i].values()){for(const previousDimensionGrandChildTitle of
 previousDimensionChildNode.children[d].keys()){currentDimensionChildTitles.add(previousDimensionGrandChildTitle);}}}
-for(var currentDimensionChildTitle of currentDimensionChildTitles){var currentDimensionChildNode=this.getOrCreateChildNode_(node,d,currentDimensionChildTitle);for(var i=0;i<d;i++){for(var previousDimensionChildNode of node.children[i].values()){var previousDimensionGrandChildNode=previousDimensionChildNode.children[d].get(currentDimensionChildTitle);if(previousDimensionGrandChildNode!==undefined){currentDimensionChildNode.children[i].set(previousDimensionChildNode.title[i],previousDimensionGrandChildNode);}}}
-this.setUpMissingChildRelationships_(currentDimensionChildNode,d);}}},finalizeTotalValues_:function(node,firstDimensionToFinalize,dimensionalSelfSumsMap){var dimensionalSelfSums=new Array(this.dimensions_);var maxChildResidualSum=0;var nodeSelfSum=node.self;for(var d=0;d<this.dimensions_;d++){var childResidualSum=0;for(var childNode of node.children[d].values()){if(d>=firstDimensionToFinalize)
-this.finalizeTotalValues_(childNode,d,dimensionalSelfSumsMap);var childNodeSelfSums=dimensionalSelfSumsMap.get(childNode);nodeSelfSum+=childNodeSelfSums[d];var residual=childNode.total-childNodeSelfSums[this.dimensions_-1];childResidualSum+=residual;}
-dimensionalSelfSums[d]=nodeSelfSum;maxChildResidualSum=Math.max(maxChildResidualSum,childResidualSum);}
-node.total=Math.max(node.total,nodeSelfSum+maxChildResidualSum);if(dimensionalSelfSumsMap.has(node))
-throw new Error('Internal error: Node finalized more than once');dimensionalSelfSumsMap.set(node,dimensionalSelfSums);},buildGenericHeavyView_:function(treeViewNodeHandler){var treeViewRoot=this.buildTopDownTreeView();var heavyViewRoot=this.createRootNode_();heavyViewRoot.total=treeViewRoot.total;heavyViewRoot.self=treeViewRoot.self;heavyViewRoot.isLowerBound=treeViewRoot.isLowerBound;var recursionDepthTrackers=new Array(this.dimensions_);for(var d=0;d<this.dimensions_;d++){recursionDepthTrackers[d]=new RecursionDepthTracker(this.maxDimensionDepths_[d],d);}
-this.addDimensionsToGenericHeavyViewNode_(treeViewRoot,heavyViewRoot,0,recursionDepthTrackers,false,treeViewNodeHandler);this.setUpMissingChildRelationships_(heavyViewRoot,0);return heavyViewRoot;},addDimensionsToGenericHeavyViewNode_:function(treeViewParentNode,heavyViewParentNode,startDimension,recursionDepthTrackers,previousDimensionsRecursive,treeViewNodeHandler){for(var d=startDimension;d<this.dimensions_;d++){this.addDimensionDescendantsToGenericHeavyViewNode_(treeViewParentNode,heavyViewParentNode,d,recursionDepthTrackers,previousDimensionsRecursive,treeViewNodeHandler);}},addDimensionDescendantsToGenericHeavyViewNode_:function(treeViewParentNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,treeViewNodeHandler){var treeViewChildren=treeViewParentNode.children[currentDimension];var recursionDepthTracker=recursionDepthTrackers[currentDimension];for(var treeViewChildNode of treeViewChildren.values()){recursionDepthTracker.push(treeViewChildNode);treeViewNodeHandler(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive);this.addDimensionDescendantsToGenericHeavyViewNode_(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,treeViewNodeHandler);recursionDepthTracker.pop();}},addDimensionToTopDownHeavyViewNode_:function(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive){this.addDimensionToTopDownHeavyViewNodeRecursively_(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,1);},addDimensionToTopDownHeavyViewNodeRecursively_:function(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,subTreeDepth){var recursionDepthTracker=recursionDepthTrackers[currentDimension];var currentDimensionRecursive=subTreeDepth<=recursionDepthTracker.recursionDepth;var currentOrPreviousDimensionsRecursive=currentDimensionRecursive||previousDimensionsRecursive;var dimensionTitle=treeViewChildNode.title[currentDimension];var heavyViewChildNode=this.getOrCreateChildNode_(heavyViewParentNode,currentDimension,dimensionTitle);heavyViewChildNode.self+=treeViewChildNode.self;if(!currentOrPreviousDimensionsRecursive)
-heavyViewChildNode.total+=treeViewChildNode.total;this.addDimensionsToGenericHeavyViewNode_(treeViewChildNode,heavyViewChildNode,currentDimension+1,recursionDepthTrackers,currentOrPreviousDimensionsRecursive,this.addDimensionToTopDownHeavyViewNode_.bind(this));for(var treeViewGrandChildNode of
-treeViewChildNode.children[currentDimension].values()){recursionDepthTracker.push(treeViewGrandChildNode);this.addDimensionToTopDownHeavyViewNodeRecursively_(treeViewGrandChildNode,heavyViewChildNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,subTreeDepth+1);recursionDepthTracker.pop();}},addDimensionToBottomUpHeavyViewNode_:function(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive){var recursionDepthTracker=recursionDepthTrackers[currentDimension];var bottomIndex=recursionDepthTracker.bottomIndex;var topIndex=recursionDepthTracker.topIndex;var firstNonRecursiveIndex=bottomIndex+recursionDepthTracker.recursionDepth;var viewNodePath=recursionDepthTracker.viewNodePath;var trackerAncestorNode=recursionDepthTracker.trackerAncestorNode;var heavyViewDescendantNode=heavyViewParentNode;for(var i=bottomIndex;i<topIndex;i++){var treeViewAncestorNode=viewNodePath[i];var dimensionTitle=treeViewAncestorNode.title[currentDimension];heavyViewDescendantNode=this.getOrCreateChildNode_(heavyViewDescendantNode,currentDimension,dimensionTitle);var currentDimensionRecursive=i<firstNonRecursiveIndex;var currentOrPreviousDimensionsRecursive=currentDimensionRecursive||previousDimensionsRecursive;heavyViewDescendantNode.self+=treeViewChildNode.self;if(!currentOrPreviousDimensionsRecursive)
-heavyViewDescendantNode.total+=treeViewChildNode.total;this.addDimensionsToGenericHeavyViewNode_(treeViewChildNode,heavyViewDescendantNode,currentDimension+1,recursionDepthTrackers,currentOrPreviousDimensionsRecursive,this.addDimensionToBottomUpHeavyViewNode_.bind(this));}}};function RecursionDepthTracker(maxDepth,dimension){this.titlePath=new Array(maxDepth);this.viewNodePath=new Array(maxDepth);this.bottomIndex=this.topIndex=maxDepth;this.dimension_=dimension;this.currentTrackerNode_=this.createNode_(0,undefined);}
-RecursionDepthTracker.prototype={push:function(viewNode){if(this.bottomIndex===0)
-throw new Error('Cannot push to a full tracker');var title=viewNode.title[this.dimension_];this.bottomIndex--;this.titlePath[this.bottomIndex]=title;this.viewNodePath[this.bottomIndex]=viewNode;var childTrackerNode=this.currentTrackerNode_.children.get(title);if(childTrackerNode!==undefined){this.currentTrackerNode_=childTrackerNode;return;}
-var maxLengths=zFunction(this.titlePath,this.bottomIndex);var recursionDepth=0;for(var i=0;i<maxLengths.length;i++)
-recursionDepth=Math.max(recursionDepth,maxLengths[i]);childTrackerNode=this.createNode_(recursionDepth,this.currentTrackerNode_);this.currentTrackerNode_.children.set(title,childTrackerNode);this.currentTrackerNode_=childTrackerNode;},pop:function(){if(this.bottomIndex===this.topIndex)
-throw new Error('Cannot pop from an empty tracker');this.titlePath[this.bottomIndex]=undefined;this.viewNodePath[this.bottomIndex]=undefined;this.bottomIndex++;this.currentTrackerNode_=this.currentTrackerNode_.parent;},get recursionDepth(){return this.currentTrackerNode_.recursionDepth;},createNode_:function(recursionDepth,parent){return{recursionDepth:recursionDepth,parent:parent,children:new Map()};}};function zFunction(list,startIndex){var n=list.length-startIndex;if(n===0)
-return[];var z=new Array(n);z[0]=0;for(var i=1,left=0,right=0;i<n;++i){var maxLength;if(i<=right)
-maxLength=Math.min(right-i+1,z[i-left]);else
-maxLength=0;while(i+maxLength<n&&list[startIndex+maxLength]===list[startIndex+i+maxLength]){++maxLength;}
+for(const currentDimensionChildTitle of currentDimensionChildTitles){const currentDimensionChildNode=this.getOrCreateChildNode_(node,d,currentDimensionChildTitle);for(let i=0;i<d;i++){for(const previousDimensionChildNode of
+node.children[i].values()){const previousDimensionGrandChildNode=previousDimensionChildNode.children[d].get(currentDimensionChildTitle);if(previousDimensionGrandChildNode!==undefined){currentDimensionChildNode.children[i].set(previousDimensionChildNode.title[i],previousDimensionGrandChildNode);}}}
+this.setUpMissingChildRelationships_(currentDimensionChildNode,d);}}},finalizeTotalValues_(node,firstDimensionToFinalize,dimensionalSelfSumsMap){const dimensionalSelfSums=new Array(this.dimensions_);const minResidual=new Array(this.valueCount_);for(let v=0;v<this.valueCount_;v++)minResidual[v]=0;const nodeValues=node.values;const nodeSelfSums=new Array(this.valueCount_);for(let v=0;v<this.valueCount_;v++){nodeSelfSums[v]=nodeValues[v].self;}
+for(let d=0;d<this.dimensions_;d++){const childResidualSums=new Array(this.valueCount_);for(let v=0;v<this.valueCount_;v++){childResidualSums[v]=0;}
+for(const childNode of node.children[d].values()){if(d>=firstDimensionToFinalize){this.finalizeTotalValues_(childNode,d,dimensionalSelfSumsMap);}
+const childNodeSelfSums=dimensionalSelfSumsMap.get(childNode);const childNodeValues=childNode.values;for(let v=0;v<this.valueCount_;v++){nodeSelfSums[v]+=childNodeSelfSums[d][v];const residual=childNodeValues[v].total-
+childNodeSelfSums[this.dimensions_-1][v];childResidualSums[v]+=residual;if(this.complete){nodeValues[v].totalState=EXACT;}else if(childNodeValues[v].totalState>NOT_PROVIDED){nodeValues[v].totalState=Math.max(nodeValues[v].totalState,LOWER_BOUND);}}}
+dimensionalSelfSums[d]=nodeSelfSums.slice();for(let v=0;v<this.valueCount_;v++){minResidual[v]=Math.max(minResidual[v],childResidualSums[v]);}}
+for(let v=0;v<this.valueCount_;v++){nodeValues[v].total=Math.max(nodeValues[v].total,nodeSelfSums[v]+minResidual[v]);}
+if(dimensionalSelfSumsMap.has(node)){throw new Error('Internal error: Node finalized more than once');}
+dimensionalSelfSumsMap.set(node,dimensionalSelfSums);},buildGenericHeavyView_(treeViewNodeHandler){const treeViewRoot=this.buildTopDownTreeView();const heavyViewRoot=this.createRootNode_();heavyViewRoot.values=treeViewRoot.values;const recursionDepthTrackers=new Array(this.dimensions_);for(let d=0;d<this.dimensions_;d++){recursionDepthTrackers[d]=new RecursionDepthTracker(this.maxDimensionDepths_[d],d);}
+this.addDimensionsToGenericHeavyViewNode_(treeViewRoot,heavyViewRoot,0,recursionDepthTrackers,false,treeViewNodeHandler);this.setUpMissingChildRelationships_(heavyViewRoot,0);return heavyViewRoot;},addDimensionsToGenericHeavyViewNode_(treeViewParentNode,heavyViewParentNode,startDimension,recursionDepthTrackers,previousDimensionsRecursive,treeViewNodeHandler){for(let d=startDimension;d<this.dimensions_;d++){this.addDimensionDescendantsToGenericHeavyViewNode_(treeViewParentNode,heavyViewParentNode,d,recursionDepthTrackers,previousDimensionsRecursive,treeViewNodeHandler);}},addDimensionDescendantsToGenericHeavyViewNode_(treeViewParentNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,treeViewNodeHandler){const treeViewChildren=treeViewParentNode.children[currentDimension];const recursionDepthTracker=recursionDepthTrackers[currentDimension];for(const treeViewChildNode of treeViewChildren.values()){recursionDepthTracker.push(treeViewChildNode);treeViewNodeHandler(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive);this.addDimensionDescendantsToGenericHeavyViewNode_(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,treeViewNodeHandler);recursionDepthTracker.pop();}},addDimensionToTopDownHeavyViewNode_(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive){this.addDimensionToTopDownHeavyViewNodeRecursively_(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,1);},addDimensionToTopDownHeavyViewNodeRecursively_(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,subTreeDepth){const recursionDepthTracker=recursionDepthTrackers[currentDimension];const currentDimensionRecursive=subTreeDepth<=recursionDepthTracker.recursionDepth;const currentOrPreviousDimensionsRecursive=currentDimensionRecursive||previousDimensionsRecursive;const dimensionTitle=treeViewChildNode.title[currentDimension];const heavyViewChildNode=this.getOrCreateChildNode_(heavyViewParentNode,currentDimension,dimensionTitle);this.addNodeValues_(treeViewChildNode,heavyViewChildNode,!currentOrPreviousDimensionsRecursive);this.addDimensionsToGenericHeavyViewNode_(treeViewChildNode,heavyViewChildNode,currentDimension+1,recursionDepthTrackers,currentOrPreviousDimensionsRecursive,this.addDimensionToTopDownHeavyViewNode_.bind(this));for(const treeViewGrandChildNode of
+treeViewChildNode.children[currentDimension].values()){recursionDepthTracker.push(treeViewGrandChildNode);this.addDimensionToTopDownHeavyViewNodeRecursively_(treeViewGrandChildNode,heavyViewChildNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,subTreeDepth+1);recursionDepthTracker.pop();}},addDimensionToBottomUpHeavyViewNode_(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive){const recursionDepthTracker=recursionDepthTrackers[currentDimension];const bottomIndex=recursionDepthTracker.bottomIndex;const topIndex=recursionDepthTracker.topIndex;const firstNonRecursiveIndex=bottomIndex+recursionDepthTracker.recursionDepth;const viewNodePath=recursionDepthTracker.viewNodePath;const trackerAncestorNode=recursionDepthTracker.trackerAncestorNode;let heavyViewDescendantNode=heavyViewParentNode;for(let i=bottomIndex;i<topIndex;i++){const treeViewAncestorNode=viewNodePath[i];const dimensionTitle=treeViewAncestorNode.title[currentDimension];heavyViewDescendantNode=this.getOrCreateChildNode_(heavyViewDescendantNode,currentDimension,dimensionTitle);const currentDimensionRecursive=i<firstNonRecursiveIndex;const currentOrPreviousDimensionsRecursive=currentDimensionRecursive||previousDimensionsRecursive;this.addNodeValues_(treeViewChildNode,heavyViewDescendantNode,!currentOrPreviousDimensionsRecursive);this.addDimensionsToGenericHeavyViewNode_(treeViewChildNode,heavyViewDescendantNode,currentDimension+1,recursionDepthTrackers,currentOrPreviousDimensionsRecursive,this.addDimensionToBottomUpHeavyViewNode_.bind(this));}},addNodeValues_(sourceNode,targetNode,addTotal){const targetNodeValues=targetNode.values;const sourceNodeValues=sourceNode.values;for(let v=0;v<this.valueCount_;v++){const targetNodeValue=targetNodeValues[v];const sourceNodeValue=sourceNodeValues[v];targetNodeValue.self+=sourceNodeValue.self;if(addTotal){targetNodeValue.total+=sourceNodeValue.total;if(this.complete){targetNodeValue.totalState=EXACT;}else if(sourceNodeValue.totalState>NOT_PROVIDED){targetNodeValue.totalState=Math.max(targetNodeValue.totalState,LOWER_BOUND);}}}}};function RecursionDepthTracker(maxDepth,dimension){this.titlePath=new Array(maxDepth);this.viewNodePath=new Array(maxDepth);this.bottomIndex=this.topIndex=maxDepth;this.dimension_=dimension;this.currentTrackerNode_=this.createNode_(0,undefined);}
+RecursionDepthTracker.prototype={push(viewNode){if(this.bottomIndex===0){throw new Error('Cannot push to a full tracker');}
+const title=viewNode.title[this.dimension_];this.bottomIndex--;this.titlePath[this.bottomIndex]=title;this.viewNodePath[this.bottomIndex]=viewNode;let childTrackerNode=this.currentTrackerNode_.children.get(title);if(childTrackerNode!==undefined){this.currentTrackerNode_=childTrackerNode;return;}
+const maxLengths=zFunction(this.titlePath,this.bottomIndex);let recursionDepth=0;for(let i=0;i<maxLengths.length;i++){recursionDepth=Math.max(recursionDepth,maxLengths[i]);}
+childTrackerNode=this.createNode_(recursionDepth,this.currentTrackerNode_);this.currentTrackerNode_.children.set(title,childTrackerNode);this.currentTrackerNode_=childTrackerNode;},pop(){if(this.bottomIndex===this.topIndex){throw new Error('Cannot pop from an empty tracker');}
+this.titlePath[this.bottomIndex]=undefined;this.viewNodePath[this.bottomIndex]=undefined;this.bottomIndex++;this.currentTrackerNode_=this.currentTrackerNode_.parent;},get recursionDepth(){return this.currentTrackerNode_.recursionDepth;},createNode_(recursionDepth,parent){return{recursionDepth,parent,children:new Map()};}};function zFunction(list,startIndex){const n=list.length-startIndex;if(n===0)return[];const z=new Array(n);z[0]=0;for(let i=1,left=0,right=0;i<n;++i){let maxLength;if(i<=right){maxLength=Math.min(right-i+1,z[i-left]);}else{maxLength=0;}
+while(i+maxLength<n&&list[startIndex+maxLength]===list[startIndex+i+maxLength]){++maxLength;}
 if(i+maxLength-1>right){left=i;right=i+maxLength-1;}
 z[i]=maxLength;}
 return z;}
-return{MultiDimensionalViewBuilder:MultiDimensionalViewBuilder,MultiDimensionalViewType:MultiDimensionalViewType,MultiDimensionalViewNode:MultiDimensionalViewNode,RecursionDepthTracker:RecursionDepthTracker,zFunction:zFunction};});'use strict';tr.exportTo('tr.ui.analysis',function(){var NO_BREAK_SPACE=String.fromCharCode(160);var RIGHTWARDS_ARROW=String.fromCharCode(8594);var COLLATOR=new Intl.Collator(undefined,{numeric:true});function TitleColumn(title){this.title=title;}
-TitleColumn.prototype={supportsCellSelection:false,value:function(row){var formattedTitle=this.formatTitle(row);var contexts=row.contexts;if(contexts===undefined||contexts.length===0)
-return formattedTitle;var firstContext=contexts[0];var lastContext=contexts[contexts.length-1];var changeDefinedContextCount=0;for(var i=1;i<contexts.length;i++){if((contexts[i]===undefined)!==(contexts[i-1]===undefined))
-changeDefinedContextCount++;}
-var color=undefined;var prefix=undefined;if(!firstContext&&lastContext){color='red';prefix='+++';}else if(firstContext&&!lastContext){color='green';prefix='---';}
+return{MultiDimensionalViewBuilder,MultiDimensionalViewNode,RecursionDepthTracker,zFunction,};});'use strict';tr.exportTo('tr.e.chrome',function(){class CpuTime{static getStageToInitiatorToSegmentBounds(segments,rangeOfInterest){const stageToInitiatorToRanges=new Map();stageToInitiatorToRanges.set('all_stages',new Map([['all_initiators',new Set()]]));const allRanges=stageToInitiatorToRanges.get('all_stages').get('all_initiators');for(const segment of segments){if(!rangeOfInterest.intersectsRangeInclusive(segment.range))continue;const intersectingRange=rangeOfInterest.findIntersection(segment.range);allRanges.add(intersectingRange);for(const expectation of segment.expectations){const stageTitle=expectation.stageTitle;if(!stageToInitiatorToRanges.has(stageTitle)){stageToInitiatorToRanges.set(stageTitle,new Map([['all_initiators',new Set()]]));}
+const initiatorToRanges=stageToInitiatorToRanges.get(stageTitle);initiatorToRanges.get('all_initiators').add(intersectingRange);const initiatorType=expectation.initiatorType;if(initiatorType){if(!initiatorToRanges.has(initiatorType)){initiatorToRanges.set(initiatorType,new Set());}
+initiatorToRanges.get(initiatorType).add(intersectingRange);}}}
+return stageToInitiatorToRanges;}
+static constructMultiDimensionalView(model,rangeOfInterest){const mdvBuilder=new tr.b.MultiDimensionalViewBuilder(3,2);const stageToInitiatorToRanges=CpuTime.getStageToInitiatorToSegmentBounds(model.userModel.segments,rangeOfInterest);const allSegmentBoundsInRange=stageToInitiatorToRanges.get('all_stages').get('all_initiators');for(const[pid,process]of Object.entries(model.processes)){const processType=tr.e.chrome.chrome_processes.canonicalizeProcessName(process.name);for(const[tid,thread]of Object.entries(process.threads)){const rangeToCpuTime=new Map();for(const range of allSegmentBoundsInRange){rangeToCpuTime.set(range,thread.getCpuTimeForRange(range));}
+for(const[stage,initiatorToRanges]of stageToInitiatorToRanges){for(const[initiator,ranges]of initiatorToRanges){const cpuTime=tr.b.math.Statistics.sum(ranges,range=>rangeToCpuTime.get(range));const duration=tr.b.math.Statistics.sum(ranges,range=>range.duration);const cpuTimePerSecond=cpuTime/duration;mdvBuilder.addPath([[processType],[thread.type],[stage,initiator]],[cpuTimePerSecond,cpuTime],tr.b.MultiDimensionalViewBuilder.ValueKind.TOTAL);}}}}
+return mdvBuilder.buildTopDownTreeView();}}
+return{CpuTime,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const CPU_PERCENTAGE_UNIT=tr.b.Unit.byName.normalizedPercentage_smallerIsBetter;const CPU_TIME_UNIT=tr.b.Unit.byName.timeDurationInMs_smallerIsBetter;function clonePath_(previousPath){return previousPath.map(subPath=>subPath.map(x=>x));}
+function decodePath_(path){return{processType:path[0][0],threadType:path[1][0],railStage:path[2][0],initiatorType:path[2][1]};}
+function stringifyPathName_(path){const decodedPath=decodePath_(path);return[decodedPath.processType,decodedPath.threadType,decodedPath.railStage,decodedPath.initiatorType].join(':');}
+class CpuTimeTreeDataReporter{constructor(){this.visitedSet_=new Set();}
+reportValuesFromNode_(node,path){const decodedPath=decodePath_(path);const processType=decodedPath.processType||'all_processes';const threadType=decodedPath.threadType||'all_threads';if(!decodedPath.railStage||!decodedPath.initiatorType)return;const{railStage,initiatorType}=decodedPath;const serializedPathName=[processType,threadType,railStage,initiatorType].join(':');const cpuPercentageValue=node.values[0].total;const cpuTimeValue=node.values[1].total;this.histogramSet_.createHistogram(`cpuPercentage:${serializedPathName}`,CPU_PERCENTAGE_UNIT,cpuPercentageValue);this.histogramSet_.createHistogram(`cpuTime:${serializedPathName}`,CPU_TIME_UNIT,cpuTimeValue);}
+reportDataFromTree_(root,rootPath){const rootPathString=stringifyPathName_(rootPath);if(this.visitedSet_.has(rootPathString))return;this.visitedSet_.add(rootPathString);this.reportValuesFromNode_(root,rootPath);for(let dimension=0;dimension<root.children.length;dimension++){const children=root.children[dimension];for(const[name,node]of children){const childPath=clonePath_(rootPath);childPath[dimension].push(name);this.reportDataFromTree_(node,childPath);}}}
+addTreeValuesToHistogramSet(rootNode,histogramSet){const rootPath=[[],[],[]];this.rootNode_=rootNode;this.histogramSet_=histogramSet;this.reportDataFromTree_(this.rootNode_,rootPath);}
+static reportToHistogramSet(rootNode,histogramSet){const reporter=new CpuTimeTreeDataReporter();reporter.addTreeValuesToHistogramSet(rootNode,histogramSet);}}
+return{CpuTimeTreeDataReporter,};});'use strict';tr.exportTo('tr.metrics.sh',function(){function newCpuTimeMetric(histograms,model,opt_options){const rangeOfInterest=opt_options&&opt_options.rangeOfInterest?opt_options.rangeOfInterest:model.bounds;const rootNode=tr.e.chrome.CpuTime.constructMultiDimensionalView(model,rangeOfInterest);tr.metrics.sh.CpuTimeTreeDataReporter.reportToHistogramSet(rootNode,histograms);}
+tr.metrics.MetricRegistry.register(newCpuTimeMetric,{supportsRangeOfInterest:true});return{newCpuTimeMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const includeHistogramNames=['cpuTime:all_processes:all_threads:all_stages:all_initiators','cpuPercentage:all_processes:all_threads:all_stages:all_initiators','cpuTime:browser_process:all_threads:all_stages:all_initiators','cpuPercentage:browser_process:all_threads:all_stages:all_initiators','cpuTime:renderer_processes:all_threads:all_stages:all_initiators','cpuPercentage:renderer_processes:all_threads:all_stages:all_initiators','cpuTime:gpu_process:all_threads:all_stages:all_initiators','cpuPercentage:gpu_process:all_threads:all_stages:all_initiators','cpuTime:renderer_processes:CrRendererMain:all_stages:all_initiators','cpuPercentage:renderer_processes:CrRendererMain:all_stages:all_initiators','cpuTime:browser_process:CrBrowserMain:all_stages:all_initiators','cpuPercentage:browser_process:CrBrowserMain:all_stages:all_initiators','cpuTime:all_processes:all_threads:Load:Successful','cpuPercentage:all_processes:all_threads:Load:Successful',];function limitedCpuTimeMetric(histograms,model,opt_options){const allCpuHistograms=new tr.v.HistogramSet();tr.metrics.sh.newCpuTimeMetric(allCpuHistograms,model,opt_options);for(const histogramName of includeHistogramNames){const histogram=allCpuHistograms.getHistogramNamed(histogramName);if(histogram)histograms.addHistogram(histogram);}}
+tr.metrics.MetricRegistry.register(limitedCpuTimeMetric,{supportsRangeOfInterest:true});return{limitedCpuTimeMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const LONG_TASK_MS=50;const LONGEST_TASK_MS=1000;function iterateLongTopLevelTasksOnThreadInRange(thread,opt_range,cb,opt_this){thread.sliceGroup.topLevelSlices.forEach(function(slice){if(opt_range&&!opt_range.intersectsExplicitRangeInclusive(slice.start,slice.end)){return;}
+if(slice.duration<LONG_TASK_MS)return;cb.call(opt_this,slice);});}
+function iterateRendererMainThreads(model,cb,opt_this){const modelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(modelHelper!==undefined){Object.values(modelHelper.rendererHelpers).forEach(function(rendererHelper){if(!rendererHelper.mainThread)return;cb.call(opt_this,rendererHelper.mainThread);});}}
+const BIN_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(LONG_TASK_MS,LONGEST_TASK_MS,40);function longTasksMetric(histograms,model,opt_options){const rangeOfInterest=opt_options?opt_options.rangeOfInterest:undefined;const longTaskHist=histograms.createHistogram('longTasks',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[],{binBoundaries:BIN_BOUNDARIES,description:'durations of long tasks',});const relatedNames=new tr.v.d.RelatedNameMap();longTaskHist.diagnostics.set('categories',relatedNames);iterateRendererMainThreads(model,function(thread){iterateLongTopLevelTasksOnThreadInRange(thread,rangeOfInterest,function(task){const breakdown=new tr.v.d.Breakdown();breakdown.colorScheme=tr.v.d.COLOR_SCHEME_CHROME_USER_FRIENDLY_CATEGORY_DRIVER;for(const slice of task.descendentSlices){const sample=slice.cpuSelfTime;if(sample===undefined)continue;const category=model.getUserFriendlyCategoryFromEvent(slice);const histName='longTasks:'+category;let hist=histograms.getHistogramNamed(histName);if(hist===undefined){hist=histograms.createHistogram(histName,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[],{binBoundaries:BIN_BOUNDARIES,});relatedNames.set(category,hist.name);}
+hist.addSample(sample,{events:new tr.v.d.RelatedEventSet([slice]),});breakdown.set(category,sample+breakdown.get(category));}
+longTaskHist.addSample(task.duration,{events:new tr.v.d.RelatedEventSet([task]),categories:breakdown,});});});}
+tr.metrics.MetricRegistry.register(longTasksMetric,{supportsRangeOfInterest:true,requiredCategories:['toplevel'],});return{longTasksMetric,iterateLongTopLevelTasksOnThreadInRange,iterateRendererMainThreads,LONG_TASK_MS,LONGEST_TASK_MS,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const BACKGROUND=tr.model.ContainerMemoryDump.LevelOfDetail.BACKGROUND;const LIGHT=tr.model.ContainerMemoryDump.LevelOfDetail.LIGHT;const DETAILED=tr.model.ContainerMemoryDump.LevelOfDetail.DETAILED;const sizeInBytes_smallerIsBetter=tr.b.Unit.byName.sizeInBytes_smallerIsBetter;const count_smallerIsBetter=tr.b.Unit.byName.count_smallerIsBetter;const DISPLAYED_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.DISPLAYED_SIZE_NUMERIC_NAME;const LEVEL_OF_DETAIL_NAMES=new Map();LEVEL_OF_DETAIL_NAMES.set(BACKGROUND,'background');LEVEL_OF_DETAIL_NAMES.set(LIGHT,'light');LEVEL_OF_DETAIL_NAMES.set(DETAILED,'detailed');const HEAP_PROFILER_DETAIL_NAME='heap_profiler';const BOUNDARIES_FOR_UNIT_MAP=new WeakMap();BOUNDARIES_FOR_UNIT_MAP.set(count_smallerIsBetter,tr.v.HistogramBinBoundaries.createLinear(0,20,20));BOUNDARIES_FOR_UNIT_MAP.set(sizeInBytes_smallerIsBetter,new tr.v.HistogramBinBoundaries(0).addBinBoundary(1024).addExponentialBins(16*1024*1024*1024,4*24));const CHROME_PROCESS_NAMES=tr.e.chrome.chrome_processes.CHROME_PROCESS_NAMES;function memoryMetric(values,model,opt_options){const rangeOfInterest=opt_options?opt_options.rangeOfInterest:undefined;const browserNameToGlobalDumps=tr.metrics.sh.splitGlobalDumpsByBrowserName(model,rangeOfInterest);addGeneralMemoryDumpValues(browserNameToGlobalDumps,values);addDetailedMemoryDumpValues(browserNameToGlobalDumps,values);addMemoryDumpCountValues(browserNameToGlobalDumps,values);}
+const USER_FRIENDLY_BROWSER_NAMES={'chrome':'Chrome','webview':'WebView','unknown_browser':'an unknown browser'};function convertBrowserNameToUserFriendlyName(browserName){for(const baseName in USER_FRIENDLY_BROWSER_NAMES){if(!browserName.startsWith(baseName))continue;const userFriendlyBaseName=USER_FRIENDLY_BROWSER_NAMES[baseName];const suffix=browserName.substring(baseName.length);if(suffix.length===0){return userFriendlyBaseName;}else if(/^\d+$/.test(suffix)){return userFriendlyBaseName+'('+suffix+')';}}
+return'\''+browserName+'\' browser';}
+function convertProcessNameToUserFriendlyName(processName,opt_requirePlural){switch(processName){case CHROME_PROCESS_NAMES.BROWSER:return opt_requirePlural?'browser processes':'the browser process';case CHROME_PROCESS_NAMES.RENDERER:return'renderer processes';case CHROME_PROCESS_NAMES.GPU:return opt_requirePlural?'GPU processes':'the GPU process';case CHROME_PROCESS_NAMES.PPAPI:return opt_requirePlural?'PPAPI processes':'the PPAPI process';case CHROME_PROCESS_NAMES.ALL:return'all processes';case CHROME_PROCESS_NAMES.UNKNOWN:return'unknown processes';default:return'\''+processName+'\' processes';}}
+function addGeneralMemoryDumpValues(browserNameToGlobalDumps,values){addMemoryDumpValues(browserNameToGlobalDumps,gmd=>true,function(processDump,addProcessScalar){addProcessScalar({source:'process_count',property:PROCESS_COUNT,value:1});if(processDump.totals!==undefined){addProcessScalar({source:'reported_by_os',property:RESIDENT_SIZE,component:['system_memory'],value:processDump.totals.residentBytes});addProcessScalar({source:'reported_by_os',property:PEAK_RESIDENT_SIZE,component:['system_memory'],value:processDump.totals.peakResidentBytes});addProcessScalar({source:'reported_by_os',property:PRIVATE_FOOTPRINT_SIZE,component:['system_memory'],value:processDump.totals.privateFootprintBytes,});}
+if(processDump.memoryAllocatorDumps===undefined)return;processDump.memoryAllocatorDumps.forEach(function(rootAllocatorDump){CHROME_VALUE_PROPERTIES.forEach(function(property){addProcessScalar({source:'reported_by_chrome',component:[rootAllocatorDump.name],property,value:rootAllocatorDump.numerics[property.name]});});if(rootAllocatorDump.numerics.allocated_objects_size===undefined){const allocatedObjectsDump=rootAllocatorDump.getDescendantDumpByFullName('allocated_objects');if(allocatedObjectsDump!==undefined){addProcessScalar({source:'reported_by_chrome',component:[rootAllocatorDump.name],property:ALLOCATED_OBJECTS_SIZE,value:allocatedObjectsDump.numerics.size});}}});addTopHeapDumpCategoryValue(processDump,addProcessScalar);addV8MemoryDumpValues(processDump,addProcessScalar);},function(componentTree){const tracingNode=componentTree.children[1].get('tracing');if(tracingNode===undefined)return;for(let i=0;i<componentTree.values.length;i++){componentTree.values[i].total-=tracingNode.values[i].total;}},values);}
+function addTopHeapDumpCategoryValue(processDump,addProcessScalar){if(!processDump.heapDumps){return;}
+for(const allocatorName in processDump.heapDumps){const heapDump=processDump.heapDumps[allocatorName];if(heapDump.entries===undefined||heapDump.entries.length===0){return;}
+const typeToSize={};for(let i=0;i<heapDump.entries.length;i+=1){const entry=heapDump.entries[i];if(!entry.objectTypeName||entry.leafStackFrame){continue;}
+if(!typeToSize[entry.objectTypeName]){typeToSize[entry.objectTypeName]=0;}
+typeToSize[entry.objectTypeName]+=entry.size;}
+let largestValue=0;let largestType='';for(const key in typeToSize){if(largestValue<typeToSize[key]){largestValue=typeToSize[key];largestType=key;}}
+addProcessScalar({source:'reported_by_chrome',component:[allocatorName,largestType],property:HEAP_CATEGORY_SIZE,value:largestValue});}}
+function addV8MemoryDumpValues(processDump,addProcessScalar){const v8Dump=processDump.getMemoryAllocatorDumpByFullName('v8');if(v8Dump===undefined)return;v8Dump.children.forEach(function(isolateDump){const mallocDump=isolateDump.getDescendantDumpByFullName('malloc');if(mallocDump!==undefined){addV8ComponentValues(mallocDump,['v8','allocated_by_malloc'],addProcessScalar);}
+let heapDump=isolateDump.getDescendantDumpByFullName('heap');if(heapDump===undefined){heapDump=isolateDump.getDescendantDumpByFullName('heap_spaces');}
+if(heapDump!==undefined){addV8ComponentValues(heapDump,['v8','heap'],addProcessScalar);heapDump.children.forEach(function(spaceDump){if(spaceDump.name==='other_spaces')return;addV8ComponentValues(spaceDump,['v8','heap',spaceDump.name],addProcessScalar);});}});addProcessScalar({source:'reported_by_chrome',component:['v8'],property:CODE_AND_METADATA_SIZE,value:v8Dump.numerics.code_and_metadata_size});addProcessScalar({source:'reported_by_chrome',component:['v8'],property:CODE_AND_METADATA_SIZE,value:v8Dump.numerics.bytecode_and_metadata_size});}
+function addV8ComponentValues(componentDump,componentPath,addProcessScalar){CHROME_VALUE_PROPERTIES.forEach(function(property){addProcessScalar({source:'reported_by_chrome',component:componentPath,property,value:componentDump.numerics[property.name]});});}
+const PROCESS_COUNT={unit:count_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){if(componentPath.length>0){throw new Error('Unexpected process count non-empty component path: '+
+componentPath.join(':'));}
+return'total number of '+convertProcessNameToUserFriendlyName(processName,true);}};const EFFECTIVE_SIZE={name:'effective_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildChromeValueDescriptionPrefix(componentPath,processName,{userFriendlyPropertyName:'effective size',componentPreposition:'of'});}};const ALLOCATED_OBJECTS_SIZE={name:'allocated_objects_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildChromeValueDescriptionPrefix(componentPath,processName,{userFriendlyPropertyName:'size of all objects allocated',totalUserFriendlyPropertyName:'size of all allocated objects',componentPreposition:'by'});}};const SHIM_ALLOCATED_OBJECTS_SIZE={name:'shim_allocated_objects_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildChromeValueDescriptionPrefix(componentPath,processName,{userFriendlyPropertyName:'size of all objects allocated through shim',totalUserFriendlyPropertyName:'size of all allocated objects through shim',componentPreposition:'by'});}};const LOCKED_SIZE={name:'locked_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildChromeValueDescriptionPrefix(componentPath,processName,{userFriendlyPropertyName:'locked (pinned) size',componentPreposition:'of'});}};const PEAK_SIZE={name:'peak_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildChromeValueDescriptionPrefix(componentPath,processName,{userFriendlyPropertyName:'peak size',componentPreposition:'of'});}};const HEAP_CATEGORY_SIZE={name:'heap_category_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildChromeValueDescriptionPrefix(componentPath,processName,{userFriendlyPropertyName:'heap profiler category size',componentPreposition:'for'});}};const CODE_AND_METADATA_SIZE={name:'code_and_metadata_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildChromeValueDescriptionPrefix(componentPath,processName,{userFriendlyPropertyNamePrefix:'size of',userFriendlyPropertyName:'code and metadata'});}};const CHROME_VALUE_PROPERTIES=[EFFECTIVE_SIZE,ALLOCATED_OBJECTS_SIZE,SHIM_ALLOCATED_OBJECTS_SIZE,LOCKED_SIZE,PEAK_SIZE];function buildChromeValueDescriptionPrefix(componentPath,processName,formatSpec){const nameParts=[];if(componentPath.length===0){nameParts.push('total');if(formatSpec.totalUserFriendlyPropertyName){nameParts.push(formatSpec.totalUserFriendlyPropertyName);}else{if(formatSpec.userFriendlyPropertyNamePrefix){nameParts.push(formatSpec.userFriendlyPropertyNamePrefix);}
+nameParts.push(formatSpec.userFriendlyPropertyName);}
+nameParts.push('reported by Chrome for');}else{if(formatSpec.componentPreposition===undefined){if(formatSpec.userFriendlyPropertyNamePrefix){nameParts.push(formatSpec.userFriendlyPropertyNamePrefix);}
+nameParts.push(componentPath.join(':'));nameParts.push(formatSpec.userFriendlyPropertyName);}else{if(formatSpec.userFriendlyPropertyNamePrefix){nameParts.push(formatSpec.userFriendlyPropertyNamePrefix);}
+nameParts.push(formatSpec.userFriendlyPropertyName);nameParts.push(formatSpec.componentPreposition);if(componentPath[componentPath.length-1]==='allocated_by_malloc'){nameParts.push('objects allocated by malloc for');nameParts.push(componentPath.slice(0,componentPath.length-1).join(':'));}else{nameParts.push(componentPath.join(':'));}}
+nameParts.push('in');}
+nameParts.push(convertProcessNameToUserFriendlyName(processName));return nameParts.join(' ');}
+const RESIDENT_SIZE={name:'resident_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildOsValueDescriptionPrefix(componentPath,processName,'resident set size (RSS)');}};const PEAK_RESIDENT_SIZE={name:'peak_resident_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildOsValueDescriptionPrefix(componentPath,processName,'peak resident set size');}};const PROPORTIONAL_RESIDENT_SIZE={name:'proportional_resident_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildOsValueDescriptionPrefix(componentPath,processName,'proportional resident size (PSS)');}};const PRIVATE_DIRTY_SIZE={name:'private_dirty_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildOsValueDescriptionPrefix(componentPath,processName,'private dirty size');}};const PRIVATE_FOOTPRINT_SIZE={name:'private_footprint_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildOsValueDescriptionPrefix(componentPath,processName,'private footprint size');}};const JAVA_BASE_CLEAN_RESIDENT={name:'java_base_clean_resident',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildOsValueDescriptionPrefix(componentPath,processName,'java base odex and vdex total clean resident size');}};const JAVA_BASE_PSS={name:'java_base_pss',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildOsValueDescriptionPrefix(componentPath,processName,'java base odex and vdex proportional resident size');}};const NATIVE_LIBRARY_PRIVATE_CLEAN_RESIDENT={name:'native_library_private_clean_resident',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildOsValueDescriptionPrefix(componentPath,processName,'native library private clean resident size');}};const NATIVE_LIBRARY_SHARED_CLEAN_RESIDENT={name:'native_library_shared_clean_resident',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildOsValueDescriptionPrefix(componentPath,processName,'native library shared clean resident size');}};const NATIVE_LIBRARY_PROPORTIONAL_RESIDENT={name:'native_library_proportional_resident',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildOsValueDescriptionPrefix(componentPath,processName,'native library proportional resident size');}};function buildOsValueDescriptionPrefix(componentPath,processName,userFriendlyPropertyName){if(componentPath.length>2){throw new Error('OS value component path for \''+
+userFriendlyPropertyName+'\' too long: '+componentPath.join(':'));}
+const nameParts=[];if(componentPath.length<2){nameParts.push('total');}
+nameParts.push(userFriendlyPropertyName);if(componentPath.length>0){switch(componentPath[0]){case'system_memory':if(componentPath.length>1){const userFriendlyComponentName=SYSTEM_VALUE_COMPONENTS[componentPath[1]].userFriendlyName;if(userFriendlyComponentName===undefined){throw new Error('System value sub-component for \''+
+userFriendlyPropertyName+'\' unknown: '+
+componentPath.join(':'));}
+nameParts.push('of',userFriendlyComponentName,'in');}else{nameParts.push('of system memory (RAM) used by');}
+break;case'gpu_memory':if(componentPath.length>1){nameParts.push('of the',componentPath[1]);nameParts.push('Android memtrack component in');}else{nameParts.push('of GPU memory (Android memtrack) used by');}
+break;default:throw new Error('OS value component for \''+
+userFriendlyPropertyName+'\' unknown: '+
+componentPath.join(':'));}}else{nameParts.push('reported by the OS for');}
+nameParts.push(convertProcessNameToUserFriendlyName(processName));return nameParts.join(' ');}
+function addDetailedMemoryDumpValues(browserNameToGlobalDumps,values){addMemoryDumpValues(browserNameToGlobalDumps,g=>g.levelOfDetail===DETAILED,function(processDump,addProcessScalar){for(const[componentName,componentSpec]of
+Object.entries(SYSTEM_VALUE_COMPONENTS)){const node=getDescendantVmRegionClassificationNode(processDump.vmRegions,componentSpec.classificationPath);const componentPath=['system_memory'];if(componentName)componentPath.push(componentName);addProcessScalar({source:'reported_by_os',component:componentPath,property:PROPORTIONAL_RESIDENT_SIZE,value:node===undefined?0:(node.byteStats.proportionalResident||0)});addProcessScalar({source:'reported_by_os',component:componentPath,property:PRIVATE_DIRTY_SIZE,value:node===undefined?0:(node.byteStats.privateDirtyResident||0)});if(node){if(node.byteStats.javaBasePss){addProcessScalar({source:'reported_by_os',component:componentPath,property:JAVA_BASE_PSS,value:node.byteStats.javaBasePss});}
+if(node.byteStats.javaBaseCleanResident){addProcessScalar({source:'reported_by_os',component:componentPath,property:JAVA_BASE_CLEAN_RESIDENT,value:node.byteStats.javaBaseCleanResident});}}
+if(node){if(node.byteStats.nativeLibraryPrivateCleanResident){addProcessScalar({source:'reported_by_os',component:componentPath,property:NATIVE_LIBRARY_PRIVATE_CLEAN_RESIDENT,value:node.byteStats.nativeLibraryPrivateCleanResident});}
+if(node.byteStats.nativeLibrarySharedCleanResident){addProcessScalar({source:'reported_by_os',component:componentPath,property:NATIVE_LIBRARY_SHARED_CLEAN_RESIDENT,value:node.byteStats.nativeLibrarySharedCleanResident});}
+if(node.byteStats.nativeLibraryProportionalResident){addProcessScalar({source:'reported_by_os',component:componentPath,property:NATIVE_LIBRARY_PROPORTIONAL_RESIDENT,value:node.byteStats.nativeLibraryProportionalResident});}}}
+const memtrackDump=processDump.getMemoryAllocatorDumpByFullName('gpu/android_memtrack');if(memtrackDump!==undefined){memtrackDump.children.forEach(function(memtrackChildDump){addProcessScalar({source:'reported_by_os',component:['gpu_memory',memtrackChildDump.name],property:PROPORTIONAL_RESIDENT_SIZE,value:memtrackChildDump.numerics.memtrack_pss});});}},function(componentTree){},values);}
+const SYSTEM_VALUE_COMPONENTS={'':{classificationPath:[],},'java_heap':{classificationPath:['Android','Java runtime','Spaces'],userFriendlyName:'the Java heap'},'ashmem':{classificationPath:['Android','Ashmem'],userFriendlyName:'ashmem'},'native_heap':{classificationPath:['Native heap'],userFriendlyName:'the native heap'},'stack':{classificationPath:['Stack'],userFriendlyName:'the thread stacks'}};function getDescendantVmRegionClassificationNode(node,path){for(let i=0;i<path.length;i++){if(node===undefined)break;node=node.children.find(c=>c.title===path[i]);}
+return node;}
+function addMemoryDumpCountValues(browserNameToGlobalDumps,values){browserNameToGlobalDumps.forEach(function(globalDumps,browserName){let totalDumpCount=0;const levelOfDetailNameToDumpCount={};LEVEL_OF_DETAIL_NAMES.forEach(function(levelOfDetailName){levelOfDetailNameToDumpCount[levelOfDetailName]=0;});levelOfDetailNameToDumpCount[HEAP_PROFILER_DETAIL_NAME]=0;globalDumps.forEach(function(globalDump){totalDumpCount++;const levelOfDetailName=LEVEL_OF_DETAIL_NAMES.get(globalDump.levelOfDetail);if(levelOfDetailName===undefined){return;}
+levelOfDetailNameToDumpCount[levelOfDetailName]++;if(globalDump.levelOfDetail===DETAILED){if(detectHeapProfilerInMemoryDump(globalDump)){levelOfDetailNameToDumpCount[HEAP_PROFILER_DETAIL_NAME]++;}}});reportMemoryDumpCountAsValue(browserName,undefined,totalDumpCount,values);for(const[levelOfDetailName,levelOfDetailDumpCount]of
+Object.entries(levelOfDetailNameToDumpCount)){reportMemoryDumpCountAsValue(browserName,levelOfDetailName,levelOfDetailDumpCount,values);}});}
+function detectHeapProfilerInMemoryDump(globalDump){for(const processDump of Object.values(globalDump.processMemoryDumps)){if(processDump.heapDumps&&processDump.heapDumps.malloc){const mallocDump=processDump.heapDumps.malloc;if(mallocDump.entries&&mallocDump.entries.length>0){return true;}}}
+return false;}
+function reportMemoryDumpCountAsValue(browserName,levelOfDetailName,levelOfDetailDumpCount,values){const nameParts=['memory',browserName,'all_processes','dump_count'];if(levelOfDetailName!==undefined){nameParts.push(levelOfDetailName);}
+const name=nameParts.join(':');const histogram=new tr.v.Histogram(name,count_smallerIsBetter,BOUNDARIES_FOR_UNIT_MAP.get(count_smallerIsBetter));histogram.addSample(levelOfDetailDumpCount);const userFriendlyLevelOfDetail=(levelOfDetailName||'all').replace('_',' ');histogram.description=['total number of',userFriendlyLevelOfDetail,'memory dumps added by',convertBrowserNameToUserFriendlyName(browserName),'to the trace'].join(' ');values.addHistogram(histogram);}
+function addMemoryDumpValues(browserNameToGlobalDumps,customGlobalDumpFilter,customProcessDumpValueExtractor,customComponentTreeModifier,values){browserNameToGlobalDumps.forEach(function(globalDumps,browserName){const filteredGlobalDumps=globalDumps.filter(customGlobalDumpFilter);const sourceToPropertyToBuilder=extractDataFromGlobalDumps(filteredGlobalDumps,customProcessDumpValueExtractor);reportDataAsValues(sourceToPropertyToBuilder,browserName,customComponentTreeModifier,values);});}
+function extractDataFromGlobalDumps(globalDumps,customProcessDumpValueExtractor){const sourceToPropertyToBuilder=new Map();const dumpCount=globalDumps.length;globalDumps.forEach(function(globalDump,dumpIndex){for(const processDump of Object.values(globalDump.processMemoryDumps)){extractDataFromProcessDump(processDump,sourceToPropertyToBuilder,dumpIndex,dumpCount,customProcessDumpValueExtractor);}});return sourceToPropertyToBuilder;}
+function extractDataFromProcessDump(processDump,sourceToPropertyToBuilder,dumpIndex,dumpCount,customProcessDumpValueExtractor){const rawProcessName=processDump.process.name;const processNamePath=[tr.e.chrome.chrome_processes.canonicalizeProcessName(rawProcessName)];customProcessDumpValueExtractor(processDump,function addProcessScalar(spec){if(spec.value===undefined)return;const component=spec.component||[];function createDetailsForErrorMessage(){return['source=',spec.source,', property=',spec.property.name||'(undefined)',', component=',component.length===0?'(empty)':component.join(':'),' in ',processDump.process.userFriendlyName].join('');}
+let value;if(spec.value instanceof tr.b.Scalar){value=spec.value.value;if(spec.value.unit!==spec.property.unit){throw new Error('Scalar unit for '+
+createDetailsForErrorMessage()+' ('+
+spec.value.unit.unitName+') doesn\'t match the unit of the property ('+
+spec.property.unit.unitName+')');}}else{value=spec.value;}
+let propertyToBuilder=sourceToPropertyToBuilder.get(spec.source);if(propertyToBuilder===undefined){propertyToBuilder=new Map();sourceToPropertyToBuilder.set(spec.source,propertyToBuilder);}
+let builder=propertyToBuilder.get(spec.property);if(builder===undefined){builder=new tr.b.MultiDimensionalViewBuilder(2,dumpCount),propertyToBuilder.set(spec.property,builder);}
+const values=new Array(dumpCount);values[dumpIndex]=value;builder.addPath([processNamePath,component],values,tr.b.MultiDimensionalViewBuilder.ValueKind.TOTAL);});}
+function reportDataAsValues(sourceToPropertyToBuilder,browserName,customComponentTreeModifier,values){sourceToPropertyToBuilder.forEach(function(propertyToBuilder,sourceName){propertyToBuilder.forEach(function(builders,property){const tree=builders.buildTopDownTreeView();reportComponentDataAsValues(browserName,sourceName,property,[],[],tree,values,customComponentTreeModifier);});});}
+function reportComponentDataAsValues(browserName,sourceName,property,processPath,componentPath,tree,values,customComponentTreeModifier,opt_cachedHistograms){const cachedHistograms=opt_cachedHistograms||new Map();function recurse(processPath,componentPath,node){return reportComponentDataAsValues(browserName,sourceName,property,processPath,componentPath,node,values,customComponentTreeModifier,cachedHistograms);}
+function buildHistogram(processPath,componentPath,node){return buildNamedMemoryNumericFromNode(browserName,sourceName,property,processPath.length===0?'all_processes':processPath[0],componentPath,node);}
+customComponentTreeModifier(tree);const histogram=buildHistogram(processPath,componentPath,tree);if(cachedHistograms.has(histogram.name)){return cachedHistograms.get(histogram.name);}
+cachedHistograms.set(histogram.name,histogram);const processNames=new tr.v.d.RelatedNameMap();for(const[childProcessName,childProcessNode]of tree.children[0]){processPath.push(childProcessName);const childProcessHistogram=recurse(processPath,componentPath,childProcessNode);processNames.set(childProcessName,childProcessHistogram.name);processPath.pop();}
+const componentNames=new tr.v.d.RelatedNameMap();for(const[childComponentName,childComponentNode]of tree.children[1]){componentPath.push(childComponentName);const childComponentHistogram=recurse(processPath,componentPath,childComponentNode);componentNames.set(childComponentName,childComponentHistogram.name);componentPath.pop();}
+values.addHistogram(histogram);if(tree.children[0].size>0){histogram.diagnostics.set('processes',processNames);}
+if(tree.children[1].size>0){histogram.diagnostics.set('components',componentNames);}
+return histogram;}
+function getNumericName(browserName,sourceName,propertyName,processName,componentPath){const nameParts=['memory',browserName,processName,sourceName].concat(componentPath);if(propertyName!==undefined)nameParts.push(propertyName);return nameParts.join(':');}
+function getNumericDescription(property,browserName,processName,componentPath){return[property.buildDescriptionPrefix(componentPath,processName),'in',convertBrowserNameToUserFriendlyName(browserName)].join(' ');}
+function buildNamedMemoryNumericFromNode(browserName,sourceName,property,processName,componentPath,node){const name=getNumericName(browserName,sourceName,property.name,processName,componentPath);const description=getNumericDescription(property,browserName,processName,componentPath);const numeric=buildMemoryNumericFromNode(name,node,property.unit);numeric.description=description;return numeric;}
+function buildSampleDiagnostics(value,node){if(node.children.length<2)return undefined;const diagnostics=new Map();const i=node.values.indexOf(value);const processBreakdown=new tr.v.d.Breakdown();processBreakdown.colorScheme=tr.e.chrome.chrome_processes.PROCESS_COLOR_SCHEME_NAME;for(const[name,subNode]of node.children[0]){processBreakdown.set(name,subNode.values[i].total);}
+if(processBreakdown.size>0){diagnostics.set('processes',processBreakdown);}
+const componentBreakdown=new tr.v.d.Breakdown();for(const[name,subNode]of node.children[1]){componentBreakdown.set(name,subNode.values[i].total);}
+if(componentBreakdown.size>0){diagnostics.set('components',componentBreakdown);}
+if(diagnostics.size===0)return undefined;return diagnostics;}
+function buildMemoryNumericFromNode(name,node,unit){const histogram=new tr.v.Histogram(name,unit,BOUNDARIES_FOR_UNIT_MAP.get(unit));node.values.forEach(v=>histogram.addSample(v.total,buildSampleDiagnostics(v,node)));return histogram;}
+tr.metrics.MetricRegistry.register(memoryMetric,{supportsRangeOfInterest:true});return{memoryMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const BYTE_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(1,1e9,1e2);function nativeCodeResidentMemoryMetric(histograms,model){const histogram=new tr.v.Histogram('NativeCodeResidentMemory',tr.b.Unit.byName.sizeInBytes_smallerIsBetter,BYTE_BOUNDARIES);for(const slice of model.getDescendantEvents()){if(slice.category==='disabled-by-default-memory-infra'&&slice.title==='ReportGlobalNativeCodeResidentMemoryKb'&&slice.args.NativeCodeResidentMemory){histogram.addSample(slice.args.NativeCodeResidentMemory);}}
+histograms.addHistogram(histogram);}
+tr.metrics.MetricRegistry.register(nativeCodeResidentMemoryMetric);return{nativeCodeResidentMemoryMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const timeDurationInMs_smallerIsBetter=tr.b.Unit.byName.timeDurationInMs_smallerIsBetter;const EventFinderUtils=tr.e.chrome.EventFinderUtils;const LOADING_METRIC_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(0,1e3,20).addLinearBins(3e3,20).addExponentialBins(20e3,20);const SUMMARY_OPTIONS={avg:true,count:false,max:false,min:false,std:false,sum:false,};function addSamplesToHistogram(pairInfo,breakdownTree,histogram,histograms,diagnostics){histogram.addSample(pairInfo.end-pairInfo.start,diagnostics);if(!breakdownTree){return;}
+for(const[category,breakdown]of Object.entries(breakdownTree)){const relatedName=`${histogram.name}:${category}`;if(!histograms.getHistogramNamed(relatedName)){const relatedHist=histograms.createHistogram(relatedName,histogram.unit,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,summaryOptions:{count:false,max:false,min:false,sum:false,},});}
+const relatedHist=histograms.getHistogramNamed(relatedName);let relatedNames=histogram.diagnostics.get('breakdown');if(!relatedNames){relatedNames=new tr.v.d.RelatedNameMap();histogram.diagnostics.set('breakdown',relatedNames);}
+relatedNames.set(category,relatedName);relatedHist.addSample(breakdown.total,{breakdown:tr.v.d.Breakdown.fromEntries(Object.entries(breakdown.events)),});}}
+function splitOneRangeIntoPerSecondRanges(startTime,endTime){const results=[];for(let i=0;startTime+(i+1)*1000<=endTime;i+=1){const start=i*1000;const end=(i+1)*1000;results.push({start,end,});}
+return results;}
+function getNavigationInfos(model){const navigationInfos=[];const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);for(const expectation of model.userModel.expectations){if(!(expectation instanceof tr.model.um.LoadExpectation))continue;if(tr.e.chrome.CHROME_INTERNAL_URLS.includes(expectation.url)){continue;}
+const rendererHelper=chromeHelper.rendererHelpers[expectation.renderProcess.pid];navigationInfos.push({navigationStart:expectation.navigationStart,rendererHelper,url:expectation.url});}
+navigationInfos.forEach((navInfo,i)=>{if(i===navigationInfos.length-1){navInfo.navigationEndTime=model.bounds.max;}else{navInfo.navigationEndTime=navigationInfos[i+1].navigationStart.start;}});return navigationInfos;}
+function getRendererHelpers(model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const rendererHelpers=[];for(const pid in chromeHelper.rendererHelpers){const rendererHelper=chromeHelper.rendererHelpers[pid];if(rendererHelper.isChromeTracingUI)continue;rendererHelpers.push(rendererHelper);}
+return rendererHelpers;}
+function getWallTimeBreakdownTree(rendererHelper,start,end){const startEndRange=tr.b.math.Range.fromExplicitRange(start,end);const networkEvents=EventFinderUtils.getNetworkEventsInRange(rendererHelper.process,startEndRange);const breakdownTree=tr.metrics.sh.generateWallClockTimeBreakdownTree(rendererHelper.mainThread,networkEvents,startEndRange);return breakdownTree;}
+function getCpuTimeBreakdownTree(rendererHelper,start,end){const startEndRange=tr.b.math.Range.fromExplicitRange(start,end);const breakdownTree=tr.metrics.sh.generateCpuTimeBreakdownTree(rendererHelper.mainThread,startEndRange);return breakdownTree;}
+function persecondMetric(histograms,model){const rendererHelpers=getRendererHelpers(model);const navigationInfos=getNavigationInfos(model);if(navigationInfos.length===0){return;}
+navigationInfos.forEach(navInfo=>{const navigationStart=navInfo.navigationStart.start;const navigationEnd=navInfo.navigationEndTime;const startEndPairs=splitOneRangeIntoPerSecondRanges(navigationStart,navigationEnd);const breakdownList=startEndPairs.map(p=>{const wallHistogramName=`wall_${p.start}_to_${p.end}`;const wallHistogramDescription=`Wall-clock time ${p.start} to ${p.end} breakdown`;const cpuHistogramName=`cpu_${p.start}_to_${p.end}`;const cpuHistogramDescription=`CPU time ${p.start} to ${p.end} breakdown`;const pid=navInfo.rendererHelper.pid;const breakdownTree=getWallTimeBreakdownTree(navInfo.rendererHelper,navigationStart+p.start,navigationStart+p.end);const cpuBreakdownTree=getCpuTimeBreakdownTree(navInfo.rendererHelper,navigationStart+p.start,navigationStart+p.end);const diagnostics={'Navigation infos':new tr.v.d.GenericSet([{url:navInfo.url,pid:navInfo.rendererHelper.pid,navStart:navigationStart,frameIdRef:navInfo.navigationStart.args.frame}]),'breakdown':tr.metrics.sh.createBreakdownDiagnostic(breakdownTree),};return Object.assign(p,{breakdownTree,cpuBreakdownTree,wallHistogramName,wallHistogramDescription,cpuHistogramName,cpuHistogramDescription,diagnostics,});});breakdownList.forEach(p=>{if(!histograms.getHistogramNamed(p.wallHistogramName)){histograms.createHistogram(p.wallHistogramName,timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:p.wallHistogramDescription,summaryOptions:SUMMARY_OPTIONS,});}
+const wallHistogram=histograms.getHistogramNamed(p.wallHistogramName);addSamplesToHistogram(p,p.breakdownTree,wallHistogram,histograms,p.diagnostics);if(!histograms.getHistogramNamed(p.cpuHistogramName)){histograms.createHistogram(p.cpuHistogramName,timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:p.cpuHistogramDescription,summaryOptions:SUMMARY_OPTIONS,});}
+const cpuHistogram=histograms.getHistogramNamed(p.cpuHistogramName);addSamplesToHistogram(p,p.cpuBreakdownTree,cpuHistogram,histograms,p.diagnostics);});});}
+tr.metrics.MetricRegistry.register(persecondMetric);return{persecondMetric,splitOneRangeIntoPerSecondRanges};});'use strict';tr.exportTo('tr.metrics.sh',function(){const CHROME_POWER_GRACE_PERIOD_MS=1;function createEmptyHistogram_(interval,histograms){if(interval.perSecond){return{perSecond:true,energy:histograms.createHistogram(`${interval.name}:power`,tr.b.Unit.byName.powerInWatts_smallerIsBetter,[],{description:`Energy consumption rate for ${interval.description}`,summaryOptions:{avg:true,count:false,max:true,min:true,std:false,sum:false,},}),};}
+return{perSecond:false,energy:histograms.createHistogram(`${interval.name}:energy`,tr.b.Unit.byName.energyInJoules_smallerIsBetter,[],{description:`Energy consumed in ${interval.description}`,summaryOptions:{avg:false,count:false,max:true,min:true,std:false,sum:true,},}),};}
+function createHistograms_(data,interval,histograms){if(data.histograms[interval.name]===undefined){data.histograms[interval.name]=createEmptyHistogram_(interval,histograms);}
+if(data.histograms[interval.name].perSecond){for(const sample of data.model.device.powerSeries.getSamplesWithinRange(interval.bounds.min,interval.bounds.max)){data.histograms[interval.name].energy.addSample(sample.powerInW);}}else{const energyInJ=data.model.device.powerSeries.getEnergyConsumedInJ(interval.bounds.min,interval.bounds.max);data.histograms[interval.name].energy.addSample(energyInJ);}}
+function getNavigationTTIIntervals_(model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const intervals=[];for(const expectation of model.userModel.expectations){if(!(expectation instanceof tr.model.um.LoadExpectation))continue;if(tr.e.chrome.CHROME_INTERNAL_URLS.includes(expectation.url)){continue;}
+if(expectation.timeToInteractive!==undefined){intervals.push(tr.b.math.Range.fromExplicitRange(expectation.navigationStart.start,expectation.timeToInteractive));}}
+return intervals.sort((x,y)=>x.min-y.min);}
+function*computeTimeIntervals_(model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const powerSeries=model.device.powerSeries;if(powerSeries===undefined||powerSeries.samples.length===0){return;}
+yield{bounds:model.bounds,name:'story',description:'user story',perSecond:true};const chromeBounds=computeChromeBounds_(model);if(chromeBounds.isEmpty)return;const powerSeriesBoundsWithGracePeriod=tr.b.math.Range.fromExplicitRange(powerSeries.bounds.min-CHROME_POWER_GRACE_PERIOD_MS,powerSeries.bounds.max+CHROME_POWER_GRACE_PERIOD_MS);if(!powerSeriesBoundsWithGracePeriod.containsRangeExclusive(chromeBounds)){return;}
+for(const interval of getRailStageIntervals_(model)){yield{bounds:interval.bounds.findIntersection(chromeBounds),name:interval.name,description:interval.description,perSecond:interval.perSecond};}
+for(const interval of getLoadingIntervals_(model,chromeBounds)){yield{bounds:interval.bounds.findIntersection(chromeBounds),name:interval.name,description:interval.description,perSecond:interval.perSecond};}}
+function*getRailStageIntervals_(model){for(const exp of model.userModel.expectations){const histogramName=exp.title.toLowerCase().replace(' ','_');const energyHist=undefined;if(histogramName.includes('response')){yield{bounds:tr.b.math.Range.fromExplicitRange(exp.start,exp.end),name:histogramName,description:'RAIL stage '+histogramName,perSecond:false};}else if(histogramName.includes('animation')||histogramName.includes('idle')){yield{bounds:tr.b.math.Range.fromExplicitRange(exp.start,exp.end),name:histogramName,description:'RAIL stage '+histogramName,perSecond:true};}}}
+function*getLoadingIntervals_(model,chromeBounds){const ttiIntervals=getNavigationTTIIntervals_(model);for(const ttiInterval of ttiIntervals){yield{bounds:ttiInterval,name:'load',description:'page loads',perSecond:false};}}
+function computeChromeBounds_(model){const chromeBounds=new tr.b.math.Range();const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(chromeHelper===undefined)return chromeBounds;for(const helper of chromeHelper.browserHelpers){if(helper.mainThread){chromeBounds.addRange(helper.mainThread.bounds);}}
+for(const pid in chromeHelper.rendererHelpers){if(chromeHelper.rendererHelpers[pid].mainThread){chromeBounds.addRange(chromeHelper.rendererHelpers[pid].mainThread.bounds);}}
+return chromeBounds;}
+function powerMetric(histograms,model){const data={model,histograms:{}};for(const interval of computeTimeIntervals_(model)){createHistograms_(data,interval,histograms);}}
+tr.metrics.MetricRegistry.register(powerMetric);return{powerMetric};});'use strict';tr.exportTo('tr.b.math',function(){function earthMoversDistance(firstHistogram,secondHistogram){const buckets=firstHistogram.length;if(secondHistogram.length!==buckets){throw new Error('Histograms have a different number of bins.');}
+const arrSum=arr=>arr.reduce((a,b)=>a+b,0);if(arrSum(firstHistogram)!==arrSum(secondHistogram)){throw new Error('The histograms\' sizes don\'t match.');}
+let total=0;let remainder=0;for(let bucket=0;bucket<buckets;bucket++){remainder+=secondHistogram[bucket]-
+firstHistogram[bucket];total+=Math.abs(remainder);}
+return total;}
+return{earthMoversDistance,};});'use strict';tr.exportTo('tr.e.chrome',function(){const earthMoversDistance=tr.b.math.earthMoversDistance;class SpeedIndex{static getSnapshotsProgress_(timestampedColorHistograms){const numberOfScreenshots=timestampedColorHistograms.length;const firstHistogram=timestampedColorHistograms[0].colorHistogram;const lastHistogram=timestampedColorHistograms[numberOfScreenshots-1].colorHistogram;const totalDistance=earthMoversDistance(firstHistogram[0],lastHistogram[0])+
+earthMoversDistance(firstHistogram[1],lastHistogram[1])+
+earthMoversDistance(firstHistogram[2],lastHistogram[2]);if(totalDistance===0){return[{value:1,ts:timestampedColorHistograms[0].ts}];}
+const snapshotsProgress=new Array(numberOfScreenshots);for(let i=0;i<numberOfScreenshots;i++){const histogram=timestampedColorHistograms[i].colorHistogram;const distance=earthMoversDistance(histogram[0],lastHistogram[0])+
+earthMoversDistance(histogram[1],lastHistogram[1])+
+earthMoversDistance(histogram[2],lastHistogram[2]);const moved=Math.max(totalDistance-distance,0);snapshotsProgress[i]={value:(moved/totalDistance),ts:timestampedColorHistograms[i].ts};}
+return snapshotsProgress;}
+static speedIndexFromSnapshotsProgress_(snapshotsProgress){if(snapshotsProgress.length===0){throw new Error('No snapshots were provided.');}
+let prevSnapshotTimeTaken=0;let prevSnapshotProgress=0;let speedIndex=0;const numberOfScreenshots=snapshotsProgress.length;for(let i=0;i<numberOfScreenshots;i++){const elapsed=snapshotsProgress[i].ts-prevSnapshotTimeTaken;speedIndex+=elapsed*(1.0-prevSnapshotProgress);prevSnapshotTimeTaken=snapshotsProgress[i].ts;prevSnapshotProgress=snapshotsProgress[i].value;}
+return Math.round(speedIndex);}
+static createColorHistogram(imagePixelValues){const n=imagePixelValues.length;const histogram=new Array(3);for(let j=0;j<3;j++){histogram[j]=new Array(256).fill(0);}
+for(let i=0;i<n;i+=4){const r=imagePixelValues[i];const g=imagePixelValues[i+1];const b=imagePixelValues[i+2];histogram[0][r]++;histogram[1][g]++;histogram[2][b]++;}
+return histogram;}
+static calculateSpeedIndex(timestampedColorHistograms){const snapshotsProgress=SpeedIndex.getSnapshotsProgress_(timestampedColorHistograms);return SpeedIndex.speedIndexFromSnapshotsProgress_(snapshotsProgress);}
+static lineSweep(lineSweepRects,viewport){const verticalSweepEdges=[];const horizontalSweepEdges=[];for(let i=0;i<lineSweepRects.length;i++){const rect=lineSweepRects[i];let left=rect.left;let right=rect.right;let top=rect.top;let bottom=rect.bottom;if(left>viewport.x+viewport.width)continue;if(right<viewport.x)continue;if(top>viewport.y+viewport.height)continue;if(bottom<viewport.y)continue;left=Math.max(left,viewport.y);right=Math.min(right,viewport.y+viewport.width);top=Math.max(top,viewport.y);bottom=Math.min(bottom,viewport.y+viewport.height);verticalSweepEdges.push({id:i,value:left,type:'left'},{id:i,value:right,type:'right'});horizontalSweepEdges.push({id:i,value:top,type:'top'},{id:i,value:bottom,type:'bottom'});}
+verticalSweepEdges.sort((a,b)=>a.value-b.value);horizontalSweepEdges.sort((a,b)=>a.value-b.value);const active=new Array(lineSweepRects.length).fill(false);let area=0;active[verticalSweepEdges[0].id]=true;for(let i=1;i<verticalSweepEdges.length;i++){const currentLine=verticalSweepEdges[i];const previousLine=verticalSweepEdges[i-1];const deltaX=currentLine.value-previousLine.value;if(deltaX===0)continue;let count=0;let firstRect;for(let j=0;j<horizontalSweepEdges.length;j++){if(active[horizontalSweepEdges[j].id]===true){if(horizontalSweepEdges[j].type==='top'){if(count===0){firstRect=j;}
+count++;}else{if(count===1){const deltaY=horizontalSweepEdges[j].value-
+horizontalSweepEdges[firstRect].value;area+=deltaX*deltaY;}
+count--;}}}
+active[currentLine.id]=(currentLine.type==='left');}
+return area;}
+static quadToRect(quad){const left=Math.min(quad[0],quad[2],quad[4]);const right=Math.max(quad[0],quad[2],quad[4]);const top=Math.min(quad[1],quad[3],quad[5]);const bottom=Math.max(quad[1],quad[3],quad[5]);return{left,right,top,bottom};}
+static calculateRectsBasedSpeedIndex(timestampedPaintRects,viewport){const numberOfRects=timestampedPaintRects.length;if(numberOfRects===0){throw new Error('Can\'t calculate speed index without any paint '+'rectangles.');}
+const areaAddedAtTimestamp=new Array(numberOfRects);const rects=[];let previousAreaOfUnion=0;let totalAreaOfUnion=0;for(let i=numberOfRects-1;i>=0;i--){rects.push(timestampedPaintRects[i].rect);const currentAreaOfUnion=SpeedIndex.lineSweep(rects,viewport);areaAddedAtTimestamp[numberOfRects-i-1]={value:currentAreaOfUnion-previousAreaOfUnion,ts:timestampedPaintRects[i].ts};totalAreaOfUnion+=areaAddedAtTimestamp[numberOfRects-i-1].value;previousAreaOfUnion=currentAreaOfUnion;}
+const paintProgressAtTimestamp=new Array(numberOfRects);let lastProgressRecorded=0;for(let i=0;i<numberOfRects;i++){paintProgressAtTimestamp[i]={value:areaAddedAtTimestamp[i].value/totalAreaOfUnion+
+lastProgressRecorded,ts:areaAddedAtTimestamp[i].ts};lastProgressRecorded=paintProgressAtTimestamp[i].value;}
+return SpeedIndex.speedIndexFromSnapshotsProgress_(paintProgressAtTimestamp);}}
+return{SpeedIndex,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const timeDurationInMs_smallerIsBetter=tr.b.Unit.byName.timeDurationInMs_smallerIsBetter;const SpeedIndex=tr.e.chrome.SpeedIndex;const EventFinderUtils=tr.e.chrome.EventFinderUtils;const BIN_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(0,1e3,20).addLinearBins(3e3,20).addExponentialBins(20e3,20);const SUMMARY_OPTIONS={avg:true,count:false,max:true,min:true,std:true,sum:false,};function addRectsBasedSpeedIndexSample(samples,rendererHelper,navigationStart,loadDuration,frameID){let viewport;for(const event of EventFinderUtils.getMainThreadEvents(rendererHelper,'viewport','loading')){if(event.args.data.frameID===frameID&&event.start<(navigationStart+loadDuration)){viewport=event.args.data;break;}}
+if(!viewport)return;const timestampedPaintRects=[];for(const event of EventFinderUtils.getMainThreadEvents(rendererHelper,'PaintTracker::LayoutObjectPainted','loading')){if(event.start>=navigationStart&&event.start<navigationStart+loadDuration){const paintRect=event.args.data.visible_new_visual_rect;if(!paintRect)continue;timestampedPaintRects.push({rect:SpeedIndex.quadToRect(paintRect),ts:event.start});}}
+const numberOfRects=timestampedPaintRects.length;if(numberOfRects===0)return;samples.push({value:SpeedIndex.calculateRectsBasedSpeedIndex(timestampedPaintRects,viewport)-navigationStart});}
+function collectRectsBasedSpeedIndexSamplesFromLoadExpectations(model,chromeHelper){const rectsBasedSpeedIndexSamples=[];for(const expectation of model.userModel.expectations){if(!(expectation instanceof tr.model.um.LoadExpectation))continue;if(tr.e.chrome.CHROME_INTERNAL_URLS.includes(expectation.url)){continue;}
+const rendererHelper=chromeHelper.rendererHelpers[expectation.renderProcess.pid];addRectsBasedSpeedIndexSample(rectsBasedSpeedIndexSamples,rendererHelper,expectation.navigationStart.start,expectation.duration,expectation.navigationStart.args.frame);}
+return rectsBasedSpeedIndexSamples;}
+function rectsBasedSpeedIndexMetric(histograms,model){const rectsBasedSpeedIndexHistogram=histograms.createHistogram('rectsBasedSpeedIndex',timeDurationInMs_smallerIsBetter,[],{binBoundaries:BIN_BOUNDARIES,description:' the average time at which visible parts of the'+' page are displayed (in ms).',summaryOptions:SUMMARY_OPTIONS,});const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const samples=collectRectsBasedSpeedIndexSamplesFromLoadExpectations(model,chromeHelper);for(const sample of samples){rectsBasedSpeedIndexHistogram.addSample(sample.value);}}
+tr.metrics.MetricRegistry.register(rectsBasedSpeedIndexMetric);return{rectsBasedSpeedIndexMetric};});'use strict';tr.exportTo('tr.metrics.sh',function(){function computeAnimationThroughput(animationExpectation){if(animationExpectation.frameEvents===undefined||animationExpectation.frameEvents.length===0){throw new Error('Animation missing frameEvents '+
+animationExpectation.stableId);}
+const durationInS=tr.b.convertUnit(animationExpectation.duration,tr.b.UnitPrefixScale.METRIC.MILLI,tr.b.UnitPrefixScale.METRIC.NONE);return animationExpectation.frameEvents.length/durationInS;}
+function computeAnimationframeTimeDiscrepancy(animationExpectation){if(animationExpectation.frameEvents===undefined||animationExpectation.frameEvents.length===0){throw new Error('Animation missing frameEvents '+
+animationExpectation.stableId);}
+let frameTimestamps=animationExpectation.frameEvents;frameTimestamps=frameTimestamps.toArray().map(function(event){return event.start;});const absolute=true;return tr.b.math.Statistics.timestampsDiscrepancy(frameTimestamps,absolute);}
+function responsivenessMetric(histograms,model,opt_options){const responseNumeric=new tr.v.Histogram('response latency',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,tr.v.HistogramBinBoundaries.createLinear(100,1e3,50));const throughputNumeric=new tr.v.Histogram('animation throughput',tr.b.Unit.byName.unitlessNumber_biggerIsBetter,tr.v.HistogramBinBoundaries.createLinear(10,60,10));const frameTimeDiscrepancyNumeric=new tr.v.Histogram('animation frameTimeDiscrepancy',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,tr.v.HistogramBinBoundaries.createLinear(0,1e3,50).addExponentialBins(1e4,10));const latencyNumeric=new tr.v.Histogram('animation latency',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,tr.v.HistogramBinBoundaries.createLinear(0,300,60));model.userModel.expectations.forEach(function(ue){if(opt_options&&opt_options.rangeOfInterest&&!opt_options.rangeOfInterest.intersectsExplicitRangeInclusive(ue.start,ue.end)){return;}
+const sampleDiagnosticMap=tr.v.d.DiagnosticMap.fromObject({relatedEvents:new tr.v.d.RelatedEventSet([ue])});if(ue instanceof tr.model.um.IdleExpectation){return;}else if(ue instanceof tr.model.um.StartupExpectation){return;}else if(ue instanceof tr.model.um.LoadExpectation){}else if(ue instanceof tr.model.um.ResponseExpectation){responseNumeric.addSample(ue.duration,sampleDiagnosticMap);}else if(ue instanceof tr.model.um.AnimationExpectation){if(ue.frameEvents===undefined||ue.frameEvents.length===0){return;}
+const throughput=computeAnimationThroughput(ue);if(throughput===undefined){throw new Error('Missing throughput for '+
+ue.stableId);}
+throughputNumeric.addSample(throughput,sampleDiagnosticMap);const frameTimeDiscrepancy=computeAnimationframeTimeDiscrepancy(ue);if(frameTimeDiscrepancy===undefined){throw new Error('Missing frameTimeDiscrepancy for '+
+ue.stableId);}
+frameTimeDiscrepancyNumeric.addSample(frameTimeDiscrepancy,sampleDiagnosticMap);ue.associatedEvents.forEach(function(event){if(!(event instanceof tr.e.cc.InputLatencyAsyncSlice)){return;}
+latencyNumeric.addSample(event.duration,sampleDiagnosticMap);});}else{throw new Error('Unrecognized stage for '+ue.stableId);}});[responseNumeric,throughputNumeric,frameTimeDiscrepancyNumeric,latencyNumeric].forEach(function(numeric){numeric.customizeSummaryOptions({avg:true,max:true,min:true,std:true});});histograms.addHistogram(responseNumeric);histograms.addHistogram(throughputNumeric);histograms.addHistogram(frameTimeDiscrepancyNumeric);histograms.addHistogram(latencyNumeric);}
+tr.metrics.MetricRegistry.register(responsivenessMetric,{supportsRangeOfInterest:true,requiredCategories:['rail'],});return{responsivenessMetric,};});var JpegImage=(function jpegImage(){"use strict";var dctZigZag=new Int32Array([0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5,12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28,35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63]);var dctCos1=4017
+var dctSin1=799
+var dctCos3=3406
+var dctSin3=2276
+var dctCos6=1567
+var dctSin6=3784
+var dctSqrt2=5793
+var dctSqrt1d2=2896
+function constructor(){}
+function buildHuffmanTable(codeLengths,values){var k=0,code=[],i,j,length=16;while(length>0&&!codeLengths[length-1])
+length--;code.push({children:[],index:0});var p=code[0],q;for(i=0;i<length;i++){for(j=0;j<codeLengths[i];j++){p=code.pop();p.children[p.index]=values[k];while(p.index>0){p=code.pop();}
+p.index++;code.push(p);while(code.length<=i){code.push(q={children:[],index:0});p.children[p.index]=q.children;p=q;}
+k++;}
+if(i+1<length){code.push(q={children:[],index:0});p.children[p.index]=q.children;p=q;}}
+return code[0].children;}
+function decodeScan(data,offset,frame,components,resetInterval,spectralStart,spectralEnd,successivePrev,successive){var precision=frame.precision;var samplesPerLine=frame.samplesPerLine;var scanLines=frame.scanLines;var mcusPerLine=frame.mcusPerLine;var progressive=frame.progressive;var maxH=frame.maxH,maxV=frame.maxV;var startOffset=offset,bitsData=0,bitsCount=0;function readBit(){if(bitsCount>0){bitsCount--;return(bitsData>>bitsCount)&1;}
+bitsData=data[offset++];if(bitsData==0xFF){var nextByte=data[offset++];if(nextByte){throw new Error("unexpected marker: "+((bitsData<<8)|nextByte).toString(16));}}
+bitsCount=7;return bitsData>>>7;}
+function decodeHuffman(tree){var node=tree,bit;while((bit=readBit())!==null){node=node[bit];if(typeof node==='number')
+return node;if(typeof node!=='object')
+throw new Error("invalid huffman sequence");}
+return null;}
+function receive(length){var n=0;while(length>0){var bit=readBit();if(bit===null)return;n=(n<<1)|bit;length--;}
+return n;}
+function receiveAndExtend(length){var n=receive(length);if(n>=1<<(length-1))
+return n;return n+(-1<<length)+1;}
+function decodeBaseline(component,zz){var t=decodeHuffman(component.huffmanTableDC);var diff=t===0?0:receiveAndExtend(t);zz[0]=(component.pred+=diff);var k=1;while(k<64){var rs=decodeHuffman(component.huffmanTableAC);var s=rs&15,r=rs>>4;if(s===0){if(r<15)
+break;k+=16;continue;}
+k+=r;var z=dctZigZag[k];zz[z]=receiveAndExtend(s);k++;}}
+function decodeDCFirst(component,zz){var t=decodeHuffman(component.huffmanTableDC);var diff=t===0?0:(receiveAndExtend(t)<<successive);zz[0]=(component.pred+=diff);}
+function decodeDCSuccessive(component,zz){zz[0]|=readBit()<<successive;}
+var eobrun=0;function decodeACFirst(component,zz){if(eobrun>0){eobrun--;return;}
+var k=spectralStart,e=spectralEnd;while(k<=e){var rs=decodeHuffman(component.huffmanTableAC);var s=rs&15,r=rs>>4;if(s===0){if(r<15){eobrun=receive(r)+(1<<r)-1;break;}
+k+=16;continue;}
+k+=r;var z=dctZigZag[k];zz[z]=receiveAndExtend(s)*(1<<successive);k++;}}
+var successiveACState=0,successiveACNextValue;function decodeACSuccessive(component,zz){var k=spectralStart,e=spectralEnd,r=0;while(k<=e){var z=dctZigZag[k];var direction=zz[z]<0?-1:1;switch(successiveACState){case 0:var rs=decodeHuffman(component.huffmanTableAC);var s=rs&15,r=rs>>4;if(s===0){if(r<15){eobrun=receive(r)+(1<<r);successiveACState=4;}else{r=16;successiveACState=1;}}else{if(s!==1)
+throw new Error("invalid ACn encoding");successiveACNextValue=receiveAndExtend(s);successiveACState=r?2:3;}
+continue;case 1:case 2:if(zz[z])
+zz[z]+=(readBit()<<successive)*direction;else{r--;if(r===0)
+successiveACState=successiveACState==2?3:0;}
+break;case 3:if(zz[z])
+zz[z]+=(readBit()<<successive)*direction;else{zz[z]=successiveACNextValue<<successive;successiveACState=0;}
+break;case 4:if(zz[z])
+zz[z]+=(readBit()<<successive)*direction;break;}
+k++;}
+if(successiveACState===4){eobrun--;if(eobrun===0)
+successiveACState=0;}}
+function decodeMcu(component,decode,mcu,row,col){var mcuRow=(mcu/mcusPerLine)|0;var mcuCol=mcu%mcusPerLine;var blockRow=mcuRow*component.v+row;var blockCol=mcuCol*component.h+col;decode(component,component.blocks[blockRow][blockCol]);}
+function decodeBlock(component,decode,mcu){var blockRow=(mcu/component.blocksPerLine)|0;var blockCol=mcu%component.blocksPerLine;decode(component,component.blocks[blockRow][blockCol]);}
+var componentsLength=components.length;var component,i,j,k,n;var decodeFn;if(progressive){if(spectralStart===0)
+decodeFn=successivePrev===0?decodeDCFirst:decodeDCSuccessive;else
+decodeFn=successivePrev===0?decodeACFirst:decodeACSuccessive;}else{decodeFn=decodeBaseline;}
+var mcu=0,marker;var mcuExpected;if(componentsLength==1){mcuExpected=components[0].blocksPerLine*components[0].blocksPerColumn;}else{mcuExpected=mcusPerLine*frame.mcusPerColumn;}
+if(!resetInterval)resetInterval=mcuExpected;var h,v;while(mcu<mcuExpected){for(i=0;i<componentsLength;i++)
+components[i].pred=0;eobrun=0;if(componentsLength==1){component=components[0];for(n=0;n<resetInterval;n++){decodeBlock(component,decodeFn,mcu);mcu++;}}else{for(n=0;n<resetInterval;n++){for(i=0;i<componentsLength;i++){component=components[i];h=component.h;v=component.v;for(j=0;j<v;j++){for(k=0;k<h;k++){decodeMcu(component,decodeFn,mcu,j,k);}}}
+mcu++;if(mcu===mcuExpected)break;}}
+bitsCount=0;marker=(data[offset]<<8)|data[offset+1];if(marker<0xFF00){throw new Error("marker was not found");}
+if(marker>=0xFFD0&&marker<=0xFFD7){offset+=2;}
+else
+break;}
+return offset-startOffset;}
+function buildComponentData(frame,component){var lines=[];var blocksPerLine=component.blocksPerLine;var blocksPerColumn=component.blocksPerColumn;var samplesPerLine=blocksPerLine<<3;var R=new Int32Array(64),r=new Uint8Array(64);function quantizeAndInverse(zz,dataOut,dataIn){var qt=component.quantizationTable;var v0,v1,v2,v3,v4,v5,v6,v7,t;var p=dataIn;var i;for(i=0;i<64;i++)
+p[i]=zz[i]*qt[i];for(i=0;i<8;++i){var row=8*i;if(p[1+row]==0&&p[2+row]==0&&p[3+row]==0&&p[4+row]==0&&p[5+row]==0&&p[6+row]==0&&p[7+row]==0){t=(dctSqrt2*p[0+row]+512)>>10;p[0+row]=t;p[1+row]=t;p[2+row]=t;p[3+row]=t;p[4+row]=t;p[5+row]=t;p[6+row]=t;p[7+row]=t;continue;}
+v0=(dctSqrt2*p[0+row]+128)>>8;v1=(dctSqrt2*p[4+row]+128)>>8;v2=p[2+row];v3=p[6+row];v4=(dctSqrt1d2*(p[1+row]-p[7+row])+128)>>8;v7=(dctSqrt1d2*(p[1+row]+p[7+row])+128)>>8;v5=p[3+row]<<4;v6=p[5+row]<<4;t=(v0-v1+1)>>1;v0=(v0+v1+1)>>1;v1=t;t=(v2*dctSin6+v3*dctCos6+128)>>8;v2=(v2*dctCos6-v3*dctSin6+128)>>8;v3=t;t=(v4-v6+1)>>1;v4=(v4+v6+1)>>1;v6=t;t=(v7+v5+1)>>1;v5=(v7-v5+1)>>1;v7=t;t=(v0-v3+1)>>1;v0=(v0+v3+1)>>1;v3=t;t=(v1-v2+1)>>1;v1=(v1+v2+1)>>1;v2=t;t=(v4*dctSin3+v7*dctCos3+2048)>>12;v4=(v4*dctCos3-v7*dctSin3+2048)>>12;v7=t;t=(v5*dctSin1+v6*dctCos1+2048)>>12;v5=(v5*dctCos1-v6*dctSin1+2048)>>12;v6=t;p[0+row]=v0+v7;p[7+row]=v0-v7;p[1+row]=v1+v6;p[6+row]=v1-v6;p[2+row]=v2+v5;p[5+row]=v2-v5;p[3+row]=v3+v4;p[4+row]=v3-v4;}
+for(i=0;i<8;++i){var col=i;if(p[1*8+col]==0&&p[2*8+col]==0&&p[3*8+col]==0&&p[4*8+col]==0&&p[5*8+col]==0&&p[6*8+col]==0&&p[7*8+col]==0){t=(dctSqrt2*dataIn[i+0]+8192)>>14;p[0*8+col]=t;p[1*8+col]=t;p[2*8+col]=t;p[3*8+col]=t;p[4*8+col]=t;p[5*8+col]=t;p[6*8+col]=t;p[7*8+col]=t;continue;}
+v0=(dctSqrt2*p[0*8+col]+2048)>>12;v1=(dctSqrt2*p[4*8+col]+2048)>>12;v2=p[2*8+col];v3=p[6*8+col];v4=(dctSqrt1d2*(p[1*8+col]-p[7*8+col])+2048)>>12;v7=(dctSqrt1d2*(p[1*8+col]+p[7*8+col])+2048)>>12;v5=p[3*8+col];v6=p[5*8+col];t=(v0-v1+1)>>1;v0=(v0+v1+1)>>1;v1=t;t=(v2*dctSin6+v3*dctCos6+2048)>>12;v2=(v2*dctCos6-v3*dctSin6+2048)>>12;v3=t;t=(v4-v6+1)>>1;v4=(v4+v6+1)>>1;v6=t;t=(v7+v5+1)>>1;v5=(v7-v5+1)>>1;v7=t;t=(v0-v3+1)>>1;v0=(v0+v3+1)>>1;v3=t;t=(v1-v2+1)>>1;v1=(v1+v2+1)>>1;v2=t;t=(v4*dctSin3+v7*dctCos3+2048)>>12;v4=(v4*dctCos3-v7*dctSin3+2048)>>12;v7=t;t=(v5*dctSin1+v6*dctCos1+2048)>>12;v5=(v5*dctCos1-v6*dctSin1+2048)>>12;v6=t;p[0*8+col]=v0+v7;p[7*8+col]=v0-v7;p[1*8+col]=v1+v6;p[6*8+col]=v1-v6;p[2*8+col]=v2+v5;p[5*8+col]=v2-v5;p[3*8+col]=v3+v4;p[4*8+col]=v3-v4;}
+for(i=0;i<64;++i){var sample=128+((p[i]+8)>>4);dataOut[i]=sample<0?0:sample>0xFF?0xFF:sample;}}
+var i,j;for(var blockRow=0;blockRow<blocksPerColumn;blockRow++){var scanLine=blockRow<<3;for(i=0;i<8;i++)
+lines.push(new Uint8Array(samplesPerLine));for(var blockCol=0;blockCol<blocksPerLine;blockCol++){quantizeAndInverse(component.blocks[blockRow][blockCol],r,R);var offset=0,sample=blockCol<<3;for(j=0;j<8;j++){var line=lines[scanLine+j];for(i=0;i<8;i++)
+line[sample+i]=r[offset++];}}}
+return lines;}
+function clampTo8bit(a){return a<0?0:a>255?255:a;}
+constructor.prototype={load:function load(path){var xhr=new XMLHttpRequest();xhr.open("GET",path,true);xhr.responseType="arraybuffer";xhr.onload=(function(){var data=new Uint8Array(xhr.response||xhr.mozResponseArrayBuffer);this.parse(data);if(this.onload)
+this.onload();}).bind(this);xhr.send(null);},parse:function parse(data){var offset=0,length=data.length;function readUint16(){var value=(data[offset]<<8)|data[offset+1];offset+=2;return value;}
+function readDataBlock(){var length=readUint16();var array=data.subarray(offset,offset+length-2);offset+=array.length;return array;}
+function prepareComponents(frame){var maxH=0,maxV=0;var component,componentId;for(componentId in frame.components){if(frame.components.hasOwnProperty(componentId)){component=frame.components[componentId];if(maxH<component.h)maxH=component.h;if(maxV<component.v)maxV=component.v;}}
+var mcusPerLine=Math.ceil(frame.samplesPerLine/8/maxH);var mcusPerColumn=Math.ceil(frame.scanLines/8/maxV);for(componentId in frame.components){if(frame.components.hasOwnProperty(componentId)){component=frame.components[componentId];var blocksPerLine=Math.ceil(Math.ceil(frame.samplesPerLine/8)*component.h/maxH);var blocksPerColumn=Math.ceil(Math.ceil(frame.scanLines/8)*component.v/maxV);var blocksPerLineForMcu=mcusPerLine*component.h;var blocksPerColumnForMcu=mcusPerColumn*component.v;var blocks=[];for(var i=0;i<blocksPerColumnForMcu;i++){var row=[];for(var j=0;j<blocksPerLineForMcu;j++)
+row.push(new Int32Array(64));blocks.push(row);}
+component.blocksPerLine=blocksPerLine;component.blocksPerColumn=blocksPerColumn;component.blocks=blocks;}}
+frame.maxH=maxH;frame.maxV=maxV;frame.mcusPerLine=mcusPerLine;frame.mcusPerColumn=mcusPerColumn;}
+var jfif=null;var adobe=null;var pixels=null;var frame,resetInterval;var quantizationTables=[],frames=[];var huffmanTablesAC=[],huffmanTablesDC=[];var fileMarker=readUint16();if(fileMarker!=0xFFD8){throw new Error("SOI not found");}
+fileMarker=readUint16();while(fileMarker!=0xFFD9){var i,j,l;switch(fileMarker){case 0xFF00:break;case 0xFFE0:case 0xFFE1:case 0xFFE2:case 0xFFE3:case 0xFFE4:case 0xFFE5:case 0xFFE6:case 0xFFE7:case 0xFFE8:case 0xFFE9:case 0xFFEA:case 0xFFEB:case 0xFFEC:case 0xFFED:case 0xFFEE:case 0xFFEF:case 0xFFFE:var appData=readDataBlock();if(fileMarker===0xFFE0){if(appData[0]===0x4A&&appData[1]===0x46&&appData[2]===0x49&&appData[3]===0x46&&appData[4]===0){jfif={version:{major:appData[5],minor:appData[6]},densityUnits:appData[7],xDensity:(appData[8]<<8)|appData[9],yDensity:(appData[10]<<8)|appData[11],thumbWidth:appData[12],thumbHeight:appData[13],thumbData:appData.subarray(14,14+3*appData[12]*appData[13])};}}
+if(fileMarker===0xFFEE){if(appData[0]===0x41&&appData[1]===0x64&&appData[2]===0x6F&&appData[3]===0x62&&appData[4]===0x65&&appData[5]===0){adobe={version:appData[6],flags0:(appData[7]<<8)|appData[8],flags1:(appData[9]<<8)|appData[10],transformCode:appData[11]};}}
+break;case 0xFFDB:var quantizationTablesLength=readUint16();var quantizationTablesEnd=quantizationTablesLength+offset-2;while(offset<quantizationTablesEnd){var quantizationTableSpec=data[offset++];var tableData=new Int32Array(64);if((quantizationTableSpec>>4)===0){for(j=0;j<64;j++){var z=dctZigZag[j];tableData[z]=data[offset++];}}else if((quantizationTableSpec>>4)===1){for(j=0;j<64;j++){var z=dctZigZag[j];tableData[z]=readUint16();}}else
+throw new Error("DQT: invalid table spec");quantizationTables[quantizationTableSpec&15]=tableData;}
+break;case 0xFFC0:case 0xFFC1:case 0xFFC2:readUint16();frame={};frame.extended=(fileMarker===0xFFC1);frame.progressive=(fileMarker===0xFFC2);frame.precision=data[offset++];frame.scanLines=readUint16();frame.samplesPerLine=readUint16();frame.components={};frame.componentsOrder=[];var componentsCount=data[offset++],componentId;var maxH=0,maxV=0;for(i=0;i<componentsCount;i++){componentId=data[offset];var h=data[offset+1]>>4;var v=data[offset+1]&15;var qId=data[offset+2];frame.componentsOrder.push(componentId);frame.components[componentId]={h:h,v:v,quantizationIdx:qId};offset+=3;}
+prepareComponents(frame);frames.push(frame);break;case 0xFFC4:var huffmanLength=readUint16();for(i=2;i<huffmanLength;){var huffmanTableSpec=data[offset++];var codeLengths=new Uint8Array(16);var codeLengthSum=0;for(j=0;j<16;j++,offset++)
+codeLengthSum+=(codeLengths[j]=data[offset]);var huffmanValues=new Uint8Array(codeLengthSum);for(j=0;j<codeLengthSum;j++,offset++)
+huffmanValues[j]=data[offset];i+=17+codeLengthSum;((huffmanTableSpec>>4)===0?huffmanTablesDC:huffmanTablesAC)[huffmanTableSpec&15]=buildHuffmanTable(codeLengths,huffmanValues);}
+break;case 0xFFDD:readUint16();resetInterval=readUint16();break;case 0xFFDA:var scanLength=readUint16();var selectorsCount=data[offset++];var components=[],component;for(i=0;i<selectorsCount;i++){component=frame.components[data[offset++]];var tableSpec=data[offset++];component.huffmanTableDC=huffmanTablesDC[tableSpec>>4];component.huffmanTableAC=huffmanTablesAC[tableSpec&15];components.push(component);}
+var spectralStart=data[offset++];var spectralEnd=data[offset++];var successiveApproximation=data[offset++];var processed=decodeScan(data,offset,frame,components,resetInterval,spectralStart,spectralEnd,successiveApproximation>>4,successiveApproximation&15);offset+=processed;break;case 0xFFFF:if(data[offset]!==0xFF){offset--;}
+break;default:if(data[offset-3]==0xFF&&data[offset-2]>=0xC0&&data[offset-2]<=0xFE){offset-=3;break;}
+throw new Error("unknown JPEG marker "+fileMarker.toString(16));}
+fileMarker=readUint16();}
+if(frames.length!=1)
+throw new Error("only single frame JPEGs supported");for(var i=0;i<frames.length;i++){var cp=frames[i].components;for(var j in cp){cp[j].quantizationTable=quantizationTables[cp[j].quantizationIdx];delete cp[j].quantizationIdx;}}
+this.width=frame.samplesPerLine;this.height=frame.scanLines;this.jfif=jfif;this.adobe=adobe;this.components=[];for(var i=0;i<frame.componentsOrder.length;i++){var component=frame.components[frame.componentsOrder[i]];this.components.push({lines:buildComponentData(frame,component),scaleX:component.h/frame.maxH,scaleY:component.v/frame.maxV});}},getData:function getData(width,height){var scaleX=this.width/width,scaleY=this.height/height;var component1,component2,component3,component4;var component1Line,component2Line,component3Line,component4Line;var x,y;var offset=0;var Y,Cb,Cr,K,C,M,Ye,R,G,B;var colorTransform;var dataLength=width*height*this.components.length;var data=new Uint8Array(dataLength);switch(this.components.length){case 1:component1=this.components[0];for(y=0;y<height;y++){component1Line=component1.lines[0|(y*component1.scaleY*scaleY)];for(x=0;x<width;x++){Y=component1Line[0|(x*component1.scaleX*scaleX)];data[offset++]=Y;}}
+break;case 2:component1=this.components[0];component2=this.components[1];for(y=0;y<height;y++){component1Line=component1.lines[0|(y*component1.scaleY*scaleY)];component2Line=component2.lines[0|(y*component2.scaleY*scaleY)];for(x=0;x<width;x++){Y=component1Line[0|(x*component1.scaleX*scaleX)];data[offset++]=Y;Y=component2Line[0|(x*component2.scaleX*scaleX)];data[offset++]=Y;}}
+break;case 3:colorTransform=true;if(this.adobe&&this.adobe.transformCode)
+colorTransform=true;else if(typeof this.colorTransform!=='undefined')
+colorTransform=!!this.colorTransform;component1=this.components[0];component2=this.components[1];component3=this.components[2];for(y=0;y<height;y++){component1Line=component1.lines[0|(y*component1.scaleY*scaleY)];component2Line=component2.lines[0|(y*component2.scaleY*scaleY)];component3Line=component3.lines[0|(y*component3.scaleY*scaleY)];for(x=0;x<width;x++){if(!colorTransform){R=component1Line[0|(x*component1.scaleX*scaleX)];G=component2Line[0|(x*component2.scaleX*scaleX)];B=component3Line[0|(x*component3.scaleX*scaleX)];}else{Y=component1Line[0|(x*component1.scaleX*scaleX)];Cb=component2Line[0|(x*component2.scaleX*scaleX)];Cr=component3Line[0|(x*component3.scaleX*scaleX)];R=clampTo8bit(Y+1.402*(Cr-128));G=clampTo8bit(Y-0.3441363*(Cb-128)-0.71413636*(Cr-128));B=clampTo8bit(Y+1.772*(Cb-128));}
+data[offset++]=R;data[offset++]=G;data[offset++]=B;}}
+break;case 4:if(!this.adobe)
+throw new Error('Unsupported color mode (4 components)');colorTransform=false;if(this.adobe&&this.adobe.transformCode)
+colorTransform=true;else if(typeof this.colorTransform!=='undefined')
+colorTransform=!!this.colorTransform;component1=this.components[0];component2=this.components[1];component3=this.components[2];component4=this.components[3];for(y=0;y<height;y++){component1Line=component1.lines[0|(y*component1.scaleY*scaleY)];component2Line=component2.lines[0|(y*component2.scaleY*scaleY)];component3Line=component3.lines[0|(y*component3.scaleY*scaleY)];component4Line=component4.lines[0|(y*component4.scaleY*scaleY)];for(x=0;x<width;x++){if(!colorTransform){C=component1Line[0|(x*component1.scaleX*scaleX)];M=component2Line[0|(x*component2.scaleX*scaleX)];Ye=component3Line[0|(x*component3.scaleX*scaleX)];K=component4Line[0|(x*component4.scaleX*scaleX)];}else{Y=component1Line[0|(x*component1.scaleX*scaleX)];Cb=component2Line[0|(x*component2.scaleX*scaleX)];Cr=component3Line[0|(x*component3.scaleX*scaleX)];K=component4Line[0|(x*component4.scaleX*scaleX)];C=255-clampTo8bit(Y+1.402*(Cr-128));M=255-clampTo8bit(Y-0.3441363*(Cb-128)-0.71413636*(Cr-128));Ye=255-clampTo8bit(Y+1.772*(Cb-128));}
+data[offset++]=255-C;data[offset++]=255-M;data[offset++]=255-Ye;data[offset++]=255-K;}}
+break;default:throw new Error('Unsupported color mode');}
+return data;},copyToImageData:function copyToImageData(imageData){var width=imageData.width,height=imageData.height;var imageDataArray=imageData.data;var data=this.getData(width,height);var i=0,j=0,x,y;var Y,K,C,M,R,G,B;switch(this.components.length){case 1:for(y=0;y<height;y++){for(x=0;x<width;x++){Y=data[i++];imageDataArray[j++]=Y;imageDataArray[j++]=Y;imageDataArray[j++]=Y;imageDataArray[j++]=255;}}
+break;case 3:for(y=0;y<height;y++){for(x=0;x<width;x++){R=data[i++];G=data[i++];B=data[i++];imageDataArray[j++]=R;imageDataArray[j++]=G;imageDataArray[j++]=B;imageDataArray[j++]=255;}}
+break;case 4:for(y=0;y<height;y++){for(x=0;x<width;x++){C=data[i++];M=data[i++];Y=data[i++];K=data[i++];R=255-clampTo8bit(C*(1-K/255)+K);G=255-clampTo8bit(M*(1-K/255)+K);B=255-clampTo8bit(Y*(1-K/255)+K);imageDataArray[j++]=R;imageDataArray[j++]=G;imageDataArray[j++]=B;imageDataArray[j++]=255;}}
+break;default:throw new Error('Unsupported color mode');}}};return constructor;})();global.jpegDecode=decode;function decode(jpegData,opts){var defaultOpts={useTArray:false,colorTransform:true};if(opts){if(typeof opts==='object'){opts={useTArray:(typeof opts.useTArray==='undefined'?defaultOpts.useTArray:opts.useTArray),colorTransform:(typeof opts.colorTransform==='undefined'?defaultOpts.colorTransform:opts.colorTransform)};}else{opts=defaultOpts;opts.useTArray=true;}}else{opts=defaultOpts;}
+var arr=new Uint8Array(jpegData);var decoder=new JpegImage();decoder.parse(arr);decoder.colorTransform=opts.colorTransform;var image={width:decoder.width,height:decoder.height,data:opts.useTArray?new Uint8Array(decoder.width*decoder.height*4):new Buffer(decoder.width*decoder.height*4)};decoder.copyToImageData(image);return image;}'use strict';tr.exportTo('tr.metrics.sh',function(){const timeDurationInMs_smallerIsBetter=tr.b.Unit.byName.timeDurationInMs_smallerIsBetter;const SpeedIndex=tr.e.chrome.SpeedIndex;const LOADING_METRIC_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(0,1e3,20).addLinearBins(3e3,20).addExponentialBins(20e3,20);const SUMMARY_OPTIONS={avg:true,count:false,max:true,min:true,std:true,sum:false,};function addSpeedIndexScreenshotsBasedSample(samples,navigationStart,loadDuration,browserHelper){const screenshotObjects=browserHelper.process.objects.getAllInstancesNamed('Screenshot');if(!screenshotObjects)return;for(let i=0;i<screenshotObjects.length;i++){const snapshots=screenshotObjects[i].snapshots;const timestampedColorHistograms=[];snapshots.map(snapshot=>{if(snapshot.ts>=navigationStart.start&&snapshot.ts<navigationStart.start+loadDuration){timestampedColorHistograms.push({colorHistogram:SpeedIndex.createColorHistogram(getPixelData(snapshot.args)),ts:snapshot.ts});}});samples.push({value:SpeedIndex.calculateSpeedIndex(timestampedColorHistograms)-
+navigationStart.start});}}
+function getPixelData(base64JpegImage){const binaryString=atob(base64JpegImage);const bytes=new DataView(new ArrayBuffer(base64JpegImage.length));tr.b.Base64.DecodeToTypedArray(base64JpegImage,bytes);const rawImageData=jpegDecode(bytes.buffer,{useTArray:true});return rawImageData.data;}
+function collectSpeedIndexSamplesFromLoadExpectations(model,chromeHelper){const speedIndexScreenshotsBasedSamples=[];for(const expectation of model.userModel.expectations){if(!(expectation instanceof tr.model.um.LoadExpectation))continue;if(tr.e.chrome.CHROME_INTERNAL_URLS.includes(expectation.url)){continue;}
+const rendererHelper=chromeHelper.rendererHelpers[expectation.renderProcess.pid];addSpeedIndexScreenshotsBasedSample(speedIndexScreenshotsBasedSamples,expectation.navigationStart,expectation.duration,chromeHelper.browserHelper);}
+return speedIndexScreenshotsBasedSamples;}
+function screenshotsBasedSpeedIndexMetric(histograms,model){const speedIndexScreenshotsBasedHistogram=histograms.createHistogram('speedIndexScreenshotsBased',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'The average time at which visible parts of the'+' page are displayed.',summaryOptions:SUMMARY_OPTIONS,});const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const samples=collectSpeedIndexSamplesFromLoadExpectations(model,chromeHelper);for(const sample of samples){speedIndexScreenshotsBasedHistogram.addSample(sample.value);}}
+tr.metrics.MetricRegistry.register(screenshotsBasedSpeedIndexMetric);return{screenshotsBasedSpeedIndexMetric};});'use strict';tr.exportTo('tr.metrics.sh',function(){function webviewStartupMetric(histograms,model){const startupWallHist=new tr.v.Histogram('webview_startup_wall_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);startupWallHist.description='WebView startup wall time';const startupCPUHist=new tr.v.Histogram('webview_startup_cpu_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);startupCPUHist.description='WebView startup CPU time';const loadWallHist=new tr.v.Histogram('webview_url_load_wall_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);loadWallHist.description='WebView blank URL load wall time';const loadCPUHist=new tr.v.Histogram('webview_url_load_cpu_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);loadCPUHist.description='WebView blank URL load CPU time';for(const slice of model.getDescendantEvents()){if(!(slice instanceof tr.model.ThreadSlice))continue;if(slice.title==='WebViewStartupInterval'){startupWallHist.addSample(slice.duration);startupCPUHist.addSample(slice.cpuDuration);}
+if(slice.title==='WebViewBlankUrlLoadInterval'){loadWallHist.addSample(slice.duration);loadCPUHist.addSample(slice.cpuDuration);}}
+histograms.addHistogram(startupWallHist);histograms.addHistogram(startupCPUHist);histograms.addHistogram(loadWallHist);histograms.addHistogram(loadCPUHist);}
+tr.metrics.MetricRegistry.register(webviewStartupMetric);return{webviewStartupMetric,};});'use strict';tr.exportTo('tr.metrics.tabs',function(){function tabsMetric(histograms,model,opt_options){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(!chromeHelper){return;}
+const tabSwitchRequestDelays=[];const TAB_SWITCHING_REQUEST_TITLE='TabSwitchVisibilityRequest';let startTabSwitchVisibilityRequest=Number.MAX_SAFE_INTEGER;for(const helper of chromeHelper.browserHelpers){if(!helper.mainThread)continue;for(const slice of helper.mainThread.asyncSliceGroup.slices){if(slice.title===TAB_SWITCHING_REQUEST_TITLE&&!slice.error){tabSwitchRequestDelays.push(slice.duration);if(slice.start<startTabSwitchVisibilityRequest){startTabSwitchVisibilityRequest=slice.start;}}}}
+histograms.createHistogram('tab_switching_request_delay',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,tabSwitchRequestDelays,{description:'Delay before tab-request is made',summaryOptions:{sum:false}});const tabSwitchLatencies=[];const TAB_SWITCHING_SLICE_TITLE='TabSwitching::Latency';function extractLatencyFromHelpers(helpers,legacy){for(const helper of helpers){if(!helper.mainThread){continue;}
+const thread=helper.mainThread;for(const slice of thread.asyncSliceGroup.slices){if(slice.title===TAB_SWITCHING_SLICE_TITLE&&(legacy||slice.args.latency)&&slice.start>startTabSwitchVisibilityRequest){tabSwitchLatencies.push(legacy?slice.duration:slice.args.latency);}}}}
+extractLatencyFromHelpers(chromeHelper.browserHelpers);extractLatencyFromHelpers(Object.values(chromeHelper.rendererHelpers));if(tabSwitchLatencies.length===0){extractLatencyFromHelpers(chromeHelper.browserHelpers,true);}
+histograms.createHistogram('tab_switching_latency',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,tabSwitchLatencies,{description:'Tab switching time in ms',summaryOptions:{sum:false}});}
+tr.metrics.MetricRegistry.register(tabsMetric,{supportsRangeOfInterest:false,});return{tabsMetric,};});'use strict';tr.exportTo('tr.metrics',function(){const MEMORY_INFRA_TRACING_CATEGORY='disabled-by-default-memory-infra';const TIME_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(1e-3,1e5,30);const BYTE_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(1,1e9,30);const COUNT_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(1,1e5,30);const SUMMARY_OPTIONS=tr.v.Histogram.AVERAGE_ONLY_SUMMARY_OPTIONS;function addMemoryInfraHistograms(histograms,model,categoryNamesToTotalEventSizes){const memoryDumpCount=model.globalMemoryDumps.length;if(memoryDumpCount===0)return;let totalOverhead=0;let nonMemoryInfraThreadOverhead=0;const overheadByProvider={};for(const process of Object.values(model.processes)){for(const thread of Object.values(process.threads)){for(const slice of Object.values(thread.sliceGroup.slices)){if(slice.category!==MEMORY_INFRA_TRACING_CATEGORY)continue;totalOverhead+=slice.duration;if(thread.name!=='MemoryInfra'){nonMemoryInfraThreadOverhead+=slice.duration;}
+if(slice.args&&slice.args['dump_provider.name']){const providerName=slice.args['dump_provider.name'];let durationAndCount=overheadByProvider[providerName];if(durationAndCount===undefined){overheadByProvider[providerName]=durationAndCount={duration:0,count:0};}
+durationAndCount.duration+=slice.duration;durationAndCount.count++;}}}}
+histograms.createHistogram('memory_dump_cpu_overhead',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,totalOverhead/memoryDumpCount,{binBoundaries:TIME_BOUNDARIES,description:'Average CPU overhead on all threads per memory-infra dump',summaryOptions:SUMMARY_OPTIONS,});histograms.createHistogram('nonmemory_thread_memory_dump_cpu_overhead',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,nonMemoryInfraThreadOverhead/memoryDumpCount,{binBoundaries:TIME_BOUNDARIES,description:'Average CPU overhead on non-memory-infra threads '+'per memory-infra dump',summaryOptions:SUMMARY_OPTIONS,});for(const[providerName,overhead]of Object.entries(overheadByProvider)){histograms.createHistogram(`${providerName}_memory_dump_cpu_overhead`,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,overhead.duration/overhead.count,{binBoundaries:TIME_BOUNDARIES,description:`Average CPU overhead of ${providerName} per OnMemoryDump call`,summaryOptions:SUMMARY_OPTIONS,});}
+const memoryInfraEventsSize=categoryNamesToTotalEventSizes.get(MEMORY_INFRA_TRACING_CATEGORY);const memoryInfraTraceBytesValue=new tr.v.Histogram('total_memory_dump_size',tr.b.Unit.byName.sizeInBytes_smallerIsBetter,BYTE_BOUNDARIES);memoryInfraTraceBytesValue.description='Total trace size of memory-infra dumps in bytes';memoryInfraTraceBytesValue.customizeSummaryOptions(SUMMARY_OPTIONS);memoryInfraTraceBytesValue.addSample(memoryInfraEventsSize);histograms.addHistogram(memoryInfraTraceBytesValue);const traceBytesPerDumpValue=new tr.v.Histogram('memory_dump_size',tr.b.Unit.byName.sizeInBytes_smallerIsBetter,BYTE_BOUNDARIES);traceBytesPerDumpValue.description='Average trace size of memory-infra dumps in bytes';traceBytesPerDumpValue.customizeSummaryOptions(SUMMARY_OPTIONS);traceBytesPerDumpValue.addSample(memoryInfraEventsSize/memoryDumpCount);histograms.addHistogram(traceBytesPerDumpValue);}
+function tracingMetric(histograms,model){if(!model.stats.hasEventSizesinBytes)return;const eventStats=model.stats.allTraceEventStatsInTimeIntervals;eventStats.sort((a,b)=>a.timeInterval-b.timeInterval);const totalTraceBytes=eventStats.reduce((a,b)=>a+b.totalEventSizeinBytes,0);let maxEventCountPerSec=0;let maxEventBytesPerSec=0;const INTERVALS_PER_SEC=Math.floor(1000/model.stats.TIME_INTERVAL_SIZE_IN_MS);let runningEventNumPerSec=0;let runningEventBytesPerSec=0;let start=0;let end=0;while(end<eventStats.length){runningEventNumPerSec+=eventStats[end].numEvents;runningEventBytesPerSec+=eventStats[end].totalEventSizeinBytes;end++;while((eventStats[end-1].timeInterval-
+eventStats[start].timeInterval)>=INTERVALS_PER_SEC){runningEventNumPerSec-=eventStats[start].numEvents;runningEventBytesPerSec-=eventStats[start].totalEventSizeinBytes;start++;}
+maxEventCountPerSec=Math.max(maxEventCountPerSec,runningEventNumPerSec);maxEventBytesPerSec=Math.max(maxEventBytesPerSec,runningEventBytesPerSec);}
+const stats=model.stats.allTraceEventStats;const categoryNamesToTotalEventSizes=(stats.reduce((map,stat)=>(map.set(stat.category,((map.get(stat.category)||0)+
+stat.totalEventSizeinBytes))),new Map()));const maxCatNameAndBytes=Array.from(categoryNamesToTotalEventSizes.entries()).reduce((a,b)=>((b[1]>=a[1])?b:a));const maxEventBytesPerCategory=maxCatNameAndBytes[1];const categoryWithMaxEventBytes=maxCatNameAndBytes[0];const maxEventCountPerSecValue=new tr.v.Histogram('peak_event_rate',tr.b.Unit.byName.count_smallerIsBetter,COUNT_BOUNDARIES);maxEventCountPerSecValue.description='Max number of events per second';maxEventCountPerSecValue.customizeSummaryOptions(SUMMARY_OPTIONS);maxEventCountPerSecValue.addSample(maxEventCountPerSec);const maxEventBytesPerSecValue=new tr.v.Histogram('peak_event_size_rate',tr.b.Unit.byName.sizeInBytes_smallerIsBetter,BYTE_BOUNDARIES);maxEventBytesPerSecValue.description='Max event size in bytes per second';maxEventBytesPerSecValue.customizeSummaryOptions(SUMMARY_OPTIONS);maxEventBytesPerSecValue.addSample(maxEventBytesPerSec);const totalTraceBytesValue=new tr.v.Histogram('trace_size',tr.b.Unit.byName.sizeInBytes_smallerIsBetter,BYTE_BOUNDARIES);totalTraceBytesValue.customizeSummaryOptions(SUMMARY_OPTIONS);totalTraceBytesValue.addSample(totalTraceBytes);const biggestCategory={name:categoryWithMaxEventBytes,size_in_bytes:maxEventBytesPerCategory};totalTraceBytesValue.diagnostics.set('category_with_max_event_size',new tr.v.d.GenericSet([biggestCategory]));histograms.addHistogram(totalTraceBytesValue);maxEventCountPerSecValue.diagnostics.set('category_with_max_event_size',new tr.v.d.GenericSet([biggestCategory]));histograms.addHistogram(maxEventCountPerSecValue);maxEventBytesPerSecValue.diagnostics.set('category_with_max_event_size',new tr.v.d.GenericSet([biggestCategory]));histograms.addHistogram(maxEventBytesPerSecValue);addMemoryInfraHistograms(histograms,model,categoryNamesToTotalEventSizes);}
+tr.metrics.MetricRegistry.register(tracingMetric);return{tracingMetric,MEMORY_INFRA_TRACING_CATEGORY,};});'use strict';tr.exportTo('tr.metrics',function(){function parseBuckets_(event,processName){const len=tr.b.Base64.getDecodedBufferLength(event.args.buckets);const buffer=new ArrayBuffer(len);const dataView=new DataView(buffer);tr.b.Base64.DecodeToTypedArray(event.args.buckets,dataView);const decoded=new Uint32Array(buffer);const sum=decoded[1]+decoded[2]*0x100000000;const bins=[];let position=4;while(position<=decoded.length-4){const min=decoded[position++];const max=decoded[position++]+decoded[position++]*0x100000000;const count=decoded[position++];const processes=new tr.v.d.Breakdown();processes.set(processName,count);const events=new tr.v.d.RelatedEventSet([event]);bins.push({min,max,count,processes,events});}
+return{sum,bins};}
+function mergeBins_(x,y){x.sum+=y.sum;const allBins=[...x.bins,...y.bins];allBins.sort((a,b)=>a.min-b.min);x.bins=[];let last=undefined;for(const bin of allBins){if(last!==undefined&&bin.min===last.min){if(last.max!==bin.max)throw new Error('Incompatible bins');if(bin.count===0)continue;last.count+=bin.count;for(const event of bin.events){last.events.add(event);}
+last.processes.addDiagnostic(bin.processes);}else{if(last!==undefined&&bin.min<last.max){throw new Error('Incompatible bins');}
+x.bins.push(bin);last=bin;}}}
+function subtractBins_(x,y){x.sum-=y.sum;let p1=0;let p2=0;while(p2<y.bins.length){while(p1<x.bins.length&&x.bins[p1].min!==y.bins[p2].min){p1++;}
+if(p1===x.bins.length)throw new Error('Cannot subtract');if(x.bins[p1].max!==y.bins[p2].max){throw new Error('Incompatible bins');}
+if(x.bins[p1].count<y.bins[p2].count){throw new Error('Cannot subtract');}
+x.bins[p1].count-=y.bins[p2].count;for(const event of y.bins[p2].events){x.bins[p1].events.add(event);}
+const processName=tr.b.getOnlyElement(x.bins[p1].processes)[0];x.bins[p1].processes.set(processName,x.bins[p1].count);p2++;}}
+function getHistogramUnit_(name){return tr.b.Unit.byName.unitlessNumber_smallerIsBetter;}
+function getHistogramBoundaries_(name){if(name.startsWith('Event.Latency.Scroll')){return tr.v.HistogramBinBoundaries.createExponential(1e3,1e5,50);}
+if(name.startsWith('Graphics.Smoothness.Throughput')){return tr.v.HistogramBinBoundaries.createLinear(0,100,101);}
+return tr.v.HistogramBinBoundaries.createExponential(1e-3,1e3,50);}
+function umaMetric(histograms,model){const histogramValues=new Map();const nameCounts=new Map();for(const process of model.getAllProcesses()){const histogramEvents=new Map();for(const event of process.instantEvents){if(event.title!=='UMAHistogramSamples')continue;const name=event.args.name;const events=histogramEvents.get(name)||[];if(!histogramEvents.has(name))histogramEvents.set(name,events);events.push(event);}
+let processName=tr.e.chrome.chrome_processes.canonicalizeProcessName(process.name);nameCounts.set(processName,(nameCounts.get(processName)||0)+1);processName=`${processName}_${nameCounts.get(processName)}`;for(const[name,events]of histogramEvents){const values=histogramValues.get(name)||{sum:0,bins:[]};if(!histogramValues.has(name))histogramValues.set(name,values);const endValues=parseBuckets_(events[events.length-1],processName);if(events.length===1){mergeBins_(values,endValues);}else if(events.length===2){subtractBins_(endValues,parseBuckets_(events[0],processName));mergeBins_(values,endValues);}else{throw new Error('There should be at most two snapshots of an UMA '+'histogram in each process');}}}
+for(const[name,values]of histogramValues){const histogram=new tr.v.Histogram(name,getHistogramUnit_(name),getHistogramBoundaries_(name));let sumOfMiddles=0;let sumOfBinLengths=0;for(const bin of values.bins){sumOfMiddles+=bin.count*(bin.min+bin.max)/2;sumOfBinLengths+=bin.count*(bin.max-bin.min);}
+const shift=(values.sum-sumOfMiddles)/sumOfBinLengths;if(Math.abs(shift)>0.5)throw new Error('Samples sum is wrong');for(const bin of values.bins){if(bin.count===0)continue;const shiftedValue=(bin.min+bin.max)/2+shift*(bin.max-bin.min);for(const[processName,count]of bin.processes){bin.processes.set(processName,shiftedValue*count/bin.count);}
+for(let i=0;i<bin.count;i++){histogram.addSample(shiftedValue,{processes:bin.processes,events:bin.events});}}
+histograms.addHistogram(histogram);}}
+tr.metrics.MetricRegistry.register(umaMetric,{requiredCategories:['benchmark'],});return{umaMetric,};});'use strict';tr.exportTo('tr.metrics.v8',function(){const CUSTOM_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(4,200,100);function computeExecuteMetrics(histograms,model){const cpuTotalExecution=new tr.v.Histogram('v8_execution_cpu_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuTotalExecution.description='cpu total time spent in script execution';const wallTotalExecution=new tr.v.Histogram('v8_execution_wall_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallTotalExecution.description='wall total time spent in script execution';const cpuSelfExecution=new tr.v.Histogram('v8_execution_cpu_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuSelfExecution.description='cpu self time spent in script execution';const wallSelfExecution=new tr.v.Histogram('v8_execution_wall_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallSelfExecution.description='wall self time spent in script execution';for(const e of model.findTopmostSlicesNamed('V8.Execute')){cpuTotalExecution.addSample(e.cpuDuration);wallTotalExecution.addSample(e.duration);cpuSelfExecution.addSample(e.cpuSelfTime);wallSelfExecution.addSample(e.selfTime);}
+histograms.addHistogram(cpuTotalExecution);histograms.addHistogram(wallTotalExecution);histograms.addHistogram(cpuSelfExecution);histograms.addHistogram(wallSelfExecution);}
+function computeParseLazyMetrics(histograms,model){const cpuSelfParseLazy=new tr.v.Histogram('v8_parse_lazy_cpu_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuSelfParseLazy.description='cpu self time spent performing lazy parsing';const wallSelfParseLazy=new tr.v.Histogram('v8_parse_lazy_wall_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallSelfParseLazy.description='wall self time spent performing lazy parsing';for(const e of model.findTopmostSlicesNamed('V8.ParseLazyMicroSeconds')){cpuSelfParseLazy.addSample(e.cpuSelfTime);wallSelfParseLazy.addSample(e.selfTime);}
+for(const e of model.findTopmostSlicesNamed('V8.ParseLazy')){cpuSelfParseLazy.addSample(e.cpuSelfTime);wallSelfParseLazy.addSample(e.selfTime);}
+histograms.addHistogram(cpuSelfParseLazy);histograms.addHistogram(wallSelfParseLazy);}
+function computeCompileFullCodeMetrics(histograms,model){const cpuSelfCompileFullCode=new tr.v.Histogram('v8_compile_full_code_cpu_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuSelfCompileFullCode.description='cpu self time spent performing compiling full code';const wallSelfCompileFullCode=new tr.v.Histogram('v8_compile_full_code_wall_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallSelfCompileFullCode.description='wall self time spent performing compiling full code';for(const e of model.findTopmostSlicesNamed('V8.CompileFullCode')){cpuSelfCompileFullCode.addSample(e.cpuSelfTime);wallSelfCompileFullCode.addSample(e.selfTime);}
+histograms.addHistogram(cpuSelfCompileFullCode);histograms.addHistogram(wallSelfCompileFullCode);}
+function computeCompileIgnitionMetrics(histograms,model){const cpuSelfCompileIgnition=new tr.v.Histogram('v8_compile_ignition_cpu_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuSelfCompileIgnition.description='cpu self time spent in compile ignition';const wallSelfCompileIgnition=new tr.v.Histogram('v8_compile_ignition_wall_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallSelfCompileIgnition.description='wall self time spent in compile ignition';for(const e of model.findTopmostSlicesNamed('V8.CompileIgnition')){cpuSelfCompileIgnition.addSample(e.cpuSelfTime);wallSelfCompileIgnition.addSample(e.selfTime);}
+histograms.addHistogram(cpuSelfCompileIgnition);histograms.addHistogram(wallSelfCompileIgnition);}
+function computeRecompileMetrics(histograms,model){const cpuTotalRecompileSynchronous=new tr.v.Histogram('v8_recompile_synchronous_cpu_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuTotalRecompileSynchronous.description='cpu total time spent in synchronous recompilation';const wallTotalRecompileSynchronous=new tr.v.Histogram('v8_recompile_synchronous_wall_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallTotalRecompileSynchronous.description='wall total time spent in synchronous recompilation';const cpuTotalRecompileConcurrent=new tr.v.Histogram('v8_recompile_concurrent_cpu_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuTotalRecompileConcurrent.description='cpu total time spent in concurrent recompilation';const wallTotalRecompileConcurrent=new tr.v.Histogram('v8_recompile_concurrent_wall_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallTotalRecompileConcurrent.description='wall total time spent in concurrent recompilation';const cpuTotalRecompileOverall=new tr.v.Histogram('v8_recompile_overall_cpu_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuTotalRecompileOverall.description='cpu total time spent in synchronous or concurrent recompilation';const wallTotalRecompileOverall=new tr.v.Histogram('v8_recompile_overall_wall_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallTotalRecompileOverall.description='wall total time spent in synchronous or concurrent recompilation';for(const e of model.findTopmostSlicesNamed('V8.RecompileSynchronous')){cpuTotalRecompileSynchronous.addSample(e.cpuDuration);wallTotalRecompileSynchronous.addSample(e.duration);cpuTotalRecompileOverall.addSample(e.cpuDuration);wallTotalRecompileOverall.addSample(e.duration);}
+histograms.addHistogram(cpuTotalRecompileSynchronous);histograms.addHistogram(wallTotalRecompileSynchronous);for(const e of model.findTopmostSlicesNamed('V8.RecompileConcurrent')){cpuTotalRecompileConcurrent.addSample(e.cpuDuration);wallTotalRecompileConcurrent.addSample(e.duration);cpuTotalRecompileOverall.addSample(e.cpuDuration);wallTotalRecompileOverall.addSample(e.duration);}
+histograms.addHistogram(cpuTotalRecompileConcurrent);histograms.addHistogram(wallTotalRecompileConcurrent);histograms.addHistogram(cpuTotalRecompileOverall);histograms.addHistogram(wallTotalRecompileOverall);}
+function computeOptimizeCodeMetrics(histograms,model){const cpuTotalOptimizeCode=new tr.v.Histogram('v8_optimize_code_cpu_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuTotalOptimizeCode.description='cpu total time spent in code optimization';const wallTotalOptimizeCode=new tr.v.Histogram('v8_optimize_code_wall_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallTotalOptimizeCode.description='wall total time spent in code optimization';for(const e of model.findTopmostSlicesNamed('V8.OptimizeCode')){cpuTotalOptimizeCode.addSample(e.cpuDuration);wallTotalOptimizeCode.addSample(e.duration);}
+histograms.addHistogram(cpuTotalOptimizeCode);histograms.addHistogram(wallTotalOptimizeCode);}
+function computeDeoptimizeCodeMetrics(histograms,model){const cpuTotalDeoptimizeCode=new tr.v.Histogram('v8_deoptimize_code_cpu_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuTotalDeoptimizeCode.description='cpu total time spent in code deoptimization';const wallTotalDeoptimizeCode=new tr.v.Histogram('v8_deoptimize_code_wall_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallTotalDeoptimizeCode.description='wall total time spent in code deoptimization';for(const e of model.findTopmostSlicesNamed('V8.DeoptimizeCode')){cpuTotalDeoptimizeCode.addSample(e.cpuDuration);wallTotalDeoptimizeCode.addSample(e.duration);}
+histograms.addHistogram(cpuTotalDeoptimizeCode);histograms.addHistogram(wallTotalDeoptimizeCode);}
+function executionMetric(histograms,model){computeExecuteMetrics(histograms,model);computeParseLazyMetrics(histograms,model);computeCompileIgnitionMetrics(histograms,model);computeCompileFullCodeMetrics(histograms,model);computeRecompileMetrics(histograms,model);computeOptimizeCodeMetrics(histograms,model);computeDeoptimizeCodeMetrics(histograms,model);}
+tr.metrics.MetricRegistry.register(executionMetric);return{executionMetric,};});'use strict';tr.exportTo('tr.metrics.v8',function(){const TARGET_FPS=60;const MS_PER_SECOND=1000;const WINDOW_SIZE_MS=MS_PER_SECOND/TARGET_FPS;function gcMetric(histograms,model){addDurationOfTopEvents(histograms,model);addTotalDurationOfTopEvents(histograms,model);addDurationOfSubEvents(histograms,model);addPercentageInV8ExecuteOfTopEvents(histograms,model);addTotalPercentageInV8Execute(histograms,model);addMarkCompactorMutatorUtilization(histograms,model);addTotalMarkCompactorTime(histograms,model);addTotalMarkCompactorMarkingTime(histograms,model);}
+tr.metrics.MetricRegistry.register(gcMetric);const timeDurationInMs_smallerIsBetter=tr.b.Unit.byName.timeDurationInMs_smallerIsBetter;const percentage_biggerIsBetter=tr.b.Unit.byName.normalizedPercentage_biggerIsBetter;const percentage_smallerIsBetter=tr.b.Unit.byName.normalizedPercentage_smallerIsBetter;const CUSTOM_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(0,20,200).addExponentialBins(200,100);function createNumericForTopEventTime(name){const n=new tr.v.Histogram(name,timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);n.customizeSummaryOptions({avg:true,count:true,max:true,min:false,std:true,sum:true,percentile:[0.90]});return n;}
+function createNumericForSubEventTime(name){const n=new tr.v.Histogram(name,timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);n.customizeSummaryOptions({avg:true,count:false,max:true,min:false,std:false,sum:false,percentile:[0.90]});return n;}
+function createNumericForIdleTime(name){const n=new tr.v.Histogram(name,timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);n.customizeSummaryOptions({avg:true,count:false,max:true,min:false,std:false,sum:true,percentile:[]});return n;}
+function createPercentage(name,numerator,denominator,unit){const hist=new tr.v.Histogram(name,unit);if(denominator===0){hist.addSample(0);}else{hist.addSample(numerator/denominator);}
+hist.customizeSummaryOptions({avg:true,count:false,max:false,min:false,std:false,sum:false,percentile:[]});return hist;}
+function addDurationOfTopEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,tr.metrics.v8.utils.isNotForcedTopGarbageCollectionEvent,tr.metrics.v8.utils.topGarbageCollectionEventName,function(name,events){const cpuDuration=createNumericForTopEventTime(name);events.forEach(function(event){cpuDuration.addSample(event.cpuDuration);});histograms.addHistogram(cpuDuration);});}
+function addTotalDurationOfTopEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,tr.metrics.v8.utils.isNotForcedTopGarbageCollectionEvent,event=>'v8-gc-total',function(name,events){const cpuDuration=createNumericForTopEventTime(name);events.forEach(function(event){cpuDuration.addSample(event.cpuDuration);});histograms.addHistogram(cpuDuration);});}
+function isV8MarkCompactorSummary(event){return!tr.metrics.v8.utils.isForcedGarbageCollectionEvent(event)&&tr.metrics.v8.utils.isMarkCompactorSummaryEvent(event);}
+function isV8MarkCompactorMarkingSummary(event){return!tr.metrics.v8.utils.isForcedGarbageCollectionEvent(event)&&tr.metrics.v8.utils.isMarkCompactorMarkingSummaryEvent(event);}
+function createHistogramFromSummary(histograms,name,events){const foregroundDuration=createNumericForTopEventTime(name+'-foreground');const backgroundDuration=createNumericForTopEventTime(name+'-background');const totalDuration=createNumericForTopEventTime(name+'-total');const relatedNames=new tr.v.d.RelatedNameMap();relatedNames.set('foreground',foregroundDuration.name);relatedNames.set('background',backgroundDuration.name);for(const event of events){foregroundDuration.addSample(event.args.duration);backgroundDuration.addSample(event.args.background_duration);const breakdownForTotal=new tr.v.d.Breakdown();breakdownForTotal.set('foreground',event.args.duration);breakdownForTotal.set('background',event.args.background_duration);totalDuration.addSample(event.args.duration+event.args.background_duration,{breakdown:breakdownForTotal});}
+histograms.addHistogram(foregroundDuration);histograms.addHistogram(backgroundDuration);histograms.addHistogram(totalDuration,{breakdown:relatedNames});}
+function addTotalMarkCompactorTime(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isV8MarkCompactorSummary,event=>'v8-gc-mark-compactor',(name,events)=>createHistogramFromSummary(histograms,name,events));}
+function addTotalMarkCompactorMarkingTime(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isV8MarkCompactorMarkingSummary,event=>'v8-gc-mark-compactor-marking',(name,events)=>createHistogramFromSummary(histograms,name,events));}
+function addDurationOfSubEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,tr.metrics.v8.utils.isNotForcedSubGarbageCollectionEvent,tr.metrics.v8.utils.subGarbageCollectionEventName,function(name,events){const cpuDuration=createNumericForSubEventTime(name);events.forEach(function(event){cpuDuration.addSample(event.cpuDuration);});histograms.addHistogram(cpuDuration);});}
+function addPercentageInV8ExecuteOfTopEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,tr.metrics.v8.utils.isNotForcedTopGarbageCollectionEvent,tr.metrics.v8.utils.topGarbageCollectionEventName,function(name,events){addPercentageInV8Execute(histograms,model,name,events);});}
+function addTotalPercentageInV8Execute(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,tr.metrics.v8.utils.isNotForcedTopGarbageCollectionEvent,event=>'v8-gc-total',function(name,events){addPercentageInV8Execute(histograms,model,name,events);});}
+function addPercentageInV8Execute(histograms,model,name,events){let cpuDurationInV8Execute=0;let cpuDurationTotal=0;events.forEach(function(event){const v8Execute=tr.metrics.v8.utils.findParent(event,tr.metrics.v8.utils.isV8ExecuteEvent);if(v8Execute){cpuDurationInV8Execute+=event.cpuDuration;}
+cpuDurationTotal+=event.cpuDuration;});const percentage=createPercentage(name+'_percentage_in_v8_execute',cpuDurationInV8Execute,cpuDurationTotal,percentage_smallerIsBetter);histograms.addHistogram(percentage);}
+function addMarkCompactorMutatorUtilization(histograms,model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const rendererHelpers=Object.values(chromeHelper.rendererHelpers);tr.metrics.v8.utils.addMutatorUtilization('v8-gc-mark-compactor-mmu',tr.metrics.v8.utils.isNotForcedMarkCompactorEvent,[100],rendererHelpers,histograms);}
+return{gcMetric,WINDOW_SIZE_MS,};});'use strict';tr.exportTo('tr.metrics.v8',function(){const COUNT_CUSTOM_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(1,1000000,50);const DURATION_CUSTOM_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(0.1,10000,50);const SUMMARY_OPTIONS={std:false,count:false,sum:false,min:false,max:false,};function computeDomContentLoadedTime_(model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);let domContentLoadedTime=0;for(const rendererHelper of Object.values(chromeHelper.rendererHelpers)){for(const ev of rendererHelper.mainThread.sliceGroup.childEvents()){if(ev.title==='domContentLoadedEventEnd'&&ev.start>domContentLoadedTime){domContentLoadedTime=ev.start;}}}
+return domContentLoadedTime;}
+function computeInteractiveTime_(model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);let interactiveTime=0;for(const expectation of model.userModel.expectations){if(tr.e.chrome.CHROME_INTERNAL_URLS.includes(expectation.url)){continue;}
+if(!(expectation instanceof tr.model.um.LoadExpectation))continue;if(expectation.timeToInteractive===undefined)continue;if(interactiveTime!==0)throw new Error('Too many navigations');interactiveTime=expectation.timeToInteractive;}
+return interactiveTime;}
+function convertMicroToMilli_(time){return tr.b.convertUnit(time,tr.b.UnitPrefixScale.METRIC.MICRO,tr.b.UnitPrefixScale.METRIC.MILLI);}
+function computeRuntimeStats(histograms,slices){const runtimeGroupCollection=new tr.e.v8.RuntimeStatsGroupCollection();runtimeGroupCollection.addSlices(slices);function addHistogramsForRuntimeGroup(runtimeGroup,optRelatedNameMaps){histograms.createHistogram(`${runtimeGroup.name}:duration`,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,{value:convertMicroToMilli_(runtimeGroup.time),diagnostics:optRelatedNameMaps?{samples:optRelatedNameMaps.durationBreakdown}:{}},{binBoundaries:DURATION_CUSTOM_BOUNDARIES,summaryOptions:SUMMARY_OPTIONS,diagnostics:optRelatedNameMaps?{samples:optRelatedNameMaps.durationNames}:{}});histograms.createHistogram(`${runtimeGroup.name}:count`,tr.b.Unit.byName.count_smallerIsBetter,{value:runtimeGroup.count,diagnostics:optRelatedNameMaps?{samples:optRelatedNameMaps.countBreakdown}:{}},{binBoundaries:COUNT_CUSTOM_BOUNDARIES,summaryOptions:SUMMARY_OPTIONS,diagnostics:optRelatedNameMaps?{samples:optRelatedNameMaps.countNames}:{}});}
+function addDetailedHistogramsForRuntimeGroup(runtimeGroup){const durationNames=new tr.v.d.RelatedNameMap();const durationBreakdown=new tr.v.d.Breakdown();const countNames=new tr.v.d.RelatedNameMap();const countBreakdown=new tr.v.d.Breakdown();for(const entry of runtimeGroup.values){const durationSampleHistogram=histograms.createHistogram(`${entry.name}:duration`,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,convertMicroToMilli_(entry.time),{binBoundaries:DURATION_CUSTOM_BOUNDARIES,summaryOptions:SUMMARY_OPTIONS,});durationNames.set(entry.name,durationSampleHistogram.name);durationBreakdown.set(entry.name,convertMicroToMilli_(entry.time));const countSampleHistogram=histograms.createHistogram(`${entry.name}:count`,tr.b.Unit.byName.count_smallerIsBetter,entry.count,{binBoundaries:COUNT_CUSTOM_BOUNDARIES,summaryOptions:SUMMARY_OPTIONS,});countNames.set(entry.name,countSampleHistogram.name);countBreakdown.set(entry.name,entry.count);}
+addHistogramsForRuntimeGroup(runtimeGroup,{durationNames,durationBreakdown,countNames,countBreakdown});}
+for(const runtimeGroup of runtimeGroupCollection.runtimeGroups){addHistogramsForRuntimeGroup(runtimeGroup);}
+const blinkGroupCollection=runtimeGroupCollection.blinkRCSGroupCollection;if(blinkGroupCollection.totalTime>0){blinkGroupCollection.runtimeGroups.forEach(addDetailedHistogramsForRuntimeGroup);}}
+function runtimeStatsMetric(histograms,model){const interactiveTime=computeInteractiveTime_(model);const domContentLoadedTime=computeDomContentLoadedTime_(model);const endTime=Math.max(interactiveTime,domContentLoadedTime);const slices=[...model.getDescendantEvents()].filter(event=>event instanceof tr.e.v8.V8ThreadSlice&&event.start<=endTime);computeRuntimeStats(histograms,slices);}
+function addDurationHistogram(railStageName,runtimeGroupName,sampleValue,histograms,durationNamesByGroupName){const histName=`${railStageName}_${runtimeGroupName}:duration`;histograms.createHistogram(histName,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,convertMicroToMilli_(sampleValue),{binBoundaries:DURATION_CUSTOM_BOUNDARIES,summaryOptions:SUMMARY_OPTIONS,});let relatedNames=durationNamesByGroupName.get(runtimeGroupName);if(!relatedNames){relatedNames=new tr.v.d.RelatedNameMap();durationNamesByGroupName.set(runtimeGroupName,relatedNames);}
+relatedNames.set(railStageName,histName);}
+function addCountHistogram(railStageName,runtimeGroupName,sampleValue,histograms,countNamesByGroupName){const histName=`${railStageName}_${runtimeGroupName}:count`;histograms.createHistogram(histName,tr.b.Unit.byName.count_smallerIsBetter,sampleValue,{binBoundaries:COUNT_CUSTOM_BOUNDARIES,summaryOptions:SUMMARY_OPTIONS,});let relatedNames=countNamesByGroupName.get(runtimeGroupName);if(!relatedNames){relatedNames=new tr.v.d.RelatedNameMap();countNamesByGroupName.set(runtimeGroupName,relatedNames);}
+relatedNames.set(railStageName,histName);}
+function addTotalDurationHistogram(histogramName,time,histograms,relatedNames){const value=convertMicroToMilli_(time);const breakdown=new tr.v.d.Breakdown();if(relatedNames){for(const[cat,histName]of relatedNames){breakdown.set(cat,histograms.getHistogramNamed(histName).average);}}
+histograms.createHistogram(`${histogramName}:duration`,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,{value,diagnostics:{'RAIL stages':breakdown}},{binBoundaries:DURATION_CUSTOM_BOUNDARIES,summaryOptions:SUMMARY_OPTIONS,diagnostics:{'RAIL stages':relatedNames},});}
+function addTotalCountHistogram(histogramName,value,histograms,relatedNames){const breakdown=new tr.v.d.Breakdown();if(relatedNames){for(const[cat,histName]of relatedNames){breakdown.set(cat,histograms.getHistogramNamed(histName).average);}}
+histograms.createHistogram(`${histogramName}:count`,tr.b.Unit.byName.count_smallerIsBetter,{value,diagnostics:{'RAIL stages':breakdown}},{binBoundaries:COUNT_CUSTOM_BOUNDARIES,summaryOptions:SUMMARY_OPTIONS,diagnostics:{'RAIL stages':relatedNames},});}
+function computeRuntimeStatsBucketOnUE(histograms,slices,v8SlicesBucketOnUEMap){const durationNamesByGroupName=new Map();const countNamesByGroupName=new Map();for(const[name,slicesUE]of v8SlicesBucketOnUEMap){const runtimeGroupCollection=new tr.e.v8.RuntimeStatsGroupCollection();runtimeGroupCollection.addSlices(slicesUE);let overallV8Time=runtimeGroupCollection.totalTime;let overallV8Count=runtimeGroupCollection.totalCount;for(const runtimeGroup of runtimeGroupCollection.runtimeGroups){addDurationHistogram(name,runtimeGroup.name,runtimeGroup.time,histograms,durationNamesByGroupName);if(runtimeGroup.name==='Blink C++'){overallV8Time-=runtimeGroup.time;}
+addCountHistogram(name,runtimeGroup.name,runtimeGroup.count,histograms,countNamesByGroupName);if(runtimeGroup.name==='Blink C++'){overallV8Count-=runtimeGroup.count;}}
+if(runtimeGroupCollection.blinkRCSGroupCollection.totalTime>0){const blinkRCSGroupCollection=runtimeGroupCollection.blinkRCSGroupCollection;for(const group of blinkRCSGroupCollection.runtimeGroups){addDurationHistogram(name,group.name,group.time,histograms,durationNamesByGroupName);addCountHistogram(name,group.name,group.count,histograms,countNamesByGroupName);}}
+addDurationHistogram(name,'V8-Only',overallV8Time,histograms,durationNamesByGroupName);addCountHistogram(name,'V8-Only',overallV8Count,histograms,countNamesByGroupName);}
+const runtimeGroupCollection=new tr.e.v8.RuntimeStatsGroupCollection();runtimeGroupCollection.addSlices(slices);let overallV8Time=runtimeGroupCollection.totalTime;let overallV8Count=runtimeGroupCollection.totalCount;for(const runtimeGroup of runtimeGroupCollection.runtimeGroups){addTotalDurationHistogram(runtimeGroup.name,runtimeGroup.time,histograms,durationNamesByGroupName.get(runtimeGroup.name));if(runtimeGroup.name==='Blink C++'){overallV8Time-=runtimeGroup.time;}
+addTotalCountHistogram(runtimeGroup.name,runtimeGroup.count,histograms,countNamesByGroupName.get(runtimeGroup.name));if(runtimeGroup.name==='Blink C++'){overallV8Count-=runtimeGroup.count;}}
+if(runtimeGroupCollection.blinkRCSGroupCollection.totalTime>0){const blinkRCSGroupCollection=runtimeGroupCollection.blinkRCSGroupCollection;for(const group of blinkRCSGroupCollection.runtimeGroups){addTotalDurationHistogram(group.name,group.time,histograms,durationNamesByGroupName.get(group.name));addTotalCountHistogram(group.name,group.count,histograms,countNamesByGroupName.get(group.name));}}
+addTotalDurationHistogram('V8-Only',overallV8Time,histograms,durationNamesByGroupName.get('V8-Only'));addTotalCountHistogram('V8-Only',overallV8Count,histograms,countNamesByGroupName.get('V8-Only'));}
+function runtimeStatsTotalMetric(histograms,model){const v8ThreadSlices=[...model.getDescendantEvents()].filter(event=>event instanceof tr.e.v8.V8ThreadSlice).sort((e1,e2)=>e1.start-e2.start);const v8SlicesBucketOnUEMap=new Map();for(const expectation of model.userModel.expectations){if(tr.e.chrome.CHROME_INTERNAL_URLS.includes(expectation.url)){continue;}
+const slices=expectation.range.filterArray(v8ThreadSlices,event=>event.start);if(slices.length===0)continue;const lastSlice=slices[slices.length-1];if(!expectation.range.intersectsRangeExclusive(lastSlice.range)){slices.pop();}
+if(v8SlicesBucketOnUEMap.get(expectation.stageTitle)===undefined){v8SlicesBucketOnUEMap.set(expectation.stageTitle,slices);}else{const totalSlices=v8SlicesBucketOnUEMap.get(expectation.stageTitle).concat(slices);v8SlicesBucketOnUEMap.set(expectation.stageTitle,totalSlices);}}
+computeRuntimeStatsBucketOnUE(histograms,v8ThreadSlices,v8SlicesBucketOnUEMap);}
+tr.metrics.MetricRegistry.register(runtimeStatsTotalMetric);tr.metrics.MetricRegistry.register(runtimeStatsMetric);return{runtimeStatsMetric,runtimeStatsTotalMetric,};});'use strict';tr.exportTo('tr.metrics.v8',function(){function v8AndMemoryMetrics(histograms,model){tr.metrics.v8.executionMetric(histograms,model);tr.metrics.v8.gcMetric(histograms,model);tr.metrics.sh.memoryMetric(histograms,model,{rangeOfInterest:tr.metrics.v8.utils.rangeForMemoryDumps(model)});}
+tr.metrics.MetricRegistry.register(v8AndMemoryMetrics);return{v8AndMemoryMetrics,};});'use strict';tr.exportTo('tr.metrics.vr',function(){const VR_GL_THREAD_NAME='VrShellGL';function createHistograms(histograms,name,options,hasCpuTime){const createdHistograms={wall:histograms.createHistogram(name+'_wall',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[],options)};if(hasCpuTime){createdHistograms.cpu=histograms.createHistogram(name+'_cpu',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[],options);}
+return createdHistograms;}
+function frameCycleDurationMetric(histograms,model,opt_options){const histogramsByEventTitle=new Map();const expectationEvents=tr.importer.VR_EXPECTATION_EVENTS;for(const eventName in expectationEvents){const extraInfo=expectationEvents[eventName];histogramsByEventTitle.set(eventName,createHistograms(histograms,extraInfo.histogramName,{description:extraInfo.description},extraInfo.hasCpuTime));}
+histogramsByEventTitle.set('UiScene::OnBeginFrame.UpdateAnimationsAndOpacity',createHistograms(histograms,'update_animations_and_opacity',{description:'Duration to apply animation and opacity changes'},true));histogramsByEventTitle.set('UiScene::OnBeginFrame.UpdateBindings',createHistograms(histograms,'update_bindings',{description:'Duration to push binding values'},true));histogramsByEventTitle.set('UiScene::OnBeginFrame.UpdateLayout',createHistograms(histograms,'update_layout',{description:'Duration to compute element sizes, layout and textures'},true));histogramsByEventTitle.set('UiScene::OnBeginFrame.UpdateWorldSpaceTransform',createHistograms(histograms,'update_world_space_transforms',{description:'Duration to calculate element transforms in world space'},true));histogramsByEventTitle.set('UiRenderer::DrawUiView',createHistograms(histograms,'draw_ui',{description:'Duration to draw the UI'},true));histogramsByEventTitle.set('UiElementRenderer::DrawTexturedQuad',createHistograms(histograms,'draw_textured_quad',{description:'Duration to draw a textured element'},true));histogramsByEventTitle.set('UiElementRenderer::DrawGradientQuad',createHistograms(histograms,'draw_gradient_quad',{description:'Duration to draw a gradient element'},true));histogramsByEventTitle.set('UiElementRenderer::DrawGradientGridQuad',createHistograms(histograms,'draw_gradient_grid_quad',{description:'Duration to draw a gradient grid element'},true));histogramsByEventTitle.set('UiElementRenderer::DrawController',createHistograms(histograms,'draw_controller',{description:'Duration to draw the controller'},true));histogramsByEventTitle.set('UiElementRenderer::DrawLaser',createHistograms(histograms,'draw_laser',{description:'Duration to draw the laser'},true));histogramsByEventTitle.set('UiElementRenderer::DrawReticle',createHistograms(histograms,'draw_reticle',{description:'Duration to draw the reticle'},true));histogramsByEventTitle.set('UiElementRenderer::DrawShadow',createHistograms(histograms,'draw_shadow',{description:'Duration to draw a shadow element'},true));histogramsByEventTitle.set('UiElementRenderer::DrawStars',createHistograms(histograms,'draw_stars',{description:'Duration to draw the stars'},true));histogramsByEventTitle.set('UiElementRenderer::DrawBackground',createHistograms(histograms,'draw_background',{description:'Duration to draw the textured background'},true));histogramsByEventTitle.set('UiElementRenderer::DrawKeyboard',createHistograms(histograms,'draw_keyboard',{description:'Duration to draw the keyboard'},true));const drawUiSubSlicesMap=new Map();const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);let rangeOfInterest=model.bounds;const userExpectationsOfInterest=[tr.model.um.AnimationExpectation];if(opt_options&&opt_options.rangeOfInterest){rangeOfInterest=opt_options.rangeOfInterest;userExpectationsOfInterest.push(tr.model.um.ResponseExpectation);}
+for(const ue of model.userModel.expectations){if(ue.initiatorType!==tr.model.um.INITIATOR_TYPE.VR){continue;}
+if(!userExpectationsOfInterest.some(function(ueOfInterest){return ue instanceof ueOfInterest;})){continue;}
+if(!rangeOfInterest.intersectsExplicitRangeInclusive(ue.start,ue.end)){continue;}
+for(const helper of chromeHelper.browserHelpers){const glThreads=helper.process.findAllThreadsNamed(VR_GL_THREAD_NAME);for(const glThread of glThreads){for(const event of glThread.getDescendantEvents()){if(!(histogramsByEventTitle.has(event.title))){continue;}
+if(event.start<ue.start||event.end>ue.end){continue;}
+if(event.start<rangeOfInterest.min||event.end>rangeOfInterest.max){continue;}
+if(event.parentSlice&&event.parentSlice.title==='UiRenderer::DrawUiView'){const guid=event.parentSlice.guid;if(!drawUiSubSlicesMap.has(guid)){drawUiSubSlicesMap.set(guid,[]);}
+drawUiSubSlicesMap.get(guid).push(event);continue;}
+const{wall:wallHist,cpu:cpuHist}=histogramsByEventTitle.get(event.title);wallHist.addSample(event.duration);if(cpuHist!==undefined){cpuHist.addSample(event.cpuDuration);}}}}}
+for(const subSlices of drawUiSubSlicesMap.values()){const eventMap=new Map();for(const event of subSlices){if(!eventMap.has(event.title)){eventMap.set(event.title,{wall:0,cpu:0});}
+eventMap.get(event.title).wall+=event.duration;eventMap.get(event.title).cpu+=event.cpuDuration;}
+for(const[title,values]of eventMap.entries()){const{wall:wallHist,cpu:cpuHist}=histogramsByEventTitle.get(title);wallHist.addSample(values.wall);if(cpuHist!==undefined){cpuHist.addSample(values.cpu);}}}}
+tr.metrics.MetricRegistry.register(frameCycleDurationMetric,{supportsRangeOfInterest:true,});return{frameCycleDurationMetric,};});'use strict';tr.exportTo('tr.metrics.vr',function(){function webvrMetric(histograms,model,opt_options){const WEBVR_COUNTERS=new Map([['gpu.WebVR FPS',{name:'webvr_fps',unit:tr.b.Unit.byName.count_biggerIsBetter,samples:{},options:{description:'WebVR frame per second',binBoundaries:tr.v.HistogramBinBoundaries.createLinear(20,120,25),},}],['gpu.WebVR frame time (ms)',{name:'webvr_frame_time',unit:tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,samples:{},options:{description:'WebVR frame time in ms',binBoundaries:tr.v.HistogramBinBoundaries.createLinear(20,120,25),},}],['gpu.WebVR pose prediction (ms)',{name:'webvr_pose_prediction',unit:tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,samples:{},options:{description:'WebVR pose prediction in ms',binBoundaries:tr.v.HistogramBinBoundaries.createLinear(20,120,25),},}],]);for(const ue of model.userModel.expectations){const rangeOfInterestEnabled=opt_options&&opt_options.rangeOfInterest;if(rangeOfInterestEnabled&&!opt_options.rangeOfInterest.intersectsExplicitRangeInclusive(ue.start,ue.end)){continue;}
+if(ue.initiatorType!==tr.model.um.INITIATOR_TYPE.VR)continue;if(!rangeOfInterestEnabled){if(!(ue instanceof tr.model.um.AnimationExpectation))continue;}else{if(!(ue instanceof tr.model.um.AnimationExpectation||ue instanceof tr.model.um.ResponseExpectation))continue;}
+for(const counter of model.getAllCounters()){if(!(WEBVR_COUNTERS.has(counter.id)))continue;for(const series of counter.series){if(!(series.name in WEBVR_COUNTERS.get(counter.id).samples)){WEBVR_COUNTERS.get(counter.id).samples[series.name]=[];}
+for(const sample of series.samples){if(sample.timestamp<ue.start||sample.timestamp>=ue.end){continue;}
+if(rangeOfInterestEnabled&&!opt_options.rangeOfInterest.intersectsExplicitRangeInclusive(sample.timestamp,sample.timestamp)){continue;}
+WEBVR_COUNTERS.get(counter.id).samples[series.name].push(sample.value);}}}}
+if(!('value'in WEBVR_COUNTERS.get('gpu.WebVR FPS').samples)){WEBVR_COUNTERS.get('gpu.WebVR FPS').samples.value=[0];}
+for(const[key,value]of WEBVR_COUNTERS){for(const[seriesName,samples]of Object.entries(value.samples)){let histogramName=value.name;if(seriesName!=='value'){histogramName=`${histogramName}_${seriesName}`;}
+histograms.createHistogram(histogramName,value.unit,samples,value.options);}}}
+tr.metrics.MetricRegistry.register(webvrMetric,{supportsRangeOfInterest:true,});return{webvrMetric,};});'use strict';tr.exportTo('tr.metrics.vr',function(){function webxrMetric(histograms,model,opt_options){const DEFAULT_BIN_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(20,120,25);const counterHistogramsByTitle=new Map();counterHistogramsByTitle.set('gpu.WebXR FPS',histograms.createHistogram('webxr_fps',tr.b.Unit.byName.count_biggerIsBetter,[],{description:'WebXR frames per second',binBoundaries:DEFAULT_BIN_BOUNDARIES,}));const instantHistogramsByTitle=new Map();const expectationEvents=tr.importer.WEBXR_INSTANT_EVENTS;for(const[eventName,eventData]of Object.entries(expectationEvents)){const argsToHistograms={};for(const[argName,argData]of Object.entries(eventData)){argsToHistograms[argName]=histograms.createHistogram(argData.histogramName,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[],{description:argData.description,binBoundaries:DEFAULT_BIN_BOUNDARIES,});}
+instantHistogramsByTitle.set(eventName,argsToHistograms);}
+const rangeOfInterestEnabled=opt_options&&opt_options.rangeOfInterest;const rangeOfInterest=(rangeOfInterestEnabled?opt_options.rangeOfInterest:tr.b.math.Range.fromExplicitRange(-Infinity,Infinity));for(const ue of model.userModel.expectations){if(!rangeOfInterest.intersectsExplicitRangeInclusive(ue.start,ue.end)){continue;}
+if(ue.initiatorType!==tr.model.um.INITIATOR_TYPE.VR)continue;if(!rangeOfInterestEnabled){if(!(ue instanceof tr.model.um.AnimationExpectation))continue;}else{if(!(ue instanceof tr.model.um.AnimationExpectation||ue instanceof tr.model.um.ResponseExpectation))continue;}
+for(const counter of model.getAllCounters()){if(!(counterHistogramsByTitle.has(counter.id)))continue;for(const series of counter.series){for(const sample of series.samples){if(sample.timestamp<ue.start||sample.timestamp>=ue.end){continue;}
+if(!rangeOfInterest.intersectsExplicitRangeInclusive(sample.timestamp,sample.timestamp)){continue;}
+counterHistogramsByTitle.get(counter.id).addSample(sample.value);}}}
+for(const event of ue.associatedEvents.asSet()){if(!(instantHistogramsByTitle.has(event.title))){continue;}
+if(!rangeOfInterest.intersectsExplicitRangeInclusive(event.start,event.start)){continue;}
+const eventHistograms=instantHistogramsByTitle.get(event.title);for(const[key,value]of Object.entries(event.args)){if(key in eventHistograms){eventHistograms[key].addSample(value,{event:new tr.v.d.RelatedEventSet(event)});}}}}
+if(counterHistogramsByTitle.get('gpu.WebXR FPS').numValues===0){counterHistogramsByTitle.get('gpu.WebXR FPS').addSample(0);}}
+tr.metrics.MetricRegistry.register(webxrMetric,{supportsRangeOfInterest:true,});return{webxrMetric,};});'use strict';tr.exportTo('tr.metrics.webrtc',function(){const DISPLAY_HERTZ=60.0;const VSYNC_DURATION_US=1e6/DISPLAY_HERTZ;const SEVERITY=3;const FROZEN_FRAME_VSYNC_COUNT_THRESHOLD=6;const WEB_MEDIA_PLAYER_UPDATE_TITLE='UpdateCurrentFrame';const IDEAL_RENDER_INSTANT_NAME='Ideal Render Instant';const ACTUAL_RENDER_BEGIN_NAME='Actual Render Begin';const ACTUAL_RENDER_END_NAME='Actual Render End';const STREAM_ID_NAME='Serial';const REQUIRED_EVENT_ARGS_NAMES=[IDEAL_RENDER_INSTANT_NAME,ACTUAL_RENDER_BEGIN_NAME,ACTUAL_RENDER_END_NAME,STREAM_ID_NAME];const SUMMARY_OPTIONS=tr.v.Histogram.AVERAGE_ONLY_SUMMARY_OPTIONS;const count_smallerIsBetter=tr.b.Unit.byName.count_smallerIsBetter;const percentage_biggerIsBetter=tr.b.Unit.byName.normalizedPercentage_biggerIsBetter;const percentage_smallerIsBetter=tr.b.Unit.byName.normalizedPercentage_smallerIsBetter;const timeDurationInMs_smallerIsBetter=tr.b.Unit.byName.timeDurationInMs_smallerIsBetter;const unitlessNumber_biggerIsBetter=tr.b.Unit.byName.unitlessNumber_biggerIsBetter;function isValidEvent(event){if(event.title!==WEB_MEDIA_PLAYER_UPDATE_TITLE||!event.args){return false;}
+for(const parameter of REQUIRED_EVENT_ARGS_NAMES){if(!(parameter in event.args)){return false;}}
+return true;}
+function webrtcRenderingMetric(histograms,model){const modelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);let webMediaPlayerMSEvents=[];for(const rendererPid in modelHelper.rendererHelpers){const rendererHelper=modelHelper.rendererHelpers[rendererPid];const compositorThread=rendererHelper.compositorThread;if(compositorThread!==undefined){webMediaPlayerMSEvents=webMediaPlayerMSEvents.concat(compositorThread.sliceGroup.slices.filter(isValidEvent));}}
+const eventsByStreamName=tr.b.groupIntoMap(webMediaPlayerMSEvents,event=>event.args[STREAM_ID_NAME]);for(const[streamName,events]of eventsByStreamName){getTimeStats(histograms,streamName,events);}}
+tr.metrics.MetricRegistry.register(webrtcRenderingMetric);function getTimeStats(histograms,streamName,events){const frameHist=getFrameDistribution(histograms,events);addFpsFromFrameDistribution(histograms,frameHist);addFreezingScore(histograms,frameHist);const driftTimeStats=getDriftStats(events);histograms.createHistogram('WebRTCRendering_drift_time',timeDurationInMs_smallerIsBetter,driftTimeStats.driftTime,{summaryOptions:{count:false,min:false,percentile:[0.75,0.9],},});histograms.createHistogram('WebRTCRendering_rendering_length_error',percentage_smallerIsBetter,driftTimeStats.renderingLengthError,{summaryOptions:SUMMARY_OPTIONS,});const smoothnessStats=getSmoothnessStats(driftTimeStats.driftTime);histograms.createHistogram('WebRTCRendering_percent_badly_out_of_sync',percentage_smallerIsBetter,smoothnessStats.percentBadlyOutOfSync,{summaryOptions:SUMMARY_OPTIONS,});histograms.createHistogram('WebRTCRendering_percent_out_of_sync',percentage_smallerIsBetter,smoothnessStats.percentOutOfSync,{summaryOptions:SUMMARY_OPTIONS,});histograms.createHistogram('WebRTCRendering_smoothness_score',percentage_biggerIsBetter,smoothnessStats.smoothnessScore,{summaryOptions:SUMMARY_OPTIONS,});histograms.createHistogram('WebRTCRendering_frames_out_of_sync',count_smallerIsBetter,smoothnessStats.framesOutOfSync,{summaryOptions:SUMMARY_OPTIONS,});histograms.createHistogram('WebRTCRendering_frames_badly_out_of_sync',count_smallerIsBetter,smoothnessStats.framesSeverelyOutOfSync,{summaryOptions:SUMMARY_OPTIONS,});}
+const FRAME_DISTRIBUTION_BIN_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(1,50,49);function getFrameDistribution(histograms,events){const cadence=tr.b.runLengthEncoding(events.map(e=>e.args[IDEAL_RENDER_INSTANT_NAME]));return histograms.createHistogram('WebRTCRendering_frame_distribution',count_smallerIsBetter,cadence.map(ticks=>ticks.count),{binBoundaries:FRAME_DISTRIBUTION_BIN_BOUNDARIES,summaryOptions:{percentile:[0.75,0.9],},});}
+function addFpsFromFrameDistribution(histograms,frameHist){let numberFrames=0;let numberVsyncs=0;for(let ticks=1;ticks<frameHist.allBins.length;++ticks){const count=frameHist.allBins[ticks].count;numberFrames+=count;numberVsyncs+=ticks*count;}
+const meanRatio=numberVsyncs/numberFrames;histograms.createHistogram('WebRTCRendering_fps',unitlessNumber_biggerIsBetter,DISPLAY_HERTZ/meanRatio,{summaryOptions:SUMMARY_OPTIONS,});}
+function frozenPenaltyWeight(numberFrozenFrames){const penalty={5:1,6:5,7:15,8:25};return penalty[numberFrozenFrames]||(8*(numberFrozenFrames-4));}
+function addFreezingScore(histograms,frameHist){let numberVsyncs=0;let freezingScore=0;let frozenFramesCount=0;for(let ticks=1;ticks<frameHist.allBins.length;++ticks){const count=frameHist.allBins[ticks].count;numberVsyncs+=ticks*count;if(ticks>=FROZEN_FRAME_VSYNC_COUNT_THRESHOLD){frozenFramesCount+=count*(ticks-1);freezingScore+=count*frozenPenaltyWeight(ticks-1);}}
+freezingScore=1-freezingScore/numberVsyncs;if(freezingScore<0){freezingScore=0;}
+histograms.createHistogram('WebRTCRendering_frozen_frames_count',count_smallerIsBetter,frozenFramesCount,{summaryOptions:SUMMARY_OPTIONS,});histograms.createHistogram('WebRTCRendering_freezing_score',percentage_biggerIsBetter,freezingScore,{summaryOptions:SUMMARY_OPTIONS,});}
+function getDriftStats(events){const driftTime=[];const discrepancy=[];let oldIdealRender=0;let expectedIdealRender=0;for(const event of events){const currentIdealRender=event.args[IDEAL_RENDER_INSTANT_NAME];expectedIdealRender+=VSYNC_DURATION_US;if(currentIdealRender===oldIdealRender){continue;}
+const actualRenderBegin=event.args[ACTUAL_RENDER_BEGIN_NAME];driftTime.push(actualRenderBegin-currentIdealRender);discrepancy.push(Math.abs(currentIdealRender-expectedIdealRender));expectedIdealRender=currentIdealRender;oldIdealRender=currentIdealRender;}
+const discrepancySum=tr.b.math.Statistics.sum(discrepancy)-
+discrepancy[0];const lastIdealRender=events[events.length-1].args[IDEAL_RENDER_INSTANT_NAME];const firstIdealRender=events[0].args[IDEAL_RENDER_INSTANT_NAME];const idealRenderSpan=lastIdealRender-firstIdealRender;const renderingLengthError=discrepancySum/idealRenderSpan;return{driftTime,renderingLengthError};}
+function getSmoothnessStats(driftTimes){const meanDriftTime=tr.b.math.Statistics.mean(driftTimes);const normDriftTimes=driftTimes.map(driftTime=>Math.abs(driftTime-meanDriftTime));const framesSeverelyOutOfSync=normDriftTimes.filter(driftTime=>driftTime>2*VSYNC_DURATION_US).length;const framesOutOfSync=normDriftTimes.filter(driftTime=>driftTime>VSYNC_DURATION_US).length;const percentBadlyOutOfSync=framesSeverelyOutOfSync/driftTimes.length;const percentOutOfSync=framesOutOfSync/driftTimes.length;const framesOutOfSyncOnlyOnce=framesOutOfSync-framesSeverelyOutOfSync;let smoothnessScore=1-(framesOutOfSyncOnlyOnce+
+SEVERITY*framesSeverelyOutOfSync)/driftTimes.length;if(smoothnessScore<0){smoothnessScore=0;}
+return{framesOutOfSync,framesSeverelyOutOfSync,percentBadlyOutOfSync,percentOutOfSync,smoothnessScore};}
+return{webrtcRenderingMetric,};});'use strict';Polymer({is:'tr-ui-a-alert-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready(){this.currentSelection_=undefined;this.$.table.tableColumns=[{title:'Label',value(row){return row.name;},width:'150px'},{title:'Value',width:'100%',value(row){return row.value;}}];this.$.table.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},getRowsForSingleAlert_(alert){const rows=[];for(const argName in alert.args){const argView=document.createElement('tr-ui-a-generic-object-view');argView.object=alert.args[argName];rows.push({name:argName,value:argView});}
+if(alert.associatedEvents.length){alert.associatedEvents.forEach(function(event,i){const linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(new tr.model.EventSet(event),event.title);let valueString='';if(event instanceof tr.model.TimedEvent){valueString='took '+event.duration.toFixed(2)+'ms';}
+rows.push({name:linkEl,value:valueString});});}
+const descriptionEl=tr.ui.b.createDiv({textContent:alert.info.description,maxWidth:'300px'});rows.push({name:'Description',value:descriptionEl});if(alert.info.docLinks){alert.info.docLinks.forEach(function(linkObject){const linkEl=document.createElement('a');linkEl.target='_blank';linkEl.href=linkObject.href;Polymer.dom(linkEl).textContent=Polymer.dom(linkObject).textContent;rows.push({name:linkObject.label,value:linkEl});});}
+return rows;},getRowsForAlerts_(alerts){if(alerts.length===1){const rows=[{name:'Alert',value:tr.b.getOnlyElement(alerts).title}];const detailRows=this.getRowsForSingleAlert_(tr.b.getOnlyElement(alerts));rows.push.apply(rows,detailRows);return rows;}
+return alerts.map(function(alert){return{name:'Alert',value:alert.title,isExpanded:alerts.size<10,subRows:this.getRowsForSingleAlert_(alert)};},this);},updateContents_(){if(this.currentSelection_===undefined){this.$.table.rows=[];this.$.table.rebuild();return;}
+const alerts=this.currentSelection_;this.$.table.tableRows=this.getRowsForAlerts_(alerts);this.$.table.rebuild();},get relatedEventsToHighlight(){if(!this.currentSelection_)return undefined;const result=new tr.model.EventSet();for(const event of this.currentSelection_){result.addEventSet(event.associatedEvents);}
+return result;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-alert-sub-view',tr.model.Alert,{multi:false,title:'Alert',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-alert-sub-view',tr.model.Alert,{multi:true,title:'Alerts',});'use strict';tr.exportTo('tr.ui.analysis',function(){const NO_BREAK_SPACE=String.fromCharCode(160);const RIGHTWARDS_ARROW=String.fromCharCode(8594);const COLLATOR=new Intl.Collator(undefined,{numeric:true});function TitleColumn(title){this.title=title;}
+TitleColumn.prototype={supportsCellSelection:false,value(row){const formattedTitle=this.formatTitle(row);const contexts=row.contexts;if(contexts===undefined||contexts.length===0){return formattedTitle;}
+const firstContext=contexts[0];const lastContext=contexts[contexts.length-1];let changeDefinedContextCount=0;for(let i=1;i<contexts.length;i++){if((contexts[i]===undefined)!==(contexts[i-1]===undefined)){changeDefinedContextCount++;}}
+let color=undefined;let prefix=undefined;if(!firstContext&&lastContext){color='red';prefix='+++';}else if(firstContext&&!lastContext){color='green';prefix='---';}
 if(changeDefinedContextCount>1){color='purple';}
-if(color===undefined&&prefix===undefined)
-return formattedTitle;var titleEl=document.createElement('span');if(prefix!==undefined){var prefixEl=tr.ui.b.createSpan({textContent:prefix});prefixEl.style.fontFamily='monospace';titleEl.appendChild(prefixEl);titleEl.appendChild(tr.ui.b.asHTMLOrTextNode(NO_BREAK_SPACE));}
-if(color!==undefined)
-titleEl.style.color=color;titleEl.appendChild(tr.ui.b.asHTMLOrTextNode(formattedTitle));return titleEl;},formatTitle:function(row){return row.title;},cmp:function(rowA,rowB){return COLLATOR.compare(rowA.title,rowB.title);}};function MemoryColumn(name,cellPath,aggregationMode){this.name=name;this.cellPath=cellPath;this.aggregationMode=aggregationMode;}
-MemoryColumn.fromRows=function(rows,cellKey,aggregationMode,rules){var cellNames=new Set();function gatherCellNames(rows){rows.forEach(function(row){if(row===undefined)
-return;var fieldCells=row[cellKey];if(fieldCells!==undefined){tr.b.iterItems(fieldCells,function(fieldName,fieldCell){if(fieldCell===undefined||fieldCell.fields===undefined)
-return;cellNames.add(fieldName);});}
-var subRows=row.subRows;if(subRows!==undefined)
-gatherCellNames(subRows);});}
-gatherCellNames(rows);var positions=[];cellNames.forEach(function(cellName){var cellPath=[cellKey,cellName];var matchingRule=MemoryColumn.findMatchingRule(cellName,rules);var constructor=matchingRule.columnConstructor;var column=new constructor(cellName,cellPath,aggregationMode);positions.push({importance:matchingRule.importance,column:column});});positions.sort(function(a,b){if(a.importance===b.importance)
-return COLLATOR.compare(a.column.name,b.column.name);return b.importance-a.importance;});return positions.map(function(position){return position.column});};MemoryColumn.spaceEqually=function(columns){var columnWidth=(100/columns.length).toFixed(3)+'%';columns.forEach(function(column){column.width=columnWidth;});};MemoryColumn.findMatchingRule=function(name,rules){for(var i=0;i<rules.length;i++){var rule=rules[i];if(MemoryColumn.nameMatchesCondition(name,rule.condition))
-return rule;}
-return undefined;};MemoryColumn.nameMatchesCondition=function(name,condition){if(condition===undefined)
-return true;if(typeof(condition)==='string')
-return name===condition;return condition.test(name);};MemoryColumn.AggregationMode={DIFF:0,MAX:1};MemoryColumn.SOME_TIMESTAMPS_INFO_QUANTIFIER='at some selected timestamps';MemoryColumn.prototype={get title(){return this.name;},cell:function(row){var cell=row;var cellPath=this.cellPath;for(var i=0;i<cellPath.length;i++){if(cell===undefined)
-return undefined;cell=cell[cellPath[i]];}
-return cell;},aggregateCells:function(row,subRows){},fields:function(row){var cell=this.cell(row);if(cell===undefined)
-return undefined;return cell.fields;},value:function(row){var fields=this.fields(row);if(this.hasAllRelevantFieldsUndefined(fields))
-return'';var contexts=row.contexts;var color=this.color(fields,contexts);var infos=[];this.addInfos(fields,contexts,infos);var formattedFields=this.formatFields(fields);if((color===undefined||formattedFields==='')&&infos.length===0)
-return formattedFields;var fieldEl=document.createElement('span');fieldEl.style.display='flex';fieldEl.style.alignItems='center';fieldEl.appendChild(tr.ui.b.asHTMLOrTextNode(formattedFields));infos.forEach(function(info){var infoEl=document.createElement('span');infoEl.style.paddingLeft='4px';infoEl.style.cursor='help';infoEl.style.fontWeight='bold';infoEl.textContent=info.icon;if(info.color!==undefined)
-infoEl.style.color=info.color;infoEl.title=info.message;fieldEl.appendChild(infoEl);},this);if(color!==undefined)
-fieldEl.style.color=color;return fieldEl;},hasAllRelevantFieldsUndefined:function(fields){if(fields===undefined)
-return true;switch(this.aggregationMode){case MemoryColumn.AggregationMode.DIFF:return fields[0]===undefined&&fields[fields.length-1]===undefined;case MemoryColumn.AggregationMode.MAX:default:return fields.every(function(field){return field===undefined;});}},color:function(fields,contexts){return undefined;},formatFields:function(fields){if(fields.length===1)
-return this.formatSingleField(fields[0]);else
-return this.formatMultipleFields(fields);},formatSingleField:function(field){throw new Error('Not implemented');},formatMultipleFields:function(fields){switch(this.aggregationMode){case MemoryColumn.AggregationMode.DIFF:return this.formatMultipleFieldsDiff(fields[0],fields[fields.length-1]);case MemoryColumn.AggregationMode.MAX:return this.formatMultipleFieldsMax(fields);default:return tr.ui.b.createSpan({textContent:'(unsupported aggregation mode)',italic:true});}},formatMultipleFieldsDiff:function(firstField,lastField){throw new Error('Not implemented');},formatMultipleFieldsMax:function(fields){return this.formatSingleField(this.getMaxField(fields));},cmp:function(rowA,rowB){var fieldsA=this.fields(rowA);var fieldsB=this.fields(rowB);if(fieldsA!==undefined&&fieldsB!==undefined&&fieldsA.length!==fieldsB.length)
-throw new Error('Different number of fields');var undefinedA=this.hasAllRelevantFieldsUndefined(fieldsA);var undefinedB=this.hasAllRelevantFieldsUndefined(fieldsB);if(undefinedA&&undefinedB)
-return 0;if(undefinedA)
-return-1;if(undefinedB)
-return 1;return this.compareFields(fieldsA,fieldsB);},compareFields:function(fieldsA,fieldsB){if(fieldsA.length===1)
-return this.compareSingleFields(fieldsA[0],fieldsB[0]);else
-return this.compareMultipleFields(fieldsA,fieldsB);},compareSingleFields:function(fieldA,fieldB){throw new Error('Not implemented');},compareMultipleFields:function(fieldsA,fieldsB){switch(this.aggregationMode){case MemoryColumn.AggregationMode.DIFF:return this.compareMultipleFieldsDiff(fieldsA[0],fieldsA[fieldsA.length-1],fieldsB[0],fieldsB[fieldsB.length-1]);case MemoryColumn.AggregationMode.MAX:return this.compareMultipleFieldsMax(fieldsA,fieldsB);default:return 0;}},compareMultipleFieldsDiff:function(firstFieldA,lastFieldA,firstFieldB,lastFieldB){throw new Error('Not implemented');},compareMultipleFieldsMax:function(fieldsA,fieldsB){return this.compareSingleFields(this.getMaxField(fieldsA),this.getMaxField(fieldsB));},getMaxField:function(fields){return fields.reduce(function(accumulator,field){if(field===undefined)
-return accumulator;if(accumulator===undefined||this.compareSingleFields(field,accumulator)>0){return field;}
-return accumulator;}.bind(this),undefined);},addInfos:function(fields,contexts,infos){},getImportance:function(importanceRules){if(importanceRules.length===0)
-return 0;var matchingRule=MemoryColumn.findMatchingRule(this.name,importanceRules);if(matchingRule!==undefined)
-return matchingRule.importance;var minImportance=importanceRules[0].importance;for(var i=1;i<importanceRules.length;i++)
-minImportance=Math.min(minImportance,importanceRules[i].importance);return minImportance-1;}};function StringMemoryColumn(name,cellPath,aggregationMode){MemoryColumn.call(this,name,cellPath,aggregationMode);}
-StringMemoryColumn.prototype={__proto__:MemoryColumn.prototype,formatSingleField:function(string){return string;},formatMultipleFieldsDiff:function(firstString,lastString){if(firstString===undefined){var spanEl=tr.ui.b.createSpan({color:'red'});spanEl.appendChild(tr.ui.b.asHTMLOrTextNode('+'));spanEl.appendChild(tr.ui.b.asHTMLOrTextNode(this.formatSingleField(lastString)));return spanEl;}else if(lastString===undefined){var spanEl=tr.ui.b.createSpan({color:'green'});spanEl.appendChild(tr.ui.b.asHTMLOrTextNode('-'));spanEl.appendChild(tr.ui.b.asHTMLOrTextNode(this.formatSingleField(firstString)));return spanEl;}else if(firstString===lastString){return this.formatSingleField(firstString);}else{var spanEl=tr.ui.b.createSpan({color:'DarkOrange'});spanEl.appendChild(tr.ui.b.asHTMLOrTextNode(this.formatSingleField(firstString)));spanEl.appendChild(tr.ui.b.asHTMLOrTextNode(' '+RIGHTWARDS_ARROW+' '));spanEl.appendChild(tr.ui.b.asHTMLOrTextNode(this.formatSingleField(lastString)));return spanEl;}},compareSingleFields:function(stringA,stringB){return COLLATOR.compare(stringA,stringB);},compareMultipleFieldsDiff:function(firstStringA,lastStringA,firstStringB,lastStringB){if(firstStringA===undefined&&firstStringB!==undefined)
-return 1;if(firstStringA!==undefined&&firstStringB===undefined)
-return-1;if(firstStringA===undefined&&firstStringB===undefined)
-return this.compareSingleFields(lastStringA,lastStringB);if(lastStringA===undefined&&lastStringB!==undefined)
-return-1;if(lastStringA!==undefined&&lastStringB===undefined)
-return 1;if(lastStringA===undefined&&lastStringB===undefined)
-return this.compareSingleFields(firstStringB,firstStringA);var areStringsAEqual=firstStringA===lastStringA;var areStringsBEqual=firstStringB===lastStringB;if(areStringsAEqual&&areStringsBEqual)
-return 0;if(areStringsAEqual)
-return-1;if(areStringsBEqual)
-return 1;return 0;}};function NumericMemoryColumn(name,cellPath,aggregationMode){MemoryColumn.call(this,name,cellPath,aggregationMode);}
-NumericMemoryColumn.DIFF_EPSILON=0.0001;NumericMemoryColumn.prototype={__proto__:MemoryColumn.prototype,aggregateCells:function(row,subRows){var subRowCells=subRows.map(this.cell,this);var hasDefinedSubRowNumeric=false;var timestampCount=undefined;subRowCells.forEach(function(subRowCell){if(subRowCell===undefined)
-return;var subRowNumerics=subRowCell.fields;if(subRowNumerics===undefined)
-return;if(timestampCount===undefined)
-timestampCount=subRowNumerics.length;else if(timestampCount!==subRowNumerics.length)
-throw new Error('Sub-rows have different numbers of timestamps');if(hasDefinedSubRowNumeric)
-return;hasDefinedSubRowNumeric=subRowNumerics.some(function(numeric){return numeric!==undefined;});});if(!hasDefinedSubRowNumeric)
-return;var cellPath=this.cellPath;var rowCell=row;for(var i=0;i<cellPath.length;i++){var nextStepName=cellPath[i];var nextStep=rowCell[nextStepName];if(nextStep===undefined){if(i<cellPath.length-1)
-nextStep={};else
-nextStep=new MemoryCell(undefined);rowCell[nextStepName]=nextStep;}
+if(color===undefined&&prefix===undefined){return formattedTitle;}
+const titleEl=document.createElement('span');if(prefix!==undefined){const prefixEl=tr.ui.b.createSpan({textContent:prefix});prefixEl.style.fontFamily='monospace';Polymer.dom(titleEl).appendChild(prefixEl);Polymer.dom(titleEl).appendChild(tr.ui.b.asHTMLOrTextNode(NO_BREAK_SPACE));}
+if(color!==undefined){titleEl.style.color=color;}
+Polymer.dom(titleEl).appendChild(tr.ui.b.asHTMLOrTextNode(formattedTitle));return titleEl;},formatTitle(row){return row.title;},cmp(rowA,rowB){return COLLATOR.compare(rowA.title,rowB.title);}};function MemoryColumn(name,cellPath,aggregationMode){this.name=name;this.cellPath=cellPath;this.shouldSetContextGroup=false;this.aggregationMode=aggregationMode;}
+MemoryColumn.fromRows=function(rows,config){const cellNames=new Set();function gatherCellNames(rows){rows.forEach(function(row){if(row===undefined)return;const fieldCells=row[config.cellKey];if(fieldCells!==undefined){for(const[fieldName,fieldCell]of Object.entries(fieldCells)){if(fieldCell===undefined||fieldCell.fields===undefined){continue;}
+cellNames.add(fieldName);}}
+const subRows=row.subRows;if(subRows!==undefined){gatherCellNames(subRows);}});}
+gatherCellNames(rows);const positions=[];cellNames.forEach(function(cellName){const cellPath=[config.cellKey,cellName];const matchingRule=MemoryColumn.findMatchingRule(cellName,config.rules);const constructor=matchingRule.columnConstructor;const column=new constructor(cellName,cellPath,config.aggregationMode);column.shouldSetContextGroup=!!config.shouldSetContextGroup;positions.push({importance:matchingRule.importance,column});});positions.sort(function(a,b){if(a.importance===b.importance){return COLLATOR.compare(a.column.name,b.column.name);}
+return b.importance-a.importance;});return positions.map(function(position){return position.column;});};MemoryColumn.spaceEqually=function(columns){const columnWidth=(100/columns.length).toFixed(3)+'%';columns.forEach(function(column){column.width=columnWidth;});};MemoryColumn.findMatchingRule=function(name,rules){for(let i=0;i<rules.length;i++){const rule=rules[i];if(MemoryColumn.nameMatchesCondition(name,rule.condition)){return rule;}}
+return undefined;};MemoryColumn.nameMatchesCondition=function(name,condition){if(condition===undefined)return true;if(typeof(condition)==='string')return name===condition;return condition.test(name);};MemoryColumn.AggregationMode={DIFF:0,MAX:1};MemoryColumn.SOME_TIMESTAMPS_INFO_QUANTIFIER='at some selected timestamps';MemoryColumn.prototype={get title(){return this.name;},cell(row){let cell=row;const cellPath=this.cellPath;for(let i=0;i<cellPath.length;i++){if(cell===undefined)return undefined;cell=cell[cellPath[i]];}
+return cell;},aggregateCells(row,subRows){},fields(row){const cell=this.cell(row);if(cell===undefined)return undefined;return cell.fields;},value(row){const fields=this.fields(row);if(this.hasAllRelevantFieldsUndefined(fields))return'';const contexts=row.contexts;const color=this.color(fields,contexts);const infos=[];this.addInfos(fields,contexts,infos);const formattedFields=this.formatFields(fields);if((color===undefined||formattedFields==='')&&infos.length===0){return formattedFields;}
+const fieldEl=document.createElement('span');fieldEl.style.display='flex';fieldEl.style.alignItems='center';fieldEl.style.justifyContent='flex-end';Polymer.dom(fieldEl).appendChild(tr.ui.b.asHTMLOrTextNode(formattedFields));infos.forEach(function(info){const infoEl=document.createElement('span');infoEl.style.paddingLeft='4px';infoEl.style.cursor='help';infoEl.style.fontWeight='bold';Polymer.dom(infoEl).textContent=info.icon;if(info.color!==undefined){infoEl.style.color=info.color;}
+infoEl.title=info.message;Polymer.dom(fieldEl).appendChild(infoEl);},this);if(color!==undefined){fieldEl.style.color=color;}
+return fieldEl;},hasAllRelevantFieldsUndefined(fields){if(fields===undefined)return true;switch(this.aggregationMode){case MemoryColumn.AggregationMode.DIFF:return fields[0]===undefined&&fields[fields.length-1]===undefined;case MemoryColumn.AggregationMode.MAX:default:return fields.every(function(field){return field===undefined;});}},color(fields,contexts){return undefined;},formatFields(fields){if(fields.length===1){return this.formatSingleField(fields[0]);}
+return this.formatMultipleFields(fields);},formatSingleField(field){throw new Error('Not implemented');},formatMultipleFields(fields){switch(this.aggregationMode){case MemoryColumn.AggregationMode.DIFF:return this.formatMultipleFieldsDiff(fields[0],fields[fields.length-1]);case MemoryColumn.AggregationMode.MAX:return this.formatMultipleFieldsMax(fields);default:return tr.ui.b.createSpan({textContent:'(unsupported aggregation mode)',italic:true});}},formatMultipleFieldsDiff(firstField,lastField){throw new Error('Not implemented');},formatMultipleFieldsMax(fields){return this.formatSingleField(this.getMaxField(fields));},cmp(rowA,rowB){const fieldsA=this.fields(rowA);const fieldsB=this.fields(rowB);if(fieldsA!==undefined&&fieldsB!==undefined&&fieldsA.length!==fieldsB.length){throw new Error('Different number of fields');}
+const undefinedA=this.hasAllRelevantFieldsUndefined(fieldsA);const undefinedB=this.hasAllRelevantFieldsUndefined(fieldsB);if(undefinedA&&undefinedB)return 0;if(undefinedA)return-1;if(undefinedB)return 1;return this.compareFields(fieldsA,fieldsB);},compareFields(fieldsA,fieldsB){if(fieldsA.length===1){return this.compareSingleFields(fieldsA[0],fieldsB[0]);}
+return this.compareMultipleFields(fieldsA,fieldsB);},compareSingleFields(fieldA,fieldB){throw new Error('Not implemented');},compareMultipleFields(fieldsA,fieldsB){switch(this.aggregationMode){case MemoryColumn.AggregationMode.DIFF:return this.compareMultipleFieldsDiff(fieldsA[0],fieldsA[fieldsA.length-1],fieldsB[0],fieldsB[fieldsB.length-1]);case MemoryColumn.AggregationMode.MAX:return this.compareMultipleFieldsMax(fieldsA,fieldsB);default:return 0;}},compareMultipleFieldsDiff(firstFieldA,lastFieldA,firstFieldB,lastFieldB){throw new Error('Not implemented');},compareMultipleFieldsMax(fieldsA,fieldsB){return this.compareSingleFields(this.getMaxField(fieldsA),this.getMaxField(fieldsB));},getMaxField(fields){return fields.reduce(function(accumulator,field){if(field===undefined){return accumulator;}
+if(accumulator===undefined||this.compareSingleFields(field,accumulator)>0){return field;}
+return accumulator;}.bind(this),undefined);},addInfos(fields,contexts,infos){},getImportance(importanceRules){if(importanceRules.length===0)return 0;const matchingRule=MemoryColumn.findMatchingRule(this.name,importanceRules);if(matchingRule!==undefined){return matchingRule.importance;}
+let minImportance=importanceRules[0].importance;for(let i=1;i<importanceRules.length;i++){minImportance=Math.min(minImportance,importanceRules[i].importance);}
+return minImportance-1;}};function StringMemoryColumn(name,cellPath,aggregationMode){MemoryColumn.call(this,name,cellPath,aggregationMode);}
+StringMemoryColumn.prototype={__proto__:MemoryColumn.prototype,formatSingleField(string){return string;},formatMultipleFieldsDiff(firstString,lastString){if(firstString===undefined){const spanEl=tr.ui.b.createSpan({color:'red'});Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode('+'));Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode(this.formatSingleField(lastString)));return spanEl;}else if(lastString===undefined){const spanEl=tr.ui.b.createSpan({color:'green'});Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode('-'));Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode(this.formatSingleField(firstString)));return spanEl;}else if(firstString===lastString){return this.formatSingleField(firstString);}
+const spanEl=tr.ui.b.createSpan({color:'DarkOrange'});Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode(this.formatSingleField(firstString)));Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode(' '+RIGHTWARDS_ARROW+' '));Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode(this.formatSingleField(lastString)));return spanEl;},compareSingleFields(stringA,stringB){return COLLATOR.compare(stringA,stringB);},compareMultipleFieldsDiff(firstStringA,lastStringA,firstStringB,lastStringB){if(firstStringA===undefined&&firstStringB!==undefined){return 1;}
+if(firstStringA!==undefined&&firstStringB===undefined){return-1;}
+if(firstStringA===undefined&&firstStringB===undefined){return this.compareSingleFields(lastStringA,lastStringB);}
+if(lastStringA===undefined&&lastStringB!==undefined){return-1;}
+if(lastStringA!==undefined&&lastStringB===undefined){return 1;}
+if(lastStringA===undefined&&lastStringB===undefined){return this.compareSingleFields(firstStringB,firstStringA);}
+const areStringsAEqual=firstStringA===lastStringA;const areStringsBEqual=firstStringB===lastStringB;if(areStringsAEqual&&areStringsBEqual)return 0;if(areStringsAEqual)return-1;if(areStringsBEqual)return 1;return 0;}};function NumericMemoryColumn(name,cellPath,aggregationMode){MemoryColumn.call(this,name,cellPath,aggregationMode);}
+NumericMemoryColumn.DIFF_EPSILON=0.0001;NumericMemoryColumn.prototype={__proto__:MemoryColumn.prototype,align:tr.ui.b.TableFormat.ColumnAlignment.RIGHT,aggregateCells(row,subRows){const subRowCells=subRows.map(this.cell,this);let hasDefinedSubRowNumeric=false;let timestampCount=undefined;subRowCells.forEach(function(subRowCell){if(subRowCell===undefined)return;const subRowNumerics=subRowCell.fields;if(subRowNumerics===undefined)return;if(timestampCount===undefined){timestampCount=subRowNumerics.length;}else if(timestampCount!==subRowNumerics.length){throw new Error('Sub-rows have different numbers of timestamps');}
+if(hasDefinedSubRowNumeric){return;}
+hasDefinedSubRowNumeric=subRowNumerics.some(function(numeric){return numeric!==undefined;});});if(!hasDefinedSubRowNumeric){return;}
+const cellPath=this.cellPath;let rowCell=row;for(let i=0;i<cellPath.length;i++){const nextStepName=cellPath[i];let nextStep=rowCell[nextStepName];if(nextStep===undefined){if(i<cellPath.length-1){nextStep={};}else{nextStep=new MemoryCell(undefined);}
+rowCell[nextStepName]=nextStep;}
 rowCell=nextStep;}
 if(rowCell.fields===undefined){rowCell.fields=new Array(timestampCount);}else if(rowCell.fields.length!==timestampCount){throw new Error('Row has a different number of timestamps than sub-rows');}
-for(var i=0;i<timestampCount;i++){if(rowCell.fields[i]!==undefined)
-continue;rowCell.fields[i]=tr.model.MemoryAllocatorDump.aggregateNumerics(subRowCells.map(function(subRowCell){if(subRowCell===undefined||subRowCell.fields===undefined)
-return undefined;return subRowCell.fields[i];}));}},formatSingleField:function(numeric){if(numeric===undefined)
-return'';return tr.v.ui.createScalarSpan(numeric);},formatMultipleFieldsDiff:function(firstNumeric,lastNumeric){return this.formatSingleField(this.getDiffField_(firstNumeric,lastNumeric));},compareSingleFields:function(numericA,numericB){return numericA.value-numericB.value;},compareMultipleFieldsDiff:function(firstNumericA,lastNumericA,firstNumericB,lastNumericB){return this.getDiffFieldValue_(firstNumericA,lastNumericA)-
-this.getDiffFieldValue_(firstNumericB,lastNumericB);},getDiffField_:function(firstNumeric,lastNumeric){var definedNumeric=firstNumeric||lastNumeric;return new tr.v.ScalarNumeric(definedNumeric.unit.correspondingDeltaUnit,this.getDiffFieldValue_(firstNumeric,lastNumeric));},getDiffFieldValue_:function(firstNumeric,lastNumeric){var firstValue=firstNumeric===undefined?0:firstNumeric.value;var lastValue=lastNumeric===undefined?0:lastNumeric.value;var diff=lastValue-firstValue;return Math.abs(diff)<NumericMemoryColumn.DIFF_EPSILON?0:diff;}};function MemoryCell(fields){this.fields=fields;}
-MemoryCell.extractFields=function(cell){if(cell===undefined)
-return undefined;return cell.fields;};var RECURSIVE_EXPANSION_MAX_VISIBLE_ROW_COUNT=10;function expandTableRowsRecursively(table){var currentLevelRows=table.tableRows;var totalVisibleRowCount=currentLevelRows.length;while(currentLevelRows.length>0){var nextLevelRowCount=0;currentLevelRows.forEach(function(currentLevelRow){var subRows=currentLevelRow.subRows;if(subRows===undefined||subRows.length===0)
-return;nextLevelRowCount+=subRows.length;});if(totalVisibleRowCount+nextLevelRowCount>RECURSIVE_EXPANSION_MAX_VISIBLE_ROW_COUNT){break;}
-var nextLevelRows=new Array(nextLevelRowCount);var nextLevelRowIndex=0;currentLevelRows.forEach(function(currentLevelRow){var subRows=currentLevelRow.subRows;if(subRows===undefined||subRows.length===0)
-return;table.setExpandedForTableRow(currentLevelRow,true);subRows.forEach(function(subRow){nextLevelRows[nextLevelRowIndex++]=subRow;});});totalVisibleRowCount+=nextLevelRowCount;currentLevelRows=nextLevelRows;}}
-function aggregateTableRowCellsRecursively(row,columns,opt_predicate){var subRows=row.subRows;if(subRows===undefined||subRows.length===0)
-return;subRows.forEach(function(subRow){aggregateTableRowCellsRecursively(subRow,columns,opt_predicate);});if(opt_predicate===undefined||opt_predicate(row.contexts))
-aggregateTableRowCells(row,subRows,columns);}
-function aggregateTableRowCells(row,subRows,columns){columns.forEach(function(column){if(!(column instanceof MemoryColumn))
-return;column.aggregateCells(row,subRows);});}
-function createCells(timeToValues,valueFieldsGetter){var fieldNameToFields=tr.b.invertArrayOfDicts(timeToValues,valueFieldsGetter);return tr.b.mapItems(fieldNameToFields,function(fieldName,fields){return new tr.ui.analysis.MemoryCell(fields);});}
-function createWarningInfo(message){return{message:message,icon:String.fromCharCode(9888),color:'red'};}
-return{TitleColumn:TitleColumn,MemoryColumn:MemoryColumn,StringMemoryColumn:StringMemoryColumn,NumericMemoryColumn:NumericMemoryColumn,MemoryCell:MemoryCell,expandTableRowsRecursively:expandTableRowsRecursively,aggregateTableRowCellsRecursively:aggregateTableRowCellsRecursively,aggregateTableRowCells:aggregateTableRowCells,createCells:createCells,createWarningInfo:createWarningInfo};});'use strict';Polymer('tr-ui-a-stacked-pane',{rebuild:function(){if(!this.paneDirty_){return;}
-this.paneDirty_=false;this.rebuildPane_();},scheduleRebuildPane_:function(){if(this.paneDirty_)
-return;this.paneDirty_=true;setTimeout(this.rebuild.bind(this),0);},rebuildPane_:function(){},set childPaneBuilder(childPaneBuilder){this.childPaneBuilder_=childPaneBuilder;this.dispatchEvent(new tr.b.Event('request-child-pane-change'));},get childPaneBuilder(){return this.childPaneBuilder_;},appended:function(){this.rebuild();}});'use strict';tr.exportTo('tr.ui.analysis',function(){var ScalarNumeric=tr.v.ScalarNumeric;var sizeInBytes_smallerIsBetter=tr.v.Unit.byName.sizeInBytes_smallerIsBetter;var RowDimension={ROOT:-1,STACK_FRAME:0,OBJECT_TYPE:1};var LATIN_SMALL_LETTER_F_WITH_HOOK=String.fromCharCode(0x0192);var CIRCLED_LATIN_CAPITAL_LETTER_T=String.fromCharCode(0x24C9);function HeapDumpNodeTitleColumn(title){tr.ui.analysis.TitleColumn.call(this,title);}
-HeapDumpNodeTitleColumn.prototype={__proto__:tr.ui.analysis.TitleColumn.prototype,formatTitle:function(row){var title=row.title;var dimension=row.dimension;switch(dimension){case RowDimension.ROOT:return title;case RowDimension.STACK_FRAME:case RowDimension.OBJECT_TYPE:return this.formatSubRow_(title,dimension);default:throw new Error('Invalid row dimension: '+row.dimension);}},cmp:function(rowA,rowB){if(rowA.dimension!==rowB.dimension)
-return rowA.dimension-rowB.dimension;return tr.ui.analysis.TitleColumn.prototype.cmp.call(this,rowA,rowB);},formatSubRow_:function(title,dimension){var titleEl=document.createElement('span');var symbolEl=document.createElement('span');var symbolColorName;if(dimension===RowDimension.STACK_FRAME){symbolEl.textContent=LATIN_SMALL_LETTER_F_WITH_HOOK;symbolEl.title='Stack frame';symbolColorName='heap_dump_stack_frame';}else{symbolEl.textContent=CIRCLED_LATIN_CAPITAL_LETTER_T;symbolEl.title='Object type';symbolColorName='heap_dump_object_type';}
-symbolEl.style.color=tr.b.ColorScheme.getColorForReservedNameAsString(symbolColorName);symbolEl.style.paddingRight='4px';symbolEl.style.cursor='help';symbolEl.style.weight='bold';titleEl.appendChild(symbolEl);titleEl.appendChild(document.createTextNode(title));return titleEl;}};var COLUMN_RULES=[{importance:0,columnConstructor:tr.ui.analysis.NumericMemoryColumn}];Polymer('tr-ui-a-memory-dump-heap-details-pane',{created:function(){this.heapDumps_=undefined;this.aggregationMode_=undefined;this.viewMode_=undefined;},ready:function(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;this.$.info_bar.message='Note: Values displayed in the heavy view '+'are lower bounds (except for the root).';this.$.view_mode_container.appendChild(tr.ui.b.createSelector(this,'viewMode','memoryDumpHeapDetailsPane.viewMode',tr.b.MultiDimensionalViewType.TOP_DOWN_TREE_VIEW,[{label:'Top-down (Tree)',value:tr.b.MultiDimensionalViewType.TOP_DOWN_TREE_VIEW},{label:'Top-down (Heavy)',value:tr.b.MultiDimensionalViewType.TOP_DOWN_HEAVY_VIEW},{label:'Bottom-up (Heavy)',value:tr.b.MultiDimensionalViewType.BOTTOM_UP_HEAVY_VIEW}]));},set heapDumps(heapDumps){this.heapDumps_=heapDumps;this.scheduleRebuildPane_();},get heapDumps(){return this.heapDumps_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuildPane_();},get aggregationMode(){return this.aggregationMode_;},set viewMode(viewMode){this.viewMode_=viewMode;this.scheduleRebuildPane_();},get viewMode(){return this.viewMode_;},get heavyView(){switch(this.viewMode){case tr.b.MultiDimensionalViewType.TOP_DOWN_HEAVY_VIEW:case tr.b.MultiDimensionalViewType.BOTTOM_UP_HEAVY_VIEW:return true;default:return false;}},rebuildPane_:function(){if(this.heapDumps_===undefined||this.heapDumps_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.view_mode_container.style.display='none';this.$.info_bar.visible=false;this.$.table.clear();this.$.table.rebuild();return;}
-this.$.info_text.style.display='none';this.$.table.style.display='block';this.$.view_mode_container.style.display='block';this.$.info_bar.visible=this.heavyView;var stackFrameTrees=this.createStackFrameTrees_(this.heapDumps_);var rows=this.createRows_(stackFrameTrees);var columns=this.createColumns_(rows);this.$.table.tableRows=rows;this.$.table.tableColumns=columns;this.$.table.rebuild();tr.ui.analysis.expandTableRowsRecursively(this.$.table);},createStackFrameTrees_:function(heapDumps){return heapDumps.map(function(heapDump){if(heapDump===undefined)
-return undefined;var builder=new tr.b.MultiDimensionalViewBuilder(2);heapDump.entries.forEach(function(entry){var leafStackFrame=entry.leafStackFrame;var stackTracePath=leafStackFrame===undefined?[]:leafStackFrame.getUserFriendlyStackTrace().reverse();var objectTypeName=entry.objectTypeName;var objectTypeNamePath=objectTypeName===undefined?[]:[objectTypeName];builder.addPath([stackTracePath,objectTypeNamePath],entry.size,tr.b.MultiDimensionalViewBuilder.ValueKind.TOTAL);},this);return builder.buildView(this.viewMode);},this);},createRows_:function(stackFrameTrees){var definedHeapDump=tr.b.findFirstInArray(this.heapDumps);if(definedHeapDump===undefined)
-return[];var rootRowTitle=definedHeapDump.allocatorName;return[this.createHeapRowRecursively_(stackFrameTrees,RowDimension.ROOT,rootRowTitle)];},createHeapRowRecursively_:function(nodes,dimension,title){var cells=tr.ui.analysis.createCells(nodes,function(node){return{'Size':new ScalarNumeric(sizeInBytes_smallerIsBetter,node.total)};});var row={dimension:dimension,title:title,contexts:nodes,cells:cells};var stackFrameSubRows=this.createHeapDimensionSubRowsRecursively_(nodes,RowDimension.STACK_FRAME);var objectTypeSubRows=this.createHeapDimensionSubRowsRecursively_(nodes,RowDimension.OBJECT_TYPE);var subRows=stackFrameSubRows.concat(objectTypeSubRows);if(subRows.length>0)
-row.subRows=subRows;return row;},createHeapDimensionSubRowsRecursively_:function(nodes,dimension){var dimensionGroupedChildNodes=tr.b.dictionaryValues(tr.b.invertArrayOfDicts(nodes,function(node){var childDict={};var displayedChildrenTotal=0;var hasDisplayedChildren=false;for(var child of node.children[dimension].values()){if(!this.heavyView&&child.isLowerBound)
-continue;childDict[child.title[dimension]]=child;displayedChildrenTotal+=child.total;hasDisplayedChildren=true;}
-if(!this.heavyView&&displayedChildrenTotal<node.total&&hasDisplayedChildren){var otherTitle=node.title.slice();otherTitle[dimension]='<other>';childDict['<other>']={title:otherTitle,total:node.total-displayedChildrenTotal,children:[new Map(),new Map()]};}
-return childDict;},this));return dimensionGroupedChildNodes.map(function(subRowNodes){var subRowTitle=tr.b.findFirstInArray(subRowNodes).title[dimension];return this.createHeapRowRecursively_(subRowNodes,dimension,subRowTitle);},this);},createColumns_:function(rows){var titleColumn=new HeapDumpNodeTitleColumn('Stack frame');titleColumn.width='500px';var numericColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'cells',this.aggregationMode_,COLUMN_RULES);tr.ui.analysis.MemoryColumn.spaceEqually(numericColumns);var columns=[titleColumn].concat(numericColumns);return columns;}});return{RowDimension:RowDimension};});'use strict';tr.exportTo('tr.ui.analysis',function(){var SUBALLOCATION_CONTEXT=true;var MemoryAllocatorDumpInfoType=tr.model.MemoryAllocatorDumpInfoType;var PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN=MemoryAllocatorDumpInfoType.PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN;var PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER=MemoryAllocatorDumpInfoType.PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER;var LEFTWARDS_OPEN_HEADED_ARROW=String.fromCharCode(0x21FD);var RIGHTWARDS_OPEN_HEADED_ARROW=String.fromCharCode(0x21FE);var EN_DASH=String.fromCharCode(0x2013);var CIRCLED_LATIN_SMALL_LETTER_I=String.fromCharCode(0x24D8);function AllocatorDumpNameColumn(){tr.ui.analysis.TitleColumn.call(this,'Component');}
-AllocatorDumpNameColumn.prototype={__proto__:tr.ui.analysis.TitleColumn.prototype,formatTitle:function(row){if(!row.suballocation)
-return row.title;return tr.ui.b.createSpan({textContent:row.title,italic:true,tooltip:row.fullNames===undefined?undefined:row.fullNames.join(', ')});}};function getAndUpdateEntry(map,name,createdCallback){var entry=map.get(name);if(entry===undefined){entry={count:0};createdCallback(entry);map.set(name,entry);}
+for(let i=0;i<timestampCount;i++){if(rowCell.fields[i]!==undefined)continue;rowCell.fields[i]=tr.model.MemoryAllocatorDump.aggregateNumerics(subRowCells.map(function(subRowCell){if(subRowCell===undefined||subRowCell.fields===undefined){return undefined;}
+return subRowCell.fields[i];}));}},formatSingleField(numeric){return tr.v.ui.createScalarSpan(numeric,{context:this.getFormattingContext(numeric.unit),contextGroup:this.shouldSetContextGroup?this.name:undefined,inline:true,});},getFormattingContext(unit){return undefined;},formatMultipleFieldsDiff(firstNumeric,lastNumeric){return this.formatSingleField(this.getDiffField_(firstNumeric,lastNumeric));},compareSingleFields(numericA,numericB){return numericA.value-numericB.value;},compareMultipleFieldsDiff(firstNumericA,lastNumericA,firstNumericB,lastNumericB){return this.getDiffFieldValue_(firstNumericA,lastNumericA)-
+this.getDiffFieldValue_(firstNumericB,lastNumericB);},getDiffField_(firstNumeric,lastNumeric){const definedNumeric=firstNumeric||lastNumeric;return new tr.b.Scalar(definedNumeric.unit.correspondingDeltaUnit,this.getDiffFieldValue_(firstNumeric,lastNumeric));},getDiffFieldValue_(firstNumeric,lastNumeric){const firstValue=firstNumeric===undefined?0:firstNumeric.value;const lastValue=lastNumeric===undefined?0:lastNumeric.value;const diff=lastValue-firstValue;return Math.abs(diff)<NumericMemoryColumn.DIFF_EPSILON?0:diff;}};function MemoryCell(fields){this.fields=fields;}
+MemoryCell.extractFields=function(cell){if(cell===undefined)return undefined;return cell.fields;};const RECURSIVE_EXPANSION_MAX_VISIBLE_ROW_COUNT=10;function expandTableRowsRecursively(table){let currentLevelRows=table.tableRows;let totalVisibleRowCount=currentLevelRows.length;while(currentLevelRows.length>0){let nextLevelRowCount=0;currentLevelRows.forEach(function(currentLevelRow){const subRows=currentLevelRow.subRows;if(subRows===undefined||subRows.length===0)return;nextLevelRowCount+=subRows.length;});if(totalVisibleRowCount+nextLevelRowCount>RECURSIVE_EXPANSION_MAX_VISIBLE_ROW_COUNT){break;}
+const nextLevelRows=new Array(nextLevelRowCount);let nextLevelRowIndex=0;currentLevelRows.forEach(function(currentLevelRow){const subRows=currentLevelRow.subRows;if(subRows===undefined||subRows.length===0)return;table.setExpandedForTableRow(currentLevelRow,true);subRows.forEach(function(subRow){nextLevelRows[nextLevelRowIndex++]=subRow;});});totalVisibleRowCount+=nextLevelRowCount;currentLevelRows=nextLevelRows;}}
+function aggregateTableRowCellsRecursively(row,columns,opt_predicate){const subRows=row.subRows;if(subRows===undefined||subRows.length===0)return;subRows.forEach(function(subRow){aggregateTableRowCellsRecursively(subRow,columns,opt_predicate);});if(opt_predicate===undefined||opt_predicate(row.contexts)){aggregateTableRowCells(row,subRows,columns);}}
+function aggregateTableRowCells(row,subRows,columns){columns.forEach(function(column){if(!(column instanceof MemoryColumn))return;column.aggregateCells(row,subRows);});}
+function createCells(timeToValues,valueFieldsGetter,opt_this){opt_this=opt_this||this;const fieldNameToFields=tr.b.invertArrayOfDicts(timeToValues,valueFieldsGetter,opt_this);const result={};for(const[fieldName,fields]of Object.entries(fieldNameToFields)){result[fieldName]=new tr.ui.analysis.MemoryCell(fields);}
+return result;}
+function createWarningInfo(message){return{message,icon:String.fromCharCode(9888),color:'red'};}
+function DetailsNumericMemoryColumn(name,cellPath,aggregationMode){NumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
+DetailsNumericMemoryColumn.prototype={__proto__:NumericMemoryColumn.prototype,getFormattingContext(unit){if(unit.baseUnit===tr.b.Unit.byName.sizeInBytes){return{unitPrefix:tr.b.UnitPrefixScale.BINARY.KIBI};}
+return undefined;}};return{TitleColumn,MemoryColumn,StringMemoryColumn,NumericMemoryColumn,MemoryCell,expandTableRowsRecursively,aggregateTableRowCellsRecursively,aggregateTableRowCells,createCells,createWarningInfo,DetailsNumericMemoryColumn,};});'use strict';tr.exportTo('tr.ui.analysis',function(){const LATIN_SMALL_LETTER_F_WITH_HOOK=String.fromCharCode(0x0192);const CIRCLED_LATIN_CAPITAL_LETTER_T=String.fromCharCode(0x24C9);const HeapDetailsRowDimension={ROOT:{},STACK_FRAME:{label:'Stack frame',symbol:LATIN_SMALL_LETTER_F_WITH_HOOK,color:'heap_dump_stack_frame'},OBJECT_TYPE:{label:'Object type',symbol:CIRCLED_LATIN_CAPITAL_LETTER_T,color:'heap_dump_object_type'}};function HeapDetailsTitleColumn(title){tr.ui.analysis.TitleColumn.call(this,title);}
+HeapDetailsTitleColumn.prototype={__proto__:tr.ui.analysis.TitleColumn.prototype,formatTitle(row){if(row.dimension===HeapDetailsRowDimension.ROOT){return row.title;}
+const symbolEl=document.createElement('span');Polymer.dom(symbolEl).textContent=row.dimension.symbol;symbolEl.title=row.dimension.label;symbolEl.style.color=tr.b.ColorScheme.getColorForReservedNameAsString(row.dimension.color);symbolEl.style.paddingRight='4px';symbolEl.style.cursor='help';symbolEl.style.fontWeight='bold';const titleEl=document.createElement('span');Polymer.dom(titleEl).appendChild(symbolEl);Polymer.dom(titleEl).appendChild(document.createTextNode(row.title));return titleEl;}};function AllocationCountColumn(name,cellPath,aggregationMode){tr.ui.analysis.DetailsNumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
+AllocationCountColumn.prototype={__proto__:tr.ui.analysis.DetailsNumericMemoryColumn.prototype,getFormattingContext(unit){return{minimumFractionDigits:0};}};const HEAP_DETAILS_COLUMN_RULES=[{condition:'Size',importance:2,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:'Count',importance:1,columnConstructor:AllocationCountColumn},{importance:0,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn}];return{HeapDetailsRowDimension,HeapDetailsTitleColumn,AllocationCountColumn,HEAP_DETAILS_COLUMN_RULES,};});'use strict';tr.exportTo('tr.ui.analysis',function(){const RebuildableBehavior={rebuild(){if(!this.paneDirty_){return;}
+this.paneDirty_=false;this.onRebuild_();},scheduleRebuild_(){if(this.paneDirty_)return;this.paneDirty_=true;tr.b.requestAnimationFrame(this.rebuild.bind(this));},onRebuild_(){}};return{RebuildableBehavior,};});'use strict';Polymer({is:'tr-ui-b-tab-view',properties:{label_:{type:String,value:()=>''},selectedSubView_:Object,subViews_:{type:Array,value:()=>[]},tabsHidden:{type:Boolean,value:false,observer:'tabsHiddenChanged_'}},ready(){this.$.tabs.addEventListener('keydown',this.onKeyDown_.bind(this),true);this.updateFocusability_();},set label(newLabel){this.set('label_',newLabel);},get tabs(){return this.get('subViews_');},get selectedSubView(){return this.selectedSubView_;},set selectedSubView(subView){if(subView===this.selectedSubView_)return;if(this.selectedSubView_){Polymer.dom(this.$.subView).removeChild(this.selectedSubView_);const oldInput=this.root.getElementById(this.computeRadioId_(this.selectedSubView_));if(oldInput){oldInput.checked=false;}}
+this.set('selectedSubView_',subView);if(subView){Polymer.dom(this.$.subView).appendChild(subView);const newInput=this.root.getElementById(this.computeRadioId_(subView));if(newInput){newInput.checked=true;}}
+this.fire('selected-tab-change');},clearSubViews(){this.splice('subViews_',0,this.subViews_.length);this.selectedSubView=undefined;this.updateFocusability_();},addSubView(subView){this.push('subViews_',subView);if(!this.selectedSubView_)this.selectedSubView=subView;this.updateFocusability_();},get subViews(){return this.subViews_;},resetSubViews(subViews){this.splice('subViews_',0,this.subViews_.length);if(subViews.length){for(const subView of subViews){this.push('subViews_',subView);}
+this.selectedSubView=subViews[0];}else{this.selectedSubView=undefined;}
+this.updateFocusability_();},onTabChanged_(event){this.selectedSubView=event.model.item;},isChecked_(subView){return this.selectedSubView_===subView;},tabsHiddenChanged_(){this.updateFocusability_();},onKeyDown_(e){if(this.tabsHidden)return;let keyHandled=false;switch(e.keyCode){case 37:keyHandled=this.selectPreviousTabIfPossible();break;case 39:keyHandled=this.selectNextTabIfPossible();break;}
+if(!keyHandled)return;e.stopPropagation();e.preventDefault();},selectNextTabIfPossible(){return this.selectTabByOffsetIfPossible_(1);},selectPreviousTabIfPossible(){return this.selectTabByOffsetIfPossible_(-1);},selectTabByOffsetIfPossible_(offset){if(!this.selectedSubView_)return false;const currentIndex=this.subViews_.indexOf(this.selectedSubView_);const newSubView=this.tabs[currentIndex+offset];if(!newSubView)return false;this.selectedSubView=newSubView;return true;},shouldBeFocusable_(){return!this.tabsHidden&&this.subViews_.length>0;},updateFocusability_(){if(this.shouldBeFocusable_()){Polymer.dom(this.$.tabs).setAttribute('tabindex',0);}else{Polymer.dom(this.$.tabs).removeAttribute('tabindex');}},computeRadioId_(subView){return subView.tagName+'-'+subView.tabLabel.replace(/ /g,'-');}});'use strict';tr.exportTo('tr.ui.analysis',function(){const RESONABLE_NUMBER_OF_ROWS=200;const TabUiState={NO_LONG_TAIL:0,HIDING_LONG_TAIL:1,SHOWING_LONG_TAIL:2,};function EmptyFillerColumn(){}
+EmptyFillerColumn.prototype={title:'',value(){return'';},};Polymer({is:'tr-ui-a-memory-dump-heap-details-breakdown-view',behaviors:[tr.ui.analysis.RebuildableBehavior],created(){this.displayedNode_=undefined;this.dimensionToTab_=new Map();},ready(){this.scheduleRebuild_();this.root.addEventListener('keydown',this.onKeyDown_.bind(this),true);},get displayedNode(){return this.displayedNode_;},set displayedNode(node){this.displayedNode_=node;this.scheduleRebuild_();},get aggregationMode(){return this.aggregationMode_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;for(const tab of this.$.tabs.tabs){tab.aggregationMode=aggregationMode;}},onRebuild_(){const previouslySelectedTab=this.$.tabs.selectedSubView;let previouslySelectedTabFocused=false;let previouslySelectedDimension=undefined;if(previouslySelectedTab){previouslySelectedTabFocused=previouslySelectedTab.isFocused;previouslySelectedDimension=previouslySelectedTab.dimension;}
+for(const tab of this.$.tabs.tabs){tab.nodes=undefined;}
+this.$.tabs.clearSubViews();if(this.displayedNode_===undefined){this.$.tabs.label='No heap node provided.';return;}
+for(const[dimension,children]of this.displayedNode_.childNodes){if(!this.dimensionToTab_.has(dimension)){this.dimensionToTab_.set(dimension,document.createElement('tr-ui-a-memory-dump-heap-details-breakdown-view-tab'));}
+const tab=this.dimensionToTab_.get(dimension);tab.aggregationMode=this.aggregationMode_;tab.dimension=dimension;tab.nodes=children;this.$.tabs.addSubView(tab);tab.rebuild();if(dimension===previouslySelectedDimension){this.$.tabs.selectedSubView=tab;if(previouslySelectedTabFocused){tab.focus();}}}
+if(this.$.tabs.tabs.length>0){this.$.tabs.label='Break selected node further by:';}else{this.$.tabs.label='Selected node cannot be broken down any further.';}},onKeyDown_(keyEvent){if(!this.displayedNode_)return;let keyHandled=false;switch(keyEvent.keyCode){case 8:{if(!this.displayedNode_.parentNode)break;const viewEvent=new tr.b.Event('enter-node');viewEvent.node=this.displayedNode_.parentNode;this.dispatchEvent(viewEvent);keyHandled=true;break;}
+case 37:case 39:{const wasFocused=this.$.tabs.selectedSubView.isFocused;keyHandled=keyEvent.keyCode===37?this.$.tabs.selectPreviousTabIfPossible():this.$.tabs.selectNextTabIfPossible();if(wasFocused&&keyHandled){this.$.tabs.selectedSubView.focus();}}}
+if(!keyHandled)return;keyEvent.stopPropagation();keyEvent.preventDefault();}});Polymer({is:'tr-ui-a-memory-dump-heap-details-breakdown-view-tab',behaviors:[tr.ui.analysis.RebuildableBehavior],created(){this.dimension_=undefined;this.nodes_=undefined;this.aggregationMode_=undefined;this.displayLongTail_=false;},ready(){this.$.table.addEventListener('step-into',function(tableEvent){const viewEvent=new tr.b.Event('enter-node');viewEvent.node=tableEvent.tableRow;this.dispatchEvent(viewEvent);}.bind(this));},get displayLongTail(){return this.displayLongTail_;},set displayLongTail(newValue){if(this.displayLongTail===newValue)return;this.displayLongTail_=newValue;this.scheduleRebuild_();},get dimension(){return this.dimension_;},set dimension(dimension){this.dimension_=dimension;this.scheduleRebuild_();},get nodes(){return this.nodes_;},set nodes(nodes){this.nodes_=nodes;this.scheduleRebuild_();},get nodes(){return this.nodes_||[];},get dimensionLabel_(){if(this.dimension_===undefined)return'(undefined)';return this.dimension_.label;},get tabLabel(){let nodeCount=0;if(this.nodes_){nodeCount=this.nodes_.length;}
+return this.dimensionLabel_+' ('+nodeCount+')';},get tabIcon(){if(this.dimension_===undefined||this.dimension_===tr.ui.analysis.HeapDetailsRowDimension.ROOT){return undefined;}
+return{text:this.dimension_.symbol,style:'color: '+tr.b.ColorScheme.getColorForReservedNameAsString(this.dimension_.color)+';'};},get aggregationMode(){return this.aggregationMode_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuild_();},focus(){this.$.table.focus();},blur(){this.$.table.blur();},get isFocused(){return this.$.table.isFocused;},onRebuild_(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;this.$.table.emptyValue='Cannot break down by '+
+this.dimensionLabel_.toLowerCase()+' any further.';const[state,rows]=this.getRows_();const total=this.nodes.length;const displayed=rows.length;const hidden=total-displayed;this.updateInfoBar_(state,[total,displayed,hidden]);this.$.table.tableRows=rows;this.$.table.tableColumns=this.createColumns_(rows);if(this.$.table.sortColumnIndex===undefined){this.$.table.sortColumnIndex=0;this.$.table.sortDescending=false;}
+this.$.table.rebuild();},createColumns_(rows){const titleColumn=new tr.ui.analysis.HeapDetailsTitleColumn(this.dimensionLabel_);titleColumn.width='400px';const numericColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'cells',aggregationMode:this.aggregationMode_,rules:tr.ui.analysis.HEAP_DETAILS_COLUMN_RULES,shouldSetContextGroup:true});if(numericColumns.length===0){numericColumns.push(new EmptyFillerColumn());}
+tr.ui.analysis.MemoryColumn.spaceEqually(numericColumns);const columns=[titleColumn].concat(numericColumns);return columns;},getRows_(){let rows=this.nodes;if(rows.length<=RESONABLE_NUMBER_OF_ROWS){return[TabUiState.NO_LONG_TAIL,rows];}else if(this.displayLongTail){return[TabUiState.SHOWING_LONG_TAIL,rows];}
+const absSize=row=>Math.max(row.cells.Size.fields[0].value);rows.sort((a,b)=>absSize(b)-absSize(a));rows=rows.slice(0,RESONABLE_NUMBER_OF_ROWS);return[TabUiState.HIDING_LONG_TAIL,rows];},updateInfoBar_(state,rowStats){if(state===TabUiState.SHOWING_LONG_TAIL){this.longTailVisibleInfoBar_(rowStats);}else if(state===TabUiState.HIDING_LONG_TAIL){this.longTailHiddenInfoBar_(rowStats);}else{this.hideInfoBar_();}},longTailVisibleInfoBar_(rowStats){const[total,visible,hidden]=rowStats;const couldHide=total-RESONABLE_NUMBER_OF_ROWS;this.$.info.message='Showing '+total+' rows. This may be slow.';this.$.info.removeAllButtons();const buttonText='Hide '+couldHide+' rows.';this.$.info.addButton(buttonText,()=>this.displayLongTail=false);this.$.info.visible=true;},longTailHiddenInfoBar_(rowStats){const[total,visible,hidden]=rowStats;this.$.info.message='Hiding the smallest '+hidden+' rows.';this.$.info.removeAllButtons();this.$.info.addButton('Show all.',()=>this.displayLongTail=true);this.$.info.visible=true;},hideInfoBar_(){this.$.info.visible=false;},});return{};});'use strict';tr.exportTo('tr.ui.analysis',function(){const DOWNWARDS_ARROW_WITH_TIP_RIGHTWARDS=String.fromCharCode(0x21B3);function HeapDetailsPathColumn(title){tr.ui.analysis.HeapDetailsTitleColumn.call(this,title);}
+HeapDetailsPathColumn.prototype={__proto__:tr.ui.analysis.HeapDetailsTitleColumn.prototype,formatTitle(row){const title=tr.ui.analysis.HeapDetailsTitleColumn.prototype.formatTitle.call(this,row);if(row.dimension===tr.ui.analysis.HeapDetailsRowDimension.ROOT){return title;}
+const arrowEl=document.createElement('span');Polymer.dom(arrowEl).textContent=DOWNWARDS_ARROW_WITH_TIP_RIGHTWARDS;arrowEl.style.paddingRight='2px';arrowEl.style.fontWeight='bold';arrowEl.style.color=tr.b.ColorScheme.getColorForReservedNameAsString('heap_dump_child_node_arrow');const rowEl=document.createElement('span');Polymer.dom(rowEl).appendChild(arrowEl);Polymer.dom(rowEl).appendChild(tr.ui.b.asHTMLOrTextNode(title));return rowEl;}};Polymer({is:'tr-ui-a-memory-dump-heap-details-path-view',behaviors:[tr.ui.analysis.RebuildableBehavior],created(){this.selectedNode_=undefined;this.aggregationMode_=undefined;},ready(){this.$.table.addEventListener('selection-changed',function(event){this.selectedNode_=this.$.table.selectedTableRow;this.didSelectedNodeChange_();}.bind(this));},didSelectedNodeChange_(){this.dispatchEvent(new tr.b.Event('selected-node-changed'));},get selectedNode(){return this.selectedNode_;},set selectedNode(node){this.selectedNode_=node;this.didSelectedNodeChange_();this.scheduleRebuild_();},get aggregationMode(){return this.aggregationMode_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuild_();},onRebuild_(){if(this.selectedNode_===undefined){this.$.table.clear();return;}
+if(this.$.table.tableRows.includes(this.selectedNode_)){this.$.table.selectedTableRow=this.selectedNode_;return;}
+this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;this.$.table.userCanModifySortOrder=false;const rows=this.createRows_(this.selectedNode_);this.$.table.tableRows=rows;this.$.table.tableColumns=this.createColumns_(rows);this.$.table.selectedTableRow=rows[rows.length-1];},createRows_(node){const rows=[];while(node){rows.push(node);node=node.parentNode;}
+rows.reverse();return rows;},createColumns_(rows){const titleColumn=new HeapDetailsPathColumn('Current path');titleColumn.width='200px';const numericColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'cells',aggregationMode:this.aggregationMode_,rules:tr.ui.analysis.HEAP_DETAILS_COLUMN_RULES,shouldSetContextGroup:true});tr.ui.analysis.MemoryColumn.spaceEqually(numericColumns);return[titleColumn].concat(numericColumns);}});return{};});'use strict';tr.exportTo('tr.ui.analysis',function(){const StackedPaneImpl={set childPaneBuilder(childPaneBuilder){this.childPaneBuilder_=childPaneBuilder;this.dispatchEvent(new tr.b.Event('request-child-pane-change'));},get childPaneBuilder(){return this.childPaneBuilder_;},appended(){this.rebuild();}};const StackedPane=[tr.ui.analysis.RebuildableBehavior,StackedPaneImpl];return{StackedPane,};});Polymer({is:'tr-ui-a-stacked-pane',behaviors:[tr.ui.analysis.StackedPane]});'use strict';tr.exportTo('tr.ui.analysis',function(){const Scalar=tr.b.Scalar;const sizeInBytes_smallerIsBetter=tr.b.Unit.byName.sizeInBytes_smallerIsBetter;const count_smallerIsBetter=tr.b.Unit.byName.count_smallerIsBetter;const MultiDimensionalViewBuilder=tr.b.MultiDimensionalViewBuilder;const TotalState=tr.b.MultiDimensionalViewNode.TotalState;function HeapDumpTreeNode(stackFrameNodes,dimension,title,heavyView,parentNode){this.dimension=dimension;this.title=title;this.parentNode=parentNode;this.heavyView_=heavyView;this.stackFrameNodes_=stackFrameNodes;this.lazyCells_=undefined;this.lazyChildNodes_=undefined;}
+HeapDumpTreeNode.prototype={get minDisplayedTotalState_(){if(this.heavyView_){return TotalState.LOWER_BOUND;}
+return TotalState.EXACT;},get childNodes(){if(!this.lazyChildNodes_){this.lazyChildNodes_=new Map();this.addDimensionChildNodes_(tr.ui.analysis.HeapDetailsRowDimension.STACK_FRAME,0);this.addDimensionChildNodes_(tr.ui.analysis.HeapDetailsRowDimension.OBJECT_TYPE,1);this.releaseStackFrameNodesIfPossible_();}
+return this.lazyChildNodes_;},get cells(){if(!this.lazyCells_){this.addCells_();this.releaseStackFrameNodesIfPossible_();}
+return this.lazyCells_;},releaseStackFrameNodesIfPossible_(){if(this.lazyCells_&&this.lazyChildNodes_){this.stackFrameNodes_=undefined;}},addDimensionChildNodes_(dimension,dimensionIndex){const dimensionChildTitleToStackFrameNodes=tr.b.invertArrayOfDicts(this.stackFrameNodes_,node=>this.convertStackFrameNodeDimensionToChildDict_(node,dimensionIndex));const dimensionChildNodes=[];for(const[childTitle,childStackFrameNodes]of
+Object.entries(dimensionChildTitleToStackFrameNodes)){dimensionChildNodes.push(new HeapDumpTreeNode(childStackFrameNodes,dimension,childTitle,this.heavyView_,this));}
+this.lazyChildNodes_.set(dimension,dimensionChildNodes);},convertStackFrameNodeDimensionToChildDict_(stackFrameNode,dimensionIndex){const childDict={};let displayedChildrenTotalSize=0;let displayedChildrenTotalCount=0;let hasDisplayedChildren=false;let allDisplayedChildrenHaveDisplayedCounts=true;for(const child of stackFrameNode.children[dimensionIndex].values()){if(child.values[0].totalState<this.minDisplayedTotalState_){continue;}
+if(child.values[1].totalState<this.minDisplayedTotalState_){allDisplayedChildrenHaveDisplayedCounts=false;}
+childDict[child.title[dimensionIndex]]=child;displayedChildrenTotalSize+=child.values[0].total;displayedChildrenTotalCount+=child.values[1].total;hasDisplayedChildren=true;}
+const nodeTotalSize=stackFrameNode.values[0].total;const nodeTotalCount=stackFrameNode.values[1].total;const hasUnclassifiedSizeOrCount=displayedChildrenTotalSize<nodeTotalSize||displayedChildrenTotalCount<nodeTotalCount;if(!this.heavyView_&&hasUnclassifiedSizeOrCount&&hasDisplayedChildren){const otherTitle=stackFrameNode.title.slice();otherTitle[dimensionIndex]='<other>';const otherNode=new tr.b.MultiDimensionalViewNode(otherTitle,2);childDict[otherTitle[dimensionIndex]]=otherNode;otherNode.values[0].total=nodeTotalSize-displayedChildrenTotalSize;otherNode.values[0].totalState=this.minDisplayedTotalState_;otherNode.values[1].total=nodeTotalCount-displayedChildrenTotalCount;otherNode.values[1].totalState=allDisplayedChildrenHaveDisplayedCounts?this.minDisplayedTotalState_:TotalState.NOT_PROVIDED;}
+return childDict;},addCells_(){this.lazyCells_=tr.ui.analysis.createCells(this.stackFrameNodes_,function(stackFrameNode){const size=stackFrameNode.values[0].total;const numerics={'Size':new Scalar(sizeInBytes_smallerIsBetter,size)};const countValue=stackFrameNode.values[1];if(countValue.totalState>=this.minDisplayedTotalState_){const count=countValue.total;numerics.Count=new Scalar(count_smallerIsBetter,count);}
+return numerics;},this);}};Polymer({is:'tr-ui-a-memory-dump-heap-details-pane',behaviors:[tr.ui.analysis.StackedPane],created(){this.heapDumps_=undefined;this.viewMode_=undefined;this.aggregationMode_=undefined;this.cachedBuilders_=new Map();},ready(){this.$.info_bar.message='Note: Values displayed in the heavy view '+'are lower bounds (except for the root).';Polymer.dom(this.$.view_mode_container).appendChild(tr.ui.b.createSelector(this,'viewMode','memoryDumpHeapDetailsPane.viewMode',MultiDimensionalViewBuilder.ViewType.TOP_DOWN_TREE_VIEW,[{label:'Top-down (Tree)',value:MultiDimensionalViewBuilder.ViewType.TOP_DOWN_TREE_VIEW},{label:'Top-down (Heavy)',value:MultiDimensionalViewBuilder.ViewType.TOP_DOWN_HEAVY_VIEW},{label:'Bottom-up (Heavy)',value:MultiDimensionalViewBuilder.ViewType.BOTTOM_UP_HEAVY_VIEW}]));this.$.drag_handle.target=this.$.path_view;this.$.drag_handle.horizontal=false;this.$.path_view.addEventListener('selected-node-changed',(function(e){this.$.breakdown_view.displayedNode=this.$.path_view.selectedNode;}).bind(this));this.$.breakdown_view.addEventListener('enter-node',(function(e){this.$.path_view.selectedNode=e.node;}).bind(this));},set heapDumps(heapDumps){this.heapDumps_=heapDumps;this.scheduleRebuild_();},get heapDumps(){return this.heapDumps_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.$.path_view.aggregationMode=aggregationMode;this.$.breakdown_view.aggregationMode=aggregationMode;},get aggregationMode(){return this.aggregationMode_;},set viewMode(viewMode){this.viewMode_=viewMode;this.scheduleRebuild_();},get viewMode(){return this.viewMode_;},get heavyView(){switch(this.viewMode){case MultiDimensionalViewBuilder.ViewType.TOP_DOWN_HEAVY_VIEW:case MultiDimensionalViewBuilder.ViewType.BOTTOM_UP_HEAVY_VIEW:return true;default:return false;}},onRebuild_(){if(this.heapDumps_===undefined||this.heapDumps_.length===0){this.$.info_text.style.display='block';this.$.split_view.style.display='none';this.$.view_mode_container.style.display='none';this.$.info_bar.hidden=true;this.$.path_view.selectedNode=undefined;return;}
+this.$.info_text.style.display='none';this.$.split_view.style.display='flex';this.$.view_mode_container.style.display='block';this.$.info_bar.hidden=!this.heavyView;this.$.path_view.selectedNode=this.createHeapTree_();this.$.path_view.rebuild();this.$.breakdown_view.rebuild();},createHeapTree_(){const definedHeapDump=this.heapDumps_.find(x=>x);if(definedHeapDump===undefined)return undefined;const rootRowTitle=definedHeapDump.allocatorName;const stackFrameTrees=this.createStackFrameTrees_(this.heapDumps_);return new HeapDumpTreeNode(stackFrameTrees,tr.ui.analysis.HeapDetailsRowDimension.ROOT,rootRowTitle,this.heavyView);},createStackFrameTrees_(heapDumps){const builders=heapDumps.map(heapDump=>this.createBuilder_(heapDump));const views=builders.map(builder=>{if(builder===undefined)return undefined;return builder.buildView(this.viewMode);});return views;},createBuilder_(heapDump){if(heapDump===undefined)return undefined;if(this.cachedBuilders_.has(heapDump)){return this.cachedBuilders_.get(heapDump);}
+const dimensions=2;const valueCount=2;const builder=new MultiDimensionalViewBuilder(dimensions,valueCount);for(const entry of heapDump.entries){const leafStackFrame=entry.leafStackFrame;const stackTracePath=leafStackFrame===undefined?[]:leafStackFrame.getUserFriendlyStackTrace().reverse();const objectTypeName=entry.objectTypeName;const objectTypeNamePath=objectTypeName===undefined?[]:[objectTypeName];const valueKind=entry.valuesAreTotals?MultiDimensionalViewBuilder.ValueKind.TOTAL:MultiDimensionalViewBuilder.ValueKind.SELF;builder.addPath([stackTracePath,objectTypeNamePath],[entry.size,entry.count],valueKind);}
+builder.complete=heapDump.isComplete;this.cachedBuilders_.set(heapDump,builder);return builder;},});return{};});'use strict';tr.exportTo('tr.ui.analysis',function(){const URL_TO_SIZE_VS_EFFECTIVE_SIZE='https://chromium.googlesource.com/chromium/src/+/master/docs/memory-infra/README.md#effective_size-vs_size';const SUBALLOCATION_CONTEXT=true;const MemoryAllocatorDumpInfoType=tr.model.MemoryAllocatorDumpInfoType;const PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN=MemoryAllocatorDumpInfoType.PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN;const PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER=MemoryAllocatorDumpInfoType.PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER;const LEFTWARDS_OPEN_HEADED_ARROW=String.fromCharCode(0x21FD);const RIGHTWARDS_OPEN_HEADED_ARROW=String.fromCharCode(0x21FE);const EN_DASH=String.fromCharCode(0x2013);const CIRCLED_LATIN_SMALL_LETTER_I=String.fromCharCode(0x24D8);function AllocatorDumpNameColumn(){tr.ui.analysis.TitleColumn.call(this,'Component');}
+AllocatorDumpNameColumn.prototype={__proto__:tr.ui.analysis.TitleColumn.prototype,formatTitle(row){if(!row.suballocation){return row.title;}
+return tr.ui.b.createSpan({textContent:row.title,italic:true,tooltip:row.fullNames===undefined?undefined:row.fullNames.join(', ')});}};function getAndUpdateEntry(map,name,createdCallback){let entry=map.get(name);if(entry===undefined){entry={count:0};createdCallback(entry);map.set(name,entry);}
 entry.count++;return entry;}
 function SizeInfoMessageBuilder(){this.parts_=[];this.indent_=0;}
-SizeInfoMessageBuilder.prototype={append:function(){this.parts_.push.apply(this.parts_,Array.prototype.slice.apply(arguments));},appendMap:function(map,hasPluralSuffix,emptyText,itemCallback,opt_this){opt_this=opt_this||this;if(map.size===0){if(emptyText)
-this.append(emptyText);}else if(map.size===1){this.parts_.push(' ');var key=map.keys().next().value;itemCallback.call(opt_this,key,map.get(key));}else{if(hasPluralSuffix)
-this.parts_.push('s');this.parts_.push(':');this.indent_++;for(var key of map.keys()){this.parts_.push('\n',' '.repeat(3*(this.indent_-1)),' - ');itemCallback.call(opt_this,key,map.get(key));}
-this.indent_--;}},appendImportanceRange:function(range){this.append(' (importance: ');if(range.min===range.max)
-this.append(range.min);else
-this.append(range.min,EN_DASH,range.max);this.append(')');},appendSizeIfDefined:function(size){if(size!==undefined)
-this.append(' (',tr.v.Unit.byName.sizeInBytes.format(size),')');},appendSomeTimestampsQuantifier:function(){this.append(' ',tr.ui.analysis.MemoryColumn.SOME_TIMESTAMPS_INFO_QUANTIFIER);},build:function(){return this.parts_.join('');}};function EffectiveSizeColumn(name,cellPath,aggregationMode){tr.ui.analysis.NumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
-EffectiveSizeColumn.prototype={__proto__:tr.ui.analysis.NumericMemoryColumn.prototype,addInfos:function(numerics,memoryAllocatorDumps,infos){if(memoryAllocatorDumps===undefined)
-return;var ownerNameToEntry=new Map();var ownedNameToEntry=new Map();for(var i=0;i<numerics.length;i++){if(numerics[i]===undefined)
-continue;var dump=memoryAllocatorDumps[i];if(dump===SUBALLOCATION_CONTEXT)
-return;dump.ownedBy.forEach(function(ownerLink){var ownerDump=ownerLink.source;this.getAndUpdateOwnershipEntry_(ownerNameToEntry,ownerDump,ownerLink);},this);var ownedLink=dump.owns;if(ownedLink!==undefined){var ownedDump=ownedLink.target;var ownedEntry=this.getAndUpdateOwnershipEntry_(ownedNameToEntry,ownedDump,ownedLink,true);var sharerNameToEntry=ownedEntry.sharerNameToEntry;ownedDump.ownedBy.forEach(function(sharerLink){var sharerDump=sharerLink.source;if(sharerDump===dump)
-return;this.getAndUpdateOwnershipEntry_(sharerNameToEntry,sharerDump,sharerLink);},this);}}
-if(ownerNameToEntry.size>0){var messageBuilder=new SizeInfoMessageBuilder();messageBuilder.append('shared by');messageBuilder.appendMap(ownerNameToEntry,false,undefined,function(ownerName,ownerEntry){messageBuilder.append(ownerName);if(ownerEntry.count<numerics.length)
-messageBuilder.appendSomeTimestampsQuantifier();messageBuilder.appendImportanceRange(ownerEntry.importanceRange);},this);infos.push({message:messageBuilder.build(),icon:LEFTWARDS_OPEN_HEADED_ARROW,color:'green'});}
-if(ownedNameToEntry.size>0){var messageBuilder=new SizeInfoMessageBuilder();messageBuilder.append('shares');messageBuilder.appendMap(ownedNameToEntry,false,undefined,function(ownedName,ownedEntry){messageBuilder.append(ownedName);var ownedCount=ownedEntry.count;if(ownedCount<numerics.length)
-messageBuilder.appendSomeTimestampsQuantifier();messageBuilder.appendImportanceRange(ownedEntry.importanceRange);messageBuilder.append(' with');messageBuilder.appendMap(ownedEntry.sharerNameToEntry,false,' no other dumps',function(sharerName,sharerEntry){messageBuilder.append(sharerName);if(sharerEntry.count<ownedCount)
-messageBuilder.appendSomeTimestampsQuantifier();messageBuilder.appendImportanceRange(sharerEntry.importanceRange);},this);},this);infos.push({message:messageBuilder.build(),icon:RIGHTWARDS_OPEN_HEADED_ARROW,color:'green'});}},getAndUpdateOwnershipEntry_:function(map,dump,link,opt_withSharerNameToEntry){var entry=getAndUpdateEntry(map,dump.quantifiedName,function(newEntry){newEntry.importanceRange=new tr.b.Range();if(opt_withSharerNameToEntry)
-newEntry.sharerNameToEntry=new Map();});entry.importanceRange.addValue(link.importance||0);return entry;}};function SizeColumn(name,cellPath,aggregationMode){tr.ui.analysis.NumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
-SizeColumn.prototype={__proto__:tr.ui.analysis.NumericMemoryColumn.prototype,addInfos:function(numerics,memoryAllocatorDumps,infos){if(memoryAllocatorDumps===undefined)
-return;this.addOverlapInfo_(numerics,memoryAllocatorDumps,infos);this.addProvidedSizeWarningInfos_(numerics,memoryAllocatorDumps,infos);},addOverlapInfo_:function(numerics,memoryAllocatorDumps,infos){var siblingNameToEntry=new Map();for(var i=0;i<numerics.length;i++){if(numerics[i]===undefined)
-continue;var dump=memoryAllocatorDumps[i];if(dump===SUBALLOCATION_CONTEXT)
-return;var ownedBySiblingSizes=dump.ownedBySiblingSizes;for(var siblingDump of ownedBySiblingSizes.keys()){var siblingName=siblingDump.name;getAndUpdateEntry(siblingNameToEntry,siblingName,function(newEntry){if(numerics.length===1)
-newEntry.size=ownedBySiblingSizes.get(siblingDump);});}}
-if(siblingNameToEntry.size>0){var messageBuilder=new SizeInfoMessageBuilder();messageBuilder.append('overlaps with its sibling');messageBuilder.appendMap(siblingNameToEntry,true,undefined,function(siblingName,siblingEntry){messageBuilder.append('\'',siblingName,'\'');messageBuilder.appendSizeIfDefined(siblingEntry.size);if(siblingEntry.count<numerics.length)
-messageBuilder.appendSomeTimestampsQuantifier();},this);infos.push({message:messageBuilder.build(),icon:CIRCLED_LATIN_SMALL_LETTER_I,color:'blue'});}},addProvidedSizeWarningInfos_:function(numerics,memoryAllocatorDumps,infos){var infoTypeToEntry=new Map();for(var i=0;i<numerics.length;i++){if(numerics[i]===undefined)
-continue;var dump=memoryAllocatorDumps[i];if(dump===SUBALLOCATION_CONTEXT)
-return;dump.infos.forEach(function(dumpInfo){getAndUpdateEntry(infoTypeToEntry,dumpInfo.type,function(newEntry){if(numerics.length===1){newEntry.providedSize=dumpInfo.providedSize;newEntry.dependencySize=dumpInfo.dependencySize;}});});}
-for(var infoType of infoTypeToEntry.keys()){var entry=infoTypeToEntry.get(infoType);var messageBuilder=new SizeInfoMessageBuilder();messageBuilder.append('provided size');messageBuilder.appendSizeIfDefined(entry.providedSize);var dependencyName;switch(infoType){case PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN:dependencyName='the aggregated size of the children';break;case PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER:dependencyName='the size of the largest owner';break;default:dependencyName='an unknown dependency';break;}
-messageBuilder.append(' was less than ',dependencyName);messageBuilder.appendSizeIfDefined(entry.dependencySize);if(entry.count<numerics.length)
-messageBuilder.appendSomeTimestampsQuantifier();infos.push(tr.ui.analysis.createWarningInfo(messageBuilder.build()));}}};var NUMERIC_COLUMN_RULES=[{condition:tr.model.MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME,importance:10,columnConstructor:EffectiveSizeColumn},{condition:tr.model.MemoryAllocatorDump.SIZE_NUMERIC_NAME,importance:9,columnConstructor:SizeColumn},{condition:'page_size',importance:0,columnConstructor:tr.ui.analysis.NumericMemoryColumn},{condition:/size/,importance:5,columnConstructor:tr.ui.analysis.NumericMemoryColumn},{importance:0,columnConstructor:tr.ui.analysis.NumericMemoryColumn}];var DIAGNOSTIC_COLUMN_RULES=[{importance:0,columnConstructor:tr.ui.analysis.StringMemoryColumn}];Polymer('tr-ui-a-memory-dump-allocator-details-pane',{created:function(){this.memoryAllocatorDumps_=undefined;this.heapDumps_=undefined;this.aggregationMode_=undefined;},ready:function(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;},set memoryAllocatorDumps(memoryAllocatorDumps){this.memoryAllocatorDumps_=memoryAllocatorDumps;this.scheduleRebuildPane_();},get memoryAllocatorDumps(){return this.memoryAllocatorDumps_;},set heapDumps(heapDumps){this.heapDumps_=heapDumps;this.scheduleRebuildPane_();},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuildPane_();},get aggregationMode(){return this.aggregationMode_;},rebuildPane_:function(){if(this.memoryAllocatorDumps_===undefined||this.memoryAllocatorDumps_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.table.clear();this.$.table.rebuild();this.childPaneBuilder=undefined;return;}
-this.$.info_text.style.display='none';this.$.table.style.display='block';var rows=this.createRows_();var columns=this.createColumns_(rows);rows.forEach(function(rootRow){tr.ui.analysis.aggregateTableRowCellsRecursively(rootRow,columns,function(contexts){return contexts!==undefined&&contexts.some(function(context){return context===SUBALLOCATION_CONTEXT;});});});this.$.table.tableRows=rows;this.$.table.tableColumns=columns;this.$.table.rebuild();tr.ui.analysis.expandTableRowsRecursively(this.$.table);if(this.heapDumps_===undefined){this.childPaneBuilder=undefined;}else{this.childPaneBuilder=function(){var pane=document.createElement('tr-ui-a-memory-dump-heap-details-pane');pane.heapDumps=this.heapDumps_;pane.aggregationMode=this.aggregationMode_;return pane;}.bind(this);}},createRows_:function(){return[this.createAllocatorRowRecursively_(this.memoryAllocatorDumps_)];},createAllocatorRowRecursively_:function(dumps){var definedDump=tr.b.findFirstInArray(dumps);var title=definedDump.name;var fullName=definedDump.fullName;var numericCells=tr.ui.analysis.createCells(dumps,function(dump){return dump.numerics;});var diagnosticCells=tr.ui.analysis.createCells(dumps,function(dump){return dump.diagnostics;});var suballocatedBy=undefined;if(title.startsWith('__')){for(var i=0;i<dumps.length;i++){var dump=dumps[i];if(dump===undefined||dump.ownedBy.length===0){continue;}
-var ownerDump=dump.ownedBy[0].source;if(dump.ownedBy.length>1||dump.children.length>0||ownerDump.containerMemoryDump!==dump.containerMemoryDump){suballocatedBy=undefined;break;}
+SizeInfoMessageBuilder.prototype={append(){this.parts_.push.apply(this.parts_,Array.prototype.slice.apply(arguments));},appendMap(map,hasPluralSuffix,emptyText,itemCallback,opt_this){opt_this=opt_this||this;if(map.size===0){if(emptyText){this.append(emptyText);}}else if(map.size===1){this.parts_.push(' ');const key=map.keys().next().value;itemCallback.call(opt_this,key,map.get(key));}else{if(hasPluralSuffix){this.parts_.push('s');}
+this.parts_.push(':');this.indent_++;for(const key of map.keys()){this.parts_.push('\n',' '.repeat(3*(this.indent_-1)),' - ');itemCallback.call(opt_this,key,map.get(key));}
+this.indent_--;}},appendImportanceRange(range){this.append(' (importance: ');if(range.min===range.max){this.append(range.min);}else{this.append(range.min,EN_DASH,range.max);}
+this.append(')');},appendSizeIfDefined(size){if(size!==undefined){this.append(' (',tr.b.Unit.byName.sizeInBytes.format(size),')');}},appendSomeTimestampsQuantifier(){this.append(' ',tr.ui.analysis.MemoryColumn.SOME_TIMESTAMPS_INFO_QUANTIFIER);},build(){return this.parts_.join('');}};function EffectiveSizeColumn(name,cellPath,aggregationMode){tr.ui.analysis.DetailsNumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
+EffectiveSizeColumn.prototype={__proto__:tr.ui.analysis.DetailsNumericMemoryColumn.prototype,get title(){return tr.ui.b.createLink({textContent:this.name,tooltip:'Memory used by this component',href:URL_TO_SIZE_VS_EFFECTIVE_SIZE});},addInfos(numerics,memoryAllocatorDumps,infos){if(memoryAllocatorDumps===undefined)return;const ownerNameToEntry=new Map();const ownedNameToEntry=new Map();for(let i=0;i<numerics.length;i++){if(numerics[i]===undefined)continue;const dump=memoryAllocatorDumps[i];if(dump===SUBALLOCATION_CONTEXT){return;}
+dump.ownedBy.forEach(function(ownerLink){const ownerDump=ownerLink.source;this.getAndUpdateOwnershipEntry_(ownerNameToEntry,ownerDump,ownerLink);},this);const ownedLink=dump.owns;if(ownedLink!==undefined){const ownedDump=ownedLink.target;const ownedEntry=this.getAndUpdateOwnershipEntry_(ownedNameToEntry,ownedDump,ownedLink,true);const sharerNameToEntry=ownedEntry.sharerNameToEntry;ownedDump.ownedBy.forEach(function(sharerLink){const sharerDump=sharerLink.source;if(sharerDump===dump)return;this.getAndUpdateOwnershipEntry_(sharerNameToEntry,sharerDump,sharerLink);},this);}}
+if(ownerNameToEntry.size>0){const messageBuilder=new SizeInfoMessageBuilder();messageBuilder.append('shared by');messageBuilder.appendMap(ownerNameToEntry,false,undefined,function(ownerName,ownerEntry){messageBuilder.append(ownerName);if(ownerEntry.count<numerics.length){messageBuilder.appendSomeTimestampsQuantifier();}
+messageBuilder.appendImportanceRange(ownerEntry.importanceRange);},this);infos.push({message:messageBuilder.build(),icon:LEFTWARDS_OPEN_HEADED_ARROW,color:'green'});}
+if(ownedNameToEntry.size>0){const messageBuilder=new SizeInfoMessageBuilder();messageBuilder.append('shares');messageBuilder.appendMap(ownedNameToEntry,false,undefined,function(ownedName,ownedEntry){messageBuilder.append(ownedName);const ownedCount=ownedEntry.count;if(ownedCount<numerics.length){messageBuilder.appendSomeTimestampsQuantifier();}
+messageBuilder.appendImportanceRange(ownedEntry.importanceRange);messageBuilder.append(' with');messageBuilder.appendMap(ownedEntry.sharerNameToEntry,false,' no other dumps',function(sharerName,sharerEntry){messageBuilder.append(sharerName);if(sharerEntry.count<ownedCount){messageBuilder.appendSomeTimestampsQuantifier();}
+messageBuilder.appendImportanceRange(sharerEntry.importanceRange);},this);},this);infos.push({message:messageBuilder.build(),icon:RIGHTWARDS_OPEN_HEADED_ARROW,color:'green'});}},getAndUpdateOwnershipEntry_(map,dump,link,opt_withSharerNameToEntry){const entry=getAndUpdateEntry(map,dump.quantifiedName,function(newEntry){newEntry.importanceRange=new tr.b.math.Range();if(opt_withSharerNameToEntry){newEntry.sharerNameToEntry=new Map();}});entry.importanceRange.addValue(link.importance||0);return entry;}};function SizeColumn(name,cellPath,aggregationMode){tr.ui.analysis.DetailsNumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
+SizeColumn.prototype={__proto__:tr.ui.analysis.DetailsNumericMemoryColumn.prototype,get title(){return tr.ui.b.createLink({textContent:this.name,tooltip:'Memory requested by this component',href:URL_TO_SIZE_VS_EFFECTIVE_SIZE});},addInfos(numerics,memoryAllocatorDumps,infos){if(memoryAllocatorDumps===undefined)return;this.addOverlapInfo_(numerics,memoryAllocatorDumps,infos);this.addProvidedSizeWarningInfos_(numerics,memoryAllocatorDumps,infos);},addOverlapInfo_(numerics,memoryAllocatorDumps,infos){const siblingNameToEntry=new Map();for(let i=0;i<numerics.length;i++){if(numerics[i]===undefined)continue;const dump=memoryAllocatorDumps[i];if(dump===SUBALLOCATION_CONTEXT){return;}
+const ownedBySiblingSizes=dump.ownedBySiblingSizes;for(const siblingDump of ownedBySiblingSizes.keys()){const siblingName=siblingDump.name;getAndUpdateEntry(siblingNameToEntry,siblingName,function(newEntry){if(numerics.length===1){newEntry.size=ownedBySiblingSizes.get(siblingDump);}});}}
+if(siblingNameToEntry.size>0){const messageBuilder=new SizeInfoMessageBuilder();messageBuilder.append('overlaps with its sibling');messageBuilder.appendMap(siblingNameToEntry,true,undefined,function(siblingName,siblingEntry){messageBuilder.append('\'',siblingName,'\'');messageBuilder.appendSizeIfDefined(siblingEntry.size);if(siblingEntry.count<numerics.length){messageBuilder.appendSomeTimestampsQuantifier();}},this);infos.push({message:messageBuilder.build(),icon:CIRCLED_LATIN_SMALL_LETTER_I,color:'blue'});}},addProvidedSizeWarningInfos_(numerics,memoryAllocatorDumps,infos){const infoTypeToEntry=new Map();for(let i=0;i<numerics.length;i++){if(numerics[i]===undefined)continue;const dump=memoryAllocatorDumps[i];if(dump===SUBALLOCATION_CONTEXT){return;}
+dump.infos.forEach(function(dumpInfo){getAndUpdateEntry(infoTypeToEntry,dumpInfo.type,function(newEntry){if(numerics.length===1){newEntry.providedSize=dumpInfo.providedSize;newEntry.dependencySize=dumpInfo.dependencySize;}});});}
+for(const infoType of infoTypeToEntry.keys()){const entry=infoTypeToEntry.get(infoType);const messageBuilder=new SizeInfoMessageBuilder();messageBuilder.append('provided size');messageBuilder.appendSizeIfDefined(entry.providedSize);let dependencyName;switch(infoType){case PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN:dependencyName='the aggregated size of the children';break;case PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER:dependencyName='the size of the largest owner';break;default:dependencyName='an unknown dependency';break;}
+messageBuilder.append(' was less than ',dependencyName);messageBuilder.appendSizeIfDefined(entry.dependencySize);if(entry.count<numerics.length){messageBuilder.appendSomeTimestampsQuantifier();}
+infos.push(tr.ui.analysis.createWarningInfo(messageBuilder.build()));}}};const NUMERIC_COLUMN_RULES=[{condition:tr.model.MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME,importance:10,columnConstructor:EffectiveSizeColumn},{condition:tr.model.MemoryAllocatorDump.SIZE_NUMERIC_NAME,importance:9,columnConstructor:SizeColumn},{condition:'page_size',importance:0,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:/size/,importance:5,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{importance:0,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn}];const DIAGNOSTIC_COLUMN_RULES=[{importance:0,columnConstructor:tr.ui.analysis.StringMemoryColumn}];Polymer({is:'tr-ui-a-memory-dump-allocator-details-pane',behaviors:[tr.ui.analysis.StackedPane],created(){this.memoryAllocatorDumps_=undefined;this.heapDumps_=undefined;this.aggregationMode_=undefined;},ready(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;},set memoryAllocatorDumps(memoryAllocatorDumps){this.memoryAllocatorDumps_=memoryAllocatorDumps;this.scheduleRebuild_();},get memoryAllocatorDumps(){return this.memoryAllocatorDumps_;},set heapDumps(heapDumps){this.heapDumps_=heapDumps;this.scheduleRebuild_();},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuild_();},get aggregationMode(){return this.aggregationMode_;},onRebuild_(){if(this.memoryAllocatorDumps_===undefined||this.memoryAllocatorDumps_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.table.clear();this.$.table.rebuild();this.childPaneBuilder=undefined;return;}
+this.$.info_text.style.display='none';this.$.table.style.display='block';const rows=this.createRows_();const columns=this.createColumns_(rows);rows.forEach(function(rootRow){tr.ui.analysis.aggregateTableRowCellsRecursively(rootRow,columns,function(contexts){return contexts!==undefined&&contexts.some(function(context){return context===SUBALLOCATION_CONTEXT;});});});this.$.table.tableRows=rows;this.$.table.tableColumns=columns;this.$.table.rebuild();tr.ui.analysis.expandTableRowsRecursively(this.$.table);if(this.heapDumps_===undefined){this.childPaneBuilder=undefined;}else{this.childPaneBuilder=function(){const pane=document.createElement('tr-ui-a-memory-dump-heap-details-pane');pane.heapDumps=this.heapDumps_;pane.aggregationMode=this.aggregationMode_;return pane;}.bind(this);}},createRows_(){return[this.createAllocatorRowRecursively_(this.memoryAllocatorDumps_)];},createAllocatorRowRecursively_(dumps){const definedDump=dumps.find(x=>x);const title=definedDump.name;const fullName=definedDump.fullName;const numericCells=tr.ui.analysis.createCells(dumps,function(dump){return dump.numerics;});const diagnosticCells=tr.ui.analysis.createCells(dumps,function(dump){return dump.diagnostics;});let suballocatedBy=undefined;if(title.startsWith('__')){for(let i=0;i<dumps.length;i++){const dump=dumps[i];if(dump===undefined||dump.ownedBy.length===0){continue;}
+const ownerDump=dump.ownedBy[0].source;if(dump.ownedBy.length>1||dump.children.length>0||ownerDump.containerMemoryDump!==dump.containerMemoryDump){suballocatedBy=undefined;break;}
 if(suballocatedBy===undefined){suballocatedBy=ownerDump.fullName;}else if(suballocatedBy!==ownerDump.fullName){suballocatedBy=undefined;break;}}}
-var row={title:title,fullNames:[fullName],contexts:dumps,numericCells:numericCells,diagnosticCells:diagnosticCells,suballocatedBy:suballocatedBy};var childDumpNameToDumps=tr.b.invertArrayOfDicts(dumps,function(dump){return tr.b.arrayToDict(dump.children,function(child){return child.name;});});var subRows=[];var suballocationClassificationRootNode=undefined;tr.b.iterItems(childDumpNameToDumps,function(childName,childDumps){var childRow=this.createAllocatorRowRecursively_(childDumps);if(childRow.suballocatedBy===undefined){subRows.push(childRow);}else{suballocationClassificationRootNode=this.classifySuballocationRow_(childRow,suballocationClassificationRootNode);}},this);if(suballocationClassificationRootNode!==undefined){var suballocationRow=this.createSuballocationRowRecursively_('suballocations',suballocationClassificationRootNode);subRows.push(suballocationRow);}
-if(subRows.length>0)
-row.subRows=subRows;return row;},classifySuballocationRow_:function(suballocationRow,rootNode){if(rootNode===undefined){rootNode={children:{},row:undefined};}
-var suballocationLevels=suballocationRow.suballocatedBy.split('/');var currentNode=rootNode;for(var i=0;i<suballocationLevels.length;i++){var suballocationLevel=suballocationLevels[i];var nextNode=currentNode.children[suballocationLevel];if(nextNode===undefined){currentNode.children[suballocationLevel]=nextNode={children:{},row:undefined};}
-var currentNode=nextNode;}
-var existingRow=currentNode.row;if(existingRow!==undefined){for(var i=0;i<suballocationRow.contexts.length;i++){var newContext=suballocationRow.contexts[i];if(newContext===undefined)
-continue;if(existingRow.contexts[i]!==undefined)
-throw new Error('Multiple suballocations with the same owner name');existingRow.contexts[i]=newContext;['numericCells','diagnosticCells'].forEach(function(cellKey){var suballocationCells=suballocationRow[cellKey];if(suballocationCells===undefined)
-return;tr.b.iterItems(suballocationCells,function(cellName,cell){if(cell===undefined)
-return;var fields=cell.fields;if(fields===undefined)
-return;var field=fields[i];if(field===undefined)
-return;var existingCells=existingRow[cellKey];if(existingCells===undefined){existingCells={};existingRow[cellKey]=existingCells;}
-var existingCell=existingCells[cellName];if(existingCell===undefined){existingCell=new tr.ui.analysis.MemoryCell(new Array(fields.length));existingCells[cellName]=existingCell;}
-existingCell.fields[i]=field;});});}
+const row={title,fullNames:[fullName],contexts:dumps,numericCells,diagnosticCells,suballocatedBy};const childDumpNameToDumps=tr.b.invertArrayOfDicts(dumps,function(dump){const results={};for(const child of dump.children){results[child.name]=child;}
+return results;});const subRows=[];let suballocationClassificationRootNode=undefined;for(const childDumps of Object.values(childDumpNameToDumps)){const childRow=this.createAllocatorRowRecursively_(childDumps);if(childRow.suballocatedBy===undefined){subRows.push(childRow);}else{suballocationClassificationRootNode=this.classifySuballocationRow_(childRow,suballocationClassificationRootNode);}}
+if(suballocationClassificationRootNode!==undefined){const suballocationRow=this.createSuballocationRowRecursively_('suballocations',suballocationClassificationRootNode);subRows.push(suballocationRow);}
+if(subRows.length>0){row.subRows=subRows;}
+return row;},classifySuballocationRow_(suballocationRow,rootNode){if(rootNode===undefined){rootNode={children:{},row:undefined};}
+const suballocationLevels=suballocationRow.suballocatedBy.split('/');let currentNode=rootNode;for(let i=0;i<suballocationLevels.length;i++){const suballocationLevel=suballocationLevels[i];let nextNode=currentNode.children[suballocationLevel];if(nextNode===undefined){currentNode.children[suballocationLevel]=nextNode={children:{},row:undefined};}
+currentNode=nextNode;}
+const existingRow=currentNode.row;if(existingRow!==undefined){for(let i=0;i<suballocationRow.contexts.length;i++){const newContext=suballocationRow.contexts[i];if(newContext===undefined)continue;if(existingRow.contexts[i]!==undefined){throw new Error('Multiple suballocations with the same owner name');}
+existingRow.contexts[i]=newContext;['numericCells','diagnosticCells'].forEach(function(cellKey){const suballocationCells=suballocationRow[cellKey];if(suballocationCells===undefined)return;for(const[cellName,cell]of Object.entries(suballocationCells)){if(cell===undefined)continue;const fields=cell.fields;if(fields===undefined)continue;const field=fields[i];if(field===undefined)continue;let existingCells=existingRow[cellKey];if(existingCells===undefined){existingCells={};existingRow[cellKey]=existingCells;}
+let existingCell=existingCells[cellName];if(existingCell===undefined){existingCell=new tr.ui.analysis.MemoryCell(new Array(fields.length));existingCells[cellName]=existingCell;}
+existingCell.fields[i]=field;}});}
 existingRow.fullNames.push.apply(existingRow.fullNames,suballocationRow.fullNames);}else{currentNode.row=suballocationRow;}
-return rootNode;},createSuballocationRowRecursively_:function(name,node){var childCount=Object.keys(node.children).length;if(childCount===0){if(node.row===undefined)
-throw new Error('Suballocation node must have a row or children');var row=node.row;row.title=name;row.suballocation=true;return row;}
-var subRows=tr.b.dictionaryValues(tr.b.mapItems(node.children,this.createSuballocationRowRecursively_,this));if(node.row!==undefined){var row=node.row;row.title='<unspecified>';row.suballocation=true;subRows.unshift(row);}
-var contexts=new Array(subRows[0].contexts.length);for(var i=0;i<subRows.length;i++){subRows[i].contexts.forEach(function(subContext,index){if(subContext!==undefined)
-contexts[index]=SUBALLOCATION_CONTEXT;});}
-return{title:name,suballocation:true,contexts:contexts,subRows:subRows};},createColumns_:function(rows){var titleColumn=new AllocatorDumpNameColumn();titleColumn.width='200px';var numericColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'numericCells',this.aggregationMode_,NUMERIC_COLUMN_RULES);var diagnosticColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'diagnosticCells',this.aggregationMode_,DIAGNOSTIC_COLUMN_RULES);var fieldColumns=numericColumns.concat(diagnosticColumns);tr.ui.analysis.MemoryColumn.spaceEqually(fieldColumns);var columns=[titleColumn].concat(fieldColumns);return columns;}});return{SUBALLOCATION_CONTEXT:SUBALLOCATION_CONTEXT,AllocatorDumpNameColumn:AllocatorDumpNameColumn,EffectiveSizeColumn:EffectiveSizeColumn,SizeColumn:SizeColumn};});'use strict';tr.exportTo('tr.ui.analysis',function(){var ScalarNumeric=tr.v.ScalarNumeric;var sizeInBytes_smallerIsBetter=tr.v.Unit.byName.sizeInBytes_smallerIsBetter;var CONSTANT_COLUMN_RULES=[{condition:'Start address',importance:0,columnConstructor:tr.ui.analysis.StringMemoryColumn}];var VARIABLE_COLUMN_RULES=[{condition:'Virtual size',importance:7,columnConstructor:tr.ui.analysis.NumericMemoryColumn},{condition:'Protection flags',importance:6,columnConstructor:tr.ui.analysis.StringMemoryColumn},{condition:'PSS',importance:5,columnConstructor:tr.ui.analysis.NumericMemoryColumn},{condition:'Private dirty',importance:4,columnConstructor:tr.ui.analysis.NumericMemoryColumn},{condition:'Private clean',importance:3,columnConstructor:tr.ui.analysis.NumericMemoryColumn},{condition:'Shared dirty',importance:2,columnConstructor:tr.ui.analysis.NumericMemoryColumn},{condition:'Shared clean',importance:1,columnConstructor:tr.ui.analysis.NumericMemoryColumn},{condition:'Swapped',importance:0,columnConstructor:tr.ui.analysis.NumericMemoryColumn}];var BYTE_STAT_COLUMN_MAP={'proportionalResident':'PSS','privateDirtyResident':'Private dirty','privateCleanResident':'Private clean','sharedDirtyResident':'Shared dirty','sharedCleanResident':'Shared clean','swapped':'Swapped'};function hexString(address,is64BitAddress){if(address===undefined)
-return undefined;var hexPadding=is64BitAddress?'0000000000000000':'00000000';return(hexPadding+address.toString(16)).substr(-hexPadding.length);}
-function pruneEmptyRuleRows(row){if(row.subRows===undefined||row.subRows.length===0)
-return;if(row.subRows[0].rule===undefined){return;}
+return rootNode;},createSuballocationRowRecursively_(name,node){const childCount=Object.keys(node.children).length;if(childCount===0){if(node.row===undefined){throw new Error('Suballocation node must have a row or children');}
+const row=node.row;row.title=name;row.suballocation=true;return row;}
+const subRows=[];for(const[subName,subNode]of Object.entries(node.children)){subRows.push(this.createSuballocationRowRecursively_(subName,subNode));}
+if(node.row!==undefined){const row=node.row;row.title='<unspecified>';row.suballocation=true;subRows.unshift(row);}
+const contexts=new Array(subRows[0].contexts.length);for(let i=0;i<subRows.length;i++){subRows[i].contexts.forEach(function(subContext,index){if(subContext!==undefined){contexts[index]=SUBALLOCATION_CONTEXT;}});}
+return{title:name,suballocation:true,contexts,subRows};},createColumns_(rows){const titleColumn=new AllocatorDumpNameColumn();titleColumn.width='200px';const numericColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'numericCells',aggregationMode:this.aggregationMode_,rules:NUMERIC_COLUMN_RULES});const diagnosticColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'diagnosticCells',aggregationMode:this.aggregationMode_,rules:DIAGNOSTIC_COLUMN_RULES});const fieldColumns=numericColumns.concat(diagnosticColumns);tr.ui.analysis.MemoryColumn.spaceEqually(fieldColumns);const columns=[titleColumn].concat(fieldColumns);return columns;}});return{SUBALLOCATION_CONTEXT,AllocatorDumpNameColumn,EffectiveSizeColumn,SizeColumn,};});'use strict';tr.exportTo('tr.ui.analysis',function(){const Scalar=tr.b.Scalar;const sizeInBytes_smallerIsBetter=tr.b.Unit.byName.sizeInBytes_smallerIsBetter;const CONSTANT_COLUMN_RULES=[{condition:'Start address',importance:0,columnConstructor:tr.ui.analysis.StringMemoryColumn}];const VARIABLE_COLUMN_RULES=[{condition:'Virtual size',importance:7,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:'Protection flags',importance:6,columnConstructor:tr.ui.analysis.StringMemoryColumn},{condition:'PSS',importance:5,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:'Private dirty',importance:4,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:'Private clean',importance:3,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:'Shared dirty',importance:2,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:'Shared clean',importance:1,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:'Swapped',importance:0,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn}];const BYTE_STAT_COLUMN_MAP={'proportionalResident':'PSS','privateDirtyResident':'Private dirty','privateCleanResident':'Private clean','sharedDirtyResident':'Shared dirty','sharedCleanResident':'Shared clean','swapped':'Swapped'};function hexString(address,is64BitAddress){if(address===undefined)return undefined;const hexPadding=is64BitAddress?'0000000000000000':'00000000';return(hexPadding+address.toString(16)).substr(-hexPadding.length);}
+function pruneEmptyRuleRows(row){if(row.subRows===undefined||row.subRows.length===0)return;if(row.subRows[0].rule===undefined){return;}
 row.subRows.forEach(pruneEmptyRuleRows);row.subRows=row.subRows.filter(function(subRow){return subRow.subRows.length>0;});}
-Polymer('tr-ui-a-memory-dump-vm-regions-details-pane',{created:function(){this.vmRegions_=undefined;this.aggregationMode_=undefined;},ready:function(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;},set vmRegions(vmRegions){this.vmRegions_=vmRegions;this.scheduleRebuildPane_();},get vmRegions(){return this.vmRegions_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuildPane_();},get aggregationMode(){return this.aggregationMode_;},rebuildPane_:function(){if(this.vmRegions_===undefined||this.vmRegions_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.table.clear();this.$.table.rebuild();return;}
-this.$.info_text.style.display='none';this.$.table.style.display='block';var rows=this.createRows_(this.vmRegions_);var columns=this.createColumns_(rows);this.$.table.tableRows=rows;this.$.table.tableColumns=columns;this.$.table.rebuild();tr.ui.analysis.expandTableRowsRecursively(this.$.table);},createRows_:function(timeToVmRegionTree){var is64BitAddress=timeToVmRegionTree.some(function(vmRegionTree){if(vmRegionTree===undefined)
-return false;return vmRegionTree.someRegion(function(region){if(region.startAddress===undefined)
-return false;return region.startAddress>=4294967296;});});return[this.createClassificationNodeRow(timeToVmRegionTree,is64BitAddress)];},createClassificationNodeRow:function(timeToNode,is64BitAddress){var definedNode=tr.b.findFirstInArray(timeToNode);var childNodeIdToTimeToNode=tr.b.dictionaryValues(tr.b.invertArrayOfDicts(timeToNode,function(node){var children=node.children;if(children===undefined)
-return undefined;var childMap={};children.forEach(function(childNode){if(!childNode.hasRegions)
-return;childMap[childNode.title]=childNode;});return childMap;}));var childNodeSubRows=childNodeIdToTimeToNode.map(function(timeToChildNode){return this.createClassificationNodeRow(timeToChildNode,is64BitAddress);},this);var regionIdToTimeToRegion=tr.b.dictionaryValues(tr.b.invertArrayOfDicts(timeToNode,function(node){var regions=node.regions;if(regions===undefined)
-return undefined;return tr.b.arrayToDict(regions,function(region){return region.uniqueIdWithinProcess;});}));var regionSubRows=regionIdToTimeToRegion.map(function(timeToRegion){return this.createRegionRow_(timeToRegion,is64BitAddress);},this);var subRows=childNodeSubRows.concat(regionSubRows);return{title:definedNode.title,contexts:timeToNode,variableCells:this.createVariableCells_(timeToNode),subRows:subRows};},createRegionRow_:function(timeToRegion,is64BitAddress){var definedRegion=tr.b.findFirstInArray(timeToRegion);return{title:definedRegion.mappedFile,contexts:timeToRegion,constantCells:this.createConstantCells_(definedRegion,is64BitAddress),variableCells:this.createVariableCells_(timeToRegion)};},createConstantCells_:function(definedRegion,is64BitAddress){return tr.ui.analysis.createCells([definedRegion],function(region){var startAddress=region.startAddress;if(startAddress===undefined)
-return undefined;return{'Start address':hexString(startAddress,is64BitAddress)};});},createVariableCells_:function(timeToRegion){return tr.ui.analysis.createCells(timeToRegion,function(region){var fields={};var sizeInBytes=region.sizeInBytes;if(sizeInBytes!==undefined){fields['Virtual size']=new ScalarNumeric(sizeInBytes_smallerIsBetter,sizeInBytes);}
-var protectionFlags=region.protectionFlagsToString;if(protectionFlags!==undefined)
-fields['Protection flags']=protectionFlags;tr.b.iterItems(BYTE_STAT_COLUMN_MAP,function(byteStatName,columnName){var byteStat=region.byteStats[byteStatName];if(byteStat===undefined)
-return;fields[columnName]=new ScalarNumeric(sizeInBytes_smallerIsBetter,byteStat);});return fields;});},createColumns_:function(rows){var titleColumn=new tr.ui.analysis.TitleColumn('Mapped file');titleColumn.width='200px';var constantColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'constantCells',undefined,CONSTANT_COLUMN_RULES);var variableColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'variableCells',this.aggregationMode_,VARIABLE_COLUMN_RULES);var fieldColumns=constantColumns.concat(variableColumns);tr.ui.analysis.MemoryColumn.spaceEqually(fieldColumns);var columns=[titleColumn].concat(fieldColumns);return columns;}});return{};});'use strict';Polymer('tr-ui-b-color-legend',{ready:function(){var blackSquareCharCode=9632;this.$.square.innerText=String.fromCharCode(blackSquareCharCode);this.label_=undefined;this.compoundEventSelectionState_=tr.model.CompoundEventSelectionState.NOT_SELECTED;},set compoundEventSelectionState(compoundEventSelectionState){this.compoundEventSelectionState_=compoundEventSelectionState;},get label(){return this.label_;},set label(label){if(label===undefined){this.setLabelAndColorId(undefined,undefined);return;}
-var colorId=tr.b.ColorScheme.getColorIdForGeneralPurposeString(label);this.setLabelAndColorId(label,colorId);},setLabelAndColorId:function(label,colorId){this.label_=label;this.$.label.textContent='';this.$.label.appendChild(tr.ui.b.asHTMLOrTextNode(label));if(colorId===undefined)
-this.$.square.style.color='initial';else
-this.$.square.style.color=tr.b.ColorScheme.colorsAsStrings[colorId];}});'use strict';Polymer('tr-ui-b-view-specific-brushing-state',{get viewId(){return this.getAttribute('view-id');},set viewId(viewId){this.setAttribute('view-id',viewId);},get:function(){var viewId=this.viewId;if(!viewId)
-throw new Error('Element must have a view-id attribute!');var brushingStateController=tr.c.BrushingStateController.getControllerForElement(this);if(!brushingStateController)
-return undefined;return brushingStateController.getViewSpecificBrushingState(viewId);},set:function(state){var viewId=this.viewId;if(!viewId)
-throw new Error('Element must have a view-id attribute!');var brushingStateController=tr.c.BrushingStateController.getControllerForElement(this);if(!brushingStateController)
-return;brushingStateController.changeViewSpecificBrushingState(viewId,state);}});'use strict';tr.exportTo('tr.ui.analysis',function(){var ColorScheme=tr.b.ColorScheme;var ScalarNumeric=tr.v.ScalarNumeric;var sizeInBytes_smallerIsBetter=tr.v.Unit.byName.sizeInBytes_smallerIsBetter;var PLATFORM_SPECIFIC_TOTAL_NAME_SUFFIX='_bytes';var DISPLAYED_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.DISPLAYED_SIZE_NUMERIC_NAME;var SOME_TIMESTAMPS_INFO_QUANTIFIER=tr.ui.analysis.MemoryColumn.SOME_TIMESTAMPS_INFO_QUANTIFIER;var RIGHTWARDS_ARROW_WITH_HOOK=String.fromCharCode(0x21AA);var RIGHTWARDS_ARROW_FROM_BAR=String.fromCharCode(0x21A6);var GREATER_THAN_OR_EQUAL_TO=String.fromCharCode(0x2265);var UNMARRIED_PARTNERSHIP_SYMBOL=String.fromCharCode(0x26AF);var TRIGRAM_FOR_HEAVEN=String.fromCharCode(0x2630);function lazyMap(list,fn,opt_this){opt_this=opt_this||this;var result=undefined;list.forEach(function(item,index){var value=fn.call(opt_this,item,index);if(value===undefined)
-return;if(result===undefined)
-result=new Array(list.length);result[index]=value;});return result;}
+Polymer({is:'tr-ui-a-memory-dump-vm-regions-details-pane',behaviors:[tr.ui.analysis.StackedPane],created(){this.vmRegions_=undefined;this.aggregationMode_=undefined;},ready(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;},set vmRegions(vmRegions){this.vmRegions_=vmRegions;this.scheduleRebuild_();},get vmRegions(){return this.vmRegions_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuild_();},get aggregationMode(){return this.aggregationMode_;},onRebuild_(){if(this.vmRegions_===undefined||this.vmRegions_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.table.clear();this.$.table.rebuild();return;}
+this.$.info_text.style.display='none';this.$.table.style.display='block';const rows=this.createRows_(this.vmRegions_);const columns=this.createColumns_(rows);this.$.table.tableRows=rows;this.$.table.tableColumns=columns;this.$.table.rebuild();tr.ui.analysis.expandTableRowsRecursively(this.$.table);},createRows_(timeToVmRegionTree){const is64BitAddress=timeToVmRegionTree.some(function(vmRegionTree){if(vmRegionTree===undefined)return false;return vmRegionTree.someRegion(function(region){if(region.startAddress===undefined)return false;return region.startAddress>=4294967296;});});return[this.createClassificationNodeRow(timeToVmRegionTree,is64BitAddress)];},createClassificationNodeRow(timeToNode,is64BitAddress){const definedNode=timeToNode.find(x=>x);const childNodeIdToTimeToNode=Object.values(tr.b.invertArrayOfDicts(timeToNode,function(node){const children=node.children;if(children===undefined)return undefined;const childMap={};children.forEach(function(childNode){if(!childNode.hasRegions)return;childMap[childNode.title]=childNode;});return childMap;}));const childNodeSubRows=childNodeIdToTimeToNode.map(function(timeToChildNode){return this.createClassificationNodeRow(timeToChildNode,is64BitAddress);},this);const regionIdToTimeToRegion=Object.values(tr.b.invertArrayOfDicts(timeToNode,function(node){const regions=node.regions;if(regions===undefined)return undefined;const results={};for(const region of regions){results[region.uniqueIdWithinProcess]=region;}
+return results;}));const regionSubRows=regionIdToTimeToRegion.map(function(timeToRegion){return this.createRegionRow_(timeToRegion,is64BitAddress);},this);const subRows=childNodeSubRows.concat(regionSubRows);return{title:definedNode.title,contexts:timeToNode,variableCells:this.createVariableCells_(timeToNode),subRows};},createRegionRow_(timeToRegion,is64BitAddress){const definedRegion=timeToRegion.find(x=>x);return{title:definedRegion.mappedFile,contexts:timeToRegion,constantCells:this.createConstantCells_(definedRegion,is64BitAddress),variableCells:this.createVariableCells_(timeToRegion)};},createConstantCells_(definedRegion,is64BitAddress){return tr.ui.analysis.createCells([definedRegion],function(region){const startAddress=region.startAddress;if(startAddress===undefined)return undefined;return{'Start address':hexString(startAddress,is64BitAddress)};});},createVariableCells_(timeToRegion){return tr.ui.analysis.createCells(timeToRegion,function(region){const fields={};const sizeInBytes=region.sizeInBytes;if(sizeInBytes!==undefined){fields['Virtual size']=new Scalar(sizeInBytes_smallerIsBetter,sizeInBytes);}
+const protectionFlags=region.protectionFlagsToString;if(protectionFlags!==undefined){fields['Protection flags']=protectionFlags;}
+for(const[byteStatName,columnName]of
+Object.entries(BYTE_STAT_COLUMN_MAP)){const byteStat=region.byteStats[byteStatName];if(byteStat===undefined)continue;fields[columnName]=new Scalar(sizeInBytes_smallerIsBetter,byteStat);}
+return fields;});},createColumns_(rows){const titleColumn=new tr.ui.analysis.TitleColumn('Mapped file');titleColumn.width='200px';const constantColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'constantCells',aggregationMode:undefined,rules:CONSTANT_COLUMN_RULES});const variableColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'variableCells',aggregationMode:this.aggregationMode_,rules:VARIABLE_COLUMN_RULES});const fieldColumns=constantColumns.concat(variableColumns);tr.ui.analysis.MemoryColumn.spaceEqually(fieldColumns);const columns=[titleColumn].concat(fieldColumns);return columns;}});return{};});'use strict';Polymer({is:'tr-ui-b-color-legend',ready(){const blackSquareCharCode=9632;this.$.square.innerText=String.fromCharCode(blackSquareCharCode);this.label_=undefined;this.compoundEventSelectionState_=tr.model.CompoundEventSelectionState.NOT_SELECTED;},set compoundEventSelectionState(compoundEventSelectionState){this.compoundEventSelectionState_=compoundEventSelectionState;},get label(){return this.label_;},set label(label){if(label===undefined){this.setLabelAndColorId(undefined,undefined);return;}
+const colorId=tr.b.ColorScheme.getColorIdForGeneralPurposeString(label);this.setLabelAndColorId(label,colorId);},setLabelAndColorId(label,colorId){this.label_=label;Polymer.dom(this.$.label).textContent='';Polymer.dom(this.$.label).appendChild(tr.ui.b.asHTMLOrTextNode(label));if(colorId===undefined){this.$.square.style.color='initial';}else{this.$.square.style.color=tr.b.ColorScheme.colorsAsStrings[colorId];}}});'use strict';Polymer({is:'tr-ui-b-view-specific-brushing-state',get viewId(){return this.getAttribute('view-id');},set viewId(viewId){Polymer.dom(this).setAttribute('view-id',viewId);},get(){const viewId=this.viewId;if(!viewId){throw new Error('Element must have a view-id attribute!');}
+const brushingStateController=tr.c.BrushingStateController.getControllerForElement(this);if(!brushingStateController)return undefined;return brushingStateController.getViewSpecificBrushingState(viewId);},set(state){const viewId=this.viewId;if(!viewId){throw new Error('Element must have a view-id attribute!');}
+const brushingStateController=tr.c.BrushingStateController.getControllerForElement(this);if(!brushingStateController)return;brushingStateController.changeViewSpecificBrushingState(viewId,state);}});'use strict';tr.exportTo('tr.ui.analysis',function(){const MemoryColumnColorScheme=tr.b.MemoryColumnColorScheme;const Scalar=tr.b.Scalar;const sizeInBytes_smallerIsBetter=tr.b.Unit.byName.sizeInBytes_smallerIsBetter;const PLATFORM_SPECIFIC_TOTAL_NAME_SUFFIX='_bytes';const DISPLAYED_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.DISPLAYED_SIZE_NUMERIC_NAME;const SOME_TIMESTAMPS_INFO_QUANTIFIER=tr.ui.analysis.MemoryColumn.SOME_TIMESTAMPS_INFO_QUANTIFIER;const RIGHTWARDS_ARROW_WITH_HOOK=String.fromCharCode(0x21AA);const RIGHTWARDS_ARROW_FROM_BAR=String.fromCharCode(0x21A6);const GREATER_THAN_OR_EQUAL_TO=String.fromCharCode(0x2265);const UNMARRIED_PARTNERSHIP_SYMBOL=String.fromCharCode(0x26AF);const TRIGRAM_FOR_HEAVEN=String.fromCharCode(0x2630);function lazyMap(list,fn,opt_this){opt_this=opt_this||this;let result=undefined;list.forEach(function(item,index){const value=fn.call(opt_this,item,index);if(value===undefined)return;if(result===undefined){result=new Array(list.length);}
+result[index]=value;});return result;}
 function ProcessNameColumn(){tr.ui.analysis.TitleColumn.call(this,'Process');}
-ProcessNameColumn.prototype={__proto__:tr.ui.analysis.TitleColumn.prototype,formatTitle:function(row){if(row.contexts===undefined)
-return row.title;var titleEl=document.createElement('tr-ui-b-color-legend');titleEl.label=row.title;return titleEl;}};function UsedMemoryColumn(name,cellPath,aggregationMode){tr.ui.analysis.NumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
-UsedMemoryColumn.COLOR=ColorScheme.getColorForReservedNameAsString('used_memory_column');UsedMemoryColumn.OLDER_COLOR=ColorScheme.getColorForReservedNameAsString('older_used_memory_column');UsedMemoryColumn.prototype={__proto__:tr.ui.analysis.NumericMemoryColumn.prototype,get title(){return tr.ui.b.createSpan({textContent:this.name,color:UsedMemoryColumn.COLOR});},color:function(numerics,processMemoryDumps){return UsedMemoryColumn.COLOR;},getChildPaneBuilder:function(processMemoryDumps){if(processMemoryDumps===undefined)
-return undefined;var vmRegions=lazyMap(processMemoryDumps,function(pmd){if(pmd===undefined)
-return undefined;return pmd.mostRecentVmRegions;});if(vmRegions===undefined)
-return undefined;return function(){var pane=document.createElement('tr-ui-a-memory-dump-vm-regions-details-pane');pane.vmRegions=vmRegions;pane.aggregationMode=this.aggregationMode;return pane;}.bind(this);}};function PeakMemoryColumn(name,cellPath,aggregationMode){UsedMemoryColumn.call(this,name,cellPath,aggregationMode);}
-PeakMemoryColumn.prototype={__proto__:UsedMemoryColumn.prototype,addInfos:function(numerics,processMemoryDumps,infos){if(processMemoryDumps===undefined)
-return;var resettableValueCount=0;var nonResettableValueCount=0;for(var i=0;i<numerics.length;i++){if(numerics[i]===undefined)
-continue;if(processMemoryDumps[i].arePeakResidentBytesResettable)
-resettableValueCount++;else
-nonResettableValueCount++;}
+ProcessNameColumn.prototype={__proto__:tr.ui.analysis.TitleColumn.prototype,formatTitle(row){if(row.contexts===undefined){return row.title;}
+const titleEl=document.createElement('tr-ui-b-color-legend');titleEl.label=row.title;return titleEl;}};function UsedMemoryColumn(name,cellPath,aggregationMode){tr.ui.analysis.NumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
+UsedMemoryColumn.COLOR=MemoryColumnColorScheme.getColor('used_memory_column').toString();UsedMemoryColumn.OLDER_COLOR=MemoryColumnColorScheme.getColor('older_used_memory_column').toString();UsedMemoryColumn.prototype={__proto__:tr.ui.analysis.NumericMemoryColumn.prototype,get title(){return tr.ui.b.createSpan({textContent:this.name,color:UsedMemoryColumn.COLOR});},getFormattingContext(unit){return{unitPrefix:tr.b.UnitPrefixScale.BINARY.MEBI};},color(numerics,processMemoryDumps){return UsedMemoryColumn.COLOR;},getChildPaneBuilder(processMemoryDumps){if(processMemoryDumps===undefined)return undefined;const vmRegions=lazyMap(processMemoryDumps,function(pmd){if(pmd===undefined)return undefined;return pmd.mostRecentVmRegions;});if(vmRegions===undefined)return undefined;return function(){const pane=document.createElement('tr-ui-a-memory-dump-vm-regions-details-pane');pane.vmRegions=vmRegions;pane.aggregationMode=this.aggregationMode;return pane;}.bind(this);}};function PeakMemoryColumn(name,cellPath,aggregationMode){UsedMemoryColumn.call(this,name,cellPath,aggregationMode);}
+PeakMemoryColumn.prototype={__proto__:UsedMemoryColumn.prototype,addInfos(numerics,processMemoryDumps,infos){if(processMemoryDumps===undefined)return;let resettableValueCount=0;let nonResettableValueCount=0;for(let i=0;i<numerics.length;i++){if(numerics[i]===undefined)continue;if(processMemoryDumps[i].arePeakResidentBytesResettable){resettableValueCount++;}else{nonResettableValueCount++;}}
 if(resettableValueCount>0&&nonResettableValueCount>0){infos.push(tr.ui.analysis.createWarningInfo('Both resettable and '+'non-resettable peak RSS values were provided by the process'));}else if(resettableValueCount>0){infos.push({icon:RIGHTWARDS_ARROW_WITH_HOOK,message:'Peak RSS since previous memory dump.'});}else{infos.push({icon:RIGHTWARDS_ARROW_FROM_BAR,message:'Peak RSS since process startup. Finer grained '+'peaks require a Linux kernel version '+
 GREATER_THAN_OR_EQUAL_TO+' 4.0.'});}}};function ByteStatColumn(name,cellPath,aggregationMode){UsedMemoryColumn.call(this,name,cellPath,aggregationMode);}
-ByteStatColumn.prototype={__proto__:UsedMemoryColumn.prototype,color:function(numerics,processMemoryDumps){if(processMemoryDumps===undefined)
-return UsedMemoryColumn.COLOR;var allOlderValues=processMemoryDumps.every(function(processMemoryDump){if(processMemoryDump===undefined)
-return true;return!processMemoryDump.hasOwnVmRegions;});if(allOlderValues)
-return UsedMemoryColumn.OLDER_COLOR;else
-return UsedMemoryColumn.COLOR;},addInfos:function(numerics,processMemoryDumps,infos){if(processMemoryDumps===undefined)
-return;var olderValueCount=0;for(var i=0;i<numerics.length;i++){var processMemoryDump=processMemoryDumps[i];if(processMemoryDump!==undefined&&!processMemoryDump.hasOwnVmRegions){olderValueCount++;}}
-if(olderValueCount===0)
-return;var infoQuantifier=olderValueCount<numerics.length?' '+SOME_TIMESTAMPS_INFO_QUANTIFIER:'';infos.push({message:'Older value'+infoQuantifier+' (only heavy (purple) memory dumps contain memory maps).',icon:UNMARRIED_PARTNERSHIP_SYMBOL});}};UsedMemoryColumn.RULES=[{condition:'Total resident',importance:10,columnConstructor:UsedMemoryColumn},{condition:'Peak total resident',importance:9,columnConstructor:PeakMemoryColumn},{condition:'PSS',importance:8,columnConstructor:ByteStatColumn},{condition:'Private dirty',importance:7,columnConstructor:ByteStatColumn},{condition:'Swapped',importance:6,columnConstructor:ByteStatColumn},{importance:0,columnConstructor:UsedMemoryColumn}];UsedMemoryColumn.TOTALS_MAP={'residentBytes':'Total resident','peakResidentBytes':'Peak total resident'};UsedMemoryColumn.BYTE_STAT_MAP={'proportionalResident':'PSS','privateDirtyResident':'Private dirty','swapped':'Swapped'};function AllocatorColumn(name,cellPath,aggregationMode){tr.ui.analysis.NumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
-AllocatorColumn.prototype={__proto__:tr.ui.analysis.NumericMemoryColumn.prototype,get title(){var titleEl=document.createElement('tr-ui-b-color-legend');titleEl.label=this.name;return titleEl;},addInfos:function(numerics,processMemoryDumps,infos){if(processMemoryDumps===undefined)
-return;var heapDumpCount=0;for(var i=0;i<processMemoryDumps.length;i++){var processMemoryDump=processMemoryDumps[i];if(processMemoryDump===undefined)
-continue;var heapDumps=processMemoryDump.heapDumps;if(heapDumps===undefined)
-continue;if(heapDumps[this.name]!==undefined)
-heapDumpCount++;}
-if(heapDumpCount===0)
-return;var infoQuantifier=heapDumpCount<numerics.length?' '+SOME_TIMESTAMPS_INFO_QUANTIFIER:'';infos.push({message:'Heap dump provided'+infoQuantifier+'.',icon:TRIGRAM_FOR_HEAVEN});},getChildPaneBuilder:function(processMemoryDumps){if(processMemoryDumps===undefined)
-return undefined;var memoryAllocatorDumps=lazyMap(processMemoryDumps,function(pmd){if(pmd===undefined)
-return undefined;return pmd.getMemoryAllocatorDumpByFullName(this.name);},this);if(memoryAllocatorDumps===undefined)
-return undefined;var heapDumps=lazyMap(processMemoryDumps,function(pmd){if(pmd===undefined||pmd.heapDumps===undefined)
-return undefined;return pmd.heapDumps[this.name];},this);return function(){var pane=document.createElement('tr-ui-a-memory-dump-allocator-details-pane');pane.memoryAllocatorDumps=memoryAllocatorDumps;pane.heapDumps=heapDumps;pane.aggregationMode=this.aggregationMode;return pane;}.bind(this);}};function TracingColumn(name,cellPath,aggregationMode){AllocatorColumn.call(this,name,cellPath,aggregationMode);}
-TracingColumn.COLOR=ColorScheme.getColorForReservedNameAsString('tracing_memory_column');TracingColumn.prototype={__proto__:AllocatorColumn.prototype,get title(){return tr.ui.b.createSpan({textContent:this.name,color:TracingColumn.COLOR});},color:function(numerics,processMemoryDumps){return TracingColumn.COLOR;}};AllocatorColumn.RULES=[{condition:'tracing',importance:0,columnConstructor:TracingColumn},{importance:1,columnConstructor:AllocatorColumn}];Polymer('tr-ui-a-memory-dump-overview-pane',{created:function(){this.processMemoryDumps_=undefined;this.aggregationMode_=undefined;},ready:function(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.CELL;this.$.table.addEventListener('selection-changed',function(tableEvent){tableEvent.stopPropagation();this.changeChildPane_();}.bind(this));},set processMemoryDumps(processMemoryDumps){this.processMemoryDumps_=processMemoryDumps;this.scheduleRebuildPane_();},get processMemoryDumps(){return this.processMemoryDumps_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuildPane_();},get aggregationMode(){return this.aggregationMode_;},get selectedMemoryCell(){if(this.processMemoryDumps_===undefined||this.processMemoryDumps_.length===0){return undefined;}
-var selectedTableRow=this.$.table.selectedTableRow;if(!selectedTableRow)
-return undefined;var selectedColumnIndex=this.$.table.selectedColumnIndex;if(selectedColumnIndex===undefined)
-return undefined;var selectedColumn=this.$.table.tableColumns[selectedColumnIndex];var selectedMemoryCell=selectedColumn.cell(selectedTableRow);return selectedMemoryCell;},changeChildPane_:function(){this.storeSelection_();this.childPaneBuilder=this.determineChildPaneBuilderFromSelection_();},determineChildPaneBuilderFromSelection_:function(){if(this.processMemoryDumps_===undefined||this.processMemoryDumps_.length===0){return undefined;}
-var selectedTableRow=this.$.table.selectedTableRow;if(!selectedTableRow)
-return undefined;var selectedColumnIndex=this.$.table.selectedColumnIndex;if(selectedColumnIndex===undefined)
-return undefined;var selectedColumn=this.$.table.tableColumns[selectedColumnIndex];return selectedColumn.getChildPaneBuilder(selectedTableRow.contexts);},rebuildPane_:function(){if(this.processMemoryDumps_===undefined||this.processMemoryDumps_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.table.clear();this.$.table.rebuild();return;}
-this.$.info_text.style.display='none';this.$.table.style.display='block';var rows=this.createRows_();var columns=this.createColumns_(rows);var footerRows=this.createFooterRows_(rows,columns);this.$.table.tableRows=rows;this.$.table.footerRows=footerRows;this.$.table.tableColumns=columns;this.$.table.rebuild();this.restoreSelection_();},createRows_:function(){var timeToPidToProcessMemoryDump=this.processMemoryDumps_;var pidToTimeToProcessMemoryDump=tr.b.invertArrayOfDicts(timeToPidToProcessMemoryDump);return tr.b.dictionaryValues(tr.b.mapItems(pidToTimeToProcessMemoryDump,function(pid,timeToDump){var process=tr.b.findFirstInArray(timeToDump).process;var usedMemoryCells=tr.ui.analysis.createCells(timeToDump,function(dump){var sizes={};var totals=dump.totals;if(totals!==undefined){tr.b.iterItems(UsedMemoryColumn.TOTALS_MAP,function(totalName,cellName){var total=totals[totalName];if(total===undefined)
-return;sizes[cellName]=new ScalarNumeric(sizeInBytes_smallerIsBetter,total);});var platformSpecific=totals.platformSpecific;if(platformSpecific!==undefined){tr.b.iterItems(platformSpecific,function(name,size){if(name.endsWith(PLATFORM_SPECIFIC_TOTAL_NAME_SUFFIX)){name=name.substring(0,name.length-
+ByteStatColumn.prototype={__proto__:UsedMemoryColumn.prototype,color(numerics,processMemoryDumps){if(processMemoryDumps===undefined){return UsedMemoryColumn.COLOR;}
+const allOlderValues=processMemoryDumps.every(function(processMemoryDump){if(processMemoryDump===undefined)return true;return!processMemoryDump.hasOwnVmRegions;});if(allOlderValues){return UsedMemoryColumn.OLDER_COLOR;}
+return UsedMemoryColumn.COLOR;},addInfos(numerics,processMemoryDumps,infos){if(processMemoryDumps===undefined)return;let olderValueCount=0;for(let i=0;i<numerics.length;i++){const processMemoryDump=processMemoryDumps[i];if(processMemoryDump!==undefined&&!processMemoryDump.hasOwnVmRegions){olderValueCount++;}}
+if(olderValueCount===0){return;}
+const infoQuantifier=olderValueCount<numerics.length?' '+SOME_TIMESTAMPS_INFO_QUANTIFIER:'';infos.push({message:'Older value'+infoQuantifier+' (only heavy (purple) memory dumps contain memory maps).',icon:UNMARRIED_PARTNERSHIP_SYMBOL});}};UsedMemoryColumn.RULES=[{condition:'Total resident',importance:10,columnConstructor:UsedMemoryColumn},{condition:'Peak total resident',importance:9,columnConstructor:PeakMemoryColumn},{condition:'PSS',importance:8,columnConstructor:ByteStatColumn},{condition:'Private dirty',importance:7,columnConstructor:ByteStatColumn},{condition:'Swapped',importance:6,columnConstructor:ByteStatColumn},{importance:0,columnConstructor:UsedMemoryColumn}];UsedMemoryColumn.TOTALS_MAP={'residentBytes':'Total resident','peakResidentBytes':'Peak total resident','privateFootprintBytes':'Private footprint',};UsedMemoryColumn.PLATFORM_SPECIFIC_TOTALS_MAP={'vm':'Total virtual','swp':'Swapped','pc':'Private clean','pd':'Private dirty','sc':'Shared clean','sd':'Shared dirty','gpu_egl':'GPU EGL','gpu_egl_pss':'GPU EGL PSS','gpu_gl':'GPU GL','gpu_gl_pss':'GPU GL PSS','gpu_etc':'GPU Other','gpu_etc_pss':'GPU Other PSS',};UsedMemoryColumn.BYTE_STAT_MAP={'proportionalResident':'PSS','privateDirtyResident':'Private dirty','swapped':'Swapped'};function AllocatorColumn(name,cellPath,aggregationMode){tr.ui.analysis.NumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
+AllocatorColumn.prototype={__proto__:tr.ui.analysis.NumericMemoryColumn.prototype,get title(){const titleEl=document.createElement('tr-ui-b-color-legend');titleEl.label=this.name;return titleEl;},getFormattingContext(unit){return{unitPrefix:tr.b.UnitPrefixScale.BINARY.MEBI};},addInfos(numerics,processMemoryDumps,infos){if(processMemoryDumps===undefined)return;let heapDumpCount=0;let missingSizeCount=0;for(let i=0;i<processMemoryDumps.length;i++){const processMemoryDump=processMemoryDumps[i];if(processMemoryDump===undefined)continue;const heapDumps=processMemoryDump.heapDumps;if(heapDumps!==undefined&&heapDumps[this.name]!==undefined){heapDumpCount++;}
+const allocatorDump=processMemoryDump.getMemoryAllocatorDumpByFullName(this.name);if(allocatorDump!==undefined&&allocatorDump.numerics[DISPLAYED_SIZE_NUMERIC_NAME]===undefined){missingSizeCount++;}}
+if(heapDumpCount>0){const infoQuantifier=heapDumpCount<numerics.length?' '+SOME_TIMESTAMPS_INFO_QUANTIFIER:'';infos.push({message:'Heap dump provided'+infoQuantifier+'.',icon:TRIGRAM_FOR_HEAVEN});}
+if(missingSizeCount>0){const infoQuantifier=missingSizeCount<numerics.length?' '+SOME_TIMESTAMPS_INFO_QUANTIFIER:'';infos.push(tr.ui.analysis.createWarningInfo('Size was not provided'+infoQuantifier+'.'));}},getChildPaneBuilder(processMemoryDumps){if(processMemoryDumps===undefined)return undefined;const memoryAllocatorDumps=lazyMap(processMemoryDumps,function(pmd){if(pmd===undefined)return undefined;return pmd.getMemoryAllocatorDumpByFullName(this.name);},this);if(memoryAllocatorDumps===undefined)return undefined;const heapDumps=lazyMap(processMemoryDumps,function(pmd){if(pmd===undefined||pmd.heapDumps===undefined)return undefined;return pmd.heapDumps[this.name];},this);return function(){const pane=document.createElement('tr-ui-a-memory-dump-allocator-details-pane');pane.memoryAllocatorDumps=memoryAllocatorDumps;pane.heapDumps=heapDumps;pane.aggregationMode=this.aggregationMode;return pane;}.bind(this);}};function TracingColumn(name,cellPath,aggregationMode){AllocatorColumn.call(this,name,cellPath,aggregationMode);}
+TracingColumn.COLOR=MemoryColumnColorScheme.getColor('tracing_memory_column').toString();TracingColumn.prototype={__proto__:AllocatorColumn.prototype,get title(){return tr.ui.b.createSpan({textContent:this.name,color:TracingColumn.COLOR});},color(numerics,processMemoryDumps){return TracingColumn.COLOR;}};AllocatorColumn.RULES=[{condition:'tracing',importance:0,columnConstructor:TracingColumn},{importance:1,columnConstructor:AllocatorColumn}];Polymer({is:'tr-ui-a-memory-dump-overview-pane',behaviors:[tr.ui.analysis.StackedPane],created(){this.processMemoryDumps_=undefined;this.aggregationMode_=undefined;},ready(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.CELL;this.$.table.addEventListener('selection-changed',function(tableEvent){tableEvent.stopPropagation();this.changeChildPane_();}.bind(this));},set processMemoryDumps(processMemoryDumps){this.processMemoryDumps_=processMemoryDumps;this.scheduleRebuild_();},get processMemoryDumps(){return this.processMemoryDumps_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuild_();},get aggregationMode(){return this.aggregationMode_;},get selectedMemoryCell(){if(this.processMemoryDumps_===undefined||this.processMemoryDumps_.length===0){return undefined;}
+const selectedTableRow=this.$.table.selectedTableRow;if(!selectedTableRow)return undefined;const selectedColumnIndex=this.$.table.selectedColumnIndex;if(selectedColumnIndex===undefined)return undefined;const selectedColumn=this.$.table.tableColumns[selectedColumnIndex];const selectedMemoryCell=selectedColumn.cell(selectedTableRow);return selectedMemoryCell;},changeChildPane_(){this.storeSelection_();this.childPaneBuilder=this.determineChildPaneBuilderFromSelection_();},determineChildPaneBuilderFromSelection_(){if(this.processMemoryDumps_===undefined||this.processMemoryDumps_.length===0){return undefined;}
+const selectedTableRow=this.$.table.selectedTableRow;if(!selectedTableRow)return undefined;const selectedColumnIndex=this.$.table.selectedColumnIndex;if(selectedColumnIndex===undefined)return undefined;const selectedColumn=this.$.table.tableColumns[selectedColumnIndex];return selectedColumn.getChildPaneBuilder(selectedTableRow.contexts);},onRebuild_(){if(this.processMemoryDumps_===undefined||this.processMemoryDumps_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.table.clear();this.$.table.rebuild();return;}
+this.$.info_text.style.display='none';this.$.table.style.display='block';const rows=this.createRows_();const columns=this.createColumns_(rows);const footerRows=this.createFooterRows_(rows,columns);this.$.table.tableRows=rows;this.$.table.footerRows=footerRows;this.$.table.tableColumns=columns;this.$.table.rebuild();this.restoreSelection_();},createRows_(){const timeToPidToProcessMemoryDump=this.processMemoryDumps_;const pidToTimeToProcessMemoryDump=tr.b.invertArrayOfDicts(timeToPidToProcessMemoryDump);const rows=[];for(const[pid,timeToDump]of
+Object.entries(pidToTimeToProcessMemoryDump)){const process=timeToDump.find(x=>x).process;const usedMemoryCells=tr.ui.analysis.createCells(timeToDump,function(dump){const sizes={};const totals=dump.totals;if(totals!==undefined){for(const[totalName,cellName]of
+Object.entries(UsedMemoryColumn.TOTALS_MAP)){const total=totals[totalName];if(total===undefined)continue;sizes[cellName]=new Scalar(sizeInBytes_smallerIsBetter,total);}
+const platformSpecific=totals.platformSpecific;if(platformSpecific!==undefined){for(const[name,size]of Object.entries(platformSpecific)){let newName=name;if(UsedMemoryColumn.PLATFORM_SPECIFIC_TOTALS_MAP[name]===undefined){if(name.endsWith(PLATFORM_SPECIFIC_TOTAL_NAME_SUFFIX)){newName=name.substring(0,name.length-
 PLATFORM_SPECIFIC_TOTAL_NAME_SUFFIX.length);}
-name=name.replace('_',' ').trim();name=name.charAt(0).toUpperCase()+name.slice(1);sizes[name]=new ScalarNumeric(sizeInBytes_smallerIsBetter,size);});}}
-var vmRegions=dump.mostRecentVmRegions;if(vmRegions!==undefined){tr.b.iterItems(UsedMemoryColumn.BYTE_STAT_MAP,function(byteStatName,cellName){var byteStat=vmRegions.byteStats[byteStatName];if(byteStat===undefined)
-return;sizes[cellName]=new ScalarNumeric(sizeInBytes_smallerIsBetter,byteStat);});}
-return sizes;});var allocatorCells=tr.ui.analysis.createCells(timeToDump,function(dump){var memoryAllocatorDumps=dump.memoryAllocatorDumps;if(memoryAllocatorDumps===undefined)
-return undefined;var sizes={};memoryAllocatorDumps.forEach(function(allocatorDump){var rootDisplayedSizeNumeric=allocatorDump.numerics[DISPLAYED_SIZE_NUMERIC_NAME];if(rootDisplayedSizeNumeric!==undefined)
-sizes[allocatorDump.fullName]=rootDisplayedSizeNumeric;});return sizes;});return{title:process.userFriendlyName,contexts:timeToDump,usedMemoryCells:usedMemoryCells,allocatorCells:allocatorCells};}));},createFooterRows_:function(rows,columns){if(rows.length<=1)
-return[];var totalRow={title:'Total'};tr.ui.analysis.aggregateTableRowCells(totalRow,rows,columns);return[totalRow];},createColumns_:function(rows){var titleColumn=new ProcessNameColumn();titleColumn.width='200px';var usedMemorySizeColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'usedMemoryCells',this.aggregationMode_,UsedMemoryColumn.RULES);var allocatorSizeColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'allocatorCells',this.aggregationMode_,AllocatorColumn.RULES);var sizeColumns=usedMemorySizeColumns.concat(allocatorSizeColumns);tr.ui.analysis.MemoryColumn.spaceEqually(sizeColumns);var columns=[titleColumn].concat(sizeColumns);return columns;},storeSelection_:function(){var selectedRowTitle;var selectedRow=this.$.table.selectedTableRow;if(selectedRow!==undefined)
-selectedRowTitle=selectedRow.title;var selectedColumnName;var selectedColumnIndex=this.$.table.selectedColumnIndex;if(selectedColumnIndex!==undefined){var selectedColumn=this.$.table.tableColumns[selectedColumnIndex];selectedColumnName=selectedColumn.name;}
-this.$.state.set({rowTitle:selectedRowTitle,columnName:selectedColumnName});},restoreSelection_:function(){var settings=this.$.state.get();if(settings===undefined||settings.rowTitle===undefined||settings.columnName===undefined)
-return;var selectedColumnName=settings.columnName;var selectedColumnIndex=tr.b.findFirstIndexInArray(this.$.table.tableColumns,function(column){return column.name===selectedColumnName;});if(selectedColumnIndex<0)
-return;var selectedRowTitle=settings.rowTitle;var selectedRow=tr.b.findFirstInArray(this.$.table.tableRows,function(row){return row.title===selectedRowTitle;});if(selectedRow===undefined)
-return;this.$.table.selectedTableRow=selectedRow;this.$.table.selectedColumnIndex=selectedColumnIndex;}});return{ProcessNameColumn:ProcessNameColumn,UsedMemoryColumn:UsedMemoryColumn,PeakMemoryColumn:PeakMemoryColumn,ByteStatColumn:ByteStatColumn,AllocatorColumn:AllocatorColumn,TracingColumn:TracingColumn};});'use strict';tr.exportTo('tr.ui.analysis',function(){Polymer('tr-ui-a-memory-dump-header-pane',{created:function(){this.containerMemoryDumps_=undefined;},ready:function(){this.$.aggregation_mode_container.appendChild(tr.ui.b.createSelector(this,'aggregationMode','memoryDumpHeaderPane.aggregationMode',tr.ui.analysis.MemoryColumn.AggregationMode.DIFF,[{label:'Diff',value:tr.ui.analysis.MemoryColumn.AggregationMode.DIFF},{label:'Max',value:tr.ui.analysis.MemoryColumn.AggregationMode.MAX}]));},set containerMemoryDumps(containerMemoryDumps){this.containerMemoryDumps_=containerMemoryDumps;this.scheduleRebuildPane_();},get containerMemoryDumps(){return this.containerMemoryDumps_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuildPane_();},get aggregationMode(){return this.aggregationMode_;},rebuildPane_:function(){this.updateLabel_();this.updateAggregationModeSelector_();this.changeChildPane_();},updateLabel_:function(){this.$.label.textContent='';if(this.containerMemoryDumps_===undefined||this.containerMemoryDumps_.length<=0){this.$.label.textContent='No memory dumps selected';return;}
-var containerDumpCount=this.containerMemoryDumps_.length;var isMultiSelection=containerDumpCount>1;this.$.label.appendChild(document.createTextNode('Selected '+containerDumpCount+' memory dump'+
-(isMultiSelection?'s':'')+' in '+this.containerMemoryDumps_[0].containerName+' at '));this.$.label.appendChild(document.createTextNode(tr.v.Unit.byName.timeStampInMs.format(this.containerMemoryDumps_[0].start)));if(isMultiSelection){var ELLIPSIS=String.fromCharCode(8230);this.$.label.appendChild(document.createTextNode(ELLIPSIS));this.$.label.appendChild(document.createTextNode(tr.v.Unit.byName.timeStampInMs.format(this.containerMemoryDumps_[containerDumpCount-1].start)));}},updateAggregationModeSelector_:function(){var displayStyle;if(this.containerMemoryDumps_===undefined||this.containerMemoryDumps_.length<=1)
-displayStyle='none';else
-displayStyle='initial';this.$.aggregation_mode_container.style.display=displayStyle;},changeChildPane_:function(){this.childPaneBuilder=function(){if(this.containerMemoryDumps_===undefined||this.containerMemoryDumps_.length<=0)
-return undefined;var overviewPane=document.createElement('tr-ui-a-memory-dump-overview-pane');overviewPane.processMemoryDumps=this.containerMemoryDumps_.map(function(containerDump){return containerDump.processMemoryDumps;});overviewPane.aggregationMode=this.aggregationMode;return overviewPane;}.bind(this);}});return{};});'use strict';Polymer('tr-ui-a-stacked-pane-view',{setPaneBuilder:function(paneBuilder,opt_parentPane){var paneContainer=this.$.pane_container;if(opt_parentPane){if(!(opt_parentPane instanceof HTMLElement))
-throw new Error('Parent pane must be an HTML element');if(opt_parentPane.parentElement!==paneContainer)
-throw new Error('Parent pane must be a child of the pane container');}
-while(paneContainer.lastElementChild!==null&&paneContainer.lastElementChild!==opt_parentPane){var removedPane=this.$.pane_container.lastElementChild;var listener=this.listeners_.get(removedPane);if(listener===undefined)
-throw new Error('No listener associated with pane');this.listeners_.delete(removedPane);removedPane.removeEventListener('request-child-pane-change',listener);paneContainer.removeChild(removedPane);}
-if(opt_parentPane&&opt_parentPane.parentElement!==paneContainer)
-throw new Error('Parent pane was removed from the pane container');if(!paneBuilder)
-return;var pane=paneBuilder();if(!pane)
-return;if(!(pane instanceof HTMLElement))
-throw new Error('Pane must be an HTML element');var listener=function(event){this.setPaneBuilder(pane.childPaneBuilder,pane);}.bind(this);if(!this.listeners_){this.listeners_=new WeakMap();}
-this.listeners_.set(pane,listener);pane.addEventListener('request-child-pane-change',listener);paneContainer.appendChild(pane);pane.appended();},rebuild:function(){var currentPane=this.$.pane_container.firstElementChild;while(currentPane){currentPane.rebuild();currentPane=currentPane.nextElementSibling;}},get panesForTesting(){var panes=[];var currentChild=this.$.pane_container.firstElementChild;while(currentChild){panes.push(currentChild);currentChild=currentChild.nextElementSibling;}
-return panes;}});'use strict';tr.exportTo('tr.ui.analysis',function(){Polymer('tr-ui-a-container-memory-dump-sub-view',{set selection(selection){if(selection===undefined){this.currentSelection_=undefined;this.dumpsByContainerName_=undefined;this.updateContents_();return;}
-selection.forEach(function(event){if(!(event instanceof tr.model.ContainerMemoryDump)){throw new Error('Memory dump sub-view only supports container memory dumps');}});this.currentSelection_=selection;this.dumpsByContainerName_=tr.b.group(this.currentSelection_.toArray(),function(dump){return dump.containerName;});tr.b.iterItems(this.dumpsByContainerName_,function(containerName,dumps){dumps.sort(function(a,b){return a.start-b.start;});});this.updateContents_();},get selection(){return this.currentSelection_;},get requiresTallView(){return true;},updateContents_:function(){this.$.content.textContent='';if(this.dumpsByContainerName_===undefined)
-return;var containerNames=Object.keys(this.dumpsByContainerName_);if(containerNames.length===0)
-return;if(containerNames.length>1)
-this.buildViewForMultipleContainerNames_();else
-this.buildViewForSingleContainerName_();},buildViewForSingleContainerName_:function(){var containerMemoryDumps=tr.b.dictionaryValues(this.dumpsByContainerName_)[0];var dumpView=this.ownerDocument.createElement('tr-ui-a-stacked-pane-view');this.$.content.appendChild(dumpView);dumpView.setPaneBuilder(function(){var headerPane=document.createElement('tr-ui-a-memory-dump-header-pane');headerPane.containerMemoryDumps=containerMemoryDumps;return headerPane;});},buildViewForMultipleContainerNames_:function(){var ownerDocument=this.ownerDocument;var rows=tr.b.dictionaryValues(tr.b.mapItems(this.dumpsByContainerName_,function(containerName,dumps){return{containerName:containerName,subRows:dumps,isExpanded:true};}));rows.sort(function(a,b){return a.containerName.localeCompare(b.containerName);});var columns=[{title:'Dump',value:function(row){if(row.subRows===undefined)
-return this.singleDumpValue_(row);else
-return this.groupedDumpValue_(row);},singleDumpValue_:function(row){var linkEl=ownerDocument.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(new tr.model.EventSet([row]));linkEl.appendChild(tr.v.ui.createScalarSpan(row.start,{unit:tr.v.Unit.byName.timeStampInMs,ownerDocument:ownerDocument}));return linkEl;},groupedDumpValue_:function(row){var linkEl=ownerDocument.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(new tr.model.EventSet(row.subRows));linkEl.appendChild(tr.ui.b.createSpan({ownerDocument:ownerDocument,textContent:row.subRows.length+' memory dump'+
-(row.subRows.length===1?'':'s')+' in '}));linkEl.appendChild(tr.ui.b.createSpan({ownerDocument:ownerDocument,textContent:row.containerName,bold:true}));return linkEl;}}];var table=this.ownerDocument.createElement('tr-ui-b-table');table.tableColumns=columns;table.tableRows=rows;table.showHeader=false;table.rebuild();this.$.content.appendChild(table);}});return{};});'use strict';(function(){var COUNTER_SAMPLE_TABLE_COLUMNS=[{title:'Counter',width:'150px',value:function(row){return row.counter;}},{title:'Series',width:'150px',value:function(row){return row.series;}},{title:'Time',width:'150px',value:function(row){return row.start;}},{title:'Value',width:'100%',value:function(row){return row.value;}}];Polymer('tr-ui-a-counter-sample-sub-view',{ready:function(){this.currentSelection_=undefined;this.$.table.tableColumns=COUNTER_SAMPLE_TABLE_COLUMNS;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},updateContents_:function(){this.$.table.tableRows=this.selection?this.getRows_(this.selection.toArray()):[];this.$.table.rebuild();},getRows_:function(samples){var samplesByCounter=tr.b.group(samples,function(sample){return sample.series.counter.guid;});var rows=[];tr.b.iterItems(samplesByCounter,function(unused,counterSamples){var samplesBySeries=tr.b.group(counterSamples,function(sample){return sample.series.guid;});tr.b.iterItems(samplesBySeries,function(unused,seriesSamples){var seriesRows=this.getRowsForSamples_(seriesSamples);seriesRows[0].counter=seriesSamples[0].series.counter.name;seriesRows[0].series=seriesSamples[0].series.name;if(seriesRows.length>1){seriesRows[0].subRows=seriesRows.slice(1);seriesRows[0].isExpanded=true;}
-rows.push(seriesRows[0]);},this);},this);return rows;},getRowsForSamples_:function(samples){return samples.map(function(sample){return{start:sample.timestamp,value:sample.value};});}});})();'use strict';tr.exportTo('tr.ui.analysis',function(){Polymer('tr-ui-a-layout-tree-sub-view',{set selection(selection){this.currentSelection_=selection;this.updateContents_();},get selection(){return this.currentSelection_;},updateContents_:function(){this.$.content.textContent='';if(!this.currentSelection_)
-return;var columns=[{title:'Tag/Name',value:function(layoutObject){return layoutObject.tag||':'+layoutObject.name;}},{title:'htmlId',value:function(layoutObject){return layoutObject.htmlId||'';}},{title:'classNames',value:function(layoutObject){return layoutObject.classNames||'';}},{title:'reasons',value:function(layoutObject){return layoutObject.needsLayoutReasons.join(', ');}},{title:'width',value:function(layoutObject){return layoutObject.absoluteRect.width;}},{title:'height',value:function(layoutObject){return layoutObject.absoluteRect.height;}},{title:'absX',value:function(layoutObject){return layoutObject.absoluteRect.left;}},{title:'absY',value:function(layoutObject){return layoutObject.absoluteRect.top;}},{title:'relX',value:function(layoutObject){return layoutObject.relativeRect.left;}},{title:'relY',value:function(layoutObject){return layoutObject.relativeRect.top;}},{title:'float',value:function(layoutObject){return layoutObject.isFloat?'float':'';}},{title:'positioned',value:function(layoutObject){return layoutObject.isPositioned?'positioned':'';}},{title:'relative',value:function(layoutObject){return layoutObject.isRelativePositioned?'relative':'';}},{title:'sticky',value:function(layoutObject){return layoutObject.isStickyPositioned?'sticky':'';}},{title:'anonymous',value:function(layoutObject){return layoutObject.isAnonymous?'anonymous':'';}},{title:'row',value:function(layoutObject){if(layoutObject.tableRow===undefined)
-return'';return layoutObject.tableRow;}},{title:'col',value:function(layoutObject){if(layoutObject.tableCol===undefined)
-return'';return layoutObject.tableCol;}},{title:'rowSpan',value:function(layoutObject){if(layoutObject.tableRowSpan===undefined)
-return'';return layoutObject.tableRowSpan;}},{title:'colSpan',value:function(layoutObject){if(layoutObject.tableColSpan===undefined)
-return'';return layoutObject.tableColSpan;}},{title:'address',value:function(layoutObject){return layoutObject.id.toString(16);}}];var table=this.ownerDocument.createElement('tr-ui-b-table');table.defaultExpansionStateCallback=function(layoutObject,parentLayoutObject){return true;};table.subRowsPropertyName='childLayoutObjects';table.tableColumns=columns;table.tableRows=this.currentSelection_.map(function(snapshot){return snapshot.rootLayoutObject;});table.rebuild();this.$.content.appendChild(table);}});return{};});'use strict';Polymer('tr-ui-a-selection-summary-table',{created:function(){this.selection_=new tr.b.Range();},ready:function(){this.$.table.showHeader=false;this.$.table.tableColumns=[{title:'Name',value:function(row){return row.title;},width:'350px'},{title:'Value',width:'100%',value:function(row){return row.value;}}];},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;this.updateContents_();},updateContents_:function(){var selection=this.selection_;var rows=[];var hasRange;if(this.selection_&&(!selection.bounds.isEmpty))
-hasRange=true;else
-hasRange=false;rows.push({title:'Selection start',value:hasRange?tr.v.ui.createScalarSpan(selection.bounds.min,{unit:tr.v.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument}):'<empty>'});rows.push({title:'Selection extent',value:hasRange?tr.v.ui.createScalarSpan(selection.bounds.range,{unit:tr.v.Unit.byName.timeDurationInMs,ownerDocument:this.ownerDocument}):'<empty>'});this.$.table.tableRows=rows;this.$.table.rebuild();}});'use strict';tr.exportTo('tr.ui.analysis',function(){function MultiEventSummary(title,events){this.title=title;this.duration_=undefined;this.selfTime_=undefined;this.events_=events;this.cpuTimesComputed_=false;this.cpuSelfTime_=undefined;this.cpuDuration_=undefined;this.maxDuration_=undefined;this.maxCpuDuration_=undefined;this.maxSelfTime_=undefined;this.maxCpuSelfTime_=undefined;this.untotallableArgs_=[];this.totalledArgs_=undefined;};MultiEventSummary.prototype={set title(title){if(title=='Totals')
-this.totalsRow=true;this.title_=title;},get title(){return this.title_;},get duration(){if(this.duration_===undefined){this.duration_=tr.b.Statistics.sum(this.events_,function(event){return event.duration;});}
-return this.duration_;},get cpuSelfTime(){this.computeCpuTimesIfNeeded_();return this.cpuSelfTime_;},get cpuDuration(){this.computeCpuTimesIfNeeded_();return this.cpuDuration_;},computeCpuTimesIfNeeded_:function(){if(this.cpuTimesComputed_)
-return;this.cpuTimesComputed_=true;var cpuSelfTime=0;var cpuDuration=0;var hasCpuData=false;for(var i=0;i<this.events_.length;i++){var event=this.events_[i];if(event.cpuDuration!==undefined){cpuDuration+=event.cpuDuration;hasCpuData=true;}
+newName=newName.replace('_',' ').trim();newName=newName.charAt(0).toUpperCase()+newName.slice(1);}else{newName=UsedMemoryColumn.PLATFORM_SPECIFIC_TOTALS_MAP[name];}
+sizes[newName]=new Scalar(sizeInBytes_smallerIsBetter,size);}}}
+const vmRegions=dump.mostRecentVmRegions;if(vmRegions!==undefined){for(const[byteStatName,cellName]of
+Object.entries(UsedMemoryColumn.BYTE_STAT_MAP)){const byteStat=vmRegions.byteStats[byteStatName];if(byteStat===undefined)continue;sizes[cellName]=new Scalar(sizeInBytes_smallerIsBetter,byteStat);}}
+return sizes;});const allocatorCells=tr.ui.analysis.createCells(timeToDump,function(dump){const memoryAllocatorDumps=dump.memoryAllocatorDumps;if(memoryAllocatorDumps===undefined)return undefined;const sizes={};memoryAllocatorDumps.forEach(function(allocatorDump){let rootDisplayedSizeNumeric=allocatorDump.numerics[DISPLAYED_SIZE_NUMERIC_NAME];if(rootDisplayedSizeNumeric===undefined){rootDisplayedSizeNumeric=new Scalar(sizeInBytes_smallerIsBetter,0);}
+sizes[allocatorDump.fullName]=rootDisplayedSizeNumeric;});return sizes;});rows.push({title:process.userFriendlyName,contexts:timeToDump,usedMemoryCells,allocatorCells});}
+return rows;},createFooterRows_(rows,columns){if(rows.length<=1)return[];const totalRow={title:'Total'};tr.ui.analysis.aggregateTableRowCells(totalRow,rows,columns);return[totalRow];},createColumns_(rows){const titleColumn=new ProcessNameColumn();titleColumn.width='200px';const usedMemorySizeColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'usedMemoryCells',aggregationMode:this.aggregationMode_,rules:UsedMemoryColumn.RULES});const allocatorSizeColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'allocatorCells',aggregationMode:this.aggregationMode_,rules:AllocatorColumn.RULES});const sizeColumns=usedMemorySizeColumns.concat(allocatorSizeColumns);tr.ui.analysis.MemoryColumn.spaceEqually(sizeColumns);const columns=[titleColumn].concat(sizeColumns);return columns;},storeSelection_(){let selectedRowTitle;const selectedRow=this.$.table.selectedTableRow;if(selectedRow!==undefined){selectedRowTitle=selectedRow.title;}
+let selectedColumnName;const selectedColumnIndex=this.$.table.selectedColumnIndex;if(selectedColumnIndex!==undefined){const selectedColumn=this.$.table.tableColumns[selectedColumnIndex];selectedColumnName=selectedColumn.name;}
+this.$.state.set({rowTitle:selectedRowTitle,columnName:selectedColumnName});},restoreSelection_(){const settings=this.$.state.get();if(settings===undefined||settings.rowTitle===undefined||settings.columnName===undefined){return;}
+const selectedColumnIndex=this.$.table.tableColumns.findIndex(col=>col.name===settings.columnName);if(selectedColumnIndex===-1)return;const selectedRowTitle=settings.rowTitle;const selectedRow=this.$.table.tableRows.find(row=>row.title===selectedRowTitle);if(selectedRow===undefined)return;this.$.table.selectedTableRow=selectedRow;this.$.table.selectedColumnIndex=selectedColumnIndex;}});return{ProcessNameColumn,UsedMemoryColumn,PeakMemoryColumn,ByteStatColumn,AllocatorColumn,TracingColumn,};});'use strict';tr.exportTo('tr.ui.analysis',function(){Polymer({is:'tr-ui-a-memory-dump-header-pane',behaviors:[tr.ui.analysis.StackedPane],created(){this.containerMemoryDumps_=undefined;},ready(){Polymer.dom(this.$.aggregation_mode_container).appendChild(tr.ui.b.createSelector(this,'aggregationMode','memoryDumpHeaderPane.aggregationMode',tr.ui.analysis.MemoryColumn.AggregationMode.DIFF,[{label:'Diff',value:tr.ui.analysis.MemoryColumn.AggregationMode.DIFF},{label:'Max',value:tr.ui.analysis.MemoryColumn.AggregationMode.MAX}]));},set containerMemoryDumps(containerMemoryDumps){this.containerMemoryDumps_=containerMemoryDumps;this.scheduleRebuild_();},get containerMemoryDumps(){return this.containerMemoryDumps_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuild_();},get aggregationMode(){return this.aggregationMode_;},onRebuild_(){this.updateLabel_();this.updateAggregationModeSelector_();this.changeChildPane_();},updateLabel_(){Polymer.dom(this.$.label).textContent='';if(this.containerMemoryDumps_===undefined||this.containerMemoryDumps_.length<=0){Polymer.dom(this.$.label).textContent='No memory dumps selected';return;}
+const containerDumpCount=this.containerMemoryDumps_.length;const isMultiSelection=containerDumpCount>1;Polymer.dom(this.$.label).appendChild(document.createTextNode('Selected '+containerDumpCount+' memory dump'+
+(isMultiSelection?'s':'')+' in '+this.containerMemoryDumps_[0].containerName+' at '));Polymer.dom(this.$.label).appendChild(document.createTextNode(tr.b.Unit.byName.timeStampInMs.format(this.containerMemoryDumps_[0].start)));if(isMultiSelection){const ELLIPSIS=String.fromCharCode(8230);Polymer.dom(this.$.label).appendChild(document.createTextNode(ELLIPSIS));Polymer.dom(this.$.label).appendChild(document.createTextNode(tr.b.Unit.byName.timeStampInMs.format(this.containerMemoryDumps_[containerDumpCount-1].start)));}},updateAggregationModeSelector_(){let displayStyle;if(this.containerMemoryDumps_===undefined||this.containerMemoryDumps_.length<=1){displayStyle='none';}else{displayStyle='initial';}
+this.$.aggregation_mode_container.style.display=displayStyle;},changeChildPane_(){this.childPaneBuilder=function(){if(this.containerMemoryDumps_===undefined||this.containerMemoryDumps_.length<=0){return undefined;}
+const overviewPane=document.createElement('tr-ui-a-memory-dump-overview-pane');overviewPane.processMemoryDumps=this.containerMemoryDumps_.map(function(containerDump){return containerDump.processMemoryDumps;});overviewPane.aggregationMode=this.aggregationMode;return overviewPane;}.bind(this);}});return{};});'use strict';Polymer({is:'tr-ui-a-stacked-pane-view',setPaneBuilder(paneBuilder,opt_parentPane){const paneContainer=this.$.pane_container;if(opt_parentPane){if(!(opt_parentPane instanceof HTMLElement)){throw new Error('Parent pane must be an HTML element');}
+if(opt_parentPane.parentElement!==paneContainer){throw new Error('Parent pane must be a child of the pane container');}}
+while(Polymer.dom(paneContainer).lastElementChild!==null&&Polymer.dom(paneContainer).lastElementChild!==opt_parentPane){const removedPane=Polymer.dom(this.$.pane_container).lastElementChild;const listener=this.listeners_.get(removedPane);if(listener===undefined){throw new Error('No listener associated with pane');}
+this.listeners_.delete(removedPane);removedPane.removeEventListener('request-child-pane-change',listener);Polymer.dom(paneContainer).removeChild(removedPane);}
+if(opt_parentPane&&opt_parentPane.parentElement!==paneContainer){throw new Error('Parent pane was removed from the pane container');}
+if(!paneBuilder)return;const pane=paneBuilder();if(!pane)return;if(!(pane instanceof HTMLElement)){throw new Error('Pane must be an HTML element');}
+const listener=function(event){this.setPaneBuilder(pane.childPaneBuilder,pane);}.bind(this);if(!this.listeners_){this.listeners_=new WeakMap();}
+this.listeners_.set(pane,listener);pane.addEventListener('request-child-pane-change',listener);Polymer.dom(paneContainer).appendChild(pane);pane.appended();},rebuild(){let currentPane=Polymer.dom(this.$.pane_container).firstElementChild;while(currentPane){currentPane.rebuild();currentPane=currentPane.nextElementSibling;}},get panesForTesting(){const panes=[];let currentChild=Polymer.dom(this.$.pane_container).firstElementChild;while(currentChild){panes.push(currentChild);currentChild=currentChild.nextElementSibling;}
+return panes;}});'use strict';tr.exportTo('tr.ui.analysis',function(){Polymer({is:'tr-ui-a-container-memory-dump-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],set selection(selection){if(selection===undefined){this.currentSelection_=undefined;this.dumpsByContainerName_=undefined;this.updateContents_();return;}
+selection.forEach(function(event){if(!(event instanceof tr.model.ContainerMemoryDump)){throw new Error('Memory dump sub-view only supports container memory dumps');}});this.currentSelection_=selection;this.dumpsByContainerName_=tr.b.groupIntoMap(this.currentSelection_.toArray(),dump=>dump.containerName);for(const dumps of this.dumpsByContainerName_.values()){dumps.sort((a,b)=>a.start-b.start);}
+this.updateContents_();},get selection(){return this.currentSelection_;},get requiresTallView(){return true;},updateContents_(){Polymer.dom(this.$.content).textContent='';if(this.dumpsByContainerName_===undefined)return;const containerNames=Array.from(this.dumpsByContainerName_.keys());if(containerNames.length===0)return;if(containerNames.length>1){this.buildViewForMultipleContainerNames_();}else{this.buildViewForSingleContainerName_();}},buildViewForSingleContainerName_(){const containerMemoryDumps=tr.b.getFirstElement(this.dumpsByContainerName_.values());const dumpView=this.ownerDocument.createElement('tr-ui-a-stacked-pane-view');Polymer.dom(this.$.content).appendChild(dumpView);dumpView.setPaneBuilder(function(){const headerPane=document.createElement('tr-ui-a-memory-dump-header-pane');headerPane.containerMemoryDumps=containerMemoryDumps;return headerPane;});},buildViewForMultipleContainerNames_(){const ownerDocument=this.ownerDocument;const rows=[];for(const[containerName,dumps]of this.dumpsByContainerName_){rows.push({containerName,subRows:dumps,isExpanded:true,});}
+rows.sort(function(a,b){return a.containerName.localeCompare(b.containerName);});const columns=[{title:'Dump',value(row){if(row.subRows===undefined){return this.singleDumpValue_(row);}
+return this.groupedDumpValue_(row);},singleDumpValue_(row){const linkEl=ownerDocument.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(new tr.model.EventSet([row]));Polymer.dom(linkEl).appendChild(tr.v.ui.createScalarSpan(row.start,{unit:tr.b.Unit.byName.timeStampInMs,ownerDocument}));return linkEl;},groupedDumpValue_(row){const linkEl=ownerDocument.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(new tr.model.EventSet(row.subRows));Polymer.dom(linkEl).appendChild(tr.ui.b.createSpan({ownerDocument,textContent:row.subRows.length+' memory dump'+
+(row.subRows.length===1?'':'s')+' in '}));Polymer.dom(linkEl).appendChild(tr.ui.b.createSpan({ownerDocument,textContent:row.containerName,bold:true}));return linkEl;}}];const table=this.ownerDocument.createElement('tr-ui-b-table');table.tableColumns=columns;table.tableRows=rows;table.showHeader=false;table.rebuild();Polymer.dom(this.$.content).appendChild(table);}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-container-memory-dump-sub-view',tr.model.GlobalMemoryDump,{multi:false,title:'Global Memory Dump',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-container-memory-dump-sub-view',tr.model.GlobalMemoryDump,{multi:true,title:'Global Memory Dumps',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-container-memory-dump-sub-view',tr.model.ProcessMemoryDump,{multi:false,title:'Process Memory Dump',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-container-memory-dump-sub-view',tr.model.ProcessMemoryDump,{multi:true,title:'Process Memory Dumps',});return{};});'use strict';(function(){const COUNTER_SAMPLE_TABLE_COLUMNS=[{title:'Counter',width:'150px',value(row){return row.counter;}},{title:'Series',width:'150px',value(row){return row.series;}},{title:'Time',width:'150px',value(row){return row.start;}},{title:'Value',width:'100%',value(row){return row.value;}}];Polymer({is:'tr-ui-a-counter-sample-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready(){this.currentSelection_=undefined;this.$.table.tableColumns=COUNTER_SAMPLE_TABLE_COLUMNS;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},updateContents_(){this.$.table.tableRows=this.selection?this.getRows_(this.selection.toArray()):[];this.$.table.rebuild();},getRows_(samples){const samplesByCounter=tr.b.groupIntoMap(samples,sample=>sample.series.counter.guid);const rows=[];for(const counterSamples of samplesByCounter.values()){const samplesBySeries=tr.b.groupIntoMap(counterSamples,sample=>sample.series.guid);for(const seriesSamples of samplesBySeries.values()){const seriesRows=this.getRowsForSamples_(seriesSamples);seriesRows[0].counter=seriesSamples[0].series.counter.name;seriesRows[0].series=seriesSamples[0].series.name;if(seriesRows.length>1){seriesRows[0].subRows=seriesRows.slice(1);seriesRows[0].isExpanded=true;}
+rows.push(seriesRows[0]);}}
+return rows;},getRowsForSamples_(samples){return samples.map(function(sample){return{start:sample.timestamp,value:sample.value};});}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-counter-sample-sub-view',tr.model.CounterSample,{multi:false,title:'Counter Sample',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-counter-sample-sub-view',tr.model.CounterSample,{multi:true,title:'Counter Samples',});})();'use strict';tr.exportTo('tr.ui.analysis',function(){function MultiEventSummary(title,events){this.title=title;this.duration_=undefined;this.selfTime_=undefined;this.events_=events;this.cpuTimesComputed_=false;this.cpuSelfTime_=undefined;this.cpuDuration_=undefined;this.maxDuration_=undefined;this.maxCpuDuration_=undefined;this.maxSelfTime_=undefined;this.maxCpuSelfTime_=undefined;this.untotallableArgs_=[];this.totalledArgs_=undefined;}
+MultiEventSummary.prototype={set title(title){if(title==='Totals'){this.totalsRow=true;}
+this.title_=title;},get title(){return this.title_;},get duration(){if(this.duration_===undefined){this.duration_=tr.b.math.Statistics.sum(this.events_,function(event){return event.duration;});}
+return this.duration_;},get cpuSelfTime(){this.computeCpuTimesIfNeeded_();return this.cpuSelfTime_;},get cpuDuration(){this.computeCpuTimesIfNeeded_();return this.cpuDuration_;},computeCpuTimesIfNeeded_(){if(this.cpuTimesComputed_)return;this.cpuTimesComputed_=true;let cpuSelfTime=0;let cpuDuration=0;let hasCpuData=false;for(const event of this.events_){if(event.cpuDuration!==undefined){cpuDuration+=event.cpuDuration;hasCpuData=true;}
 if(event.cpuSelfTime!==undefined){cpuSelfTime+=event.cpuSelfTime;hasCpuData=true;}}
-if(hasCpuData){this.cpuDuration_=cpuDuration;this.cpuSelfTime_=cpuSelfTime;}},get selfTime(){if(this.selfTime_===undefined){this.selfTime_=0;for(var i=0;i<this.events_.length;i++){if(this.events_[i].selfTime!==undefined)
-this.selfTime_+=this.events[i].selfTime;}}
-return this.selfTime_;},get events(){return this.events_;},get numEvents(){return this.events_.length;},get numAlerts(){if(this.numAlerts_===undefined){this.numAlerts_=tr.b.Statistics.sum(this.events_,function(event){return event.associatedAlerts.length;});}
-return this.numAlerts_;},get untotallableArgs(){this.updateArgsIfNeeded_();return this.untotallableArgs_;},get totalledArgs(){this.updateArgsIfNeeded_();return this.totalledArgs_;},get maxDuration(){if(this.maxDuration_===undefined){this.maxDuration_=tr.b.Statistics.max(this.events_,function(event){return event.duration;});}
-return this.maxDuration_;},get maxCpuDuration(){if(this.maxCpuDuration_===undefined){this.maxCpuDuration_=tr.b.Statistics.max(this.events_,function(event){return event.cpuDuration;});}
-return this.maxCpuDuration_;},get maxSelfTime(){if(this.maxSelfTime_===undefined){this.maxSelfTime_=tr.b.Statistics.max(this.events_,function(event){return event.selfTime;});}
-return this.maxSelfTime_;},get maxCpuSelfTime(){if(this.maxCpuSelfTime_===undefined){this.maxCpuSelfTime_=tr.b.Statistics.max(this.events_,function(event){return event.cpuSelfTime;});}
-return this.maxCpuSelfTime_;},updateArgsIfNeeded_:function(){if(this.totalledArgs_!==undefined)
-return;var untotallableArgs={};var totalledArgs={};for(var i=0;i<this.events_.length;i++){var event=this.events_[i];for(var argName in event.args){var argVal=event.args[argName];var type=typeof argVal;if(type!=='number'){untotallableArgs[argName]=true;delete totalledArgs[argName];continue;}
+if(hasCpuData){this.cpuDuration_=cpuDuration;this.cpuSelfTime_=cpuSelfTime;}},get selfTime(){if(this.selfTime_===undefined){this.selfTime_=0;for(const event of this.events_){if(event.selfTime!==undefined){this.selfTime_+=event.selfTime;}}}
+return this.selfTime_;},get events(){return this.events_;},get numEvents(){return this.events_.length;},get numAlerts(){if(this.numAlerts_===undefined){this.numAlerts_=tr.b.math.Statistics.sum(this.events_,event=>event.associatedAlerts.length);}
+return this.numAlerts_;},get untotallableArgs(){this.updateArgsIfNeeded_();return this.untotallableArgs_;},get totalledArgs(){this.updateArgsIfNeeded_();return this.totalledArgs_;},get maxDuration(){if(this.maxDuration_===undefined){this.maxDuration_=tr.b.math.Statistics.max(this.events_,function(event){return event.duration;});}
+return this.maxDuration_;},get maxCpuDuration(){if(this.maxCpuDuration_===undefined){this.maxCpuDuration_=tr.b.math.Statistics.max(this.events_,function(event){return event.cpuDuration;});}
+return this.maxCpuDuration_;},get maxSelfTime(){if(this.maxSelfTime_===undefined){this.maxSelfTime_=tr.b.math.Statistics.max(this.events_,function(event){return event.selfTime;});}
+return this.maxSelfTime_;},get maxCpuSelfTime(){if(this.maxCpuSelfTime_===undefined){this.maxCpuSelfTime_=tr.b.math.Statistics.max(this.events_,function(event){return event.cpuSelfTime;});}
+return this.maxCpuSelfTime_;},updateArgsIfNeeded_(){if(this.totalledArgs_!==undefined)return;const untotallableArgs={};const totalledArgs={};for(const event of this.events_){for(const argName in event.args){const argVal=event.args[argName];const type=typeof argVal;if(type!=='number'){untotallableArgs[argName]=true;delete totalledArgs[argName];continue;}
 if(untotallableArgs[argName]){continue;}
-if(totalledArgs[argName]===undefined)
-totalledArgs[argName]=0;totalledArgs[argName]+=argVal;}}
-this.untotallableArgs_=tr.b.dictionaryKeys(untotallableArgs);this.totalledArgs_=totalledArgs;}};return{MultiEventSummary:MultiEventSummary};});'use strict';Polymer('tr-ui-a-multi-event-summary-table',{ready:function(){this.showTotals_=false;this.eventsHaveDuration_=true;this.eventsHaveSubRows_=true;this.eventsByTitle_=undefined;},updateTableColumns_:function(rows,maxValues){var hasCpuData=false;var hasAlerts=false;rows.forEach(function(row){if(row.cpuDuration!==undefined)
-hasCpuData=true;if(row.cpuSelfTime!==undefined)
-hasCpuData=true;if(row.numAlerts)
-hasAlerts=true;});var ownerDocument=this.ownerDocument;var columns=[];columns.push({title:'Name',value:function(row){if(row.title==='Totals')
-return'Totals';var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(row.events);},row.title);return linkEl;},width:'350px',cmp:function(rowA,rowB){return rowA.title.localeCompare(rowB.title);}});if(this.eventsHaveDuration_){columns.push({title:'Wall Duration',value:function(row){return tr.v.ui.createScalarSpan(row.duration,{unit:tr.v.Unit.byName.timeDurationInMs,total:row.totalsRow?undefined:maxValues.duration,ownerDocument:ownerDocument,rightAlign:true});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.duration-rowB.duration;}});}
-if(this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Duration',value:function(row){return tr.v.ui.createScalarSpan(row.cpuDuration,{unit:tr.v.Unit.byName.timeDurationInMs,total:row.totalsRow?undefined:maxValues.cpuDuration,ownerDocument:ownerDocument,rightAlign:true});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.cpuDuration-rowB.cpuDuration;}});}
-if(this.eventsHaveSubRows_&&this.eventsHaveDuration_){columns.push({title:'Self time',value:function(row){return tr.v.ui.createScalarSpan(row.selfTime,{unit:tr.v.Unit.byName.timeDurationInMs,total:row.totalsRow?undefined:maxValues.selfTime,ownerDocument:ownerDocument,rightAlign:true});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.selfTime-rowB.selfTime;}});}
-if(this.eventsHaveSubRows_&&this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Self Time',value:function(row){return tr.v.ui.createScalarSpan(row.cpuSelfTime,{unit:tr.v.Unit.byName.timeDurationInMs,total:row.totalsRow?undefined:maxValues.cpuSelfTime,ownerDocument:ownerDocument,rightAlign:true});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.cpuSelfTime-rowB.cpuSelfTime;}});}
-columns.push({title:'Occurrences',value:function(row){return row.numEvents;},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.numEvents-rowB.numEvents;}});var alertsColumnIndex;if(hasAlerts){columns.push({title:'Num Alerts',value:function(row){return row.numAlerts;},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.numAlerts-rowB.numAlerts;}});alertsColumnIndex=columns.length-1;}
-var colWidthPercentage;if(columns.length==1)
-colWidthPercentage='100%';else
-colWidthPercentage=(100/(columns.length-1)).toFixed(3)+'%';for(var i=1;i<columns.length;i++)
-columns[i].width=colWidthPercentage;this.$.table.tableColumns=columns;if(hasAlerts){this.$.table.sortColumnIndex=alertsColumnIndex;this.$.table.sortDescending=true;}},configure:function(config){if(config.eventsByTitle===undefined)
-throw new Error('Required: eventsByTitle');if(config.showTotals!==undefined)
-this.showTotals_=config.showTotals;else
-this.showTotals_=true;if(config.eventsHaveDuration!==undefined)
-this.eventsHaveDuration_=config.eventsHaveDuration;else
-this.eventsHaveDuration_=true;if(config.eventsHaveSubRows!==undefined)
-this.eventsHaveSubRows_=config.eventsHaveSubRows;else
-this.eventsHaveSubRows_=true;this.eventsByTitle_=config.eventsByTitle;this.updateContents_();},get showTotals(){return this.showTotals_;},set showTotals(showTotals){this.showTotals_=showTotals;this.updateContents_();},get eventsHaveDuration(){return this.eventsHaveDuration_;},set eventsHaveDuration(eventsHaveDuration){this.eventsHaveDuration_=eventsHaveDuration;this.updateContents_();},get eventsHaveSubRows(){return this.eventsHaveSubRows_;},set eventsHaveSubRows(eventsHaveSubRows){this.eventsHaveSubRows_=eventsHaveSubRows;this.updateContents_();},get eventsByTitle(){return this.eventsByTitle_;},set eventsByTitle(eventsByTitle){this.eventsByTitle_=eventsByTitle;this.updateContents_();},get selectionBounds(){return this.selectionBounds_;},set selectionBounds(selectionBounds){this.selectionBounds_=selectionBounds;this.updateContents_();},updateContents_:function(){var eventsByTitle;if(this.eventsByTitle_!==undefined)
-eventsByTitle=this.eventsByTitle_;else
-eventsByTitle=[];var allEvents=[];var rows=[];tr.b.iterItems(eventsByTitle,function(title,eventsOfSingleTitle){allEvents.push.apply(allEvents,eventsOfSingleTitle);var row=new tr.ui.analysis.MultiEventSummary(title,eventsOfSingleTitle);rows.push(row);});this.updateTableColumns_(rows);this.$.table.tableRows=rows;var maxValues={duration:undefined,selfTime:undefined,cpuSelfTime:undefined,cpuDuration:undefined};if(this.eventsHaveDuration){for(var column in maxValues){maxValues[column]=tr.b.Statistics.max(rows,function(event){return event[column];});}}
-var footerRows=[];if(this.showTotals_){var multiEventSummary=new tr.ui.analysis.MultiEventSummary('Totals',allEvents);footerRows.push(multiEventSummary);}
-this.updateTableColumns_(rows,maxValues);this.$.table.tableRows=rows;this.$.table.footerRows=footerRows;this.$.table.rebuild();}});'use strict';Polymer('tr-ui-a-multi-event-details-table',{created:function(){this.selection_=undefined;this.eventsHaveDuration_=true;this.eventsHaveSubRows_=true;},ready:function(){this.initTitleTable_();},get eventsHaveDuration(){return this.eventsHaveDuration_;},set eventsHaveDuration(eventsHaveDuration){this.eventsHaveDuration_=eventsHaveDuration;this.updateContents_();},get eventsHaveSubRows(){return this.eventsHaveSubRows_;},set eventsHaveSubRows(eventsHaveSubRows){this.eventsHaveSubRows_=eventsHaveSubRows;this.updateContents_();},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;this.updateContents_();},updateContents_:function(){var selection=this.selection_;this.updateTitleTable_();if(this.selection_===undefined){this.$.table.tableRows=[];this.$.table.tableFooterRows=[];this.$.table.rebuild();return;}
-var summary=new tr.ui.analysis.MultiEventSummary('Totals',this.selection_);this.updateColumns_(summary);this.updateRows_(summary);this.$.table.rebuild();},initTitleTable_:function(){var table=this.$.titletable;table.showHeader=false;table.tableColumns=[{title:'Title',value:function(row){return row.title;},width:'350px'},{title:'Value',width:'100%',value:function(row){return row.value;}}];},updateTitleTable_:function(){var title;if(this.selection_&&this.selection_.length)
-title=this.selection_[0].title;else
-title='<No selection>';var table=this.$.titletable;table.tableRows=[{title:'Title',value:title}];},updateColumns_:function(summary){var hasCpuData;if(summary.cpuDuration!==undefined)
-hasCpuData=true;if(summary.cpuSelfTime!==undefined)
-hasCpuData=true;var colWidthPercentage;if(hasCpuData)
-colWidthPercentage='20%';else
-colWidthPercentage='33.3333%';var ownerDocument=this.ownerDocument;var columns=[];columns.push({title:'Start',value:function(row){if(row.__proto__===tr.ui.analysis.MultiEventSummary.prototype){return row.title;}
-var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(row.event);});linkEl.appendChild(tr.v.ui.createScalarSpan(row.start,{unit:tr.v.Unit.byName.timeStampInMs,ownerDocument:ownerDocument}));return linkEl;},width:'350px',cmp:function(rowA,rowB){return rowA.start-rowB.start;}});if(this.eventsHaveDuration_){columns.push({title:'Wall Duration (ms)',value:function(row){return tr.v.ui.createScalarSpan(row.duration,{unit:tr.v.Unit.byName.timeDurationInMs,ownerDocument:ownerDocument});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.duration-rowB.duration;}});}
-if(this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Duration (ms)',value:function(row){return tr.v.ui.createScalarSpan(row.cpuDuration,{unit:tr.v.Unit.byName.timeDurationInMs,ownerDocument:ownerDocument});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.cpuDuration-rowB.cpuDuration;}});}
-if(this.eventsHaveSubRows_&&this.eventsHaveDuration_){columns.push({title:'Self time (ms)',value:function(row){return tr.v.ui.createScalarSpan(row.selfTime,{unit:tr.v.Unit.byName.timeDurationInMs,ownerDocument:ownerDocument});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.selfTime-rowB.selfTime;}});}
-if(this.eventsHaveSubRows_&&this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Self Time (ms)',value:function(row){return tr.v.ui.createScalarSpan(row.cpuSelfTime,{unit:tr.v.Unit.byName.timeDurationInMs,ownerDocument:ownerDocument});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.cpuSelfTime-rowB.cpuSelfTime;}});}
-var argKeys=tr.b.dictionaryKeys(summary.totalledArgs);argKeys.sort();var otherKeys=summary.untotallableArgs.slice(0);otherKeys.sort();argKeys.push.apply(argKeys,otherKeys);var keysWithColumns=argKeys.slice(0,4);var keysInOtherColumn=argKeys.slice(4);keysWithColumns.forEach(function(argKey){var hasTotal=summary.totalledArgs[argKey];var colDesc={title:'Arg: '+argKey,value:function(row){if(row.__proto__!==tr.ui.analysis.MultiEventSummary.prototype){var argView=document.createElement('tr-ui-a-generic-object-view');argView.object=row.args[argKey];return argView;}
-if(hasTotal)
-return row.totalledArgs[argKey];return'';},width:'<upated further down>'};if(hasTotal){colDesc.cmp=function(rowA,rowB){return rowA.args[argKey]-rowB.args[argKey];};}
-columns.push(colDesc);});if(keysInOtherColumn.length){columns.push({title:'Other Args',value:function(row){if(row.__proto__===tr.ui.analysis.MultiEventSummary.prototype)
-return'';var argView=document.createElement('tr-ui-a-generic-object-view');var obj={};for(var i=0;i<keysInOtherColumn.length;i++)
-obj[keysInOtherColumn[i]]=row.args[keysInOtherColumn[i]];argView.object=obj;return argView;},width:'<upated further down>'});}
-var colWidthPercentage;if(columns.length==1)
-colWidthPercentage='100%';else
-colWidthPercentage=(100/(columns.length-1)).toFixed(3)+'%';for(var i=1;i<columns.length;i++)
-columns[i].width=colWidthPercentage;this.$.table.tableColumns=columns;},updateRows_:function(summary){this.$.table.sortColumnIndex=0;function Row(event){this.event=event;}
-Row.prototype={get start(){return this.event.start;},get duration(){return this.event.duration;},get cpuDuration(){return this.event.cpuDuration;},get selfTime(){return this.event.selfTime;},get cpuSelfTime(){return this.event.cpuSelfTime;},get args(){return this.event.args;}};this.$.table.tableRows=this.selection_.map(function(event){return new Row(event);});this.$.table.footerRows=[summary];}});'use strict';Polymer('tr-ui-a-multi-event-sub-view',{created:function(){this.currentSelection_=undefined;this.eventsHaveDuration_=true;this.eventsHaveSubRows_=true;},set selection(selection){if(selection.length<=1)
-throw new Error('Only supports multiple items');this.setSelectionWithoutErrorChecks(selection);},get selection(){return this.currentSelection_;},setSelectionWithoutErrorChecks:function(selection){this.currentSelection_=selection;this.updateContents_();},get eventsHaveDuration(){return this.eventsHaveDuration_;},set eventsHaveDuration(eventsHaveDuration){this.eventsHaveDuration_=eventsHaveDuration;this.updateContents_();},get eventsHaveSubRows(){return this.eventsHaveSubRows_;},set eventsHaveSubRows(eventsHaveSubRows){this.eventsHaveSubRows_=eventsHaveSubRows;this.updateContents_();},updateContents_:function(){var selection=this.currentSelection_;this.$.content.textContent='';if(!selection)
-return;var eventsByTitle=selection.getEventsOrganizedByTitle();var numTitles=tr.b.dictionaryLength(eventsByTitle);var summaryTableEl=document.createElement('tr-ui-a-multi-event-summary-table');summaryTableEl.configure({showTotals:numTitles>1,eventsByTitle:eventsByTitle,eventsHaveDuration:this.eventsHaveDuration_,eventsHaveSubRows:this.eventsHaveSubRows_});this.$.content.appendChild(summaryTableEl);var selectionSummaryTableEl=document.createElement('tr-ui-a-selection-summary-table');selectionSummaryTableEl.selection=this.currentSelection_;this.$.content.appendChild(selectionSummaryTableEl);if(numTitles===1){var detailsTableEl=document.createElement('tr-ui-a-multi-event-details-table');detailsTableEl.eventsHaveDuration=this.eventsHaveDuration_;detailsTableEl.eventsHaveSubRows=this.eventsHaveSubRows_;detailsTableEl.selection=selection;this.$.content.appendChild(detailsTableEl);}}});'use strict';tr.exportTo('tr.ui.analysis',function(){var FLOW_IN=0x1;var FLOW_OUT=0x2;var FLOW_IN_OUT=FLOW_IN|FLOW_OUT;function FlowClassifier(){this.numEvents_=0;this.eventsByGUID_={};}
-FlowClassifier.prototype={getFS_:function(event){var fs=this.eventsByGUID_[event.guid];if(fs===undefined){this.numEvents_++;fs={state:0,event:event};this.eventsByGUID_[event.guid]=fs;}
-return fs;},addInFlow:function(event){var fs=this.getFS_(event);fs.state|=FLOW_IN;return event;},addOutFlow:function(event){var fs=this.getFS_(event);fs.state|=FLOW_OUT;return event;},hasEvents:function(){return this.numEvents_>0;},get inFlowEvents(){var selection=new tr.model.EventSet();for(var guid in this.eventsByGUID_){var fs=this.eventsByGUID_[guid];if(fs.state===FLOW_IN)
-selection.push(fs.event);}
-return selection;},get outFlowEvents(){var selection=new tr.model.EventSet();for(var guid in this.eventsByGUID_){var fs=this.eventsByGUID_[guid];if(fs.state===FLOW_OUT)
-selection.push(fs.event);}
-return selection;},get internalFlowEvents(){var selection=new tr.model.EventSet();for(var guid in this.eventsByGUID_){var fs=this.eventsByGUID_[guid];if(fs.state===FLOW_IN_OUT)
-selection.push(fs.event);}
-return selection;}};return{FlowClassifier:FlowClassifier};});'use strict';Polymer('tr-ui-a-related-events',{ready:function(){this.eventGroups_=[];this.cancelFunctions_=[];this.$.table.tableColumns=[{title:'Event(s)',value:function(row){var typeEl=document.createElement('span');typeEl.innerText=row.type;if(row.tooltip)
-typeEl.title=row.tooltip;return typeEl;},width:'150px'},{title:'Link',width:'100%',value:function(row){var linkEl=document.createElement('tr-ui-a-analysis-link');if(row.name)
-linkEl.setSelectionAndContent(row.selection,row.name);else
-linkEl.selection=row.selection;return linkEl;}}];},hasRelatedEvents:function(){return(this.eventGroups_&&this.eventGroups_.length>0);},setRelatedEvents:function(eventSet){this.cancelAllTasks_();this.eventGroups_=[];this.addConnectedFlows_(eventSet);this.addConnectedEvents_(eventSet);this.addOverlappingSamples_(eventSet);this.updateContents_();},addConnectedFlows_:function(eventSet){var classifier=new tr.ui.analysis.FlowClassifier();eventSet.forEach(function(slice){if(slice.inFlowEvents){slice.inFlowEvents.forEach(function(flow){classifier.addInFlow(flow);});}
-if(slice.outFlowEvents){slice.outFlowEvents.forEach(function(flow){classifier.addOutFlow(flow);});}});if(!classifier.hasEvents())
-return;var addToEventGroups=function(type,flowEvent){this.eventGroups_.push({type:type,selection:new tr.model.EventSet(flowEvent),name:flowEvent.title});};classifier.inFlowEvents.forEach(addToEventGroups.bind(this,'Incoming flow'));classifier.outFlowEvents.forEach(addToEventGroups.bind(this,'Outgoing flow'));classifier.internalFlowEvents.forEach(addToEventGroups.bind(this,'Internal flow'));},cancelAllTasks_:function(){this.cancelFunctions_.forEach(function(cancelFunction){cancelFunction();});this.cancelFunctions_=[];},addConnectedEvents_:function(eventSet){this.cancelFunctions_.push(this.createEventsLinkIfNeeded_('Preceding events','Add all events that have led to the selected one(s), connected by '+'flow arrows or by call stack.',eventSet,function(event,events){this.addInFlowEvents_(event,events);this.addAncestors_(event,events);if(event.startSlice)
-events.push(event.startSlice);}.bind(this)));this.cancelFunctions_.push(this.createEventsLinkIfNeeded_('Following events','Add all events that have been caused by the selected one(s), '+'connected by flow arrows or by call stack.',eventSet,function(event,events){this.addOutFlowEvents_(event,events);this.addDescendents_(event,events);if(event.endSlice)
-events.push(event.endSlice);}.bind(this)));this.cancelFunctions_.push(this.createEventsLinkIfNeeded_('All connected events','Add all events connected to the selected one(s) by flow arrows or '+'by call stack.',eventSet,function(event,events){this.addInFlowEvents_(event,events);this.addOutFlowEvents_(event,events);this.addAncestors_(event,events);this.addDescendents_(event,events);if(event.startSlice)
-events.push(event.startSlice);if(event.endSlice)
-events.push(event.endSlice);}.bind(this)));},createEventsLinkIfNeeded_:function(title,tooltip,events,addFunction){events=new tr.model.EventSet(events);var lengthBefore=events.length;var task;var isCanceled=false;function addEventsUntilTimeout(startingIndex){if(isCanceled)
-return;var startingTime=window.performance.now();while(startingIndex<events.length){addFunction(events[startingIndex],events);startingIndex++;if(window.performance.now()-startingTime>8){var newTask=new tr.b.Task(addEventsUntilTimeout.bind(this,startingIndex),this);task.after(newTask);task=newTask;return;}}
-if(lengthBefore===events.length)
-return;this.eventGroups_.push({type:title,tooltip:tooltip,selection:events});this.updateContents_();};function cancelTask(){isCanceled=true;}
-task=new tr.b.Task(addEventsUntilTimeout.bind(this,0),this);tr.b.Task.RunWhenIdle(task);return cancelTask;},addInFlowEvents_:function(event,eventSet){if(!event.inFlowEvents)
-return;event.inFlowEvents.forEach(function(e){eventSet.push(e);});},addOutFlowEvents_:function(event,eventSet){if(!event.outFlowEvents)
-return;event.outFlowEvents.forEach(function(e){eventSet.push(e);});},addAncestors_:function(event,eventSet){if(!event.iterateAllAncestors)
-return;event.iterateAllAncestors(function(e){eventSet.push(e);});},addDescendents_:function(event,eventSet){if(!event.iterateAllDescendents)
-return;event.iterateAllDescendents(function(e){eventSet.push(e);});},addOverlappingSamples_:function(eventSet){var samples=new tr.model.EventSet;eventSet.forEach(function(slice){if(!slice.parentContainer||!slice.parentContainer.samples)
-return;var candidates=slice.parentContainer.samples;var range=tr.b.Range.fromExplicitRange(slice.start,slice.start+slice.duration);var filteredSamples=range.filterArray(candidates,function(value){return value.start;});filteredSamples.forEach(function(sample){samples.push(sample);});}.bind(this));if(samples.length>0){this.eventGroups_.push({type:'Overlapping samples',tooltip:'All samples overlapping the selected slice(s).',selection:samples});}},updateContents_:function(){var table=this.$.table;if(this.eventGroups_===undefined)
-table.tableRows=[];else
-table.tableRows=this.eventGroups_.slice();table.rebuild();}});'use strict';Polymer('tr-ui-a-multi-async-slice-sub-view',{get selection(){return this.$.content.selection;},set selection(selection){this.$.content.selection=selection;this.$.relatedEvents.setRelatedEvents(selection);if(this.$.relatedEvents.hasRelatedEvents()){this.$.relatedEvents.style.display='';}else{this.$.relatedEvents.style.display='none';}},get relatedEventsToHighlight(){if(!this.$.content.selection)
-return undefined;var selection=new tr.model.EventSet();this.$.content.selection.forEach(function(asyncEvent){if(!asyncEvent.associatedEvents)
-return;asyncEvent.associatedEvents.forEach(function(event){selection.push(event);});});if(selection.length)
-return selection;return undefined;}});'use strict';Polymer('tr-ui-a-multi-cpu-slice-sub-view',{ready:function(){this.$.content.eventsHaveSubRows=false;},get selection(){return this.$.content.selection;},set selection(selection){this.$.content.setSelectionWithoutErrorChecks(selection);}});'use strict';Polymer('tr-ui-a-multi-flow-event-sub-view',{ready:function(){this.$.content.eventsHaveDuration=false;this.$.content.eventsHaveSubRows=false;},set selection(selection){this.$.content.selection=selection;},get selection(){return this.$.content.selection;}});'use strict';Polymer('tr-ui-a-multi-frame-sub-view',{created:function(){this.currentSelection_=undefined;},set selection(selection){this.textContent='';var realView=document.createElement('tr-ui-a-multi-event-sub-view');realView.eventsHaveDuration=false;realView.eventsHaveSubRows=false;this.appendChild(realView);realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;},get selection(){return this.currentSelection_;},get relatedEventsToHighlight(){if(!this.currentSelection_)
-return undefined;var selection=new tr.model.EventSet();this.currentSelection_.forEach(function(frameEvent){frameEvent.associatedEvents.forEach(function(event){selection.push(event);});});return selection;}});'use strict';Polymer('tr-ui-a-multi-instant-event-sub-view',{created:function(){this.currentSelection_=undefined;},set selection(selection){this.$.content.textContent='';var realView=document.createElement('tr-ui-a-multi-event-sub-view');realView.eventsHaveDuration=false;realView.eventsHaveSubRows=false;this.$.content.appendChild(realView);realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;},get selection(){return this.currentSelection_;}});'use strict';Polymer('tr-ui-a-multi-object-sub-view',{created:function(){this.currentSelection_=undefined;},ready:function(){this.$.content.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;var objectEvents=tr.b.asArray(selection).sort(tr.b.Range.compareByMinTimes);var timeSpanConfig={unit:tr.v.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument};var table=this.$.content;table.tableColumns=[{title:'First',value:function(event){if(event instanceof tr.model.ObjectSnapshot)
-return tr.v.ui.createScalarSpan(event.ts,timeSpanConfig);var spanEl=document.createElement('span');spanEl.appendChild(tr.v.ui.createScalarSpan(event.creationTs,timeSpanConfig));spanEl.appendChild(tr.ui.b.createSpan({textContent:'-',marginLeft:'4px',marginRight:'4px'}));if(event.deletionTs!=Number.MAX_VALUE){spanEl.appendChild(tr.v.ui.createScalarSpan(event.deletionTs,timeSpanConfig));}
-return spanEl;},width:'200px'},{title:'Second',value:function(event){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(event);},event.userFriendlyName);return linkEl;},width:'100%'}];table.tableRows=objectEvents;table.rebuild();}});'use strict';var EventSet=tr.model.EventSet;var CHART_TITLE='Power (W) by ms since vertical sync';var CHART_WIDTH_FRACTION_OF_BODY=0.5;Polymer('tr-ui-a-frame-power-usage-chart',{ready:function(){this.chart_=undefined;this.samples_=new EventSet();this.vSyncTimestamps_=[];},get chart(){return this.chart_;},get samples(){return this.samples_;},get vSyncTimestamps(){return this.vSyncTimestamps_;},setData:function(samples,vSyncTimestamps){this.samples_=(samples===undefined)?new EventSet():samples;this.vSyncTimestamps_=(vSyncTimestamps===undefined)?[]:vSyncTimestamps;this.updateContents_();},updateContents_:function(){this.clearChart_();var data=this.getDataForLineChart_();if(data.length===0)
-return;this.chart_=this.createChart_(data);this.$.content.appendChild(this.chart_);},createChart_:function(data){var chart=new tr.ui.b.LineChart();var width=document.body.clientWidth*CHART_WIDTH_FRACTION_OF_BODY;chart.setSize({width:width,height:chart.height});chart.chartTitle=CHART_TITLE;chart.data=data;return chart;},clearChart_:function(){var content=this.$.content;while(content.firstChild)
-content.removeChild(content.firstChild);this.chart_=undefined;},getDataForLineChart_:function(){var sortedSamples=this.sortSamplesByTimestampAscending_(this.samples);var vSyncTimestamps=this.vSyncTimestamps.slice();var lastVSyncTimestamp=undefined;var points=[];var frameNumber=0;sortedSamples.forEach(function(sample){while(vSyncTimestamps.length>0&&vSyncTimestamps[0]<=sample.start){lastVSyncTimestamp=vSyncTimestamps.shift();frameNumber++;}
-if(lastVSyncTimestamp===undefined)
-return;var point={x:sample.start-lastVSyncTimestamp};point['f'+frameNumber]=sample.power/1000;points.push(point);});return points;},sortSamplesByTimestampAscending_:function(samples){return samples.toArray().sort(function(smpl1,smpl2){return smpl1.start-smpl2.start;});}});'use strict';Polymer('tr-ui-a-power-sample-summary-table',{ready:function(){this.$.table.tableColumns=[{title:'Min power',width:'100px',value:function(row){return tr.v.Unit.byName.powerInWatts.format(row.min/1000.0);}},{title:'Max power',width:'100px',value:function(row){return tr.v.Unit.byName.powerInWatts.format(row.max/1000.0);}},{title:'Time-weighted average',width:'100px',value:function(row){return tr.v.Unit.byName.powerInWatts.format(row.timeWeightedAverage/1000.0);}},{title:'Energy consumed',width:'100px',value:function(row){return tr.v.Unit.byName.energyInJoules.format(row.energyConsumed);}},{title:'Sample count',width:'100%',value:function(row){return row.sampleCount;}}];this.samples=new tr.model.EventSet();},get samples(){return this.samples_;},set samples(samples){if(samples===this.samples)
-return;this.samples_=(samples===undefined)?new tr.model.EventSet():samples;this.updateContents_();},updateContents_:function(){if(this.samples.length===0){this.$.table.tableRows=[];}else{this.$.table.tableRows=[{min:this.getMin(),max:this.getMax(),timeWeightedAverage:this.getTimeWeightedAverage(),energyConsumed:this.getEnergyConsumed(),sampleCount:this.samples.length}];}
-this.$.table.rebuild();},getMin:function(){return Math.min.apply(null,this.samples.map(function(sample){return sample.power;}));},getMax:function(){return Math.max.apply(null,this.samples.map(function(sample){return sample.power;}));},getTimeWeightedAverage:function(){var energyConsumed=this.getEnergyConsumed();if(energyConsumed==='N/A')
-return'N/A';var energyInMillijoules=this.getEnergyConsumed()*1000;var durationInSeconds=this.samples.bounds.duration/1000;return energyInMillijoules/durationInSeconds;},getEnergyConsumed:function(){if(this.samples.length<2)
-return'N/A';var bounds=this.samples.bounds;return this.samples[0].series.getEnergyConsumed(bounds.min,bounds.max);}});'use strict';var EventSet=tr.model.EventSet;Polymer('tr-ui-a-power-sample-table',{ready:function(){this.$.table.tableColumns=[{title:'Time',width:'100px',value:function(row){return tr.v.ui.createScalarSpan(row.start,{unit:tr.v.Unit.byName.timeStampInMs});}},{title:'Power',width:'100%',value:function(row){return tr.v.ui.createScalarSpan(row.power/1000,{unit:tr.v.Unit.byName.powerInWatts});}}];this.samples=new EventSet();},get samples(){return this.samples_;},set samples(samples){this.samples_=(samples===undefined)?new EventSet():samples;this.updateContents_();},updateContents_:function(){this.$.table.tableRows=this.samples.toArray();this.$.table.rebuild();}});'use strict';Polymer('tr-ui-a-multi-power-sample-sub-view',{ready:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},updateContents_:function(){var samples=this.selection;var vSyncTimestamps=(this.selection===undefined)?[]:this.selection[0].series.device.vSyncTimestamps;this.$.summaryTable.samples=samples;this.$.samplesTable.samples=samples;this.$.chart.setData(this.selection,vSyncTimestamps);}});'use strict';(function(){Polymer('tr-ui-a-multi-sample-sub-view',{created:function(){this.viewOption_=undefined;this.selection_=undefined;},ready:function(){var viewSelector=tr.ui.b.createSelector(this,'viewOption','tracing.ui.analysis.multi_sample_sub_view',tr.b.MultiDimensionalViewType.TOP_DOWN_TREE_VIEW,[{label:'Top-down (Tree)',value:tr.b.MultiDimensionalViewType.TOP_DOWN_TREE_VIEW},{label:'Top-down (Heavy)',value:tr.b.MultiDimensionalViewType.TOP_DOWN_HEAVY_VIEW},{label:'Bottom-up (Heavy)',value:tr.b.MultiDimensionalViewType.BOTTOM_UP_HEAVY_VIEW}]);this.$.control.appendChild(viewSelector);this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;this.updateContents_();},get viewOption(){return this.viewOption_;},set viewOption(viewOption){this.viewOption_=viewOption;this.updateContents_();},createSamplingSummary_:function(selection,viewOption){var builder=new tr.b.MultiDimensionalViewBuilder(1);var samples=selection.getEventsOrganizedByBaseType().sample;samples.forEach(function(sample){builder.addPath([sample.getUserFriendlyStackTrace().reverse()],1,tr.b.MultiDimensionalViewBuilder.ValueKind.SELF);});return builder.buildView(viewOption);},updateContents_:function(){if(this.selection===undefined){this.$.table.tableColumns=[];this.$.table.tableRows=[];this.$.table.rebuild();return;}
-var samplingData=this.createSamplingSummary_(this.selection,this.viewOption);var columns=[this.createPercentColumn_('Total',samplingData.total),this.createSamplesColumn_('Total'),this.createPercentColumn_('Self',samplingData.total),this.createSamplesColumn_('Self'),{title:'Symbol',value:function(row){return row.title[0];},width:'250px',cmp:function(a,b){return a.title[0].localeCompare(b.title[0]);},showExpandButtons:true}];this.$.table.tableColumns=columns;this.$.table.sortColumnIndex=1;this.$.table.sortDescending=true;this.$.table.tableRows=samplingData.subRows;this.$.table.rebuild();},createPercentColumn_:function(title,samplingDataTotal){var field=title.toLowerCase();return{title:title+' percent',value:function(row){var percent=row[field]/samplingDataTotal;var span=document.createElement('tr-v-ui-scalar-span');span.value=(percent*100).toFixed(2);span.percentage=percent;span.unit=tr.v.Unit.byName.unitlessNumber;return span;}.bind(this),width:'60px',cmp:function(a,b){return a[field]-b[field];}};},createSamplesColumn_:function(title){var field=title.toLowerCase();return{title:title+' samples',value:function(row){return row[field];},width:'60px',cmp:function(a,b){return a[field]-b[field];}};}});})();'use strict';Polymer('tr-ui-a-multi-thread-slice-sub-view',{created:function(){this.selection_=undefined;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;if(tr.isExported('tr.ui.e.chrome.cc.RasterTaskSelection')){if(tr.ui.e.chrome.cc.RasterTaskSelection.supports(selection)){var ltvSelection=new tr.ui.e.chrome.cc.RasterTaskSelection(selection);var ltv=new tr.ui.e.chrome.cc.LayerTreeHostImplSnapshotView();ltv.objectSnapshot=ltvSelection.containingSnapshot;ltv.selection=ltvSelection;ltv.extraHighlightsByLayerId=ltvSelection.extraHighlightsByLayerId;this.$.content.textContent='';this.$.content.appendChild(ltv);this.requiresTallView_=true;return;}}
-this.$.content.textContent='';var mesv=document.createElement('tr-ui-a-multi-event-sub-view');mesv.selection=selection;this.$.content.appendChild(mesv);var relatedEvents=document.createElement('tr-ui-a-related-events');relatedEvents.setRelatedEvents(selection);if(relatedEvents.hasRelatedEvents()){this.$.content.appendChild(relatedEvents);}},get requiresTallView(){if(this.$.content.children.length===0)
-return false;var childTagName=this.$.content.children[0].tagName;if(childTagName==='TR-UI-A-MULTI-EVENT-SUB-VIEW')
-return false;return true;}});'use strict';Polymer('tr-ui-a-multi-thread-time-slice-sub-view',{ready:function(){this.$.content.eventsHaveSubRows=false;},get selection(){return this.$.content.selection;},set selection(selection){this.$.content.setSelectionWithoutErrorChecks(selection);}});'use strict';Polymer('tr-ui-a-multi-user-expectation-sub-view',{created:function(){this.currentSelection_=undefined;},set selection(selection){this.currentSelection_=selection;this.textContent='';var realView=document.createElement('tr-ui-a-multi-event-sub-view');this.appendChild(realView);realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;},get selection(){return this.currentSelection_;},get relatedEventsToHighlight(){if(!this.currentSelection_)
-return undefined;var selection=new tr.model.EventSet();this.currentSelection_.forEach(function(ir){ir.associatedEvents.forEach(function(event){selection.push(event);});});return selection;}});'use strict';Polymer('tr-ui-a-single-async-slice-sub-view',{get selection(){return this.$.content.selection;},set selection(selection){if(selection.length!==1)
-throw new Error('Only supports single slices');this.$.content.setSelectionWithoutErrorChecks(selection);this.$.relatedEvents.setRelatedEvents(selection);if(this.$.relatedEvents.hasRelatedEvents()){this.$.relatedEvents.style.display='';}else{this.$.relatedEvents.style.display='none';}},getEventRows_:function(event){var rows=this.__proto__.__proto__.getEventRows_(event);rows.splice(0,0,{name:'ID',value:event.id});return rows;},get relatedEventsToHighlight(){if(!this.currentSelection_)
-return undefined;return this.currentSelection_[0].associatedEvents;}});'use strict';Polymer('tr-ui-a-single-cpu-slice-sub-view',{created:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1)
-throw new Error('Only supports single slices');if(!(selection[0]instanceof tr.model.CpuSlice))
-throw new Error('Only supports thread time slices');this.currentSelection_=selection;var cpuSlice=selection[0];var thread=cpuSlice.threadThatWasRunning;var shadowRoot=this.shadowRoot;if(thread){shadowRoot.querySelector('#process-name').textContent=thread.parent.userFriendlyName;shadowRoot.querySelector('#thread-name').textContent=thread.userFriendlyName;}else{shadowRoot.querySelector('#process-name').parentElement.style.display='none';shadowRoot.querySelector('#thread-name').textContent=cpuSlice.title;}
-shadowRoot.querySelector('#start').setValueAndUnit(cpuSlice.start,tr.v.Unit.byName.timeStampInMs);shadowRoot.querySelector('#duration').setValueAndUnit(cpuSlice.duration,tr.v.Unit.byName.timeDurationInMs);var runningThreadEl=shadowRoot.querySelector('#running-thread');var timeSlice=cpuSlice.getAssociatedTimeslice();if(!timeSlice){runningThreadEl.parentElement.style.display='none';}else{var threadLink=document.createElement('tr-ui-a-analysis-link');threadLink.selection=new tr.model.EventSet(timeSlice);threadLink.textContent='Click to select';runningThreadEl.parentElement.style.display='';runningThreadEl.textContent='';runningThreadEl.appendChild(threadLink);}
-shadowRoot.querySelector('#args').object=cpuSlice.args;}});'use strict';Polymer('tr-ui-a-single-flow-event-sub-view',{getEventRows_:function(event){var rows=this.__proto__.__proto__.getEventRows_(event);rows.splice(0,0,{name:'ID',value:event.id});function createLinkTo(slice){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(slice);});linkEl.textContent=slice.userFriendlyName;return linkEl;}
-rows.push({name:'From',value:createLinkTo(event.startSlice)});rows.push({name:'To',value:createLinkTo(event.endSlice)});return rows;}});'use strict';Polymer('tr-ui-a-single-frame-sub-view',{ready:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!=1)
-throw new Error('Only supports single frame!');this.currentSelection_=selection;this.$.asv.selection=selection[0].associatedAlerts;},get relatedEventsToHighlight(){if(!this.currentSelection_)
-return undefined;return this.currentSelection_[0].associatedEvents;}});'use strict';Polymer('tr-ui-a-single-instant-event-sub-view',{created:function(){this.currentSelection_=undefined;},set selection(selection){this.$.content.textContent='';var realView=document.createElement('tr-ui-a-single-event-sub-view');realView.setSelectionWithoutErrorChecks(selection);this.$.content.appendChild(realView);this.currentSelection_=selection;},get selection(){return this.currentSelection_;}});'use strict';tr.exportTo('tr.ui.analysis',function(){var ObjectInstanceView=tr.ui.b.define('object-instance-view');ObjectInstanceView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.objectInstance_=undefined;},get requiresTallView(){return true;},set modelEvent(obj){this.objectInstance=obj;},get modelEvent(){return this.objectInstance;},get objectInstance(){return this.objectInstance_;},set objectInstance(i){this.objectInstance_=i;this.updateContents();},updateContents:function(){throw new Error('Not implemented');}};var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectInstanceView;options.defaultMetadata={showInTrackView:true};tr.b.decorateExtensionRegistry(ObjectInstanceView,options);return{ObjectInstanceView:ObjectInstanceView};});'use strict';Polymer('tr-ui-a-single-object-instance-sub-view',{created:function(){this.currentSelection_=undefined;},get requiresTallView(){if(this.$.content.children.length===0)
-return false;if(this.$.content.children[0]instanceof
-tr.ui.analysis.ObjectInstanceView)
-return this.$.content.children[0].requiresTallView;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1)
-throw new Error('Only supports single item selections');if(!(selection[0]instanceof tr.model.ObjectInstance))
-throw new Error('Only supports object instances');this.$.content.textContent='';this.currentSelection_=selection;var instance=selection[0];var typeInfo=tr.ui.analysis.ObjectInstanceView.getTypeInfo(instance.category,instance.typeName);if(typeInfo){var customView=new typeInfo.constructor();this.$.content.appendChild(customView);customView.modelEvent=instance;}else{this.appendGenericAnalysis_(instance);}},appendGenericAnalysis_:function(instance){var html='';html+='<div class="title">'+
+if(totalledArgs[argName]===undefined){totalledArgs[argName]=0;}
+totalledArgs[argName]+=argVal;}}
+this.untotallableArgs_=Object.keys(untotallableArgs);this.totalledArgs_=totalledArgs;}};return{MultiEventSummary,};});'use strict';Polymer({is:'tr-ui-a-multi-event-summary-table',ready(){this.showTotals_=false;this.eventsHaveDuration_=true;this.eventsHaveSubRows_=true;this.eventsByTitle_=undefined;},updateTableColumns_(rows,maxValues){let hasCpuData=false;let hasAlerts=false;rows.forEach(function(row){if(row.cpuDuration!==undefined){hasCpuData=true;}
+if(row.cpuSelfTime!==undefined){hasCpuData=true;}
+if(row.numAlerts){hasAlerts=true;}});const ownerDocument=this.ownerDocument;const columns=[];columns.push({title:'Name',value(row){if(row.title==='Totals')return'Totals';const container=document.createElement('div');const linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(row.events);},row.title);container.appendChild(linkEl);if(tr.isExported('tr-ui-e-chrome-codesearch')){const link=document.createElement('tr-ui-e-chrome-codesearch');link.searchPhrase=row.title;container.appendChild(link);}
+return container;},width:'350px',cmp(rowA,rowB){return rowA.title.localeCompare(rowB.title);}});if(this.eventsHaveDuration_){columns.push({title:'Wall Duration',value(row){return tr.v.ui.createScalarSpan(row.duration,{unit:tr.b.Unit.byName.timeDurationInMs,customContextRange:row.totalsRow?undefined:tr.b.math.Range.fromExplicitRange(0,maxValues.duration),ownerDocument,});},width:'<upated further down>',cmp(rowA,rowB){return rowA.duration-rowB.duration;}});}
+if(this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Duration',value(row){return tr.v.ui.createScalarSpan(row.cpuDuration,{unit:tr.b.Unit.byName.timeDurationInMs,customContextRange:row.totalsRow?undefined:tr.b.math.Range.fromExplicitRange(0,maxValues.cpuDuration),ownerDocument,});},width:'<upated further down>',cmp(rowA,rowB){return rowA.cpuDuration-rowB.cpuDuration;}});}
+if(this.eventsHaveSubRows_&&this.eventsHaveDuration_){columns.push({title:'Self time',value(row){return tr.v.ui.createScalarSpan(row.selfTime,{unit:tr.b.Unit.byName.timeDurationInMs,customContextRange:row.totalsRow?undefined:tr.b.math.Range.fromExplicitRange(0,maxValues.selfTime),ownerDocument,});},width:'<upated further down>',cmp(rowA,rowB){return rowA.selfTime-rowB.selfTime;}});}
+if(this.eventsHaveSubRows_&&this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Self Time',value(row){return tr.v.ui.createScalarSpan(row.cpuSelfTime,{unit:tr.b.Unit.byName.timeDurationInMs,customContextRange:row.totalsRow?undefined:tr.b.math.Range.fromExplicitRange(0,maxValues.cpuSelfTime),ownerDocument,});},width:'<upated further down>',cmp(rowA,rowB){return rowA.cpuSelfTime-rowB.cpuSelfTime;}});}
+if(this.eventsHaveDuration_){columns.push({title:'Average '+(hasCpuData?'CPU':'Wall')+' Duration',value(row){const totalDuration=hasCpuData?row.cpuDuration:row.duration;return tr.v.ui.createScalarSpan(totalDuration/row.numEvents,{unit:tr.b.Unit.byName.timeDurationInMs,customContextRange:row.totalsRow?undefined:tr.b.math.Range.fromExplicitRange(0,maxValues.duration),ownerDocument,});},width:'<upated further down>',cmp(rowA,rowB){if(hasCpuData){return rowA.cpuDuration/rowA.numEvents-
+rowB.cpuDuration/rowB.numEvents;}
+return rowA.duration/rowA.numEvents-
+rowB.duration/rowB.numEvents;}});}
+columns.push({title:'Occurrences',value(row){return row.numEvents;},width:'<upated further down>',cmp(rowA,rowB){return rowA.numEvents-rowB.numEvents;}});let alertsColumnIndex;if(hasAlerts){columns.push({title:'Num Alerts',value(row){return row.numAlerts;},width:'<upated further down>',cmp(rowA,rowB){return rowA.numAlerts-rowB.numAlerts;}});alertsColumnIndex=columns.length-1;}
+let colWidthPercentage;if(columns.length===1){colWidthPercentage='100%';}else{colWidthPercentage=(100/(columns.length-1)).toFixed(3)+'%';}
+for(let i=1;i<columns.length;i++){columns[i].width=colWidthPercentage;}
+this.$.table.tableColumns=columns;if(hasAlerts){this.$.table.sortColumnIndex=alertsColumnIndex;this.$.table.sortDescending=true;}},configure(config){if(config.eventsByTitle===undefined){throw new Error('Required: eventsByTitle');}
+if(config.showTotals!==undefined){this.showTotals_=config.showTotals;}else{this.showTotals_=true;}
+if(config.eventsHaveDuration!==undefined){this.eventsHaveDuration_=config.eventsHaveDuration;}else{this.eventsHaveDuration_=true;}
+if(config.eventsHaveSubRows!==undefined){this.eventsHaveSubRows_=config.eventsHaveSubRows;}else{this.eventsHaveSubRows_=true;}
+this.eventsByTitle_=config.eventsByTitle;this.updateContents_();},get showTotals(){return this.showTotals_;},set showTotals(showTotals){this.showTotals_=showTotals;this.updateContents_();},get eventsHaveDuration(){return this.eventsHaveDuration_;},set eventsHaveDuration(eventsHaveDuration){this.eventsHaveDuration_=eventsHaveDuration;this.updateContents_();},get eventsHaveSubRows(){return this.eventsHaveSubRows_;},set eventsHaveSubRows(eventsHaveSubRows){this.eventsHaveSubRows_=eventsHaveSubRows;this.updateContents_();},get eventsByTitle(){return this.eventsByTitle_;},set eventsByTitle(eventsByTitle){this.eventsByTitle_=eventsByTitle;this.updateContents_();},get selectionBounds(){return this.selectionBounds_;},set selectionBounds(selectionBounds){this.selectionBounds_=selectionBounds;this.updateContents_();},updateContents_(){let eventsByTitle;if(this.eventsByTitle_!==undefined){eventsByTitle=this.eventsByTitle_;}else{eventsByTitle=[];}
+const allEvents=new tr.model.EventSet();const rows=[];for(const[title,eventsOfSingleTitle]of Object.entries(eventsByTitle)){for(const event of eventsOfSingleTitle)allEvents.push(event);const row=new tr.ui.analysis.MultiEventSummary(title,eventsOfSingleTitle);rows.push(row);}
+this.updateTableColumns_(rows);this.$.table.tableRows=rows;const maxValues={duration:undefined,selfTime:undefined,cpuSelfTime:undefined,cpuDuration:undefined};if(this.eventsHaveDuration){for(const column in maxValues){maxValues[column]=tr.b.math.Statistics.max(rows,function(event){return event[column];});}}
+const footerRows=[];if(this.showTotals_){const multiEventSummary=new tr.ui.analysis.MultiEventSummary('Totals',allEvents);footerRows.push(multiEventSummary);}
+this.updateTableColumns_(rows,maxValues);this.$.table.tableRows=rows;this.$.table.footerRows=footerRows;this.$.table.rebuild();}});'use strict';Polymer({is:'tr-ui-a-selection-summary-table',created(){this.selection_=new tr.b.math.Range();},ready(){this.$.table.showHeader=false;this.$.table.tableColumns=[{title:'Name',value(row){return row.title;},width:'350px'},{title:'Value',width:'100%',value(row){return row.value;}}];},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;this.updateContents_();},updateContents_(){const selection=this.selection_;const rows=[];let hasRange;if(this.selection_&&(!selection.bounds.isEmpty)){hasRange=true;}else{hasRange=false;}
+rows.push({title:'Selection start',value:hasRange?tr.v.ui.createScalarSpan(selection.bounds.min,{unit:tr.b.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument}):'<empty>'});rows.push({title:'Selection extent',value:hasRange?tr.v.ui.createScalarSpan(selection.bounds.range,{unit:tr.b.Unit.byName.timeDurationInMs,ownerDocument:this.ownerDocument}):'<empty>'});this.$.table.tableRows=rows;this.$.table.rebuild();}});'use strict';Polymer({is:'tr-ui-b-radio-picker',created(){this.needsInit_=true;this.settingsKey_=undefined;this.isReady_=false;this.radioButtons_=undefined;this.selectedKey_=undefined;},ready(){this.isReady_=true;this.maybeInit_();this.maybeRenderRadioButtons_();},get vertical(){return this.getAttribute('vertical');},set vertical(vertical){if(vertical){this.setAttribute('vertical',true);}else{this.removeAttribute('vertical');}},get settingsKey(){return this.settingsKey_;},set settingsKey(settingsKey){if(!this.needsInit_){throw new Error('Already initialized.');}
+this.settingsKey_=settingsKey;this.maybeInit_();},maybeInit_(){if(!this.needsInit_)return;if(this.settingsKey_===undefined)return;this.needsInit_=false;this.select(tr.b.Settings.get(this.settingsKey_));},set items(items){this.radioButtons_={};items.forEach(function(e){if(e.key in this.radioButtons_){throw new Error(e.key+' already exists');}
+const radioButton=document.createElement('div');const input=document.createElement('input');const label=document.createElement('label');input.type='radio';input.id=e.label;input.addEventListener('click',function(){this.select(e.key);}.bind(this));Polymer.dom(label).innerHTML=e.label;label.htmlFor=e.label;label.style.display='inline';Polymer.dom(radioButton).appendChild(input);Polymer.dom(radioButton).appendChild(label);this.radioButtons_[e.key]=input;}.bind(this));this.maybeInit_();this.maybeRenderRadioButtons_();},maybeRenderRadioButtons_(){if(!this.isReady_)return;if(this.radioButtons_===undefined)return;for(const key in this.radioButtons_){Polymer.dom(this.$.container).appendChild(this.radioButtons_[key].parentElement);}
+if(this.selectedKey_!==undefined){this.select(this.selectedKey_);}},select(key){if(key===undefined||key===this.selectedKey_){return;}
+if(this.radioButtons_===undefined){this.selectedKey_=key;return;}
+if(!(key in this.radioButtons_)){throw new Error(key+' does not exists');}
+if(this.selectedKey_!==undefined){this.radioButtons_[this.selectedKey_].checked=false;}
+this.selectedKey_=key;tr.b.Settings.set(this.settingsKey_,this.selectedKey_);if(this.selectedKey_!==undefined){this.radioButtons_[this.selectedKey_].checked=true;}
+this.dispatchEvent(new tr.b.Event('change',false));},get selectedKey(){return this.selectedKey_;},});'use strict';tr.exportTo('tr.ui.b',function(){const MIN_GUIDELINE_HEIGHT_PX=3;const CHECKBOX_WIDTH_PX=18;const NameColumnChart=tr.ui.b.define('name-column-chart',tr.ui.b.ColumnChart);NameColumnChart.prototype={__proto__:tr.ui.b.ColumnChart.prototype,get xAxisHeight(){return 5+(this.textHeightPx_*this.data_.length);},updateMargins_(){super.updateMargins_();let xAxisTickOverhangPx=0;for(let i=0;i<this.data_.length;++i){const datum=this.data_[i];xAxisTickOverhangPx=Math.max(xAxisTickOverhangPx,this.xScale_(i)+tr.ui.b.getSVGTextSize(this,datum.x).width-
+this.graphWidth);}
+this.margin.right=Math.max(this.margin.right,xAxisTickOverhangPx);},getXForDatum_(datum,index){return index;},get xAxisTickOffset(){return 0.5;},updateXAxis_(xAxis){xAxis.selectAll('*').remove();if(this.hideXAxis)return;const nameTexts=xAxis.selectAll('text').data(this.data_);nameTexts.enter().append('text').attr('transform',(d,index)=>'translate(0, '+
+this.textHeightPx_*(this.data_.length-index)+')').attr('x',(d,index)=>this.xScale_(index)).attr('y',d=>this.graphHeight).text(d=>d.x);nameTexts.exit().remove();const guideLines=xAxis.selectAll('line.guide').data(this.data_);guideLines.enter().append('line').attr('x1',(d,index)=>this.xScale_(index+this.xAxisTickOffset)).attr('x2',(d,index)=>this.xScale_(index+this.xAxisTickOffset)).attr('y1',()=>this.graphHeight).attr('y2',(d,index)=>this.graphHeight+Math.max(MIN_GUIDELINE_HEIGHT_PX,(this.textHeightPx_*(this.data_.length-index-1))));}};return{NameColumnChart,};});'use strict';tr.exportTo('tr.ui.b',function(){const LineChart=tr.ui.b.LineChart;const NameLineChart=tr.ui.b.define('name-line-chart',LineChart);NameLineChart.prototype={__proto__:LineChart.prototype,getXForDatum_(datum,index){return index;},get xAxisHeight(){return 5+(this.textHeightPx_*this.data_.length);},get xAxisTickOffset(){return 0;},updateMargins_(){tr.ui.b.NameColumnChart.prototype.updateMargins_.call(this);},updateXAxis_(xAxis){xAxis.selectAll('*').remove();if(this.hideXAxis)return;tr.ui.b.NameColumnChart.prototype.updateXAxis_.call(this,xAxis);const baseline=xAxis.selectAll('path').data([this]);baseline.enter().append('line').attr('stroke','black').attr('x1',this.xScale_(0)).attr('x2',this.xScale_(this.data_.length-1)).attr('y1',this.graphHeight).attr('y2',this.graphHeight);baseline.exit().remove();}};return{NameLineChart,};});'use strict';tr.exportTo('tr.ui.b',function(){const BoxChart=tr.ui.b.define('box-chart',tr.ui.b.NameLineChart);BoxChart.prototype={__proto__:tr.ui.b.NameLineChart.prototype,get hideLegend(){return true;},updateDataRange_(){if(this.overrideDataRange_!==undefined){return;}
+this.autoDataRange_.reset();for(const datum of this.data_){this.autoDataRange_.addValue(datum.percentile_0);this.autoDataRange_.addValue(datum.percentile_100);}},updateScales_(){super.updateScales_();this.xScale_.domain([0,this.data_.length]);},get xAxisTickOffset(){return 0.5;},updateDataRange_(){if(this.overrideDataRange_!==undefined)return;this.autoDataRange_.reset();for(const datum of this.data_){this.autoDataRange_.addValue(datum.percentile_0);this.autoDataRange_.addValue(datum.percentile_100);}},updateXAxis_(xAxis){xAxis.selectAll('*').remove();if(this.hideXAxis)return;tr.ui.b.NameColumnChart.prototype.updateXAxis_.call(this,xAxis);const baseline=xAxis.selectAll('path').data([this]);baseline.enter().append('line').attr('stroke','black').attr('x1',this.xScale_(0)).attr('x2',this.xScale_(this.data_.length)).attr('y1',this.graphHeight).attr('y2',this.graphHeight);baseline.exit().remove();},updateDataContents_(dataSel){dataSel.selectAll('*').remove();const boxesSel=dataSel.selectAll('path');for(let index=0;index<this.data_.length;++index){const datum=this.data_[index];const color=datum.color||'black';let sel=boxesSel.data([datum]);sel.enter().append('rect').attr('fill',color).attr('x',this.xScale_(index+0.2)).attr('width',this.xScale_(index+0.8)-this.xScale_(index+0.2)).attr('y',this.yScale_(datum.percentile_75)).attr('height',this.yScale_(datum.percentile_25)-
+this.yScale_(datum.percentile_75));sel.exit().remove();sel=boxesSel.data([datum]);sel.enter().append('line').attr('stroke',color).attr('x1',this.xScale_(index)).attr('x2',this.xScale_(index+1)).attr('y1',this.yScale_(datum.percentile_50)).attr('y2',this.yScale_(datum.percentile_50));sel.exit().remove();sel=boxesSel.data([datum]);sel.enter().append('line').attr('stroke',color).attr('x1',this.xScale_(index+0.4)).attr('x2',this.xScale_(index+0.6)).attr('y1',this.yScale_(datum.percentile_0)).attr('y2',this.yScale_(datum.percentile_0));sel.exit().remove();sel=boxesSel.data([datum]);sel.enter().append('line').attr('stroke',color).attr('x1',this.xScale_(index+0.4)).attr('x2',this.xScale_(index+0.6)).attr('y1',this.yScale_(datum.percentile_100)).attr('y2',this.yScale_(datum.percentile_100));sel.exit().remove();sel=boxesSel.data([datum]);sel.enter().append('line').attr('stroke',color).attr('x1',this.xScale_(index+0.5)).attr('x2',this.xScale_(index+0.5)).attr('y1',this.yScale_(datum.percentile_100)).attr('y2',this.yScale_(datum.percentile_0));sel.exit().remove();}}};return{BoxChart,};});'use strict';tr.exportTo('tr.ui.b',function(){const BarChart=tr.ui.b.define('bar-chart',tr.ui.b.ColumnChart);BarChart.prototype={__proto__:tr.ui.b.ColumnChart.prototype,decorate(){super.decorate();this.verticalScale_=undefined;this.horizontalScale_=undefined;this.isWaterfall_=false;},updateScales_(){super.updateScales_();this.yScale_.range([this.graphWidth,0]);this.xScale_.range([0,this.graphHeight]);this.verticalScale_=this.isYLogScale_?d3.scale.log(10):d3.scale.linear();this.verticalScale_.domain(this.xScale_.domain());this.verticalScale_.range([this.graphHeight,0]);this.horizontalScale_=d3.scale.linear();this.horizontalScale_.domain(this.yScale_.domain());this.horizontalScale_.range([0,this.graphWidth]);},set isWaterfall(waterfall){this.isWaterfall_=waterfall;if(waterfall){this.getDataSeries('hide').color='transparent';}
+this.updateContents_();},get isWaterfall(){return this.isWaterfall_;},get defaultGraphHeight(){return Math.max(20,10*this.data_.length);},get defaultGraphWidth(){return 100;},get barHeight(){return this.graphHeight/this.data.length;},drawBrush_(brushRectsSel){brushRectsSel.attr('x',0).attr('width',this.graphWidth).attr('y',d=>this.verticalScale_(d.max)).attr('height',d=>this.verticalScale_(d.min)-this.verticalScale_(d.max)).attr('fill','rgb(213, 236, 229)');},getDataPointAtChartPoint_(chartPoint){const flippedPoint={x:this.graphHeight-chartPoint.y,y:this.graphWidth-chartPoint.x};return super.getDataPointAtChartPoint_(flippedPoint);},drawXAxis_(xAxis){xAxis.attr('transform','translate(0,'+this.graphHeight+')').call(d3.svg.axis().scale(this.horizontalScale_).orient('bottom'));},get yAxisWidth(){return this.computeScaleTickWidth_(this.verticalScale_);},drawYAxis_(yAxis){const axisModifier=d3.svg.axis().scale(this.verticalScale_).orient('left');yAxis.call(axisModifier);},drawHoverValueBox_(rect){const rectHoverEvent=new tr.b.Event('rect-mouseenter');rectHoverEvent.rect=rect;this.dispatchEvent(rectHoverEvent);if(!this.enableHoverBox||(this.isWaterfall_&&rect.key==='hide')){return;}
+const seriesKeys=[...this.seriesByKey_.keys()];const chartAreaSel=d3.select(this.chartAreaElement);chartAreaSel.selectAll('.hover').remove();let keyWidthPx=0;let keyHeightPx=0;let xWidthPx=0;let xHeightPx=0;let groupWidthPx=0;let groupHeightPx=0;if(seriesKeys.length>1&&!this.isGrouped&&!this.isWaterfall_){keyWidthPx=tr.ui.b.getSVGTextSize(this.chartAreaElement,rect.key).width;keyHeightPx=this.textHeightPx_;}
+if(this.data.length>1&&!this.isWaterfall_){xWidthPx=tr.ui.b.getSVGTextSize(this.chartAreaElement,''+rect.datum.x).width;xHeightPx=this.textHeightPx_;}
+if(this.isGrouped&&rect.datum.group!==undefined){groupWidthPx=tr.ui.b.getSVGTextSize(this.chartAreaElement,rect.datum.group).width;groupHeightPx=this.textHeightPx_;}
+const valueWidthPx=tr.ui.b.getSVGTextSize(this.chartAreaElement,rect.value).width;const valueHeightPx=this.textHeightPx_;const maxWidthPx=Math.max(keyWidthPx,xWidthPx,groupWidthPx,valueWidthPx)+5;const hoverWidthPx=this.isGrouped?maxWidthPx:Math.min(maxWidthPx,Math.max(50,rect.widthPx));let hoverTopPx=rect.topPx;hoverTopPx=Math.min(hoverTopPx,this.getBoundingClientRect().height-
+valueHeightPx);let hoverLeftPx=rect.leftPx+(rect.widthPx/2);hoverLeftPx=Math.max(hoverLeftPx-hoverWidthPx,-this.margin.left);chartAreaSel.append('rect').attr('class','hover').attr('fill','white').attr('x',hoverLeftPx).attr('y',hoverTopPx).attr('width',hoverWidthPx).attr('height',keyHeightPx+xHeightPx+
+valueHeightPx+groupHeightPx);if(seriesKeys.length>1&&!this.isGrouped&&!this.isWaterfall_){chartAreaSel.append('text').attr('class','hover').attr('fill',rect.color==='transparent'?'#000000':rect.color).attr('x',hoverLeftPx+2).attr('y',hoverTopPx+keyHeightPx-3).text(rect.key);}
+if(this.data.length>1&&!this.isWaterfall_){chartAreaSel.append('text').attr('class','hover').attr('fill',rect.color==='transparent'?'#000000':rect.color).attr('x',hoverLeftPx+2).attr('y',hoverTopPx+keyHeightPx+valueHeightPx-3).text(''+rect.datum.x);}
+if(this.isGrouped&&rect.datum.group!==undefined){chartAreaSel.append('text').on('mouseleave',()=>this.clearHoverValueBox_(rect)).attr('class','hover').attr('fill',rect.color==='transparent'?'#000000':rect.color).attr('x',hoverLeftPx+2).attr('y',hoverTopPx+keyHeightPx+xHeightPx+groupHeightPx-3).text(rect.datum.group);}
+chartAreaSel.append('text').attr('class','hover').attr('fill',rect.color==='transparent'?'#000000':rect.color).attr('x',hoverLeftPx+2).attr('y',hoverTopPx+xHeightPx+keyHeightPx+
+groupHeightPx+valueHeightPx-3).text(rect.value);},flipRect_(rect){return{datum:rect.datum,index:rect.index,key:rect.key,value:rect.value,color:rect.color,topPx:this.graphHeight-rect.leftPx-rect.widthPx,leftPx:this.graphWidth-rect.topPx-rect.heightPx,widthPx:rect.heightPx,heightPx:rect.widthPx,underflow:rect.underflow,overflow:rect.overflow,};},drawRect_(rect,sel){super.drawRect_(this.flipRect_(rect),sel);},drawUnderflow_(rect,rectsSel){let sel=rectsSel.data([rect]);sel.enter().append('text').text('*').attr('fill',rect.color).attr('x',0).attr('y',this.graphHeight-rect.leftPx+
+3+(rect.widthPx/2));sel.exit().remove();sel=rectsSel.data([rect]);sel.enter().append('rect').attr('fill','rgba(0, 0, 0, 0)').attr('x',0).attr('y',this.graphHeight-rect.leftPx-rect.widthPx).attr('width',10).attr('height',rect.widthPx).on('mouseenter',()=>this.drawHoverValueBox_(this.flipRect_(rect))).on('mouseleave',()=>this.clearHoverValueBox_(rect));sel.exit().remove();},drawOverflow_(rect,sel){sel=sel.data([rect]);sel.enter().append('text').text('*').attr('fill',rect.color).attr('x',this.graphWidth).attr('y',this.graphHeight-rect.leftPx+
+3+(rect.widthPx/2));sel.exit().remove();}};return{BarChart,};});'use strict';tr.exportTo('tr.ui.b',function(){const NameBarChart=tr.ui.b.define('name-bar-chart',tr.ui.b.BarChart);const Y_AXIS_PADDING=2;NameBarChart.prototype={__proto__:tr.ui.b.BarChart.prototype,getDataPointAtChartPoint_(chartPoint){return{x:tr.ui.b.BarChart.prototype.getDataPointAtChartPoint_.call(this,chartPoint).x,y:parseInt(Math.floor((this.graphHeight-chartPoint.y)/this.barHeight))};},getXForDatum_(datum,index){return index;},get yAxisWidth(){if(this.data.length===0)return 0;return Y_AXIS_PADDING+tr.b.math.Statistics.max(this.data_,d=>tr.ui.b.getSVGTextSize(this,d.x).width);},get defaultGraphHeight(){return(3+this.textHeightPx_)*this.data.length;},updateYAxis_(yAxis){if(tr.ui.b.getSVGTextSize(this,'test').width===0){tr.b.requestAnimationFrame(()=>this.updateYAxis_(yAxis));return;}
+yAxis.selectAll('*').remove();if(this.hideYAxis)return;const nameTexts=yAxis.selectAll('text').data(this.data_);nameTexts.enter().append('text').attr('x',d=>-(tr.ui.b.getSVGTextSize(this,d.x).width+Y_AXIS_PADDING)).attr('y',(d,index)=>this.verticalScale_(index)).text(d=>d.x);nameTexts.exit().remove();let previousTop=undefined;for(const text of nameTexts[0]){const bbox=text.getBBox();if((previousTop===undefined)||(previousTop>(bbox.y+bbox.height))){previousTop=bbox.y;}else{text.style.opacity=0;}}}};return{NameBarChart,};});'use strict';tr.exportTo('tr.v.ui',function(){const DIAGNOSTIC_SPAN_BEHAVIOR={created(){this.diagnostic_=undefined;this.name_=undefined;this.histogram_=undefined;},attached(){if(this.diagnostic_)this.updateContents_();},get diagnostic(){return this.diagnostic_;},build(diagnostic,name,histogram){this.diagnostic_=diagnostic;this.name_=name;this.histogram_=histogram;if(this.isAttached)this.updateContents_();},updateContents_(){throw new Error('dom-modules must override updateContents_()');}};return{DIAGNOSTIC_SPAN_BEHAVIOR,};});'use strict';tr.exportTo('tr.v.ui',function(){const DEFAULT_COLOR_SCHEME=new tr.b.SinebowColorGenerator();function getHistogramName(histogram,diagnosticName,key){if(histogram===undefined)return undefined;const nameMap=histogram.diagnostics.get(diagnosticName);if(nameMap===undefined)return undefined;return nameMap.get(key);}
+class BreakdownTableSummaryRow{constructor(displayElement,histogramNames){this.displayElement_=displayElement;this.histogramNames_=histogramNames;this.keySpan_=undefined;}
+get numberValue(){return undefined;}
+get keySpan(){if(this.keySpan_===undefined){if(this.histogramNames_.length){this.keySpan_=document.createElement('tr-ui-a-analysis-link');this.keySpan_.setSelectionAndContent(this.histogramNames_,'Select All');}else{this.keySpan_='Sum';}}
+return this.keySpan_;}
+get name(){return'Sum';}
+get displayElement(){return this.displayElement_;}
+get stringPercent(){return'100%';}}
+class BreakdownTableRow{constructor(name,value,histogramName,unit,color){this.name_=name;this.value_=value;this.histogramName_=histogramName;this.unit_=unit;if(typeof value!=='number'){throw new Error('unsupported value '+value);}
+this.tableSum_=undefined;this.keySpan_=undefined;this.color_=color;const hsl=this.color.toHSL();hsl.l*=0.85;this.highlightedColor_=tr.b.Color.fromHSL(hsl);if(this.unit_){this.displayElement_=tr.v.ui.createScalarSpan(this.numberValue,{unit:this.unit_,});}else{this.displayElement_=tr.ui.b.createSpan({textContent:this.stringValue,});}}
+get name(){return this.name_;}
+get color(){return this.color_;}
+get highlightedColor(){return this.highlightedColor_;}
+get keySpan(){if(this.keySpan_===undefined){if(this.histogramName_){this.keySpan_=document.createElement('tr-ui-a-analysis-link');this.keySpan_.setSelectionAndContent([this.histogramName_],this.name);this.keySpan_.color=this.color;this.keySpan_.title=this.histogramName_;}else{this.keySpan_=document.createElement('span');this.keySpan_.innerText=this.name;this.keySpan_.style.color=this.color;}}
+return this.keySpan_;}
+get numberValue(){if(!isNaN(this.value_)&&(this.value_!==Infinity)&&(this.value_!==-Infinity)&&(this.value_>0))return this.value_;return undefined;}
+get stringValue(){if((this.unit_!==undefined)&&!isNaN(this.value_)&&(this.value_!==Infinity)&&(this.value_!==-Infinity)){return this.unit_.format(this.value_);}
+return this.value_.toString();}
+set tableSum(s){this.tableSum_=s;}
+get stringPercent(){if(this.tableSum_===undefined)return'';const num=this.numberValue;if(num===undefined)return'';return Math.floor(num*100.0/this.tableSum_)+'%';}
+get displayElement(){return this.displayElement_;}
+compare(other){if(this.numberValue===undefined){if(other.numberValue===undefined){return this.name.localeCompare(other.name);}
+return 1;}
+if(other.numberValue===undefined){return-1;}
+if(this.numberValue===other.numberValue){return this.name.localeCompare(other.name);}
+return other.numberValue-this.numberValue;}}
+Polymer({is:'tr-v-ui-breakdown-span',behaviors:[tr.v.ui.DIAGNOSTIC_SPAN_BEHAVIOR],created(){this.chart_=new tr.ui.b.ColumnChart();this.chart_.graphHeight=130;this.chart_.isStacked=true;this.chart_.hideXAxis=true;this.chart_.hideLegend=true;this.chart_.enableHoverBox=false;this.chart_.addEventListener('rect-mouseenter',event=>this.onRectMouseEnter_(event));this.chart_.addEventListener('rect-mouseleave',event=>this.onRectMouseLeave_(event));},onRectMouseEnter_(event){for(const row of this.$.table.tableRows){if(row.name===event.rect.key){row.displayElement.style.background=event.rect.color;row.keySpan.scrollIntoViewIfNeeded();}else{row.displayElement.style.background='';}}},onRectMouseLeave_(event){for(const row of this.$.table.tableRows){row.displayElement.style.background='';}},ready(){Polymer.dom(this.$.container).appendChild(this.chart_);this.$.table.zebra=true;this.$.table.showHeader=false;this.$.table.tableColumns=[{value:row=>row.keySpan,},{value:row=>row.displayElement,align:tr.ui.b.TableFormat.ColumnAlignment.RIGHT,},{value:row=>row.stringPercent,align:tr.ui.b.TableFormat.ColumnAlignment.RIGHT,},];},updateContents_(){this.$.container.style.display='none';this.$.table.style.display='none';this.$.empty.style.display='block';if(!this.diagnostic_){this.chart_.data=[];return;}
+if(this.histogram_)this.chart_.unit=this.histogram_.unit;let colorScheme=undefined;if(this.diagnostic.colorScheme===tr.v.d.COLOR_SCHEME_CHROME_USER_FRIENDLY_CATEGORY_DRIVER){colorScheme=(name)=>{let cat=name.split(' ');cat=cat[cat.length-1];return tr.e.chrome.ChromeUserFriendlyCategoryDriver.getColor(cat);};}else if(this.diagnostic.colorScheme){colorScheme=(name)=>tr.b.FixedColorSchemeRegistry.lookUp(this.diagnostic.colorScheme).getColor(name);}else{colorScheme=(name)=>DEFAULT_COLOR_SCHEME.colorForKey(name);}
+const tableRows=[];let tableSum=0;const histogramNames=[];for(const[key,value]of this.diagnostic){const histogramName=getHistogramName(this.histogram_,this.name_,key);const row=new BreakdownTableRow(key,value,histogramName,this.chart_.unit,colorScheme(key));tableRows.push(row);if(row.numberValue!==undefined)tableSum+=row.numberValue;if(histogramName){histogramNames.push(histogramName);}}
+tableRows.sort((x,y)=>x.compare(y));if(tableSum>0){let summaryDisplayElement=tableSum;if(this.chart_.unit!==undefined){summaryDisplayElement=this.chart_.unit.format(tableSum);}
+summaryDisplayElement=tr.ui.b.createSpan({textContent:summaryDisplayElement,});tableRows.unshift(new BreakdownTableSummaryRow(summaryDisplayElement,histogramNames));}
+const chartData={x:0};for(const row of tableRows){if(row.numberValue===undefined)continue;row.tableSum=tableSum;chartData[row.name]=row.numberValue;const dataSeries=this.chart_.getDataSeries(row.name);dataSeries.color=row.color;dataSeries.highlightedColor=row.highlightedColor;}
+if(tableRows.length>0){this.$.table.style.display='block';this.$.empty.style.display='none';this.$.table.tableRows=tableRows;this.$.table.rebuild();}
+if(Object.keys(chartData).length>1){this.$.container.style.display='block';this.$.empty.style.display='none';this.chart_.data=[chartData];}}});return{};});'use strict';tr.exportTo('tr.v.ui',function(){Polymer({is:'tr-v-ui-collected-related-event-set-span',behaviors:[tr.v.ui.DIAGNOSTIC_SPAN_BEHAVIOR],updateContents_(){Polymer.dom(this).textContent='';for(const[canonicalUrl,events]of this.diagnostic){const link=document.createElement('a');if(events.length===1){const event=tr.b.getOnlyElement(events);link.textContent=event.title+' '+
+tr.b.Unit.byName.timeDurationInMs.format(event.duration);}else{link.textContent=events.length+' events';}
+link.href=canonicalUrl;Polymer.dom(this).appendChild(link);Polymer.dom(this).appendChild(document.createElement('br'));}}});return{};});'use strict';tr.exportTo('tr.v.ui',function(){Polymer({is:'tr-v-ui-date-range-span',behaviors:[tr.v.ui.DIAGNOSTIC_SPAN_BEHAVIOR],updateContents_(){if(this.diagnostic===undefined){Polymer.dom(this).textContent='';return;}
+Polymer.dom(this).textContent=this.diagnostic.toString();}});return{};});'use strict';tr.exportTo('tr.v.ui',function(){function isLinkTuple(value){return((value instanceof Array)&&(value.length===2)&&(typeof value[0]==='string')&&tr.b.isUrl(value[1]));}
+Polymer({is:'tr-v-ui-generic-set-span',behaviors:[tr.v.ui.DIAGNOSTIC_SPAN_BEHAVIOR],updateContents_(){this.$.generic.style.display='none';this.$.links.textContent='';if(this.diagnostic===undefined)return;const values=Array.from(this.diagnostic);let areAllStrings=true;let areAllNumbers=true;for(const value of values){if(typeof value!=='number'){areAllNumbers=false;if(typeof value!=='string'&&!isLinkTuple(value)){areAllStrings=false;break;}}}
+if(!areAllStrings){this.$.generic.style.display='';this.$.generic.object=values;return;}
+if(areAllNumbers){values.sort((x,y)=>x-y);}else{values.sort();}
+for(const value of values){const link={textContent:''+value};if(isLinkTuple(value)){link.textContent=value[0];link.href=value[1];}else if(tr.b.isUrl(value)){link.href=value;}
+if(this.name_===tr.v.d.RESERVED_NAMES.TRACE_URLS){link.textContent=value.substr(1+value.lastIndexOf('/'));}
+const linkEl=tr.ui.b.createLink(link);if(link.href){linkEl.target='_blank';linkEl.addEventListener('click',e=>e.stopPropagation());}
+this.$.links.appendChild(linkEl);}}});return{};});'use strict';tr.exportTo('tr.v.ui',function(){Polymer({is:'tr-v-ui-related-event-set-span',behaviors:[tr.v.ui.DIAGNOSTIC_SPAN_BEHAVIOR],updateContents_(){Polymer.dom(this).textContent='';const events=new tr.model.EventSet([...this.diagnostic]);const link=document.createElement('tr-ui-a-analysis-link');let label=events.length+' events';if(events.length===1){const event=tr.b.getOnlyElement(events);label=event.title+' ';label+=tr.b.Unit.byName.timeDurationInMs.format(event.duration);}
+link.setSelectionAndContent(events,label);Polymer.dom(this).appendChild(link);}});return{};});'use strict';tr.exportTo('tr.v.ui',function(){Polymer({is:'tr-v-ui-scalar-diagnostic-span',behaviors:[tr.v.ui.DIAGNOSTIC_SPAN_BEHAVIOR],updateContents_(){this.$.scalar.setValueAndUnit(this.diagnostic.value.value,this.diagnostic.value.unit);}});return{};});'use strict';tr.exportTo('tr.v.ui',function(){Polymer({is:'tr-v-ui-unmergeable-diagnostic-set-span',behaviors:[tr.v.ui.DIAGNOSTIC_SPAN_BEHAVIOR],updateContents_(){Polymer.dom(this).textContent='';for(const diagnostic of this.diagnostic){if(diagnostic instanceof tr.v.d.RelatedNameMap)continue;const div=document.createElement('div');div.appendChild(tr.v.ui.createDiagnosticSpan(diagnostic,this.name_,this.histogram_));Polymer.dom(this).appendChild(div);}}});return{};});'use strict';tr.exportTo('tr.v.ui',function(){function findElementNameForDiagnostic(diagnostic){let typeInfo=undefined;let curProto=diagnostic.constructor.prototype;while(curProto){typeInfo=tr.v.d.Diagnostic.findTypeInfo(curProto.constructor);if(typeInfo&&typeInfo.metadata.elementName)break;typeInfo=undefined;curProto=curProto.__proto__;}
+if(typeInfo===undefined){throw new Error(diagnostic.constructor.name+' or a base class must have a registered elementName');}
+const tagName=typeInfo.metadata.elementName;if(tr.ui.b.isUnknownElementName(tagName)){throw new Error('Element not registered: '+tagName);}
+return tagName;}
+function createDiagnosticSpan(diagnostic,name,histogram){const tagName=findElementNameForDiagnostic(diagnostic);const span=document.createElement(tagName);if(span.build===undefined)throw new Error(tagName);span.build(diagnostic,name,histogram);return span;}
+return{createDiagnosticSpan,};});'use strict';tr.exportTo('tr.v.ui',function(){function makeColumn(title,histogram){return{title,value(map){const diagnostic=map.get(title);if(!diagnostic)return'';return tr.v.ui.createDiagnosticSpan(diagnostic,title,histogram);}};}
+Polymer({is:'tr-v-ui-diagnostic-map-table',created(){this.diagnosticMaps_=undefined;this.histogram_=undefined;this.isMetadata_=false;},set histogram(h){this.histogram_=h;},set isMetadata(m){this.isMetadata_=m;this.$.table.showHeader=!this.isMetadata_;},set diagnosticMaps(maps){this.diagnosticMaps_=maps;this.updateContents_();},get diagnosticMaps(){return this.diagnosticMaps_;},updateContents_(){if(this.isMetadata_&&this.diagnosticMaps_.length!==1){throw new Error('Metadata diagnostic-map-tables require exactly 1 DiagnosticMap');}
+if(this.diagnosticMaps_===undefined||this.diagnosticMaps_.length===0){this.$.table.tableRows=[];this.$.table.tableColumns=[];return;}
+let names=new Set();for(const map of this.diagnosticMaps_){for(const[name,diagnostic]of map){if(diagnostic instanceof tr.v.d.UnmergeableDiagnosticSet)continue;if(diagnostic instanceof tr.v.d.CollectedRelatedEventSet)continue;names.add(name);}}
+names=Array.from(names).sort();const histogram=this.histogram_;if(this.isMetadata_){const diagnosticMap=this.diagnosticMaps_[0];this.$.table.tableColumns=[{value(name){return name.name;}},{value(name){const diagnostic=diagnosticMap.get(name.name);if(!diagnostic)return'';return tr.v.ui.createDiagnosticSpan(diagnostic,name.name,histogram);}},];this.$.table.tableRows=names.map(name=>{return{name};});}else{this.$.table.tableColumns=names.map(name=>makeColumn(name,histogram));this.$.table.tableRows=this.diagnosticMaps_;}
+this.$.table.rebuild();}});return{};});'use strict';tr.exportTo('tr.b',function(){class Serializable{constructor(){Object.defineProperty(this,'properties_',{configurable:false,enumerable:false,value:new Map(),});}
+define(name,initialValue){if(this[name]!==undefined){throw new Error(`"${name}" is already defined.`);}
+if(name[name.length-1]==='_'){throw new Error(`"${name}" cannot end with an underscore.`);}
+this.properties_.set(name,initialValue);Object.defineProperty(this,name,{configurable:false,enumerable:true,get:()=>this.properties_.get(name),set:value=>this.setProperty_(name,value),});}
+setProperty_(name,value){this.properties_.set(name,value);}
+clone(){return Serializable.fromDict(this.asDict());}
+asDict(){function visit(obj){if(obj instanceof Serializable)return obj.asDict();if(obj instanceof Set)return Array.from(obj);if(obj instanceof Array)return obj.map(visit);if(!(obj instanceof Map))return obj;const result={};for(const[name,value]of obj){result[name]=visit(value);}
+return result;}
+const dict={type:this.constructor.name};for(const[name,value]of this.properties_){dict[name.replace(/_$/,'')]=visit(value);}
+return dict;}
+static fromDict(dict){function visit(d){if(d instanceof Array)return d.map(visit);if(!(d instanceof Object))return d;if(typeof d.type==='string')return Serializable.fromDict(d);const result=new Map();for(const[name,value]of Object.entries(d)){result.set(name,visit(value));}
+return result;}
+const typeInfo=Serializable.findTypeInfoWithName(dict.type);const result=new typeInfo.constructor();for(const[name,value]of Object.entries(dict)){result[name]=visit(value);}
+return result;}}
+const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Serializable;tr.b.decorateExtensionRegistry(Serializable,options);return{Serializable,};});'use strict';tr.exportTo('tr.b',function(){class ViewState extends tr.b.Serializable{constructor(){super();tr.b.EventTarget.decorate(this);}
+setProperty_(name,value){this.update(new Map([[name,value]]));}
+async updateFromViewState(other){await this.update(other.properties_);}
+async update(delta){if(!(delta instanceof Map))delta=new Map(Object.entries(delta));const actualDelta={};for(const[name,current]of delta){const previous=this[name];if(previous===current)continue;actualDelta[name]={previous,current};tr.b.Serializable.prototype.setProperty_.call(this,name,current);}
+if(Object.keys(actualDelta).length===0)return;await tr.b.dispatchSimpleEventAsync(this,this.updateEventName_,{delta:actualDelta});}
+get updateEventName_(){return this.constructor.name+'.update';}
+addUpdateListener(listener){this.addEventListener(this.updateEventName_,listener);}
+removeUpdateListener(listener){this.removeEventListener(this.updateEventName_,listener);}}
+return{ViewState,};});'use strict';tr.exportTo('tr.v.ui',function(){class HistogramSetViewState extends tr.b.ViewState{constructor(){super();this.define('searchQuery','');this.define('referenceDisplayLabel','');this.define('displayStatisticName','');this.define('showAll',true);this.define('groupings',[]);this.define('sortColumnIndex',0);this.define('sortDescending',false);this.define('constrainNameColumn',true);this.define('tableRowStates',new Map());this.define('alpha',0.01);}}
+tr.b.ViewState.register(HistogramSetViewState);class HistogramSetTableRowState extends tr.b.ViewState{constructor(){super();this.define('isExpanded',false);this.define('isOverviewed',false);this.define('cells',new Map());this.define('subRows',new Map());this.define('diagnosticsTab','');}
+asCompactDict(){const result={};if(this.isExpanded)result.e='1';if(this.isOverviewed)result.o='1';if(this.diagnosticsTab)result.d=this.diagnosticsTab;const cells={};for(const[name,cell]of this.cells){const cellDict=cell.asCompactDict();if(cellDict===undefined)continue;cells[name]=cellDict;}
+if(Object.keys(cells).length>0)result.c=cells;const subRows={};for(const[name,row]of this.subRows){const rowDict=row.asCompactDict();if(rowDict===undefined)continue;subRows[name]=rowDict;}
+if(Object.keys(subRows).length>0)result.r=subRows;if(Object.keys(result).length===0)return undefined;return result;}
+async updateFromCompactDict(dict){await this.update({isExpanded:dict.e==='1',isOverviewed:dict.o==='1',diagnosticsTab:dict.d||'',});for(const[name,cellDict]of Object.entries(dict.c||{})){const cell=this.cells.get(name);if(cell===undefined)continue;await cell.updateFromCompactDict(cellDict);}
+for(const[name,subRowDict]of Object.entries(dict.r||{})){const subRow=this.subRows.get(name);if(subRow===undefined)continue;await subRow.updateFromCompactDict(subRowDict);}}*walk(){yield this;for(const row of this.subRows.values())yield*row.walk();}
+static*walkAll(rootRows){for(const rootRow of rootRows)yield*rootRow.walk();}}
+tr.b.ViewState.register(HistogramSetTableRowState);class HistogramSetTableCellState extends tr.b.ViewState{constructor(){super();this.define('isOpen',false);this.define('brushedBinRange',new tr.b.math.Range());this.define('mergeSampleDiagnostics',true);}
+asCompactDict(){const result={};if(this.isOpen)result.o='1';if(!this.mergeSampleDiagnostics)result.m='0';if(!this.brushedBinRange.isEmpty){result.b=this.brushedBinRange.min+'_'+this.brushedBinRange.max;}
+if(Object.keys(result).length===0)return undefined;return result;}
+async updateFromCompactDict(dict){let binRange=this.brushedBinRange;if(dict.b){let[bMin,bMax]=dict.b.split('_');bMin=parseInt(bMin);bMax=parseInt(bMax);if(bMin!==binRange.min||bMax!==binRange.max){binRange=tr.b.math.Range.fromExplicitRange(bMin,bMax);}}
+await this.update({isOpen:dict.o==='1',brushedBinRange:binRange,mergeSampleDiagnostics:dict.m!=='0',});}}
+tr.b.ViewState.register(HistogramSetTableCellState);return{HistogramSetTableCellState,HistogramSetTableRowState,HistogramSetViewState,};});'use strict';Polymer({is:'tr-v-ui-scalar-map-table',created(){this.scalarMap_=new Map();this.significance_=new Map();},ready(){this.$.table.showHeader=false;this.$.table.tableColumns=[{value(row){return row.name;}},{value(row){const span=tr.v.ui.createScalarSpan(row.value);if(row.significance!==undefined){span.significance=row.significance;}else if(row.anyRowsHaveSignificance){span.style.marginRight='18px';}
+span.style.whiteSpace='nowrap';return span;}}];},get scalarMap(){return this.scalarMap_;},set scalarMap(map){this.scalarMap_=map;this.updateContents_();},setSignificanceForKey(key,significance){this.significance_.set(key,significance);this.updateContents_();},updateContents_(){const rows=[];for(const[key,scalar]of this.scalarMap){rows.push({name:key,value:scalar,significance:this.significance_.get(key),anyRowsHaveSignificance:(this.significance_.size>0)});}
+this.$.table.tableRows=rows;this.$.table.rebuild();}});'use strict';tr.exportTo('tr.v.ui',function(){const DEFAULT_BAR_HEIGHT_PX=5;const TRUNCATE_BIN_MARGIN=0.15;const IGNORE_DELTA_STATISTICS_NAMES=[`${tr.v.DELTA}min`,`%${tr.v.DELTA}min`,`${tr.v.DELTA}max`,`%${tr.v.DELTA}max`,`${tr.v.DELTA}sum`,`%${tr.v.DELTA}sum`,`${tr.v.DELTA}count`,`%${tr.v.DELTA}count`,];Polymer({is:'tr-v-ui-histogram-span',created(){this.viewStateListener_=this.onViewStateUpdate_.bind(this);this.viewState=new tr.v.ui.HistogramSetTableCellState();this.rowStateListener_=this.onRowStateUpdate_.bind(this);this.rowState=new tr.v.ui.HistogramSetTableRowState();this.rootStateListener_=this.onRootStateUpdate_.bind(this);this.rootState=new tr.v.ui.HistogramSetViewState();this.histogram_=undefined;this.referenceHistogram_=undefined;this.graphWidth_=undefined;this.graphHeight_=undefined;this.mouseDownBin_=undefined;this.prevBrushedBinRange_=new tr.b.math.Range();this.anySampleDiagnostics_=false;this.canMergeSampleDiagnostics_=true;this.mwuResult_=undefined;},get rowState(){return this.rowState_;},set rowState(rs){if(this.rowState){this.rowState.removeUpdateListener(this.rowStateListener_);}
+this.rowState_=rs;this.rowState.addUpdateListener(this.rowStateListener_);if(this.isAttached)this.updateContents_();},get viewState(){return this.viewState_;},set viewState(vs){if(this.viewState){this.viewState.removeUpdateListener(this.viewStateListener_);}
+this.viewState_=vs;this.viewState.addUpdateListener(this.viewStateListener_);if(this.isAttached)this.updateContents_();},get rootState(){return this.rootState_;},set rootState(vs){if(this.rootState){this.rootState.removeUpdateListener(this.rootStateListener_);}
+this.rootState_=vs;this.rootState.addUpdateListener(this.rootStateListener_);if(this.isAttached)this.updateContents_();},build(histogram,opt_referenceHistogram){this.histogram_=histogram;this.$.metric_diagnostics.histogram=histogram;this.$.sample_diagnostics.histogram=histogram;this.referenceHistogram_=opt_referenceHistogram;if(this.histogram.canCompare(this.referenceHistogram)){this.mwuResult_=tr.b.math.Statistics.mwu(this.histogram.sampleValues,this.referenceHistogram.sampleValues,this.rootState.alpha);}
+this.anySampleDiagnostics_=false;for(const bin of this.histogram.allBins){if(bin.diagnosticMaps.length>0){this.anySampleDiagnostics_=true;break;}}
+if(this.isAttached)this.updateContents_();},onViewStateUpdate_(event){if(event.delta.brushedBinRange){if(this.chart_!==undefined){this.chart_.brushedRange=this.viewState.brushedBinRange;}
+this.updateDiagnostics_();}
+if(event.delta.mergeSampleDiagnostics&&(this.viewState.mergeSampleDiagnostics!==this.$.merge_sample_diagnostics.checked)){this.$.merge_sample_diagnostics.checked=this.canMergeSampleDiagnostics&&this.viewState.mergeSampleDiagnostics;this.updateDiagnostics_();}},updateSignificance_(){if(!this.mwuResult_)return;this.$.stats.setSignificanceForKey(`${tr.v.DELTA}avg`,this.mwuResult_.significance);},onRootStateUpdate_(event){if(event.delta.alpha&&this.mwuResult_){this.mwuResult_.compare(this.rootState.alpha);this.updateSignificance_();}},onRowStateUpdate_(event){if(event.delta.diagnosticsTab){if(this.rowState.diagnosticsTab===this.$.sample_diagnostics_container.tabLabel){this.updateDiagnostics_();}else{for(const tab of this.$.diagnostics.subViews){if(this.rowState.diagnosticsTab===tab.tabLabel){this.$.diagnostics.selectedSubView=tab;break;}}}}},ready(){this.$.metric_diagnostics.tabLabel='histogram diagnostics';this.$.sample_diagnostics_container.tabLabel='sample diagnostics';this.$.metadata_diagnostics.tabLabel='metadata';this.$.metadata_diagnostics.isMetadata=true;this.$.diagnostics.addEventListener('selected-tab-change',this.onSelectedDiagnosticsChanged_.bind(this));this.$.drag_handle.target=this.$.container;this.$.drag_handle.addEventListener('drag-handle-resize',this.onResize_.bind(this));},attached(){if(this.histogram_!==undefined)this.updateContents_();},get canMergeSampleDiagnostics(){return this.canMergeSampleDiagnostics_;},set canMergeSampleDiagnostics(merge){this.canMergeSampleDiagnostics_=merge;if(!merge)this.viewState.mergeSampleDiagnostics=false;this.$.merge_sample_diagnostics_container.style.display=(merge?'':'none');},onResize_(event){event.stopPropagation();let heightPx=parseInt(this.$.container.style.height);if(heightPx<this.defaultGraphHeight){heightPx=this.defaultGraphHeight;this.$.container.style.height=this.defaultGraphHeight+'px';}
+this.chart_.graphHeight=heightPx-(this.chart_.margin.top+
+this.chart_.margin.bottom);this.$.stats_container.style.maxHeight=this.chart_.getBoundingClientRect().height+'px';},get graphWidth(){return this.graphWidth_||this.defaultGraphWidth;},set graphWidth(width){this.graphWidth_=width;},get graphHeight(){return this.graphHeight_||this.defaultGraphHeight;},set graphHeight(height){this.graphHeight_=height;},get barHeight(){return this.chart_.barHeight;},set barHeight(px){this.graphHeight=this.computeChartHeight_(px);},computeChartHeight_(barHeightPx){return(this.chart_.margin.top+
+this.chart_.margin.bottom+
+(barHeightPx*this.histogram.allBins.length));},get defaultGraphHeight(){if(this.histogram&&this.histogram.allBins.length===1){return 150;}
+return this.computeChartHeight_(DEFAULT_BAR_HEIGHT_PX);},get defaultGraphWidth(){if(this.histogram.allBins.length===1){return 100;}
+return 300;},get brushedBins(){const bins=[];if(this.histogram&&!this.viewState.brushedBinRange.isEmpty){for(let i=this.viewState.brushedBinRange.min;i<this.viewState.brushedBinRange.max;++i){bins.push(this.histogram.allBins[i]);}}
+return bins;},async updateBrushedRange_(binIndex){const brushedBinRange=new tr.b.math.Range();brushedBinRange.addValue(tr.b.math.clamp(this.mouseDownBinIndex_,0,this.histogram.allBins.length-1));brushedBinRange.addValue(tr.b.math.clamp(binIndex,0,this.histogram.allBins.length-1));brushedBinRange.max+=1;await this.viewState.update({brushedBinRange});},onMouseDown_(chartEvent){chartEvent.stopPropagation();if(!this.histogram)return;this.prevBrushedBinRange_=this.viewState.brushedBinRange;this.mouseDownBinIndex_=chartEvent.y;this.updateBrushedRange_(chartEvent.y);},onMouseMove_(chartEvent){chartEvent.stopPropagation();if(!this.histogram)return;this.updateBrushedRange_(chartEvent.y);},onMouseUp_(chartEvent){chartEvent.stopPropagation();if(!this.histogram)return;this.updateBrushedRange_(chartEvent.y);if(this.prevBrushedBinRange_.range===1&&this.viewState.brushedBinRange.range===1&&(this.prevBrushedBinRange_.min===this.viewState.brushedBinRange.min)){tr.b.Timing.instant('histogram-span','clearBrushedBins');this.viewState.update({brushedBinRange:new tr.b.math.Range()});}else{tr.b.Timing.instant('histogram-span','brushBins');}
+this.mouseDownBinIndex_=undefined;},async onSelectedDiagnosticsChanged_(){await this.rowState.update({diagnosticsTab:this.$.diagnostics.selectedSubView.tabLabel,});if((this.$.diagnostics.selectedSubView===this.$.sample_diagnostics_container)&&this.histogram&&this.viewState.brushedBinRange.isEmpty){const brushedBinRange=tr.b.math.Range.fromExplicitRange(0,this.histogram.allBins.length);await this.viewState.update({brushedBinRange});this.updateDiagnostics_();}},updateDiagnostics_(){let maps=[];for(const bin of this.brushedBins){for(const map of bin.diagnosticMaps){maps.push(map);}}
+if(this.$.merge_sample_diagnostics.checked!==this.viewState.mergeSampleDiagnostics){this.viewState.update({mergeSampleDiagnostics:this.$.merge_sample_diagnostics.checked});}
+if(this.viewState.mergeSampleDiagnostics){const merged=new tr.v.d.DiagnosticMap();for(const map of maps){merged.addDiagnostics(map);}
+maps=[merged];}
+const mark=tr.b.Timing.mark('histogram-span',(this.viewState.mergeSampleDiagnostics?'merge':'split')+'SampleDiagnostics');this.$.sample_diagnostics.diagnosticMaps=maps;mark.end();if(this.anySampleDiagnostics_){this.$.diagnostics.selectedSubView=this.$.sample_diagnostics_container;}},get histogram(){return this.histogram_;},get referenceHistogram(){return this.referenceHistogram_;},getDeltaScalars_(statNames,scalarMap){if(!this.histogram.canCompare(this.referenceHistogram))return;for(const deltaStatName of tr.v.Histogram.getDeltaStatisticsNames(statNames)){if(IGNORE_DELTA_STATISTICS_NAMES.includes(deltaStatName))continue;const scalar=this.histogram.getStatisticScalar(deltaStatName,this.referenceHistogram,this.mwuResult_);if(scalar===undefined)continue;scalarMap.set(deltaStatName,scalar);}},set isYLogScale(logScale){this.chart_.isYLogScale=logScale;},async updateContents_(){this.$.chart.style.display='none';this.$.drag_handle.style.display='none';this.$.container.style.justifyContent='';while(Polymer.dom(this.$.chart).lastChild){Polymer.dom(this.$.chart).removeChild(Polymer.dom(this.$.chart).lastChild);}
+if(!this.histogram)return;this.$.container.style.display='';const scalarMap=new Map();this.getDeltaScalars_(this.histogram.statisticsNames,scalarMap);for(const[name,scalar]of this.histogram.statisticsScalars){scalarMap.set(name,scalar);}
+this.$.stats.scalarMap=scalarMap;this.updateSignificance_();const metricDiagnosticMap=new tr.v.d.DiagnosticMap();const metadataDiagnosticMap=new tr.v.d.DiagnosticMap();for(const[key,diagnostic]of this.histogram.diagnostics){if(diagnostic instanceof tr.v.d.RelatedNameMap)continue;if(tr.v.d.RESERVED_NAMES_SET.has(key)){metadataDiagnosticMap.set(key,diagnostic);}else{metricDiagnosticMap.set(key,diagnostic);}}
+const diagnosticTabs=[];if(metricDiagnosticMap.size){this.$.metric_diagnostics.diagnosticMaps=[metricDiagnosticMap];diagnosticTabs.push(this.$.metric_diagnostics);}
+if(this.anySampleDiagnostics_){diagnosticTabs.push(this.$.sample_diagnostics_container);}
+if(metadataDiagnosticMap.size){this.$.metadata_diagnostics.diagnosticMaps=[metadataDiagnosticMap];diagnosticTabs.push(this.$.metadata_diagnostics);}
+this.$.diagnostics.resetSubViews(diagnosticTabs);this.$.diagnostics.set('tabsHidden',diagnosticTabs.length<2);if(this.histogram.numValues<=1){await this.viewState.update({brushedBinRange:tr.b.math.Range.fromExplicitRange(0,this.histogram.allBins.length)});this.$.container.style.justifyContent='flex-end';return;}
+this.$.chart.style.display='block';this.$.drag_handle.style.display='block';if(this.histogram.allBins.length===1){if(this.histogram.min!==this.histogram.max){this.chart_=new tr.ui.b.BoxChart();Polymer.dom(this.$.chart).appendChild(this.chart_);this.chart_.graphWidth=this.graphWidth;this.chart_.graphHeight=this.graphHeight;this.chart_.hideXAxis=true;this.chart_.data=[{x:'',color:'blue',percentile_0:this.histogram.running.min,percentile_25:this.histogram.getApproximatePercentile(0.25),percentile_50:this.histogram.getApproximatePercentile(0.5),percentile_75:this.histogram.getApproximatePercentile(0.75),percentile_100:this.histogram.running.max,}];}
+this.$.stats_container.style.maxHeight=this.chart_.getBoundingClientRect().height+'px';await this.viewState.update({brushedBinRange:tr.b.math.Range.fromExplicitRange(0,this.histogram.allBins.length)});return;}
+this.chart_=new tr.ui.b.NameBarChart();Polymer.dom(this.$.chart).appendChild(this.chart_);this.chart_.graphWidth=this.graphWidth;this.chart_.graphHeight=this.graphHeight;this.chart_.addEventListener('item-mousedown',this.onMouseDown_.bind(this));this.chart_.addEventListener('item-mousemove',this.onMouseMove_.bind(this));this.chart_.addEventListener('item-mouseup',this.onMouseUp_.bind(this));this.chart_.hideLegend=true;this.chart_.getDataSeries('y').color='blue';this.chart_.xAxisLabel='#';this.chart_.brushedRange=this.viewState.brushedBinRange;if(!this.viewState.brushedBinRange.isEmpty){this.updateDiagnostics_();}
+const chartData=[];const binCounts=[];for(const bin of this.histogram.allBins){let x=bin.range.min;if(x===-Number.MAX_VALUE){x='<'+new tr.b.Scalar(this.histogram.unit,bin.range.max).toString();}else{x=new tr.b.Scalar(this.histogram.unit,x).toString();}
+chartData.push({x,y:bin.count});binCounts.push(bin.count);}
+binCounts.sort((x,y)=>y-x);const dataRange=tr.b.math.Range.fromExplicitRange(0,binCounts[0]);if(binCounts[1]>0&&binCounts[0]>(binCounts[1]*2)){dataRange.max=binCounts[1]*(1+TRUNCATE_BIN_MARGIN);}
+if(binCounts[2]>0&&binCounts[1]>(binCounts[2]*2)){dataRange.max=binCounts[2]*(1+TRUNCATE_BIN_MARGIN);}
+this.chart_.overrideDataRange=dataRange;this.chart_.data=chartData;this.$.stats_container.style.maxHeight=this.chart_.getBoundingClientRect().height+'px';}});});'use strict';tr.exportTo('tr.ui.analysis',function(){const EVENT_FIELD=[{key:'start',label:'Start'},{key:'cpuDuration',label:'CPU Duration'},{key:'duration',label:'Duration'},{key:'cpuSelfTime',label:'CPU Self Time'},{key:'selfTime',label:'Self Time'}];function buildDiagnostics_(slice){const diagnostics={};for(const item of EVENT_FIELD){const fieldName=item.key;if(slice[fieldName]===undefined)continue;diagnostics[fieldName]=new tr.v.d.Scalar(new tr.b.Scalar(tr.b.Unit.byName.timeDurationInMs,slice[fieldName]));}
+diagnostics.args=new tr.v.d.GenericSet([slice.args]);diagnostics.event=new tr.v.d.RelatedEventSet(slice);return diagnostics;}
+Polymer({is:'tr-ui-a-multi-event-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;this.eventsHaveDuration_=true;this.eventsHaveSubRows_=true;},ready(){this.$.radioPicker.style.display='none';this.$.radioPicker.items=EVENT_FIELD;this.$.radioPicker.select('cpuSelfTime');this.$.radioPicker.addEventListener('change',()=>{if(this.isAttached)this.updateContents_();});this.$.histogramSpan.graphWidth=400;this.$.histogramSpan.canMergeSampleDiagnostics=false;this.$.histogramContainer.style.display='none';},attached(){if(this.currentSelection_!==undefined)this.updateContents_();},set selection(selection){if(selection.length<=1){throw new Error('Only supports multiple items');}
+this.setSelectionWithoutErrorChecks(selection);},get selection(){return this.currentSelection_;},setSelectionWithoutErrorChecks(selection){this.currentSelection_=selection;if(this.isAttached)this.updateContents_();},get eventsHaveDuration(){return this.eventsHaveDuration_;},set eventsHaveDuration(eventsHaveDuration){this.eventsHaveDuration_=eventsHaveDuration;if(this.isAttached)this.updateContents_();},get eventsHaveSubRows(){return this.eventsHaveSubRows_;},set eventsHaveSubRows(eventsHaveSubRows){this.eventsHaveSubRows_=eventsHaveSubRows;if(this.isAttached)this.updateContents_();},buildHistogram_(selectedKey){let leftBoundary=Number.MAX_VALUE;let rightBoundary=tr.b.math.Statistics.percentile(this.currentSelection_,0.95,function(value){leftBoundary=Math.min(leftBoundary,value[selectedKey]);return value[selectedKey];});if(leftBoundary===rightBoundary)rightBoundary+=1;const histogram=new tr.v.Histogram('',tr.b.Unit.byName.timeDurationInMs,tr.v.HistogramBinBoundaries.createLinear(leftBoundary,rightBoundary,Math.ceil(Math.sqrt(this.currentSelection_.length))));histogram.customizeSummaryOptions({sum:false,percentile:[0.5,0.9],});for(const slice of this.currentSelection_){histogram.addSample(slice[selectedKey],buildDiagnostics_(slice));}
+return histogram;},updateContents_(){const selection=this.currentSelection_;if(!selection)return;const eventsByTitle=selection.getEventsOrganizedByTitle();const numTitles=Object.keys(eventsByTitle).length;this.$.eventSummaryTable.configure({showTotals:numTitles>1,eventsByTitle,eventsHaveDuration:this.eventsHaveDuration_,eventsHaveSubRows:this.eventsHaveSubRows_});this.$.selectionSummaryTable.selection=this.currentSelection_;if(numTitles===1){this.$.radioPicker.style.display='block';this.$.histogramContainer.style.display='flex';this.$.histogramSpan.build(this.buildHistogram_(this.$.radioPicker.selectedKey));if(this.$.histogramSpan.histogram.numValues===0){this.$.histogramContainer.style.display='none';}}else{this.$.radioPicker.style.display='none';this.$.histogramContainer.style.display='none';}}});return{};});'use strict';tr.exportTo('tr.ui.analysis',function(){const FLOW_IN=0x1;const FLOW_OUT=0x2;const FLOW_IN_OUT=FLOW_IN|FLOW_OUT;function FlowClassifier(){this.numEvents_=0;this.eventsByGUID_={};}
+FlowClassifier.prototype={getFS_(event){let fs=this.eventsByGUID_[event.guid];if(fs===undefined){this.numEvents_++;fs={state:0,event};this.eventsByGUID_[event.guid]=fs;}
+return fs;},addInFlow(event){const fs=this.getFS_(event);fs.state|=FLOW_IN;return event;},addOutFlow(event){const fs=this.getFS_(event);fs.state|=FLOW_OUT;return event;},hasEvents(){return this.numEvents_>0;},get inFlowEvents(){const selection=new tr.model.EventSet();for(const guid in this.eventsByGUID_){const fs=this.eventsByGUID_[guid];if(fs.state===FLOW_IN){selection.push(fs.event);}}
+return selection;},get outFlowEvents(){const selection=new tr.model.EventSet();for(const guid in this.eventsByGUID_){const fs=this.eventsByGUID_[guid];if(fs.state===FLOW_OUT){selection.push(fs.event);}}
+return selection;},get internalFlowEvents(){const selection=new tr.model.EventSet();for(const guid in this.eventsByGUID_){const fs=this.eventsByGUID_[guid];if(fs.state===FLOW_IN_OUT){selection.push(fs.event);}}
+return selection;}};return{FlowClassifier,};});'use strict';function*getEventInFlowEvents(event){if(!event.inFlowEvents)return;yield*event.inFlowEvents;}
+function*getEventOutFlowEvents(event){if(!event.outFlowEvents)return;yield*event.outFlowEvents;}
+function*getEventAncestors(event){if(!event.enumerateAllAncestors)return;yield*event.enumerateAllAncestors();}
+function*getEventDescendents(event){if(!event.enumerateAllDescendents)return;yield*event.enumerateAllDescendents();}
+Polymer({is:'tr-ui-a-related-events',ready(){this.eventGroups_=[];this.cancelFunctions_=[];this.$.table.tableColumns=[{title:'Event(s)',value(row){const typeEl=document.createElement('span');typeEl.innerText=row.type;if(row.tooltip){typeEl.title=row.tooltip;}
+return typeEl;},width:'150px'},{title:'Link',width:'100%',value(row){const linkEl=document.createElement('tr-ui-a-analysis-link');if(row.name){linkEl.setSelectionAndContent(row.selection,row.name);}else{linkEl.selection=row.selection;}
+return linkEl;}}];},hasRelatedEvents(){return(this.eventGroups_&&this.eventGroups_.length>0);},setRelatedEvents(eventSet){this.cancelAllTasks_();this.eventGroups_=[];this.addRuntimeCallStats_(eventSet);this.addOverlappingV8ICStats_(eventSet);this.addV8GCObjectStats_(eventSet);this.addV8Slices_(eventSet);this.addConnectedFlows_(eventSet);this.addConnectedEvents_(eventSet);this.addOverlappingSamples_(eventSet);this.updateContents_();},addConnectedFlows_(eventSet){const classifier=new tr.ui.analysis.FlowClassifier();eventSet.forEach(function(slice){if(slice.inFlowEvents){slice.inFlowEvents.forEach(function(flow){classifier.addInFlow(flow);});}
+if(slice.outFlowEvents){slice.outFlowEvents.forEach(function(flow){classifier.addOutFlow(flow);});}});if(!classifier.hasEvents())return;const addToEventGroups=function(type,flowEvent){this.eventGroups_.push({type,selection:new tr.model.EventSet(flowEvent),name:flowEvent.title});};classifier.inFlowEvents.forEach(addToEventGroups.bind(this,'Incoming flow'));classifier.outFlowEvents.forEach(addToEventGroups.bind(this,'Outgoing flow'));classifier.internalFlowEvents.forEach(addToEventGroups.bind(this,'Internal flow'));},cancelAllTasks_(){this.cancelFunctions_.forEach(function(cancelFunction){cancelFunction();});this.cancelFunctions_=[];},addConnectedEvents_(eventSet){this.cancelFunctions_.push(this.createEventsLinkIfNeeded_('Preceding events','Add all events that have led to the selected one(s), connected by '+'flow arrows or by call stack.',eventSet,function*(event){yield*getEventInFlowEvents(event);yield*getEventAncestors(event);if(event.startSlice){yield event.startSlice;}}.bind(this)));this.cancelFunctions_.push(this.createEventsLinkIfNeeded_('Following events','Add all events that have been caused by the selected one(s), '+'connected by flow arrows or by call stack.',eventSet,function*(event){yield*getEventOutFlowEvents(event);yield*getEventDescendents(event);if(event.endSlice){yield event.endSlice;}}.bind(this)));this.cancelFunctions_.push(this.createEventsLinkIfNeeded_('All connected events','Add all events connected to the selected one(s) by flow arrows or '+'by call stack.',eventSet,function*(event){yield*getEventInFlowEvents(event);yield*getEventOutFlowEvents(event);yield*getEventAncestors(event);yield*getEventDescendents(event);if(event.startSlice){yield event.startSlice;}
+if(event.endSlice){yield event.endSlice;}}.bind(this)));},createEventsLinkIfNeeded_(title,tooltip,events,connectedFn){events=new tr.model.EventSet(events);const eventsToProcess=new Set(events);let wasChanged=false;let task;let isCanceled=false;function addEventsUntilTimeout(){if(isCanceled)return;const timeout=window.performance.now()+8;while(eventsToProcess.size>0&&window.performance.now()<=timeout){const nextEvent=tr.b.getFirstElement(eventsToProcess);eventsToProcess.delete(nextEvent);for(const eventToAdd of connectedFn(nextEvent)){if(!events.contains(eventToAdd)){events.push(eventToAdd);eventsToProcess.add(eventToAdd);wasChanged=true;}}}
+if(eventsToProcess.size>0){const newTask=new tr.b.Task(addEventsUntilTimeout.bind(this),this);task.after(newTask);task=newTask;return;}
+if(!wasChanged)return;this.eventGroups_.push({type:title,tooltip,selection:events});this.updateContents_();}
+function cancelTask(){isCanceled=true;}
+task=new tr.b.Task(addEventsUntilTimeout.bind(this),this);tr.b.Task.RunWhenIdle(task);return cancelTask;},addOverlappingSamples_(eventSet){const samples=new tr.model.EventSet();for(const slice of eventSet){if(!slice.parentContainer||!slice.parentContainer.samples){continue;}
+const candidates=slice.parentContainer.samples;const range=tr.b.math.Range.fromExplicitRange(slice.start,slice.start+slice.duration);const filteredSamples=range.filterArray(candidates,function(value){return value.start;});for(const sample of filteredSamples){samples.push(sample);}}
+if(samples.length>0){this.eventGroups_.push({type:'Overlapping samples',tooltip:'All samples overlapping the selected slice(s).',selection:samples});}},addV8Slices_(eventSet){const v8Slices=new tr.model.EventSet();for(const slice of eventSet){if(slice.category==='v8'){v8Slices.push(slice);}}
+if(v8Slices.length>0){this.eventGroups_.push({type:'V8 Slices',tooltip:'All V8 slices in the selected slice(s).',selection:v8Slices});}},addRuntimeCallStats_(eventSet){const slices=eventSet.filter(function(slice){return(slice.category==='v8'||slice.category==='disabled-by-default-v8.runtime_stats')&&slice.runtimeCallStats;});if(slices.length>0){this.eventGroups_.push({type:'Runtime call stats table',tooltip:'All V8 slices containing runtime call stats table in the selected slice(s).',selection:slices});}},addV8GCObjectStats_(eventSet){const slices=new tr.model.EventSet();for(const slice of eventSet){if(slice.title==='V8.GC_Objects_Stats'){slices.push(slice);}}
+if(slices.length>0){this.eventGroups_.push({type:'V8 GC stats table',tooltip:'All V8 GC statistics slices in the selected set.',selection:slices});}},addOverlappingV8ICStats_(eventSet){const slices=new tr.model.EventSet();for(const slice of eventSet){if(!slice.parentContainer||!slice.parentContainer.sliceGroup){continue;}
+const sliceGroup=slice.parentContainer.sliceGroup.slices;const range=tr.b.math.Range.fromExplicitRange(slice.start,slice.start+slice.duration);const filteredSlices=range.filterArray(sliceGroup,value=>value.start);const icSlices=filteredSlices.filter(x=>x.title==='V8.ICStats');for(const icSlice of icSlices){slices.push(icSlice);}}
+if(slices.length>0){this.eventGroups_.push({type:'Overlapping V8 IC stats',tooltip:'All V8 IC statistics overlapping the selected set.',selection:slices});}},updateContents_(){const table=this.$.table;if(this.eventGroups_===undefined){table.tableRows=[];}else{table.tableRows=this.eventGroups_.slice();}
+table.rebuild();}});'use strict';Polymer({is:'tr-ui-a-multi-async-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){this.$.content.selection=selection;this.$.relatedEvents.setRelatedEvents(selection);if(this.$.relatedEvents.hasRelatedEvents()){this.$.relatedEvents.style.display='';}else{this.$.relatedEvents.style.display='none';}},get relatedEventsToHighlight(){if(!this.$.content.selection)return undefined;const selection=new tr.model.EventSet();this.$.content.selection.forEach(function(asyncEvent){if(!asyncEvent.associatedEvents)return;asyncEvent.associatedEvents.forEach(function(event){selection.push(event);});});if(selection.length)return selection;return undefined;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-async-slice-sub-view',tr.model.AsyncSlice,{multi:true,title:'Async Slices',});'use strict';Polymer({is:'tr-ui-a-multi-cpu-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready(){this.$.content.eventsHaveSubRows=false;},get selection(){return this.$.content.selection;},set selection(selection){this.$.content.setSelectionWithoutErrorChecks(selection);}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-cpu-slice-sub-view',tr.model.CpuSlice,{multi:true,title:'CPU Slices',});'use strict';Polymer({is:'tr-ui-a-multi-flow-event-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready(){this.$.content.eventsHaveDuration=false;this.$.content.eventsHaveSubRows=false;},set selection(selection){this.$.content.selection=selection;},get selection(){return this.$.content.selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-flow-event-sub-view',tr.model.FlowEvent,{multi:true,title:'Flow Events',});'use strict';Polymer({is:'tr-ui-a-multi-frame-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},set selection(selection){Polymer.dom(this).textContent='';const realView=document.createElement('tr-ui-a-multi-event-sub-view');realView.eventsHaveDuration=false;realView.eventsHaveSubRows=false;Polymer.dom(this).appendChild(realView);realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;},get selection(){return this.currentSelection_;},get relatedEventsToHighlight(){if(!this.currentSelection_)return undefined;const selection=new tr.model.EventSet();this.currentSelection_.forEach(function(frameEvent){frameEvent.associatedEvents.forEach(function(event){selection.push(event);});});return selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-frame-sub-view',tr.model.Frame,{multi:true,title:'Frames',});'use strict';Polymer({is:'tr-ui-a-multi-instant-event-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},set selection(selection){Polymer.dom(this.$.content).textContent='';const realView=document.createElement('tr-ui-a-multi-event-sub-view');realView.eventsHaveDuration=false;realView.eventsHaveSubRows=false;Polymer.dom(this.$.content).appendChild(realView);realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;},get selection(){return this.currentSelection_;}});'use strict';Polymer({is:'tr-ui-a-multi-object-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},ready(){this.$.content.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;const objectEvents=Array.from(selection).sort(tr.b.math.Range.compareByMinTimes);const timeSpanConfig={unit:tr.b.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument};const table=this.$.content;table.tableColumns=[{title:'First',value(event){if(event instanceof tr.model.ObjectSnapshot){return tr.v.ui.createScalarSpan(event.ts,timeSpanConfig);}
+const spanEl=document.createElement('span');Polymer.dom(spanEl).appendChild(tr.v.ui.createScalarSpan(event.creationTs,timeSpanConfig));Polymer.dom(spanEl).appendChild(tr.ui.b.createSpan({textContent:'-',marginLeft:'4px',marginRight:'4px'}));if(event.deletionTs!==Number.MAX_VALUE){Polymer.dom(spanEl).appendChild(tr.v.ui.createScalarSpan(event.deletionTs,timeSpanConfig));}
+return spanEl;},width:'200px'},{title:'Second',value(event){const linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(event);},event.userFriendlyName);return linkEl;},width:'100%'}];table.tableRows=objectEvents;table.rebuild();}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-object-sub-view',tr.model.ObjectInstance,{multi:true,title:'Object Instances',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-object-sub-view',tr.model.ObjectSnapshot,{multi:true,title:'Object Snapshots',});'use strict';const EventSet=tr.model.EventSet;const CHART_TITLE='Power (W) by ms since vertical sync';Polymer({is:'tr-ui-a-frame-power-usage-chart',ready(){this.chart_=undefined;this.samples_=new EventSet();this.vSyncTimestamps_=[];},attached(){if(this.samples_)this.updateContents_();},get chart(){return this.chart_;},get samples(){return this.samples_;},get vSyncTimestamps(){return this.vSyncTimestamps_;},setData(samples,vSyncTimestamps){this.samples_=(samples===undefined)?new EventSet():samples;this.vSyncTimestamps_=(vSyncTimestamps===undefined)?[]:vSyncTimestamps;if(this.isAttached)this.updateContents_();},updateContents_(){this.clearChart_();const data=this.getDataForLineChart_();if(data.length===0)return;this.chart_=new tr.ui.b.LineChart();Polymer.dom(this.$.content).appendChild(this.chart_);this.chart_.chartTitle=CHART_TITLE;this.chart_.data=data;},clearChart_(){const content=this.$.content;while(Polymer.dom(content).firstChild){Polymer.dom(content).removeChild(Polymer.dom(content).firstChild);}
+this.chart_=undefined;},getDataForLineChart_(){const sortedSamples=this.sortSamplesByTimestampAscending_(this.samples);const vSyncTimestamps=this.vSyncTimestamps.slice();let lastVSyncTimestamp=undefined;const points=[];let frameNumber=0;sortedSamples.forEach(function(sample){while(vSyncTimestamps.length>0&&vSyncTimestamps[0]<=sample.start){lastVSyncTimestamp=vSyncTimestamps.shift();frameNumber++;}
+if(lastVSyncTimestamp===undefined)return;const point={x:sample.start-lastVSyncTimestamp};point['f'+frameNumber]=sample.powerInW;points.push(point);});return points;},sortSamplesByTimestampAscending_(samples){return samples.toArray().sort(function(smpl1,smpl2){return smpl1.start-smpl2.start;});}});'use strict';Polymer({is:'tr-ui-a-power-sample-summary-table',ready(){this.$.table.tableColumns=[{title:'Min power',width:'100px',value(row){return tr.b.Unit.byName.powerInWatts.format(row.min);}},{title:'Max power',width:'100px',value(row){return tr.b.Unit.byName.powerInWatts.format(row.max);}},{title:'Time-weighted average',width:'100px',value(row){return tr.b.Unit.byName.powerInWatts.format(row.timeWeightedAverageInW);}},{title:'Energy consumed',width:'100px',value(row){return tr.b.Unit.byName.energyInJoules.format(row.energyConsumedInJ);}},{title:'Sample count',width:'100%',value(row){return row.sampleCount;}}];this.samples=new tr.model.EventSet();},get samples(){return this.samples_;},set samples(samples){if(samples===this.samples)return;this.samples_=(samples===undefined)?new tr.model.EventSet():samples;this.updateContents_();},updateContents_(){if(this.samples.length===0){this.$.table.tableRows=[];}else{this.$.table.tableRows=[{min:this.getMin(),max:this.getMax(),timeWeightedAverageInW:this.getTimeWeightedAverageInW(),energyConsumedInJ:this.getEnergyConsumedInJ(),sampleCount:this.samples.length}];}
+this.$.table.rebuild();},getMin(){return Math.min.apply(null,this.samples.map(function(sample){return sample.powerInW;}));},getMax(){return Math.max.apply(null,this.samples.map(function(sample){return sample.powerInW;}));},getTimeWeightedAverageInW(){const energyConsumedInJ=this.getEnergyConsumedInJ();if(energyConsumedInJ==='N/A')return'N/A';const durationInS=tr.b.convertUnit(this.samples.bounds.duration,tr.b.UnitPrefixScale.METRIC.MILLI,tr.b.UnitPrefixScale.METRIC.NONE);return energyConsumedInJ/durationInS;},getEnergyConsumedInJ(){if(this.samples.length<2)return'N/A';const bounds=this.samples.bounds;const series=tr.b.getFirstElement(this.samples).series;return series.getEnergyConsumedInJ(bounds.min,bounds.max);}});'use strict';Polymer({is:'tr-ui-a-multi-power-sample-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},updateContents_(){const samples=this.selection;const vSyncTimestamps=(!samples?[]:tr.b.getFirstElement(samples).series.device.vSyncTimestamps);this.$.summaryTable.samples=samples;this.$.chart.setData(this.selection,vSyncTimestamps);}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-power-sample-sub-view',tr.model.PowerSample,{multi:true,title:'Power Samples',});'use strict';(function(){const MultiDimensionalViewBuilder=tr.b.MultiDimensionalViewBuilder;Polymer({is:'tr-ui-a-multi-sample-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.viewOption_=undefined;this.selection_=undefined;},ready(){const viewSelector=tr.ui.b.createSelector(this,'viewOption','tracing.ui.analysis.multi_sample_sub_view',MultiDimensionalViewBuilder.ViewType.TOP_DOWN_TREE_VIEW,[{label:'Top-down (Tree)',value:MultiDimensionalViewBuilder.ViewType.TOP_DOWN_TREE_VIEW},{label:'Top-down (Heavy)',value:MultiDimensionalViewBuilder.ViewType.TOP_DOWN_HEAVY_VIEW},{label:'Bottom-up (Heavy)',value:MultiDimensionalViewBuilder.ViewType.BOTTOM_UP_HEAVY_VIEW}]);Polymer.dom(this.$.control).appendChild(viewSelector);this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;this.updateContents_();},get viewOption(){return this.viewOption_;},set viewOption(viewOption){this.viewOption_=viewOption;this.updateContents_();},createSamplingSummary_(selection,viewOption){const builder=new MultiDimensionalViewBuilder(1,1);const samples=selection.filter(event=>event instanceof tr.model.Sample);samples.forEach(function(sample){builder.addPath([sample.userFriendlyStack.reverse()],[1],MultiDimensionalViewBuilder.ValueKind.SELF);});return builder.buildView(viewOption);},processSampleRows_(rows){for(const row of rows){let title=row.title[0];let results=/(.*) (Deoptimized reason: .*)/.exec(title);if(results!==null){row.deoptReason=results[2];title=results[1];}
+results=/(.*) url: (.*)/.exec(title);if(results!==null){row.functionName=results[1];row.url=results[2];if(row.functionName===''){row.functionName='(anonymous function)';}
+if(row.url===''){row.url='unknown';}}else{row.functionName=title;row.url='unknown';}
+this.processSampleRows_(row.subRows);}},updateContents_(){if(this.selection===undefined){this.$.table.tableColumns=[];this.$.table.tableRows=[];this.$.table.rebuild();return;}
+const samplingData=this.createSamplingSummary_(this.selection,this.viewOption);const total=samplingData.values[0].total;const columns=[this.createPercentColumn_('Total',total),this.createSamplesColumn_('Total'),this.createPercentColumn_('Self',total),this.createSamplesColumn_('Self'),{title:'Function Name',value(row){if(row.deoptReason!==undefined){const spanEl=tr.ui.b.createSpan({italic:true,color:'#F44336',tooltip:row.deoptReason});spanEl.innerText=row.functionName;return spanEl;}
+return row.functionName;},width:'150px',cmp:(a,b)=>a.functionName.localeCompare(b.functionName),showExpandButtons:true},{title:'Location',value(row){return row.url;},width:'250px',cmp:(a,b)=>a.url.localeCompare(b.url),}];this.processSampleRows_(samplingData.subRows);this.$.table.tableColumns=columns;this.$.table.sortColumnIndex=1;this.$.table.sortDescending=true;this.$.table.tableRows=samplingData.subRows;this.$.table.rebuild();},createPercentColumn_(title,samplingDataTotal){const field=title.toLowerCase();return{title:title+' percent',value(row){return tr.v.ui.createScalarSpan(row.values[0][field]/samplingDataTotal,{customContextRange:tr.b.math.Range.PERCENT_RANGE,unit:tr.b.Unit.byName.normalizedPercentage,context:{minimumFractionDigits:2,maximumFractionDigits:2},});},width:'60px',cmp:(a,b)=>a.values[0][field]-b.values[0][field]};},createSamplesColumn_(title){const field=title.toLowerCase();return{title:title+' samples',value(row){return tr.v.ui.createScalarSpan(row.values[0][field],{unit:tr.b.Unit.byName.unitlessNumber,context:{maximumFractionDigits:0},});},width:'60px',cmp:(a,b)=>a.values[0][field]-b.values[0][field]};}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-sample-sub-view',tr.model.Sample,{multi:true,title:'Samples',});})();'use strict';Polymer({is:'tr-ui-a-multi-thread-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.selection_=undefined;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;if(tr.isExported('tr.ui.e.chrome.cc.RasterTaskSelection')){if(tr.ui.e.chrome.cc.RasterTaskSelection.supports(selection)){const ltvSelection=new tr.ui.e.chrome.cc.RasterTaskSelection(selection);const ltv=new tr.ui.e.chrome.cc.LayerTreeHostImplSnapshotView();ltv.objectSnapshot=ltvSelection.containingSnapshot;ltv.selection=ltvSelection;ltv.extraHighlightsByLayerId=ltvSelection.extraHighlightsByLayerId;Polymer.dom(this.$.content).textContent='';Polymer.dom(this.$.content).appendChild(ltv);this.requiresTallView_=true;return;}}
+Polymer.dom(this.$.content).textContent='';const mesv=document.createElement('tr-ui-a-multi-event-sub-view');mesv.selection=selection;Polymer.dom(this.$.content).appendChild(mesv);const relatedEvents=document.createElement('tr-ui-a-related-events');relatedEvents.setRelatedEvents(selection);if(relatedEvents.hasRelatedEvents()){Polymer.dom(this.$.content).appendChild(relatedEvents);}},get requiresTallView(){if(this.$.content.children.length===0)return false;const childTagName=this.$.content.children[0].tagName;if(childTagName==='TR-UI-A-MULTI-EVENT-SUB-VIEW'){return false;}
+return true;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-thread-slice-sub-view',tr.model.ThreadSlice,{multi:true,title:'Slices',});'use strict';Polymer({is:'tr-ui-a-multi-thread-time-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready(){this.$.content.eventsHaveSubRows=false;},get selection(){return this.$.content.selection;},set selection(selection){this.$.content.setSelectionWithoutErrorChecks(selection);}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-thread-time-slice-sub-view',tr.model.ThreadTimeSlice,{multi:true,title:'Thread Timeslices',});'use strict';Polymer({is:'tr-ui-a-user-expectation-related-samples-table',ready(){this.samples_=[];this.$.table.tableColumns=[{title:'Event(s)',value(row){const typeEl=document.createElement('span');typeEl.innerText=row.type;if(row.tooltip){typeEl.title=row.tooltip;}
+return typeEl;},width:'150px'},{title:'Link',width:'100%',value(row){const linkEl=document.createElement('tr-ui-a-analysis-link');if(row.name){linkEl.setSelectionAndContent(row.selection,row.name);}else{linkEl.selection=row.selection;}
+return linkEl;}}];},hasRelatedSamples(){return(this.samples_&&this.samples_.length>0);},set selection(eventSet){this.samples_=[];const samples=new tr.model.EventSet;eventSet.forEach(function(ue){samples.addEventSet(ue.associatedSamples);}.bind(this));if(samples.length>0){this.samples_.push({type:'Overlapping samples',tooltip:'All samples overlapping the selected user expectation(s).',selection:samples});}
+this.updateContents_();},updateContents_(){const table=this.$.table;if(this.samples_&&this.samples_.length>0){table.tableRows=this.samples_.slice();}else{table.tableRows=[];}
+table.rebuild();}});'use strict';Polymer({is:'tr-ui-a-multi-interaction-record-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},set selection(selection){this.currentSelection_=selection;this.$.realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;this.$.relatedSamples.selection=selection;if(this.$.relatedSamples.hasRelatedSamples()){this.$.events.style.display='';}else{this.$.events.style.display='none';}},get selection(){return this.currentSelection_;},get relatedEventsToHighlight(){if(!this.currentSelection_)return undefined;const selection=new tr.model.EventSet();this.currentSelection_.forEach(function(ir){ir.associatedEvents.forEach(function(event){selection.push(event);});});return selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-user-expectation-sub-view',tr.model.um.UserExpectation,{multi:true,title:'User Expectations',});'use strict';Polymer({is:'tr-ui-a-single-async-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){if(selection.length!==1){throw new Error('Only supports single slices');}
+this.$.content.setSelectionWithoutErrorChecks(selection);this.$.relatedEvents.setRelatedEvents(selection);if(this.$.relatedEvents.hasRelatedEvents()){this.$.relatedEvents.style.display='';}else{this.$.relatedEvents.style.display='none';}},getEventRows_(event){const rows=this.__proto__.__proto__.getEventRows_(event);rows.splice(0,0,{name:'ID',value:event.id});return rows;},get relatedEventsToHighlight(){if(!this.currentSelection_)return undefined;return tr.b.getOnlyElement(this.currentSelection_).associatedEvents;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-async-slice-sub-view',tr.model.AsyncSlice,{multi:false,title:'Async Slice',});'use strict';Polymer({is:'tr-ui-a-single-cpu-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){const cpuSlice=tr.b.getOnlyElement(selection);if(!(cpuSlice instanceof tr.model.CpuSlice)){throw new Error('Only supports thread time slices');}
+this.currentSelection_=selection;const thread=cpuSlice.threadThatWasRunning;const root=Polymer.dom(this.root);if(thread){Polymer.dom(root.querySelector('#process-name')).textContent=thread.parent.userFriendlyName;Polymer.dom(root.querySelector('#thread-name')).textContent=thread.userFriendlyName;}else{root.querySelector('#process-name').parentElement.style.display='none';Polymer.dom(root.querySelector('#thread-name')).textContent=cpuSlice.title;}
+root.querySelector('#start').setValueAndUnit(cpuSlice.start,tr.b.Unit.byName.timeStampInMs);root.querySelector('#duration').setValueAndUnit(cpuSlice.duration,tr.b.Unit.byName.timeDurationInMs);const runningThreadEl=root.querySelector('#running-thread');const timeSlice=cpuSlice.getAssociatedTimeslice();if(!timeSlice){runningThreadEl.parentElement.style.display='none';}else{const threadLink=document.createElement('tr-ui-a-analysis-link');threadLink.selection=new tr.model.EventSet(timeSlice);Polymer.dom(threadLink).textContent='Click to select';runningThreadEl.parentElement.style.display='';Polymer.dom(runningThreadEl).textContent='';Polymer.dom(runningThreadEl).appendChild(threadLink);}
+root.querySelector('#args').object=cpuSlice.args;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-cpu-slice-sub-view',tr.model.CpuSlice,{multi:false,title:'CPU Slice',});'use strict';function createAnalysisLinkTo(event){const linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(new tr.model.EventSet(event),event.userFriendlyName);return linkEl;}
+Polymer({is:'tr-ui-a-single-flow-event-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],listeners:{'singleEventSubView.customize-rows':'onCustomizeRows_'},set selection(selection){this.currentSelection_=selection;this.$.singleEventSubView.setSelectionWithoutErrorChecks(selection);},get selection(){return this.currentSelection_;},onCustomizeRows_(e){const event=tr.b.getOnlyElement(this.currentSelection_);const rows=e.rows;rows.unshift({name:'ID',value:event.id});rows.push({name:'From',value:createAnalysisLinkTo(event.startSlice)});rows.push({name:'To',value:createAnalysisLinkTo(event.endSlice)});}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-flow-event-sub-view',tr.model.FlowEvent,{multi:false,title:'Flow Event',});'use strict';Polymer({is:'tr-ui-a-single-frame-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.$.asv.selection=tr.b.getOnlyElement(selection).associatedAlerts;},get relatedEventsToHighlight(){if(!this.currentSelection_)return undefined;return tr.b.getOnlyElement(this.currentSelection_).associatedEvents;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-frame-sub-view',tr.model.Frame,{multi:false,title:'Frame',});'use strict';Polymer({is:'tr-ui-a-single-instant-event-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},set selection(selection){Polymer.dom(this.$.content).textContent='';const realView=document.createElement('tr-ui-a-single-event-sub-view');realView.setSelectionWithoutErrorChecks(selection);Polymer.dom(this.$.content).appendChild(realView);this.currentSelection_=selection;},get selection(){return this.currentSelection_;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-instant-event-sub-view',tr.model.InstantEvent,{multi:false,title:'Instant Event',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-instant-event-sub-view',tr.model.InstantEvent,{multi:true,title:'Instant Events',});'use strict';tr.exportTo('tr.ui.analysis',function(){const ObjectInstanceView=tr.ui.b.define('object-instance-view');ObjectInstanceView.prototype={__proto__:HTMLDivElement.prototype,decorate(){this.objectInstance_=undefined;},get requiresTallView(){return true;},set modelEvent(obj){this.objectInstance=obj;},get modelEvent(){return this.objectInstance;},get objectInstance(){return this.objectInstance_;},set objectInstance(i){this.objectInstance_=i;this.updateContents();},updateContents(){throw new Error('Not implemented');}};const options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectInstanceView;options.defaultMetadata={showInTrackView:true};tr.b.decorateExtensionRegistry(ObjectInstanceView,options);return{ObjectInstanceView,};});'use strict';Polymer({is:'tr-ui-a-single-object-instance-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},get requiresTallView(){if(this.$.content.children.length===0){return false;}
+if(this.$.content.children[0]instanceof
+tr.ui.analysis.ObjectInstanceView){return this.$.content.children[0].requiresTallView;}},get selection(){return this.currentSelection_;},set selection(selection){const instance=tr.b.getOnlyElement(selection);if(!(instance instanceof tr.model.ObjectInstance)){throw new Error('Only supports object instances');}
+Polymer.dom(this.$.content).textContent='';this.currentSelection_=selection;const typeInfo=tr.ui.analysis.ObjectInstanceView.getTypeInfo(instance.category,instance.typeName);if(typeInfo){const customView=new typeInfo.constructor();Polymer.dom(this.$.content).appendChild(customView);customView.modelEvent=instance;}else{this.appendGenericAnalysis_(instance);}},appendGenericAnalysis_(instance){let html='';html+='<div class="title">'+
 instance.typeName+' '+
 instance.id+'</div>\n';html+='<table>';html+='<tr>';html+='<tr><td>creationTs:</td><td>'+
-instance.creationTs+'</td></tr>\n';if(instance.deletionTs!=Number.MAX_VALUE){html+='<tr><td>deletionTs:</td><td>'+
+instance.creationTs+'</td></tr>\n';if(instance.deletionTs!==Number.MAX_VALUE){html+='<tr><td>deletionTs:</td><td>'+
 instance.deletionTs+'</td></tr>\n';}else{html+='<tr><td>deletionTs:</td><td>not deleted</td></tr>\n';}
-html+='<tr><td>snapshots:</td><td id="snapshots"></td></tr>\n';html+='</table>';this.$.content.innerHTML=html;var snapshotsEl=this.$.content.querySelector('#snapshots');instance.snapshots.forEach(function(snapshot){var snapshotLink=document.createElement('tr-ui-a-analysis-link');snapshotLink.selection=new tr.model.EventSet(snapshot);snapshotsEl.appendChild(snapshotLink);});}});'use strict';Polymer('tr-ui-a-single-object-snapshot-sub-view',{created:function(){this.currentSelection_=undefined;},get requiresTallView(){if(this.children.length===0)
-return false;if(this.children[0]instanceof tr.ui.analysis.ObjectSnapshotView)
-return this.children[0].requiresTallView;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1)
-throw new Error('Only supports single item selections');if(!(selection[0]instanceof tr.model.ObjectSnapshot))
-throw new Error('Only supports object instances');this.textContent='';this.currentSelection_=selection;var snapshot=selection[0];var typeInfo=tr.ui.analysis.ObjectSnapshotView.getTypeInfo(snapshot.objectInstance.category,snapshot.objectInstance.typeName);if(typeInfo){var customView=new typeInfo.constructor();this.appendChild(customView);customView.modelEvent=snapshot;}else{this.appendGenericAnalysis_(snapshot);}},appendGenericAnalysis_:function(snapshot){var instance=snapshot.objectInstance;this.textContent='';var titleEl=document.createElement('div');titleEl.classList.add('title');titleEl.appendChild(document.createTextNode('Snapshot of '));this.appendChild(titleEl);var instanceLinkEl=document.createElement('tr-ui-a-analysis-link');instanceLinkEl.selection=new tr.model.EventSet(instance);titleEl.appendChild(instanceLinkEl);titleEl.appendChild(document.createTextNode(' @ '));titleEl.appendChild(tr.v.ui.createScalarSpan(snapshot.ts,{unit:tr.v.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument}));var tableEl=document.createElement('table');this.appendChild(tableEl);var rowEl=document.createElement('tr');tableEl.appendChild(rowEl);var labelEl=document.createElement('td');labelEl.textContent='args:';rowEl.appendChild(labelEl);var argsEl=document.createElement('td');argsEl.id='args';rowEl.appendChild(argsEl);var objectViewEl=document.createElement('tr-ui-a-generic-object-view');objectViewEl.object=snapshot.args;argsEl.appendChild(objectViewEl);}});'use strict';Polymer('tr-ui-a-single-power-sample-sub-view',{ready:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},updateContents_:function(){this.$.samplesTable.samples=this.selection;}});'use strict';Polymer('tr-ui-a-single-sample-sub-view',{created:function(){this.currentSelection_=undefined;},ready:function(){this.$.content.tableColumns=[{title:'FirstColumn',value:function(row){return row.title;},width:'250px'},{title:'SecondColumn',value:function(row){return row.value;},width:'100%'}];this.$.content.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;if(this.currentSelection_===undefined){this.$.content.tableRows=[];return;}
-var sample=this.currentSelection_[0];var table=this.$.content;var rows=[];rows.push({title:'Title',value:sample.title});rows.push({title:'Sample time',value:tr.v.ui.createScalarSpan(sample.start,{unit:tr.v.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument})});var sfEl=document.createElement('tr-ui-a-stack-frame');sfEl.stackFrame=sample.leafStackFrame;rows.push({title:'Stack trace',value:sfEl});table.tableRows=rows;table.rebuild();}});'use strict';Polymer('tr-ui-a-single-thread-slice-sub-view',{get selection(){return this.$.content.selection;},set selection(selection){this.$.content.selection=selection;this.$.relatedEvents.setRelatedEvents(selection);if(this.$.relatedEvents.hasRelatedEvents())
-this.$.relatedEvents.style.display='';else
-this.$.relatedEvents.style.display='none';}});'use strict';Polymer('tr-ui-a-single-thread-time-slice-sub-view',{created:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1)
-throw new Error('Only supports single slices');if(!(selection[0]instanceof tr.model.ThreadTimeSlice))
-throw new Error('Only supports thread time slices');this.currentSelection_=selection;var timeSlice=selection[0];var thread=timeSlice.thread;var shadowRoot=this.shadowRoot;shadowRoot.querySelector('#state').textContent=timeSlice.title;var stateColor=tr.b.ColorScheme.colorsAsStrings[timeSlice.colorId];shadowRoot.querySelector('#state').style.backgroundColor=stateColor;shadowRoot.querySelector('#process-name').textContent=thread.parent.userFriendlyName;shadowRoot.querySelector('#thread-name').textContent=thread.userFriendlyName;shadowRoot.querySelector('#start').setValueAndUnit(timeSlice.start,tr.v.Unit.byName.timeStampInMs);shadowRoot.querySelector('#duration').setValueAndUnit(timeSlice.duration,tr.v.Unit.byName.timeDurationInMs);var onCpuEl=shadowRoot.querySelector('#on-cpu');onCpuEl.textContent='';var runningInsteadEl=shadowRoot.querySelector('#running-instead');if(timeSlice.cpuOnWhichThreadWasRunning){runningInsteadEl.parentElement.removeChild(runningInsteadEl);var cpuLink=document.createElement('tr-ui-a-analysis-link');cpuLink.selection=new tr.model.EventSet(timeSlice.getAssociatedCpuSlice());cpuLink.textContent=timeSlice.cpuOnWhichThreadWasRunning.userFriendlyName;onCpuEl.appendChild(cpuLink);}else{onCpuEl.parentElement.removeChild(onCpuEl);var cpuSliceThatTookCpu=timeSlice.getCpuSliceThatTookCpu();if(cpuSliceThatTookCpu){var cpuLink=document.createElement('tr-ui-a-analysis-link');cpuLink.selection=new tr.model.EventSet(cpuSliceThatTookCpu);if(cpuSliceThatTookCpu.thread)
-cpuLink.textContent=cpuSliceThatTookCpu.thread.userFriendlyName;else
-cpuLink.textContent=cpuSliceThatTookCpu.title;runningInsteadEl.appendChild(cpuLink);}else{runningInsteadEl.parentElement.removeChild(runningInsteadEl);}}
-var argsEl=shadowRoot.querySelector('#args');if(tr.b.dictionaryKeys(timeSlice.args).length>0){var argsView=document.createElement('tr-ui-a-generic-object-view');argsView.object=timeSlice.args;argsEl.parentElement.style.display='';argsEl.textContent='';argsEl.appendChild(argsView);}else{argsEl.parentElement.style.display='none';}}});'use strict';tr.exportTo('tr.metrics',function(){function ValueList(values){if(values!==undefined)
-this.values_=values;else
-this.values_=[];}
-ValueList.prototype={get valueDicts(){return this.values_.map(function(v){return v.asDict();});},getValuesWithName:function(name){return this.values_.filter(function(value){return value.name.indexOf(name)>-1;});},addValue:function(v){if(!(v instanceof tr.v.NumericValue)){var err=new Error('Tried to add value '+v+' which is non-Numeric');err.name='ValueError';throw err;}
-this.values_.push(v);}};return{ValueList:ValueList};});'use strict';Polymer('tr-ui-a-single-user-expectation-sub-view',{created:function(){this.currentSelection_=undefined;this.realView_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.textContent='';this.realView_=document.createElement('tr-ui-a-single-event-sub-view');this.realView_.addEventListener('customize-rows',this.onCustomizeRows_.bind(this));this.appendChild(this.realView_);this.currentSelection_=selection;this.realView_.setSelectionWithoutErrorChecks(selection);},get relatedEventsToHighlight(){if(!this.currentSelection_)
-return undefined;return this.currentSelection_[0].associatedEvents;},onCustomizeRows_:function(event){var ue=this.selection[0];var valueList=new tr.metrics.ValueList();function runMetric(metricInfo){try{metricInfo.constructor(valueList,ue.parentModel);}catch(failure){console.error(metricInfo,failure);}}
-tr.metrics.MetricRegistry.getAllRegisteredTypeInfos().forEach(runMetric);var metricValues={};valueList.valueDicts.forEach(function(value){if(value.grouping_keys.userExpectationStableId!==ue.stableId)
-return;if((value.type!=='numeric')||(value.numeric.type!=='scalar'))
-return;metricValues[value.grouping_keys.name]=value.numeric;});for(var name in metricValues){event.rows.push({name:name,value:tr.v.ui.createScalarSpan(metricValues[name].value,{unit:tr.v.Unit.fromJSON(metricValues[name].unit)})});}
-if(ue.rawCpuMs){event.rows.push({name:'Total CPU',value:tr.v.ui.createScalarSpan(ue.totalCpuMs,{unit:tr.v.Unit.byName.timeDurationInMs})});}}});'use strict';Polymer('tr-ui-a-tab-view',{ready:function(){this.$.tshh.style.display='none';this.tabs_=[];this.selectedTab_=undefined;for(var i=0;i<this.children.length;i++)
-this.processAddedChild_(this.children[i]);this.childrenObserver_=new MutationObserver(this.childrenUpdated_.bind(this));this.childrenObserver_.observe(this,{childList:'true'});},get tabStripHeadingText(){return this.$.tsh.textContent;},set tabStripHeadingText(tabStripHeadingText){this.$.tsh.textContent=tabStripHeadingText;if(!!tabStripHeadingText)
-this.$.tshh.style.display='';else
-this.$.tshh.style.display='none';},get selectedTab(){this.childrenUpdated_(this.childrenObserver_.takeRecords(),this.childrenObserver_);if(this.selectedTab_)
-return this.selectedTab_.content;return undefined;},set selectedTab(content){this.childrenUpdated_(this.childrenObserver_.takeRecords(),this.childrenObserver_);if(content===undefined||content===null){this.changeSelectedTabById_(undefined);return;}
-var contentTabId=undefined;for(var i=0;i<this.tabs_.length;i++)
-if(this.tabs_[i].content===content){contentTabId=this.tabs_[i].id;break;}
-if(contentTabId===undefined)
-return;this.changeSelectedTabById_(contentTabId);},get tabsHidden(){var ts=this.shadowRoot.querySelector('tab-strip');return ts.hasAttribute('tabs-hidden');},set tabsHidden(tabsHidden){tabsHidden=!!tabsHidden;var ts=this.shadowRoot.querySelector('tab-strip');if(tabsHidden)
-ts.setAttribute('tabs-hidden',true);else
-ts.removeAttribute('tabs-hidden');},get tabs(){return this.tabs_.map(function(tabObject){return tabObject.content;});},processAddedChild_:function(child){var observerAttributeSelected=new MutationObserver(this.childAttributesChanged_.bind(this));var observerAttributeTabLabel=new MutationObserver(this.childAttributesChanged_.bind(this));var tabObject={id:this.tabs_.length,content:child,label:child.getAttribute('tab-label'),observers:{forAttributeSelected:observerAttributeSelected,forAttributeTabLabel:observerAttributeTabLabel}};this.tabs_.push(tabObject);if(child.hasAttribute('selected')){if(this.selectedTab_)
-child.removeAttribute('selected');else
-this.setSelectedTabById_(tabObject.id);}
-var previousSelected=child.selected;var tabView=this;Object.defineProperty(child,'selected',{configurable:true,set:function(value){if(value){tabView.changeSelectedTabById_(tabObject.id);return;}
-var wasSelected=tabView.selectedTab_===tabObject;if(wasSelected)
-tabView.changeSelectedTabById_(undefined);},get:function(){return this.hasAttribute('selected');}});if(previousSelected)
-child.selected=previousSelected;observerAttributeSelected.observe(child,{attributeFilter:['selected']});observerAttributeTabLabel.observe(child,{attributeFilter:['tab-label']});},processRemovedChild_:function(child){for(var i=0;i<this.tabs_.length;i++){this.tabs_[i].id=i;if(this.tabs_[i].content===child){this.tabs_[i].observers.forAttributeSelected.disconnect();this.tabs_[i].observers.forAttributeTabLabel.disconnect();if(this.tabs_[i]===this.selectedTab_){this.clearSelectedTab_();this.fire('selected-tab-change');}
-child.removeAttribute('selected');delete child.selected;this.tabs_.splice(i,1);i--;}}},childAttributesChanged_:function(mutations,observer){var tabObject=undefined;for(var i=0;i<this.tabs_.length;i++){var observers=this.tabs_[i].observers;if(observers.forAttributeSelected===observer||observers.forAttributeTabLabel===observer){tabObject=this.tabs_[i];break;}}
-if(!tabObject)
-return;for(var i=0;i<mutations.length;i++){var node=tabObject.content;if(mutations[i].attributeName==='tab-label')
-tabObject.label=node.getAttribute('tab-label');if(mutations[i].attributeName==='selected'){var nodeIsSelected=node.hasAttribute('selected');if(nodeIsSelected)
-this.changeSelectedTabById_(tabObject.id);else
-this.changeSelectedTabById_(undefined);}}},childrenUpdated_:function(mutations,observer){mutations.forEach(function(mutation){for(var i=0;i<mutation.removedNodes.length;i++)
-this.processRemovedChild_(mutation.removedNodes[i]);for(var i=0;i<mutation.addedNodes.length;i++)
-this.processAddedChild_(mutation.addedNodes[i]);},this);},tabButtonSelectHandler_:function(event,detail,sender){this.changeSelectedTabById_(sender.getAttribute('button-id'));},changeSelectedTabById_:function(id){var newTab=id!==undefined?this.tabs_[id]:undefined;var changed=this.selectedTab_!==newTab;this.saveCurrentTabScrollPosition_();this.clearSelectedTab_();if(id!==undefined){this.setSelectedTabById_(id);this.restoreCurrentTabScrollPosition_();}
-if(changed)
-this.fire('selected-tab-change');},setSelectedTabById_:function(id){this.selectedTab_=this.tabs_[id];this.selectedTab_.observers.forAttributeSelected.disconnect();this.selectedTab_.content.setAttribute('selected','selected');this.selectedTab_.observers.forAttributeSelected.observe(this.selectedTab_.content,{attributeFilter:['selected']});},saveTabStates:function(){this.saveCurrentTabScrollPosition_();},saveCurrentTabScrollPosition_:function(){if(this.selectedTab_){this.selectedTab_.content._savedScrollTop=this.$['content-container'].scrollTop;this.selectedTab_.content._savedScrollLeft=this.$['content-container'].scrollLeft;}},restoreCurrentTabScrollPosition_:function(){if(this.selectedTab_){this.$['content-container'].scrollTop=this.selectedTab_.content._savedScrollTop||0;this.$['content-container'].scrollLeft=this.selectedTab_.content._savedScrollLeft||0;}},clearSelectedTab_:function(){if(this.selectedTab_){this.selectedTab_.observers.forAttributeSelected.disconnect();this.selectedTab_.content.removeAttribute('selected');this.selectedTab_.observers.forAttributeSelected.observe(this.selectedTab_.content,{attributeFilter:['selected']});this.selectedTab_=undefined;}}});'use strict';(function(){var EventRegistry=tr.model.EventRegistry;Polymer('tr-ui-a-analysis-view',{ready:function(){this.tabView_=document.createElement('tr-ui-a-tab-view');this.tabView_.style.flex='1 1 auto';this.appendChild(this.tabView_);this.brushingStateController_=undefined;this.onSelectedTabChange_=this.onSelectedTabChange_.bind(this);this.onSelectionChanged_=this.onSelectionChanged_.bind(this);this.lastSeenSelection_=new tr.model.EventSet();},set tallMode(value){if(value)
-this.classList.add('tall-mode');else
-this.classList.remove('tall-mode');},get tallMode(){return this.classList.contains('tall-mode');},get tabView(){return this.tabView_;},get brushingStateController(){return this.brushingStateController_;},set brushingStateController(brushingStateController){if(this.brushingStateController){this.brushingStateController_.removeEventListener('change',this.onSelectionChanged_);}
-this.brushingStateController_=brushingStateController;if(this.brushingStateController){this.brushingStateController_.addEventListener('change',this.onSelectionChanged_);}
-this.onSelectionChanged_();},get selection(){return this.brushingStateController_.selection;},onSelectionChanged_:function(e){var selection=this.brushingStateController_.selection;var selectionHasSameValue=this.lastSeenSelection_.equals(selection);this.lastSeenSelection_=selection;if(selectionHasSameValue)
-return;var lastSelectedTabTagName;var lastSelectedTabTypeName;if(this.tabView_.selectedTab){lastSelectedTabTagName=this.tabView_.selectedTab.tagName;lastSelectedTabTypeName=this.tabView_.selectedTab._eventTypeName;}
-this.tallMode=false;var previouslySelectedTab=this.tabView_.selectedTab;this.tabView_.removeEventListener('selected-tab-change',this.onSelectedTabChange_);var previousSubViews={};for(var i=0;i<this.tabView_.children.length;i++){var previousSubView=this.tabView_.children[i];previousSubViews[previousSubView._eventTypeName]=previousSubView;}
-this.tabView_.saveTabStates();this.tabView_.textContent='';if(selection.length==0){this.tabView_.tabStripHeadingText='Nothing selected. Tap stuff.';}else if(selection.length==1){this.tabView_.tabStripHeadingText='1 item selected: ';}else{this.tabView_.tabStripHeadingText=selection.length+' items selected: ';}
-var eventsByBaseTypeName=selection.getEventsOrganizedByBaseType(true);var numBaseTypesToAnalyze=tr.b.dictionaryLength(eventsByBaseTypeName);for(var eventTypeName in eventsByBaseTypeName){var subSelection=eventsByBaseTypeName[eventTypeName];var subView=this.createSubViewForSelection_(eventTypeName,subSelection,previousSubViews[eventTypeName]);subView._eventTypeName=eventTypeName;this.tabView_.appendChild(subView);subView.selection=subSelection;}
-var tab;if(lastSelectedTabTagName)
-tab=this.tabView_.querySelector(lastSelectedTabTagName);if(!tab&&lastSelectedTabTypeName){var tab=tr.b.findFirstInArray(this.tabView_.children,function(tab){return tab._eventTypeName===lastSelectedTabTypeName;});}
-if(!tab)
-tab=this.tabView_.firstChild;this.tabView_.selectedTab=tab;this.onSelectedTabChange_();this.tabView_.addEventListener('selected-tab-change',this.onSelectedTabChange_);},createSubViewForSelection_:function(eventTypeName,subSelection,previousSubView){var eventTypeInfo=EventRegistry.getEventTypeInfoByTypeName(eventTypeName);var singleMode=subSelection.length==1;var tagName;if(subSelection.length===1)
-tagName=eventTypeInfo.metadata.singleViewElementName;else
-tagName=eventTypeInfo.metadata.multiViewElementName;if(!tr.ui.b.getPolymerElementNamed(tagName))
-throw new Error('Element not registered: '+tagName);var subView;if(previousSubView&&previousSubView.tagName===tagName.toUpperCase())
-subView=previousSubView;else
-subView=document.createElement(tagName);var camelLabel;if(subSelection.length===1)
-camelLabel=EventRegistry.getUserFriendlySingularName(eventTypeName);else
-camelLabel=EventRegistry.getUserFriendlyPluralName(eventTypeName);subView.tabLabel=camelLabel+' ('+subSelection.length+')';return subView;},onSelectedTabChange_:function(){var brushingStateController=this.brushingStateController_;if(this.tabView_.selectedTab){var selectedTab=this.tabView_.selectedTab;this.tallMode=selectedTab.requiresTallView;if(brushingStateController){var rlth=selectedTab.relatedEventsToHighlight;brushingStateController.changeAnalysisViewRelatedEvents(rlth);}}else{this.tallMode=false;if(brushingStateController)
-brushingStateController.changeAnalysisViewRelatedEvents(undefined);}}});})();'use strict';Polymer('tr-ui-b-dropdown',{ready:function(){this.$.outer.tabIndex=0;},get iconElement(){return this.$.icon;},onOuterKeyDown_:function(e){if(e.keyCode===' '.charCodeAt(0)){this.toggle_();e.preventDefault();e.stopPropagation();}},onOuterClick_:function(e){var or=this.$.outer.getBoundingClientRect();var inside=true;inside&=e.clientX>=or.left;inside&=e.clientX<or.right;inside&=e.clientY>=or.top;inside&=e.clientY<or.bottom;if(!inside)
-return;e.preventDefault();this.toggle_();},toggle_:function(){if(!this.isOpen)
-this.show();else
-this.close();},show:function(){if(this.isOpen)
-return;this.$.outer.classList.add('open');var ddr=this.$.outer.getBoundingClientRect();var rW=Math.max(ddr.width,150);this.$.dialog.style.minWidth=rW+'px';this.$.dialog.showModal();var ddw=this.$.outer.getBoundingClientRect().width;var w=this.$.dialog.getBoundingClientRect().width;this.$.dialog.style.top=ddr.bottom-1+'px';this.$.dialog.style.left=ddr.left+'px';},onDialogClick_:function(e){if(!this.isOpen)
-return;if(e.srcElement!==this.$.dialog)
-return;e.preventDefault();this.close();},onDialogCancel_:function(e){e.preventDefault();this.close();},close:function(){if(!this.isOpen)
-return;this.$.dialog.close();this.$.outer.classList.remove('open');this.$.outer.focus();},get isOpen(){return this.$.dialog.hasAttribute('open');}});'use strict';tr.exportTo('tr.ui.b',function(){var FaviconsByHue={blue:'data:image/vndmicrosofticon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjj8xAGArIgqOPzE8nUY3dqJJOJeiSTiXnUY3do4/MTxhKyIKjkAxAAAAAAAAAAAAAAAAAAAAAABQJBwAAAAAAZJBMzSoSzqlsU8+6bRQP/21UT//tVE//7RQP/2wTz3ppko6pY9AMjQAAAABTyMbAAAAAAB7e3sAAP//AKFSRE+wTz3dtVE//7VRP/+1UT//tVE//7VRP/+zUD7/sE89/7BOPf+qTDvdl0M0TwAAAABWJx4A+fn5ANjd3TnIiX7ftVA9/7VRP/+1UT//tVE//7VRP/+xTz3/rE08/6xMO/+sTDv/rE08/6dKOt+SQTM5q0w7ALO0tA3v8fGu05uR/7NMOf+0Tzz/tE88/7RPPv+uTT3/p0o7/6ZJOv+mSTr/pkk6/6ZJOv+mSjr/n0Y4rnIwKg3h4eFK9/j48N2zrP/FeGr/xnps/8Z6bP/AaUv/tlw1/7RbNf+1WzX/tFs1/7RbNf+0WzX/tFs1/7NbNPCqWy1K7e3tjPn5+f/49vX/9vLy//by8v/28vH/8bZv/+6RH//ukyP/7pMj/+6SI//ukiP/7pMj/+2SIv/qjyL/34kfjPHx8bL5+fn/+fn5//n5+f/5+fr/+fn5//W7cP/zlB3/85Yh//OWIf/zliH/85Yh//GVIf/rkR//6ZAf/+KLHrLz8/O2+fn5//n5+f/5+fn/+fn5//n5+f/1unD/85Qd//OWIf/zliH/85Yh//CUIP/mjh//44we/+OMHv/diR628vLymfn5+f/5+fn/+fn5//n5+f/5+fn/9bx0//OXI//zmCb/85gm/++VIv/hjB//3Yoe/92KHv/dih7/2IYdmfHx8Vz4+Pj3+fn5//n5+f/5+fn/+fn5//jo0//33bv/9929//bbtf/euDX/06oJ/9OrC//Tqwv/06oM98yfD1zr6+sY9/f3xvn5+f/5+fn/+fn5//n5+f/5+vv/+fv8//n7/f/3+PH/3Ms6/9O8AP/UvQD/1L0A/9K8AMbItAAY////APT09Fb4+Pjy+fn5//n5+f/5+fn/+fn5//n5+f/5+fr/9/bu/9zKOf/TuwD/1LwA/9S8APLQuABW3cQAAOzs7ADm5uYF9vb2ePn5+fT5+fn/+fn5//n5+f/5+fn/+fn6//f27v/cyTn/07sA/9S8APTRugB4w60ABcmyAAAAAAAA8PDwAOzs7Ab29vZd+Pj40vn5+fz5+fn/+fn5//n5+f/49/H/5Ndu/NjEIdLSugBdybIABsy1AAAAAAAAAAAAAAAAAADn5+cAqKioAPT09CH39/dy+Pj4tvj4+NX4+PjV+Pj4tvX063Lt6MMhOQAAAM+/RAAAAAAAAAAAAPAPAADAAwAAwAMAAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAACAAQAAwAMAAPAPAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCwUEDDgZExxWJx4tYiwiN2IsIjdWJx4tOBkTHAsFBAwAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAbDAkKZS0jMYs+MWydRjeipko6x6tMO9utTTzjrU0846tMO9umSjrHnUY3oos+MWxlLSMxGwwJCv///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgZFAAPBwUHcjMoPJtFNpqsTTzhs1A+/LVRP/+2UT//tVE//7VRP/+1UT//tVE//7ZRP/+1UT//s1A+/KxNPOGbRTaacTInPA8HBQc4GRMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/yp4AUCQcGZVDNICtTjzktVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+0UT//s1A+/7JQPv+rTDvkkkEzgE8jGxn/xZoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAA////AGswJSqiSTivs1A++7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tFA+/7FPPf+xTz3/sU89/7FPPf+vTj37nkc3r2guJCr///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAP/DogB/VEwsqE09v7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7NQPv+vTj3/r049/69OPf+vTj3/r049/69OPf+uTjz/oUg4v20xJiz/nnsAAgEBAAAAAAAAAAAAAAAAAAAAAAD19fUAkp2fHdK2sbW5W0r/tVA+/7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+yUD7/rU08/6xNPP+tTTz/rU08/61NPP+tTTz/rU08/61NPP+sTTz/nkY3tWAqIR2pSzsAAAAAAAAAAAAAAAAAeXl5ADY2Ngnd39+O6tbT/blbSv+1UD7/tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//slA+/6xNPP+rTDv/q0w7/6tMO/+rTDv/q0w7/6tMO/+rTDv/q0w7/6tMO/+qTDv9lkM0jiUQDQlSJR0AAAAAAAAAAAD///8AxMTES/X29u3s2NX/uVtK/7VQPv+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7FPPv+qTDv/qEs6/6hLOv+oSzr/qEs6/6hLOv+oSzr/qEs6/6hLOv+oSzr/qEs6/6lLOv+lSTnthDsuS/+TcgAAAAAAm5ubAHBwcA/o6Oix+vv8/+zY1P+5W0r/tVA+/7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+xTz3/qEs6/6ZKOv+mSjr/pko6/6ZKOv+mSjr/pko6/6ZKOv+mSjr/pko6/6ZKOv+mSjr/pko6/6ZKOv+bRTaxSiEaD2cuJAD///8AycnJRfX19fD6+/z/69fU/7hYR/+0Tjv/tE48/7ROPP+0Tjz/tE48/7ROPP+0Tz3/r04+/6VJOv+jSDn/o0g5/6NIOf+jSDn/o0g5/6NIOf+jSDn/o0g5/6NIOf+jSDr/o0g5/6NIOf+jSDn/o0g6/6BHOfCCOS9F0FxKAAAAAALk5OSN+fn5//n6+v/y5+X/05uS/9CTiP/QlIn/0JSJ/9CUif/QlIn/0JSK/8yGb//AaDb/vWc0/71nNf+9ZzT/vWc0/71nNP+9ZjT/vWY0/71mNP+9ZjT/vGY0/7xmNP+8ZjT/vGY0/7xmNP+8ZjT/u2U0/7FiLY0AAAACk5OTFu/v78X5+fn/+fn5//n5+f/5+vr/+fn5//n5+f/5+fn/+fn5//n5+f/5+/3/99iy//KWI//ylSH/8ZUh//GVIf/xlSH/8ZUh//GVIf/xlSH/8ZUh//GVIf/xlSH/8ZUh//GVIf/xlSH/8ZUh//CUIf/vkyD/5Y0fxY1XExbDw8Mz9PT05fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n7/f/32LL/85cj//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/wlCD/7pIg/+6SIP/pjx/lunIZM9XV1VD39/f0+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fv9//fYsv/zlyP/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/75Mg/+uRH//qkB//6pAf/+iPH/TIfBtQ3d3dYfj4+Pn5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+/3/99iy//OXI//zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh/+6TIP/ojx//548f/+ePH//njx//5o4f+c1/HGHh4eFl+Pj4+vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n7/f/32LL/85cj//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/tkiD/5Y0f/+SNH//ljR//5Y0f/+WNH//kjB/6zn8cZeDg4Fr4+Pj3+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fv9//fYsv/zlyP/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/65Eg/+KMHv/iix7/4ose/+KLHv/iix7/4ose/+CLHvfLfRta3NzcQvf39+/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+/3/99iy//OXI//zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh/+qRIP/gih7/34oe/9+KHv/fih7/34oe/9+KHv/fih7/3Yge78V6GkLS0tIj9fX12fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n7/f/32LH/85Yg//OVHv/zlR7/85Ue//OVHv/zlR7/85Ue//OVIf/pjyH/3ogf/92HH//dhx//3Ycf/92HH//dhx//3Ycf/92HH//ahh7ZunMZI56engjy8vKu+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fr7//jr2f/2ypL/9smP//bJkP/2yZD/9smQ//bJkP/2yZD/5rNI/9OeFP/SnhX/0p4V/9KeFf/SnhX/0Z0V/9GdFf/RnRX/0Z0V/8yWFq6KVBcI////AO3t7Wr5+fn++fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn6//n6/P/5+vz/+fr8//n6/P/5+vz/+fr8//n6/P/h013/0rsA/9O8AP/TvAD/07wA/9O8AP/TvAD/07wA/9O8AP/SvAD+yLMAav/mAADr6+sA4eHhJPb29tv5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/+LSW//TuwD/1LwA/9S8AP/UvAD/1LwA/9S8AP/UvAD/1LwA/9K6ANu/qgAkyLEAALu7uwAAAAAA8vLygfn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/4tJb/9O7AP/UvAD/1LwA/9S8AP/UvAD/1LwA/9S8AP/UvAD/zrYAgQAAAACfjQAAAAAAAOzs7ADk5OQe9vb2zPn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/i0lv/07sA/9S8AP/UvAD/1LwA/9S8AP/UvAD/1LwA/9K6AMzCrAAeybIAAAAAAAAAAAAAsLCwAP///wDv7+9O+Pj47Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/+LSW//TuwD/1LwA/9S8AP/UvAD/1LwA/9S8AP/TuwDsy7QATu7UAACXhQAAAAAAAAAAAAAAAAAA1tbWALS0tAPy8vJv+Pj49Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/4tJb/9O7AP/UvAD/1LwA/9S8AP/UvAD/07wA9M63AG6ZiQADtqIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4uLiANfX1wbz8/Nz+Pj48Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/i0lv/07sA/9S8AP/UvAD/1LwA/9O8APDPuABzuKMABsGrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4+PjANjY2ATy8vJZ+Pj42vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/+HSW//TugD/1LsA/9S8AP/TuwDazrcAWbejAATBqwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1NTUAB8fHwDw8PAr9vb2nPj4+O35+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/7uas/+bZdv/j1mvt2cYznMu0ACsUFAAAtaEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOvr6wDj4+MG8vLyOvb29pD4+PjS+fn58vn5+f35+fn/+fn5//n5+f/5+fn/+fn5/fn5+fL4+frS9/j8kPT1/Trs8v8G8PP/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADh4eEA1tbWAu/v7xv09PRJ9vb2dvb29pf39/eo9/f3qPb29pf29vZ29PT0Se/v7xvW1tYC4eHhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gB///gAH//gAAf/wAAD/4AAAf8AAAD+AAAAfAAAADwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABwAAAA8AAAAPgAAAH4AAAB/AAAA/4AAAf/gAAf/8AAP//wAP/',green:'data:image/vndmicrosofticon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbWJLAEpCMwptYks8eWxTdn1wVpd9cFaXeWxTdm1iSzxKQzMKbWJLAAAAAAAAAAAAAAAAAAAAAAA+OCsAAAAAAXBlTTSBdFmliHpe6Yp8X/2LfWD/i31g/4p8X/2HeV3pf3NYpW5jTDQAAAABPTcqAAAAAAB7e3sAlv//AIB1Xk+HeV3di31g/4t9YP+LfWD/i31g/4t9YP+Je1//h3pd/4d5Xf+DdVrddGhQTwAAAABDPC4A+fn5ANrb3DmupZPfinxf/4t9YP+LfWD/i31g/4t9YP+Iel7/hHdb/4R2W/+Edlv/hHdb/4BzWN9wZU05g3ZaALS0tA3w8PGuu7Sj/4h5W/+Je17/iXte/4t8X/+HeFz/gnNY/4FyWP+Bclj/gXJY/4FyWP+Bclj/fG1Url9NPA3h4eFK9/j48MvFuf+kmoP/ppuF/6abhf+JkHL/c4Rj/3OEY/9zhGP/coNj/3KDY/9yg2P/coNj/3CDYvBgf19K7e3tjPn5+f/39vb/9fTz//X08//09PP/itKw/0m+h/9Mv4n/TL+J/0y/if9Mv4n/TL+J/0y+iP9Lu4b/RrJ/jPHx8bL5+fn/+fn5//n5+f/5+fn/+fn5/4rXtP9Hwon/SsOL/0rDi/9Kw4v/SsOL/0nCiv9HvYb/RruF/0S1gbLz8/O2+fn5//n5+f/5+fn/+fn5//n5+f+K17P/R8KJ/0rDi/9Kw4v/SsOL/0nBif9GuYT/RbaC/0W2gv9Dsn+28vLymfn5+f/5+fn/+fn5//n5+f/5+fn/jdi1/0vDjP9OxI7/TsSO/0rAiv9FtoP/RLKA/0SygP9EsoD/Qq59mfHx8Vz4+Pj3+fn5//n5+f/5+fn/+fn5/9rw5v/H6tn/yOra/8Lp2f9e1b7/O8yz/z3MtP89zLT/Pcuy9zzApVzr6+sY9/f3xvn5+f/5+fn/+fn5//n5+f/7+vr//Pr7//z6+//z+fn/ZuPY/zbczv853c7/Od3O/zjbzcY10sYY////APT09Fb4+Pjy+fn5//n5+f/5+fn/+fn5//n5+f/6+fn/8Pj3/2Xj1/823Mz/OdzN/znczfI42MlWO+XWAOzs7ADm5uYF9vb2ePn5+fT5+fn/+fn5//n5+f/5+fn/+vn5//D49/9j4tf/NdvM/znczfQ42ct4Ncu9BTbRwgAAAAAA8PDwAOzs7Ab29vZd+Pj40vn5+fz5+fn/+fn5//n5+f/z+Pj/jung/FLf0tI42ctdNdHCBjfUxgAAAAAAAAAAAAAAAADn5+cAqKioAPT09CH39/dy+Pj4tvj4+NX4+PjV+Pj4tu329XLO7+whAFQmAGrUygAAAAAAAAAAAPAPAADAAwAAwAMAAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAACAAQAAwAMAAPAPAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCQgGDCsmHRxCOy4tS0M0N0tDNDdCOy4tKyYdHAkIBgwAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAVEg4KTUU1MWtgSmx5bVOigHNYx4N2W9uFd1zjhXdc44N2W9uAc1jHeW1TomtgSmxNRjUxFRMOCv///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACsnHgALCggHWE88PHdrUpqEd1vhiXxf/It9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/iXxf/IR3W+F3a1KaV048PAsKCAcrJx4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///AAPjcqGXJnT4CFeFzki31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+KfWD/iXxf/4l7Xv+DdlrkcGVNgDw2Khn//+sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AFJKOSp9cFavinxf+4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/inxf/4h6Xv+Iel3/iHpd/4h6Xv+GeV37eW1Ur1BINyr///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAP//3gBsZ1osgnVbv4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4l8X/+HeV3/hnlc/4Z5XP+GeVz/hnlc/4Z5XP+GeFz/fG9Vv1RLOiz/9LoAAgIBAAAAAAAAAAAAAAAAAAAAAAD19fUAl5ibHcbCurWShGn/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+Je1//hXhc/4R3W/+Fd1v/hXdb/4V3W/+Fd1v/hXdb/4V3W/+Ed1v/eW1TtUlCMh2CdVkAAAAAAAAAAAAAAAAAeXl5ADY2Ngne3t+O4t/Z/ZKFaf+LfV//i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/iXte/4R3W/+Ddlr/g3Za/4N2Wv+Ddlr/g3Za/4N2Wv+Ddlr/g3Za/4N2Wv+CdVr9c2dPjhwZEwk/OSsAAAAAAAAAAAD///8AxMTES/X19u3k4dv/koRp/4t9X/+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4h6Xv+CdVr/gXRZ/4F0Wf+BdFn/gXRZ/4F0Wf+BdFn/gXRZ/4F0Wf+BdFn/gXRZ/4F0Wf9+clftZVtGS/3jrgAAAAAAm5ubAHBwcA/o6Oix+/v7/+Pg2/+ShGn/i31f/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+Iel7/gXRZ/4BzWP+Ac1j/gHNY/4BzWP+Ac1j/gHNY/4BzWP+Ac1j/gHNY/4BzWP+Ac1j/gHNY/4BzWP93a1KxOTMnD1BHNwD///8AycnJRfX19fD7+/v/4+Da/5CCZ/+Jel3/iXtd/4l7Xf+Je13/iXtd/4l7Xf+Ke17/iHhd/4BxV/9/cFb/f3BW/39wVv9/cFb/f3BW/39wVv9/cFb/f3BW/39wVv9/cFb/f3BW/39wVv9/cFb/f3BW/31uVPBnWURFo45tAAAAAALk5OSN+fn5//r6+v/t7Oj/vLSk/7aunP+3rp3/t66d/7eunf+3rp3/uK+e/6Gmjv9vkG3/bI5r/2yOa/9sjmv/bI5r/2yOa/9sjmv/bI5r/2yOa/9sjmr/bI1q/2yNav9sjWr/bI1q/2uNav9rjWr/a41q/16GZI0AAAACk5OTFu/v78X5+fn/+fn5//n5+f/5+fr/+fn5//n5+f/5+fn/+fn5//n5+f/8+vv/wOfV/0vCi/9Kwor/SsKK/0rCiv9Kwor/SsKK/0rCiv9Kwor/SsKK/0rCiv9Kwor/SsKK/0rCiv9Kwor/SsKK/0nAif9Jv4j/RreCxStxUBbDw8Mz9PT05fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z6+/+/59X/TMSM/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9JwYn/SL6I/0i+iP9GuoXlOJVqM9XV1VD39/f0+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//Pr7/7/n1f9Mw4z/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/ScCJ/0e8hv9HvIb/R7yG/0a6hfQ9oXJQ3d3dYfj4+Pn5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/8+vv/v+fV/0zDjP9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0i/iP9GuoX/RrqE/0a6hP9GuoT/RrmD+T6ldWHh4eFl+Pj4+vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z6+/+/59X/TMOM/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Ivof/RbiD/0W3gv9FuIP/RbiD/0W4g/9Ft4L6PqZ2ZeDg4Fr4+Pj3+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//Pr7/7/n1f9Mw4z/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SL2H/0W2gv9FtYH/RbWB/0W1gf9FtYH/RbWB/0S0gPc+o3Ra3NzcQvf39+/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/8+vv/v+fV/0zDjP9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0e8hv9EtID/RLOA/0SzgP9Es4D/RLOA/0SzgP9Es4D/Q7F/7zyecULS0tIj9fX12fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z6+/+/59X/SsOL/0jCiv9Iwor/SMKK/0jCiv9Iwor/SMKK/0rCiv9HuoT/RLF+/0Owff9EsH3/RLB9/0Swff9EsH3/RLB9/0Swff9CrnzZOJZrI56engjy8vKu+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+vn6/9/x6f+l38X/o9/D/6Tfw/+k38P/pN/D/6Tfw/+k38T/a9Kz/0DBof9BwKH/QcCh/0HAof9BwKD/QcCg/0G/oP9Bv6D/Qb+g/0C4mK4tbU4I////AO3t7Wr5+fn++fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+vn6//v6+//7+vv/+/r7//v6+//7+vv//Pr7//v6+/+B597/NdvN/znczf853M3/OdzN/znczf853M3/OdzN/znczf85283+NtHDakb/+gDr6+sA4eHhJPb29tv5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/3/n3f823Mz/OdzN/znczf853M3/OdzN/znczf853M3/OdzN/zjay9s0x7kkNs/BALu7uwAAAAAA8vLygfn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/f+fd/zbbzP853M3/OdzN/znczf853M3/OdzN/znczf853M3/N9XHgQAAAAAspZoAAAAAAOzs7ADk5OQe9vb2zPn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f9/593/NtvM/znczf853M3/OdzN/znczf853M3/OdzN/zjay8w0yrweNtDCAAAAAAAAAAAAsLCwAP///wDv7+9O+Pj47Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/3/n3f8228z/OdzN/znczf853M3/OdzN/znczf8528zsN9PETkD45gAonJEAAAAAAAAAAAAAAAAA1tbWALS0tAPy8vJv+Pj49Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/f+fd/zbbzP853M3/OdzN/znczf853M3/OdvM9DjWx24qoJUDMb2wAAAAAAAAAAAAAAAAAAAAAAAAAAAA4uLiANfX1wbz8/Nz+Pj48Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f9/593/NtvM/znczf853M3/OdzN/znbzPA418hzMr6xBjTIugAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4+PjANjY2ATy8vJZ+Pj42vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/37m3f8z28z/N9zN/znczf8528zaONbIWTK/sgQ0yLsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1NTUAB8fHwDw8PAr9vb2nPj4+O35+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/vfDr/5Tq4v+L6ODtYODUnDTTxSsAGBsAMrywAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOvr6wDj4+MG8vLyOvb29pD4+PjS+fn58vn5+f35+fn/+fn5//n5+f/5+fn/+fn5/fn5+fL6+PjS+vf3kPv09Tr/6u4G/+/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADh4eEA1tbWAu/v7xv09PRJ9vb2dvb29pf39/eo9/f3qPb29pf29vZ29PT0Se/v7xvW1tYC4eHhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gB///gAH//gAAf/wAAD/4AAAf8AAAD+AAAAfAAAADwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABwAAAA8AAAAPgAAAH4AAAB/AAAA/4AAAf/gAAf/8AAP//wAP/',red:'data:image/vndmicrosofticon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQxmbAC0RagpDGZs8ShysdkwdspdMHbKXShysdkMZmzwuEWoKQxmcAAAAAAAAAAAAAAAAAAAAAAAmDlgAAAAAAUQanzRPHrilUx/B6VQgxf1VIMb/VSDG/1Qgxf1TH8DpTh22pUMZnDQAAAABJQ5XAAAAAAB7ensA//8AAFUrr09SH8DdVSDG/1Ugxv9VIMb/VSDG/1Ugxv9UH8P/Ux/B/1IfwP9QHrrdRxqlTwAAAAAoD14A+fn5ANzf1zmMatPfVB7G/1Ugxv9VIMb/VSDG/1Ugxv9TH8L/UR68/1AevP9QHrz/UR68/04dt99EGaA5UB67ALS0sw3x8u+unYDd/1AZxP9THcX/Ux3F/1Qexf9THr//Tx23/08ctv9PHbb/Tx22/08dtv9PHbb/SxuurjkSfg3h4eFK+Pj38LWf5P97UtL/fVXS/31V0/9fOcz/SSfC/0knwP9JJ8D/SSfA/0knwP9JJ8D/SSfA/0gnv/A/KLNK7e3tjPn5+f/29fj/8vD3//Px9//y8Pf/fILz/zQ/8P83QvD/N0Lw/zdC8P83QvD/N0Lw/zdB7/82QOz/Mz3gjPHx8bL5+fn/+fn5//n6+f/5+vn/+fn5/36G9v8yQPT/NkP0/zZD9P82Q/T/NkP0/zVC8v80QOz/M0Dq/zI+47Lz8/O2+fn5//n5+f/5+fn/+fn5//n5+f99hvb/MkD0/zZD9P82Q/T/NkP0/zVC8f8zP+f/Mj7k/zI+5P8xPd628vLymfn5+f/5+fn/+fn5//n5+f/5+fn/gYn2/zdE9P87R/T/O0f0/zZF8P8yQOP/MT/e/zE/3v8xP97/Lz3ZmfHx8Vz4+Pj3+fn5//n5+f/5+fn/+fn5/9fZ+P/Bxfj/wsb4/7vD+P87j/X/Dnzx/xF98f8RffH/EXzw9xZv5Vzr6+sY9/f3xvn5+f/5+fn/+fn5//n5+f/7+/n//Pz5//38+f/x+Pn/OrD+/wCY//8Amf//AJn//wCZ/cYAlPMY////APT09Fb4+Pjy+fn5//n5+f/5+fn/+fn5//n5+f/6+fn/7vX5/zmu/v8Al///AJj//wCY/vIAlfpWAJ//AOzs7ADm5uYF9vb2ePn5+fT5+fn/+fn5//n5+f/5+fn/+vn5/+71+f85rf7/AJb//wCY//QAlvx4AIzrBQCQ8gAAAAAA8PDwAOzs7Ab29vZd+Pj40vn5+fz5+fn/+fn5//n5+f/x9vn/bsP8/CGk/tIAlvxdAJDyBgCT9QAAAAAAAAAAAAAAAADn5+cAqKioAPT09CH39/dy+Pj4tvj4+NX4+PjV+Pj4tuvy93LD4fUhAAC7AESo6wAAAAAAAAAAAPAPAADAAwAAwAMAAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAACAAQAAwAMAAPAPAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBgIMDBoKPRwoD14tLhFrNy4RazcoD14tGgo9HAYCDAwAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+3/wANBR0KLxJuMUEYmGxKHKyiTh22x1Aeu9tRHr3jUR6941Aeu9tOHbbHShysokEYmGwvEm4xDQUeCv+6/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABoKPgAHAxAHNhR9PEkbqppRHr3hVCDE/FUgxv9VIMf/VSDH/1Ugxv9VIMb/VSDH/1Ugx/9VIMb/VCDE/FEevOFIG6maNRR8PAcDEAcaCj0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADVUP8AJg5YGUYao4BRH77kVSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMX/VB/E/1Qfw/9QHrvkRRmggCUOVhnQTv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEA////ADITdSpMHbKvVCDE+1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VCDE/1Mfwv9TH8H/Ux/B/1Mfwv9SH7/7ShytrzEScSr///8AAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAMto/wBVPoYsUSC3v1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1QfxP9SHsD/Uh6//1Iev/9SHr//Uh6//1Iev/9SHr//SxywvzMTdyymPf8AAQACAAAAAAAAAAAAAAAAAAAAAAD19fUAnaKQHbep1rVfLcn/VB/G/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9UH8P/UR6+/1Eevf9RHr3/UR69/1Eevf9RHr3/UR69/1Eevf9RHr3/ShuttS0RaB1PHrkAAAAAAAAAAAAAAAAAeXl5ADY2Ngnf4NyO18zu/V8tyf9UH8b/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VB/D/1EevP9QHrr/UB67/1Aeu/9QHrv/UB67/1Aeu/9QHrv/UB67/1Aeu/9QHrr9RhqkjhEGKAknDloAAAAAAAAAAAD///8AxMTES/b39O3Zzu//Xy3J/1Qfxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Mfwv9QHbr/Tx24/08duP9PHbj/Tx24/08duP9PHbj/Tx24/08duP9PHbj/Tx24/08duf9NHLTtPheRS5s5/wAAAAAAm5ubAHBwcA/o6Oix+/z6/9jO7/9fLcn/VB/G/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9TH8H/Tx24/04dtv9OHbb/Th22/04dtv9OHbb/Th22/04dtv9OHbb/Th22/04dtv9OHbb/Th22/04dtv9JG6mxIw1RDzAScQD///8AycnJRfX19fD7/Pr/2M3v/1wqyP9SHMX/UhzF/1Icxf9SHMX/UhzF/1Icxf9THcX/Ux7A/04ctf9NHLL/Thyz/04cs/9NHLP/TRyz/00cs/9OHLP/Thyz/04cs/9OHLP/Thyz/04cs/9NHLP/Thyz/0wcsPA/Fo9FYyTkAAAAAALk5OSN+fn5//r6+f/n4vT/noDd/5Z22v+Wdtr/lnba/5Z22v+Wdtr/mHfb/35g1/9KMMr/SC/H/0gvx/9IL8f/SC/H/0gvx/9IL8b/SC/G/0gvxv9HL8b/Ry/G/0cvxv9HL8b/Ry/G/0cvxv9HL8X/Ry7F/z8tuI0AAAACk5OTFu/v78X5+fn/+fn5//n5+f/6+vn/+fr5//n6+f/5+vn/+fr5//n6+f/9/fn/ub73/zhF8v82Q/L/NkPy/zZD8v82Q/L/NkPy/zZD8v82Q/L/NkPy/zZD8v82Q/L/NkPy/zZD8v82Q/L/NkPy/zVC8f81QvD/Mz/mxR8njhbDw8Mz9PT05fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z8+f+5vff/OEX0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P81QvH/NEHv/zRB7/8zQOrlKTO6M9XV1VD39/f0+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//Pz5/7m99/84RfT/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NULw/zRA7P80QOv/NEDr/zNA6fQsN8lQ3d3dYfj4+Pn5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/8/Pn/ub33/zhF9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zVB7/8zQOn/Mz/o/zM/6P8zQOj/Mz/n+S04zmHh4eFl+Pj4+vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z8+f+5vff/OEX0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P80Qe7/Mz/m/zM/5f8zP+b/Mz/m/zM/5v8yP+X6LjnPZeDg4Fr4+Pj3+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//Pz5/7m99/84RfT/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NEHs/zI+4/8yPuP/Mj7j/zI+4/8yPuP/Mj7j/zI+4fctOMxa3NzcQvf39+/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/8/Pn/ub33/zhF9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zRA6/8xPeH/MT3g/zE94P8xPeD/MT3g/zE94P8xPeD/MT3e7ys2xkLS0tIj9fX12fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z8+f+4vff/NkP0/zNB9P80QfT/NEH0/zRB9P80QfT/NEH0/zZC8/81P+n/Mjze/zI73f8yO93/Mjvd/zI73f8yO93/Mjvd/zI73f8xO9rZKTO7I56engjy8vKu+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+/r5/9ze+P+covf/mqD3/5qg9/+aoPf/mqD3/5qg9/+aoPf/UoLz/x1p5/8eaeb/Hmnm/x5p5v8eaeX/Hmnl/x5p5f8eaOX/Hmjl/yBh3a4jJokI////AO3t7Wr5+fn++fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+vr5//z8+f/8/Pn//Pz5//z8+f/8/Pn//Pz5//z8+f9dvfz/AJf+/wCZ/v8Amf7/AJn+/wCZ/v8Amf7/AJn+/wCZ/v8AmP7+AJLxagC4/wDr6+sA4eHhJPb29tv5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/1u8/f8Alv//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCW/NsAieckAI/xALu7uwAAAAAA8vLygfn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/W7z9/wCW//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJP3gQAAAAAAcr8AAAAAAOzs7ADk5OQe9vb2zPn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f9bvP3/AJb//wCY//8AmP//AJj//wCY//8AmP//AJj//wCW/MwAi+oeAJDxAAAAAAAAAAAAsLCwAP///wDv7+9O+Pj47Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/1u8/f8Alv//AJj//wCY//8AmP//AJj//wCY//8Al/7sAJL0TgCr/wAAa7QAAAAAAAAAAAAAAAAA1tbWALS0tAPy8vJv+Pj49Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/W7z9/wCW//8AmP//AJj//wCY//8AmP//AJj+9ACU+G4AbrgDAIPaAAAAAAAAAAAAAAAAAAAAAAAAAAAA4uLiANfX1wbz8/Nz+Pj48Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f9bvP3/AJb//wCY//8AmP//AJj//wCY/vAAlflzAITcBgCK5wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4+PjANjY2ATy8vJZ+Pj42vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/1u7/f8Alf//AJf//wCY//8Al/7aAJT4WQCE3AQAiucAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1NTUAB8fHwDw8PAr9vb2nPj4+O35+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/rNv7/3bG/P9rwfztM6r7nACR9SsAER0AAIPZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOvr6wDj4+MG8vLyOvb29pD4+PjS+fn58vn5+f35+fn/+fn5//n5+f/5+fn/+fn5/fn5+fL6+fjS/Pj2kP338jr/+eIG//fqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADh4eEA1tbWAu/v7xv09PRJ9vb2dvb29pf39/eo9/f3qPb29pf29vZ29PT0Se/v7xvW1tYC4eHhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gB///gAH//gAAf/wAAD/4AAAf8AAAD+AAAAfAAAADwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABwAAAA8AAAAPgAAAH4AAAB/AAAA/4AAAf/gAAf/8AAP//wAP/',yellow:'data:image/vndmicrosofticon;base64,AAABAAIAICAAAAEAIACoEAAAJgAAABAQAAABACAAaAQAAM4QAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAZKhQAOWAiAEV0KgBFdCoAOWAiABkqFAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8ZAAAChAHAEp8JwBvu10AgNeSAInluACN7c4Aj/DXAI/w1wCN7c4AieW4AIDXkgBvu10ASnwnAAoQBwA8ZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbLgAAAAAFAFmWMwB/1YwAj/DXAJX7+QCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJX7+QCP79cAftWMAFmVMwAAAAUAGy4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7v8AAD1mFQB6zXYAkPLdAJf+/gCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP7/AJf+/wCV/P4AjvDdAHjKdgA8ZBUA6f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AABWkCYAh+KoAJb8+QCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJf+/wCV+v8AlPr/AJT6/wCV+v8Akvf5AIPdqABTjCYA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICABb//wAka5wqAozquwCY/v8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCX/f8Ak/j/AJP3/wCT9/8Ak/f/AJP3/wCT9/8Akvb/AIbiuwBZlyoA//8AAAECAAAAAAAAAAAAAAAAAAAAAADz8/MAqJaJHZDD5rQLnP7/AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8Alvz/AJL2/wCR9P8AkfT/AJH0/wCR9P8AkfT/AJH0/wCR9P8AkfT/AITftABQhh0AjO0AAAAAAAAAAAAAAAAAfX19ADw8PAni3tuPuuD5/Quc//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJb8/wCQ8/8Aj/H/AI/x/wCP8f8Aj/H/AI/x/wCP8f8Aj/H/AI/x/wCP8f8AjvD9AH7UjwAiOQkASHkAAAAAAAgICAD///8AxcXFT/j19O+94vv/Cpz//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCV+/8Aj/H/AI3u/wCN7v8Aje7/AI3u/wCN7v8Aje7/AI3u/wCN7v8Aje7/AI3u/wCO7v8AiunvAHC8TwD//wAABQgAqKioAHp6ehHp6em3/fv5/7zh+v8KnP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8Alfr/AI7u/wCM6/8AjOv/AIzr/wCM6/8AjOv/AIzr/wCM6/8AjOv/AIzr/wCM6/8AjOv/AIzr/wCM6/8Ag9y3AERyEQBenQD///8AzMzMTfb29vP9+/n/vOH6/wqb//8Alv//AJb//wCW//8Alv//AJb//wCW//8Al///AJT5/wCL6/8Aiej/AIno/wCJ6P8Aiej/AIno/wCJ6P8Aiej/AIno/wCJ6P8Aiej/AIno/wCJ6P8Aiej/AIno/wCH5fMAb75NAMP/AAAAAAXl5eWX+fn5//v6+f/T6vr/Wbv9/0+3/f9Qt/3/ULf9/1C3/f9Qt/3/Ubj9/zew+/8InO//B5nr/weZ6/8Hmev/B5nq/weZ6v8Hmer/B5nq/weZ6v8Hmer/B5jq/weY6v8HmOn/B5jp/weY6f8HmOn/Bpjp/weP15cBAAAFpKSkHfDw8M/5+fn/+fn5//n5+f/1+Pn/9Pf5//T3+f/09/n/9Pf5//T3+f/4+Pn/o+T6/wq//f8Hv/3/CL/9/wi//f8Iv/3/CL/9/wi//f8Iv/3/CL/8/wi+/P8Ivvz/CL78/wi+/P8Ivvz/CL78/we9+/8HvPr/BrbxzwR9pR3Ly8tA9fX17Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//36+f+l5vv/CcL//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hv/3/Br36/wa9+v8GuvbsBZnLQNra2mD39/f4+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//fr5/6Xm+/8Jwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B778/wa79/8Guvf/Brr3/wa59fgFo9hg4uLidPj4+P35+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/9+vn/peb7/wnB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//we++/8GufX/Brj0/wa49P8GuPT/Brfz/QWm3XTk5OR6+Pj4/fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//36+f+l5vv/CcH//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hvfr/Brfy/wa28f8GtvH/Brbx/wa28f8GtfD9BafdeuXl5W/4+Pj8+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//fr5/6Xm+/8Jwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B7z5/wa17/8GtO7/BrTu/wa07v8GtO7/BrTu/waz7fwFpdtv4eHhVvj4+Pb5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/9+vn/peb7/wnB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//we7+P8Gsu3/BrHr/wax6/8Gsev/BrHr/wax6/8Gsev/BrDq9gWh1Vba2toz9vb25vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//36+f+k5fv/BsH//wPA//8DwP//A8D//wPA//8DwP//A8D//wXA//8Guvb/BrDq/wau6P8Gruj/Bq7o/wau6P8Gruj/Bq7o/wau6P8GreXmBZnLM7+/vxH09PTC+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+/r5/83v+v9x2vz/btn9/2/Z/f9v2f3/b9n9/2/Z/f9v2f3/RdL5/yXG7v8mxOz/JsTs/ybE6/8mxOv/JsTr/yXE6/8lw+v/JcPr/yK95cIQirAR////APDw8IH5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+vn5//r5+f/6+fn/+vn5//r5+f/6+fn/+vn5//r5+f+H8Pz/Oer+/zzq/v886v7/POr+/zzq/v886v7/POr+/zzq/v886v3/OuDzgWz//wD09PQA5+fnNPf39+n5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/4Xw/f846///O+v//zvr//876///O+v//zvr//876///O+v//zvp/ek32+00Ouf6AMrKygCzs7MF8/Pzmvn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/hfD9/zjr//876///O+v//zvr//876///O+v//zvr//876///OuX5miqptwUwv88AAAAAAPPz8wDp6eku9/f33fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f+F8P3/OOv//zvr//876///O+v//zvr//876///O+v//zvp/d033O8uOuX5AAAAAAAAAAAAvr6+AP///wDx8fFl+Pj49fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/4Xw/f846///O+v//zvr//876///O+v//zvr//876v71OeP2ZY7//wAus8IAAAAAAAAAAAAAAAAA4ODgANPT0wj09PSI+fn5+vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/hfD9/zjr//876///O+v//zvr//876///O+v/+jrm+Ygyx9gINdPlAAAAAAAAAAAAAAAAAAAAAAAAAAAA6enpAOHh4Q309PSM+fn5+Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f+F8P3/OOv//zvr//876///O+v//zvr//g65/qMNtXnDTjd7wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6enpAOLi4gr09PRw+Pj45/n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/4Pw/f816///Oev//zvr//876v7nOub5cDbW5wo33O4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ODgANHR0QLx8fE89/f3sfn5+fX5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/t/T7/4Xx/f+A8P31Xez8sTnk9zwuxdUCNtTkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAREREAP///wDo6OgM9PT0Tff396T4+Pjf+fn5+Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+fj5+Pjf9vf3pPL09E3m6OgM7/3/APtbOwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACMjIwD19fUA4uLiBvHx8Sn19fVd9vb2jff396739/e99/f3vff396729vaN9fX1XfHx8Snl4uIG9PX1AFEnIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/wD///gAH//gAAf/wAAD/4AAAf8AAAD+AAAAfAAAADwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABgAAAAcAAAAPgAAAH4AAAB/AAAA/4AAAf/AAAP/8AAP//wAP/KAAAABAAAAAgAAAAAQAgAAAAAAAABAAAEgsAABILAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABorgAAS34IAHTDNQCC22wAh+OMAIfjjACC22wAdMQ1AEx/CABorwAAAAAAAAAAAAAAAAAAAAAAAEBrAAAAAAAAecswAIzsngCU+OUAl/37AJj+/wCY/v8Al/37AJP35QCL6Z4Ad8gwAAAAAAA+aQAAAAAAcXd6AP8AAAAOiNtNAJP32gCY//8AmP//AJj//wCY//8AmP//AJb8/wCU+f8Ak/j/AI7w2gB+1E0AAAAAAEd4APn7/ADc2NU5T7P33gCX//8AmP//AJj//wCY//8AmP//AJX6/wCR8/8AkPL/AJDz/wCQ8/8AjOzeAHrOOQCR9AC3t7cO8e/vsGnA/f8Alf//AJf//wCX//8Al///AJP4/wCN7v8AjOz/AIzs/wCM7P8AjOz/AIzt/wCG4rAAY6oO4uLiT/j39/GIzfz/Mav+/zSs/v80rP7/FaH5/wOV7f8DlOv/A5Tr/wOU6/8DlOv/A5Tr/wOU6/8Dk+jxBIvVT+3t7ZT5+fn/8fb5/+vz+f/r9Pn/6vP5/1nR+/8EvPz/B738/we9/P8Hvfz/B738/we9/P8HvPv/B7r4/wax7ZTy8vK7+fn5//n5+f/6+fn/+vn5//n5+f9e1f3/A8D//wfB//8Hwf//B8H//wfB//8HwP3/Brv3/wa59f8GtO678/Pzwfn5+f/5+fn/+fn5//n5+f/4+fn/XtX9/wPA//8Hwf//B8H//wfB//8Hv/z/Brfz/wa17/8Gte//BrHqwfPz86X5+fn/+fn5//n5+f/5+fn/+Pn5/2DW/f8Gwf//CsL//wrC//8Jv/v/CLXu/wix6f8Isen/CLHp/wet5KXy8vJo+fn5+vn5+f/5+fn/+fn5//n5+f/I7vr/quf7/6zn+/+m5/v/Tdz5/yzV9P8u1fT/LtX0/y7U8/ooyOpo7OzsH/f399D5+fn/+fn5//n5+f/5+fn//Pr5//36+f/++vn/9fn5/2rv/v857P//POz//zzs//886/3QOuLzH////wD09PRh+fn59vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//H4+f9o7v7/OOv//zvr//876//2Ouf6YUH//wDu7u4A6enpB/b29oT5+fn3+fn5//n5+f/5+fn/+fn5//n5+f/x+Pn/Zu7+/zfr//876//3Ouj8hDfc7wc44PMAAAAAAPHx8QDu7u4I9vb2aPj4+Nn5+fn9+fn5//n5+f/5+fn/8/n5/4zx/P1S7P7ZO+n8aDfh9Ag55PcAAAAAAAAAAAAAAAAA6+vrAN/f3wH19fUo9/f3fvj4+MH4+Pje+Pj43vj4+MHq9vh+w/H2KADM5wFk4e8AAAAAAAAAAADwDwAA4AcAAMADAACAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAAgAEAAMADAADgBwAA'};return{FaviconsByHue:FaviconsByHue};});'use strict';Polymer('tr-ui-b-info-bar-group',{ready:function(){this.messages_=[];},clearMessages:function(){this.messages_=[];this.updateContents_();},addMessage:function(text,opt_buttons){opt_buttons=opt_buttons||[];for(var i=0;i<opt_buttons.length;i++){if(opt_buttons[i].buttonText===undefined)
-throw new Error('buttonText must be provided');if(opt_buttons[i].onClick===undefined)
-throw new Error('onClick must be provided');}
-this.messages_.push({text:text,buttons:opt_buttons||[]});this.updateContents_();},updateContents_:function(){this.$.messages.textContent='';this.messages_.forEach(function(message){var bar=document.createElement('tr-ui-b-info-bar');bar.message=message.text;bar.visible=true;message.buttons.forEach(function(button){bar.addButton(button.buttonText,button.onClick);},this);this.$.messages.appendChild(bar);},this);}});'use strict';tr.exportTo('tr.ui',function(){var Task=tr.b.Task;function FindController(brushingStateController){this.brushingStateController_=brushingStateController;this.filterHits_=new tr.model.EventSet();this.currentHitIndex_=-1;this.activePromise_=Promise.resolve();this.activeTask_=undefined;};FindController.prototype={__proto__:Object.prototype,get model(){return this.brushingStateController_.model;},get brushingStateController(){return this.brushingStateController_;},enqueueOperation_:function(operation){var task;if(operation instanceof tr.b.Task)
-task=operation;else
-task=new tr.b.Task(operation,this);if(this.activeTask_){this.activeTask_=this.activeTask_.enqueue(task);}else{this.activeTask_=task;this.activePromise_=Task.RunWhenIdle(this.activeTask_);this.activePromise_.then(function(){this.activePromise_=undefined;this.activeTask_=undefined;}.bind(this));}},startFiltering:function(filterText){var sc=this.brushingStateController_;if(!sc)
-return;this.enqueueOperation_(function(){this.filterHits_=new tr.model.EventSet();this.currentHitIndex_=-1;}.bind(this));var stateFromString;try{stateFromString=sc.uiStateFromString(filterText);}catch(e){this.enqueueOperation_(function(){var overlay=new tr.ui.b.Overlay();overlay.textContent=e.message;overlay.title='UI State Navigation Error';overlay.visible=true;});return this.activePromise_;}
-if(stateFromString!==undefined){this.enqueueOperation_(sc.navToPosition.bind(this,stateFromString,true));}else{if(filterText.length===0){this.enqueueOperation_(sc.findTextCleared.bind(sc));}else{var filter=new tr.c.FullTextFilter(filterText);var filterHits=new tr.model.EventSet();this.enqueueOperation_(sc.addAllEventsMatchingFilterToSelectionAsTask(filter,filterHits));this.enqueueOperation_(function(){this.filterHits_=filterHits;sc.findTextChangedTo(filterHits);}.bind(this));}}
-return this.activePromise_;},get filterHits(){return this.filterHits_;},get currentHitIndex(){return this.currentHitIndex_;},find_:function(dir){var firstHit=this.currentHitIndex_===-1;if(firstHit&&dir<0)
-this.currentHitIndex_=0;var N=this.filterHits.length;this.currentHitIndex_=(this.currentHitIndex_+dir+N)%N;if(!this.brushingStateController_)
-return;this.brushingStateController_.findFocusChangedTo(this.filterHits.subEventSet(this.currentHitIndex_,1));},findNext:function(){this.find_(1);},findPrevious:function(){this.find_(-1);}};return{FindController:FindController};});'use strict';tr.exportTo('tr.ui.b',function(){function TimingTool(viewport,targetElement){this.viewport_=viewport;this.onMouseMove_=this.onMouseMove_.bind(this);this.onDblClick_=this.onDblClick_.bind(this);this.targetElement_=targetElement;this.isMovingLeftEdge_=false;};TimingTool.prototype={onEnterTiming:function(e){this.targetElement_.addEventListener('mousemove',this.onMouseMove_);this.targetElement_.addEventListener('dblclick',this.onDblClick_);},onBeginTiming:function(e){if(!this.isTouchPointInsideTrackBounds_(e.clientX,e.clientY))
-return;var pt=this.getSnappedToEventPosition_(e);this.mouseDownAt_(pt.x,pt.y);this.updateSnapIndicators_(pt);},updateSnapIndicators_:function(pt){if(!pt.snapped)
-return;var ir=this.viewport_.interestRange;if(ir.min===pt.x)
-ir.leftSnapIndicator=new tr.ui.SnapIndicator(pt.y,pt.height);if(ir.max===pt.x)
-ir.rightSnapIndicator=new tr.ui.SnapIndicator(pt.y,pt.height);},onUpdateTiming:function(e){var pt=this.getSnappedToEventPosition_(e);this.mouseMoveAt_(pt.x,pt.y,true);this.updateSnapIndicators_(pt);},onEndTiming:function(e){this.mouseUp_();},onExitTiming:function(e){this.targetElement_.removeEventListener('mousemove',this.onMouseMove_);this.targetElement_.removeEventListener('dblclick',this.onDblClick_);},onMouseMove_:function(e){if(e.button)
-return;var worldX=this.getWorldXFromEvent_(e);this.mouseMoveAt_(worldX,e.clientY,false);},onDblClick_:function(e){console.error('not implemented');},isTouchPointInsideTrackBounds_:function(clientX,clientY){if(!this.viewport_||!this.viewport_.modelTrackContainer||!this.viewport_.modelTrackContainer.canvas)
-return false;var canvas=this.viewport_.modelTrackContainer.canvas;var canvasRect=canvas.getBoundingClientRect();if(clientX>=canvasRect.left&&clientX<=canvasRect.right&&clientY>=canvasRect.top&&clientY<=canvasRect.bottom)
-return true;return false;},mouseDownAt_:function(worldX,y){var ir=this.viewport_.interestRange;var dt=this.viewport_.currentDisplayTransform;var pixelRatio=window.devicePixelRatio||1;var nearnessThresholdWorld=dt.xViewVectorToWorld(6*pixelRatio);if(ir.isEmpty){ir.setMinAndMax(worldX,worldX);ir.rightSelected=true;this.isMovingLeftEdge_=false;return;}
+html+='<tr><td>snapshots:</td><td id="snapshots"></td></tr>\n';html+='</table>';Polymer.dom(this.$.content).innerHTML=html;const snapshotsEl=Polymer.dom(this.$.content).querySelector('#snapshots');instance.snapshots.forEach(function(snapshot){const snapshotLink=document.createElement('tr-ui-a-analysis-link');snapshotLink.selection=new tr.model.EventSet(snapshot);Polymer.dom(snapshotsEl).appendChild(snapshotLink);});}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-object-instance-sub-view',tr.model.ObjectInstance,{multi:false,title:'Object Instance',});'use strict';Polymer({is:'tr-ui-a-single-object-snapshot-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},get requiresTallView(){if(this.children.length===0){return false;}
+if(this.children[0]instanceof tr.ui.analysis.ObjectSnapshotView){return this.children[0].requiresTallView;}},get selection(){return this.currentSelection_;},set selection(selection){const snapshot=tr.b.getOnlyElement(selection);if(!(snapshot instanceof tr.model.ObjectSnapshot)){throw new Error('Only supports object instances');}
+Polymer.dom(this).textContent='';this.currentSelection_=selection;const typeInfo=tr.ui.analysis.ObjectSnapshotView.getTypeInfo(snapshot.objectInstance.category,snapshot.objectInstance.typeName);if(typeInfo){const customView=new typeInfo.constructor();Polymer.dom(this).appendChild(customView);customView.modelEvent=snapshot;}else{this.appendGenericAnalysis_(snapshot);}},appendGenericAnalysis_(snapshot){const instance=snapshot.objectInstance;Polymer.dom(this).textContent='';const titleEl=document.createElement('div');Polymer.dom(titleEl).classList.add('title');Polymer.dom(titleEl).appendChild(document.createTextNode('Snapshot of '));Polymer.dom(this).appendChild(titleEl);const instanceLinkEl=document.createElement('tr-ui-a-analysis-link');instanceLinkEl.selection=new tr.model.EventSet(instance);Polymer.dom(titleEl).appendChild(instanceLinkEl);Polymer.dom(titleEl).appendChild(document.createTextNode(' @ '));Polymer.dom(titleEl).appendChild(tr.v.ui.createScalarSpan(snapshot.ts,{unit:tr.b.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument,inline:true,}));const tableEl=document.createElement('table');Polymer.dom(this).appendChild(tableEl);const rowEl=document.createElement('tr');Polymer.dom(tableEl).appendChild(rowEl);const labelEl=document.createElement('td');Polymer.dom(labelEl).textContent='args:';Polymer.dom(rowEl).appendChild(labelEl);const argsEl=document.createElement('td');argsEl.id='args';Polymer.dom(rowEl).appendChild(argsEl);const objectViewEl=document.createElement('tr-ui-a-generic-object-view');objectViewEl.object=snapshot.args;Polymer.dom(argsEl).appendChild(objectViewEl);}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-object-snapshot-sub-view',tr.model.ObjectSnapshot,{multi:false,title:'Object Snapshot',});'use strict';Polymer({is:'tr-ui-a-power-sample-table',ready(){this.$.table.tableColumns=[{title:'Time',width:'100px',value(row){return tr.v.ui.createScalarSpan(row.start,{unit:tr.b.Unit.byName.timeStampInMs});}},{title:'Power',width:'100%',value(row){return tr.v.ui.createScalarSpan(row.powerInW,{unit:tr.b.Unit.byName.powerInWatts});}}];this.sample=undefined;},get sample(){return this.sample_;},set sample(sample){this.sample_=sample;this.updateContents_();},updateContents_(){if(this.sample===undefined){this.$.table.tableRows=[];}else{this.$.table.tableRows=[this.sample];}
+this.$.table.rebuild();}});'use strict';Polymer({is:'tr-ui-a-single-power-sample-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},updateContents_(){if(this.selection.length!==1){throw new Error('Cannot pass multiple samples to sample table.');}
+this.$.samplesTable.sample=tr.b.getOnlyElement(this.selection);}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-power-sample-sub-view',tr.model.PowerSample,{multi:false,title:'Power Sample',});'use strict';Polymer({is:'tr-ui-a-single-sample-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},ready(){this.$.content.tableColumns=[{title:'',value:row=>row.title,width:'100px'},{title:'',value:row=>row.value,width:'100%'}];this.$.content.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;if(this.currentSelection_===undefined){this.$.content.tableRows=[];return;}
+const sample=tr.b.getOnlyElement(this.currentSelection_);const table=this.$.content;const rows=[];rows.push({title:'Title',value:sample.title});rows.push({title:'Sample time',value:tr.v.ui.createScalarSpan(sample.start,{unit:tr.b.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument})});const callStackTableEl=document.createElement('tr-ui-b-table');callStackTableEl.tableRows=sample.getNodesAsArray().reverse();callStackTableEl.tableColumns=[{title:'function name',value:row=>row.functionName||'(anonymous function)'},{title:'location',value:row=>row.url}];callStackTableEl.rebuild();rows.push({title:'Call stack',value:callStackTableEl});table.tableRows=rows;table.rebuild();}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-sample-sub-view',tr.model.Sample,{multi:false,title:'Sample',});'use strict';Polymer({is:'tr-ui-a-single-thread-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){this.$.content.selection=selection;this.$.relatedEvents.setRelatedEvents(selection);if(this.$.relatedEvents.hasRelatedEvents()){this.$.relatedEvents.style.display='';}else{this.$.relatedEvents.style.display='none';}}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-thread-slice-sub-view',tr.model.ThreadSlice,{multi:false,title:'Slice',});'use strict';Polymer({is:'tr-ui-a-single-thread-time-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){const timeSlice=tr.b.getOnlyElement(selection);if(!(timeSlice instanceof tr.model.ThreadTimeSlice)){throw new Error('Only supports thread time slices');}
+this.currentSelection_=selection;const thread=timeSlice.thread;const root=Polymer.dom(this.root);Polymer.dom(root.querySelector('#state')).textContent=timeSlice.title;const stateColor=tr.b.ColorScheme.colorsAsStrings[timeSlice.colorId];root.querySelector('#state').style.backgroundColor=stateColor;Polymer.dom(root.querySelector('#process-name')).textContent=thread.parent.userFriendlyName;Polymer.dom(root.querySelector('#thread-name')).textContent=thread.userFriendlyName;root.querySelector('#start').setValueAndUnit(timeSlice.start,tr.b.Unit.byName.timeStampInMs);root.querySelector('#duration').setValueAndUnit(timeSlice.duration,tr.b.Unit.byName.timeDurationInMs);const onCpuEl=root.querySelector('#on-cpu');Polymer.dom(onCpuEl).textContent='';const runningInsteadEl=root.querySelector('#running-instead');if(timeSlice.cpuOnWhichThreadWasRunning){Polymer.dom(runningInsteadEl.parentElement).removeChild(runningInsteadEl);const cpuLink=document.createElement('tr-ui-a-analysis-link');cpuLink.selection=new tr.model.EventSet(timeSlice.getAssociatedCpuSlice());Polymer.dom(cpuLink).textContent=timeSlice.cpuOnWhichThreadWasRunning.userFriendlyName;Polymer.dom(onCpuEl).appendChild(cpuLink);}else{Polymer.dom(onCpuEl.parentElement).removeChild(onCpuEl);const cpuSliceThatTookCpu=timeSlice.getCpuSliceThatTookCpu();if(cpuSliceThatTookCpu){const cpuLink=document.createElement('tr-ui-a-analysis-link');cpuLink.selection=new tr.model.EventSet(cpuSliceThatTookCpu);if(cpuSliceThatTookCpu.thread){Polymer.dom(cpuLink).textContent=cpuSliceThatTookCpu.thread.userFriendlyName;}else{Polymer.dom(cpuLink).textContent=cpuSliceThatTookCpu.title;}
+Polymer.dom(runningInsteadEl).appendChild(cpuLink);}else{Polymer.dom(runningInsteadEl.parentElement).removeChild(runningInsteadEl);}}
+const argsEl=root.querySelector('#args');if(Object.keys(timeSlice.args).length>0){const argsView=document.createElement('tr-ui-a-generic-object-view');argsView.object=timeSlice.args;argsEl.parentElement.style.display='';Polymer.dom(argsEl).textContent='';Polymer.dom(argsEl).appendChild(argsView);}else{argsEl.parentElement.style.display='none';}}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-thread-time-slice-sub-view',tr.model.ThreadTimeSlice,{multi:false,title:'Thread Timeslice',});'use strict';Polymer({is:'tr-ui-a-single-user-expectation-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.$.realView.addEventListener('customize-rows',this.onCustomizeRows_.bind(this));this.currentSelection_=selection;this.$.realView.setSelectionWithoutErrorChecks(selection);this.$.relatedSamples.selection=selection;if(this.$.relatedSamples.hasRelatedSamples()){this.$.events.style.display='';}else{this.$.events.style.display='none';}},get relatedEventsToHighlight(){if(!this.currentSelection_)return undefined;return tr.b.getOnlyElement(this.currentSelection_).associatedEvents;},onCustomizeRows_(event){const ue=tr.b.getOnlyElement(this.selection);if(ue.rawCpuMs){event.rows.push({name:'Total CPU',value:tr.v.ui.createScalarSpan(ue.totalCpuMs,{unit:tr.b.Unit.byName.timeDurationInMs})});}}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-user-expectation-sub-view',tr.model.um.UserExpectation,{multi:false,title:'User Expectation',});'use strict';(function(){const EventRegistry=tr.model.EventRegistry;function getTabStripLabel(numEvents){if(numEvents===0){return'Nothing selected. Tap stuff.';}else if(numEvents===1){return'1 item selected.';}
+return numEvents+' items selected.';}
+function createSubView(subViewTypeInfo,selection){let tagName;if(selection.length===1){tagName=subViewTypeInfo.singleTagName;}else{tagName=subViewTypeInfo.multiTagName;}
+if(tagName===undefined){throw new Error('No view registered for '+
+subViewTypeInfo.eventConstructor.name);}
+const subView=document.createElement(tagName);let title;if(selection.length===1){title=subViewTypeInfo.singleTitle;}else{title=subViewTypeInfo.multiTitle;}
+title+=' ('+selection.length+')';subView.tabLabel=title;subView.selection=selection;return subView;}
+Polymer({is:'tr-ui-a-analysis-view',ready(){this.brushingStateController_=undefined;this.lastSelection_=undefined;this.tabView_=document.createElement('tr-ui-b-tab-view');this.tabView_.addEventListener('selected-tab-change',this.onSelectedSubViewChanged_.bind(this));Polymer.dom(this).appendChild(this.tabView_);},set tallMode(value){Polymer.dom(this).classList.toggle('tall-mode',value);},get tallMode(){return Polymer.dom(this).classList.contains('tall-mode');},get tabView(){return this.tabView_;},get brushingStateController(){return this.brushingStateController_;},set brushingStateController(brushingStateController){if(this.brushingStateController_){this.brushingStateController_.removeEventListener('change',this.onSelectionChanged_.bind(this));}
+this.brushingStateController_=brushingStateController;if(this.brushingStateController){this.brushingStateController_.addEventListener('change',this.onSelectionChanged_.bind(this));}
+this.onSelectionChanged_();},get selection(){return this.brushingStateController_.selection;},onSelectionChanged_(e){if(this.lastSelection_&&this.selection.equals(this.lastSelection_)){return;}
+this.lastSelection_=this.selection;this.tallMode=false;this.tabView_.label=getTabStripLabel(this.selection.length);const eventsByBaseTypeName=this.selection.getEventsOrganizedByBaseType(true);const ASV=tr.ui.analysis.AnalysisSubView;const eventsByTagName=ASV.getEventsOrganizedByTypeInfo(this.selection);const newSubViews=[];eventsByTagName.forEach(function(events,typeInfo){newSubViews.push(createSubView(typeInfo,events));});this.tabView_.resetSubViews(newSubViews);},onSelectedSubViewChanged_(){const selectedSubView=this.tabView_.selectedSubView;if(!selectedSubView){this.tallMode=false;this.maybeChangeRelatedEvents_(undefined);return;}
+this.tallMode=selectedSubView.requiresTallView;this.maybeChangeRelatedEvents_(selectedSubView.relatedEventsToHighlight);},maybeChangeRelatedEvents_(events){if(this.brushingStateController){this.brushingStateController.changeAnalysisViewRelatedEvents(events);}}});})();'use strict';tr.exportTo('tr.ui.b',function(){Polymer({is:'tr-ui-b-dropdown',properties:{label:{type:String,value:'',},},open(){if(this.isOpen)return;Polymer.dom(this.$.button).classList.add('open');const buttonRect=this.$.button.getBoundingClientRect();this.$.dialog.style.top=buttonRect.bottom-1+'px';this.$.dialog.style.left=buttonRect.left+'px';this.$.dialog.showModal();const dialogRect=this.$.dialog.getBoundingClientRect();if(dialogRect.right>window.innerWidth){this.$.dialog.style.left=Math.max(0,buttonRect.right-
+dialogRect.width)+'px';}},onDialogTap_(event){if(event.detail.sourceEvent.srcElement!==this.$.dialog)return;const dialogRect=this.$.dialog.getBoundingClientRect();let inside=true;inside&=event.detail.x>=dialogRect.left;inside&=event.detail.x<dialogRect.right;inside&=event.detail.y>=dialogRect.top;inside&=event.detail.y<dialogRect.bottom;if(inside)return;event.preventDefault();this.close();},close(){if(!this.isOpen)return;this.$.dialog.close();Polymer.dom(this.$.button).classList.remove('open');this.$.button.focus();},get isOpen(){return this.$.button.classList.contains('open');}});return{};});'use strict';tr.exportTo('tr.ui.b',function(){const FaviconsByHue={blue:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALgAAAC4CAYAAABQMybHAAAlrklEQVR4Ae2dCXwdVb3H5265yc3SpEk3ukEXCqVUBLT4Wm19oFKtaN0fKijy9CMguPBarIJsIiA8qsjTh7SllAoFeVBaEARkLV1ooXtL0yRdkqZp9u3uy/v/5uY/OZm75y659+acdnLOnP385zv/+58zZ2YMinTplIAhzsoDceaT2RKUQLwHIMFqh0V2ll0kn4XA6byv9/Vw834kX19e7keRQCzhRyk6bJJYRvD1YTXuhRdeqDj77LPPtNls400mU7HRaCzFFggEVJ/iSqhsicFgKIXUKL6bvB6fz9fj9/u7Kb4bPjaK67Xb7Q0HDhw49IUvfKEd2XUb7WpxHIYvXRgJ8AELkzRso1gmKrwkBfjG7373u5Zly5ZNKS8vn2G1Ws80m83YphPI0wnQUemQFp0IzQR9tdfrxXbI5XId6ujo+PCuu+6qXbNmjYfa9NMmngDoBmt+hIe944M53AUhwqwCvXTp0qJrr732opKSkk8XFhZ+imC+gIAryAZB0QnlJuB3OJ3Ot3p6el5/6KGHttxzzz0O6pse+GEP+3AGnKE2EhgG0tAFt99++4WkoT9tsVgW0DaH4guzAeg4+uD0eDxbaXuDNPzrt9xyy3bS8G4qB8BF6OOoKr+yDDfAB0B91VVXFf72t7+9lLT05QUFBZfQoYWtnA+ux+12v0ra/W+/+tWvXlq5cqWTBjUsYR8OgDPU8KGtjR9++OHHx4wZ8+2ioqKv0X4lbfnsWh0Ox9+bmprWzpgxYxsNFBpd1Op5bcbkM+AMtgr11q1bTz/zzDP/gy4Qv02zGtPzmehIY6MZmmq6UF176NChJ+bMmXOkD3QR9khFczY+HwEXwTbV1NTMI229FCYIXSTm43gTho8uUgMwYUir3zN16tR3qAIfbXkJej4dcIxF1dbkm44ePfqZqqqqpTT7MZf2pYsgAZqN2dTS0nLP5MmTX6EsDDrDHqFU7kTnA+Aa2BMmTDBv2bLliyNHjlxCZsgFuXMYhr6nZL7saGtru/eiiy7aUF9f76UeAfKcBz2XAUffVbgJbAuB/Y3KysoldONl5tDjkrs9oBtL+1tbWwH6UwS6/mZSzg0sVwHXTJG9e/deOGXKlOWksS/MOelncYdJo2+vra396axZs7ZTN0XTJYt7Hdq1XANc1dg0DNOqVatGLl68+DZa/3E1XTwCeOn6JLCly6ncU9+mNLnBZRLOYPAHHI5H2l5/8TdHbl3SRjUx6DkztZgrgKOfDLf5xIkT36moqLiLzJG0rAFJAomsKDp1W51S74IZnSIX8DcrXV3LlK/Oe5xqZPsckGc96LkAOPpowrZ79+5ZNK31BzkzQtKI4qxvV0dJTSLJ592kHKu7QfnPxXupFmhzbFkNeTb/tGsae/bs2Va6wr/lrLPO2izhTgLQZIuaaMp1yvTNyvNbb1HomFB1ZtrAUNYqymztGMNt2rhx44T58+evohs1n0r2+AyX8mnT4KIAvZ63lA82f1/55TX1FJ21tnk2As4zJObq6urP0BTgCmlri2TFDmcEcHQDtnlz4w+Uyz+Hm0Rsm2PuPGtcNpkomtZesGBBYXNz8210d+05CXfWsBLaEQNd5I+e8JyyYettCh0zyoBrpawyWbJFg2twv/jiixPnzZu3mhZFzQ2VqIyJRwIZ0+BiZzyeTcqebVcqS350nKKzxmTJBsDRB3WWZN++fXPpps060tpVouxkODEJDAng6GIg0KI0Hv+mcsXnN9FeVsyyDLWJwnCbadXfomnTpm2UcCcGc1blNhiqlNMmblT+9soi6hdmWKC4hlSJDiXgaBsCsNDKvysnTpz4JIWLaJMupyVgKFLGjHtSefrNK2kYFtpwjIeMs6FqWIOb7kr+Yty4cX+m2+0446XLBwkESHuPrPqz8uymX9BwhhTyoQBchZseQiigdcj30grAO+SDCPlAtW4MeLikdMQdyvqt9yp0rCl1SDR5pgFX4V64cGERvdhmRWlp6XU6scjdfJNAcfF1ysqNK5Q5C2F+ZhzyTF4AqHCPGjXKSjdwHqUHfr+ab8cyW8YzZLMo0QTgcj2jfO/S7ynNzS7KxtOI0UqkJC1TGlyFm3pccPDgwfsk3Ck5drlVidX6VWXFxvvAAG0Z0+SZAJzhtjQ2Ni6ld5D8KLeOjOxtyiRgK/6R8uy7S6m+jF14phtwmEBow3L8+PGr6FnJm1MmLFlRbkqgtOxm5am3rgITtIGNtJrJ6QQcHcdPkYUuKL9MsybLKSydlICijKxcrjz+0pdJFKzJ0wZ5ugBnuM27du2aT7ffV9JUIGCXTkqAJEAsjJ2wQlm1fj7tpPWOZzoAB9yo1/zSSy/NoLdJraMwFsdLJyUgSqBQGX/GOuX+FTMoEpCDmZRr8nQBbqIHgovnzp27mtaWlImjkmEpAU0CYGPmR1crF19cTHH4hU854KmuECcMOmo9derUAyNGjLiawtJlWAJZOQ8eTQb27keUyz7xM8qS8jnyVGpwNk0s+/fv/4qEO9oRlWkDJGArvVpZ89JXKC7lMyupApzhNm/YsGH6GWec8eCAAcgdKYFYEhhz2oPK3X+ZTtlSao+nEnDzxWRL0eNmj0q7O9bRlOkhEoA9ft6cR5WPq/Y4IE+J+ZyKSjS7m56jvK+srEzeqQw5epmNyDkbXBRPT8//Kl++6EaKSok9nqwG10yTHTt2fJpWB0q4xYMlw4lLoJhu5z/y3KepYEpMlWQBV7U3mSXFNN99H71YPfEByRJSAqIEwND4yfcpFyzgqcOkGE2mMGtvy2OPPXY9vZjnTLGfMiwlMGgJWCxnKktv/QmVT3pWZbCAM9zmxx9//IzRo0fj0STppARSJ4HykTcqN//3GVRhUqZKMoCrC6no6Zy7yTSxpW5ksiYpAZKA0WhTPj73dxRKakHWYABn7W3Zs2cPvjH5eXlApATSIoGi4i8oK56/tA9ysAr2EnKDARxlzJdddlkJ3dC5N6HWZGYpgUQlMH7SvbRWpYSKsamSUA2JAs7a2/ynP/3pOvrc9eSEWpOZpQQSlYDZPFn54a/xcDoDnpAWTxRw5DfRJ7DL6HUPP060rzK/lMCgJFA+8sfKZd/CqlRc9yXEbCKZWXtbli1b9gN6EX3loDorC0kJJCoBk6lS+ebVP6BiCU8bJgI48ppxU2fs2LHXJNpHmV9KICkJVFZdo3zsY7j5w6ZKXNXFCzhrb/PDDz/8HbK9x8ZVu8wkJZAqCZjNY5Wf3vkdqo4Bj8sWjxdw5DPRt3KKTjvtNNxhkk5KIPMSqBz1E2Xq7ITekBUP4Ky9LevWrfsGae9JmR+ZbFFKgCRgLpik3HL3NygUty0eD+Cq9h4/fnwBbTdIQUsJDKkERo+9QSkr47ubMfmNlQHaG5v56aef/ndaUDVtSAcnG5cSMFumKXc/fDGYpI35jCiXeADH3KOZ7lp+Sy6HjShHmZApCWA57dgJ3wKTtIFNQB7RxQIc6abLL7+cniEesTBiLTJBSiCTEiguWah8/isjqEkAHpXhaIk4M5BuXrp06ZfoOUtcvUonJTD0EjCaipSvff9L1JGYU4bRAEeaCjh9P+fr0jwZ+uMqe9AnAZgpo0Z/nfYY8IgcR0qA9sZmeuCBBybZbLZ/66taelIC2SEBKzF5zTJMWbMdDl5DXDTAVe29aNGib5D2jpQvpEIZISWQEQkYicm5C0QtnjDg6uwJPY72tYx0WDYiJZCoBMorGXDW4iE1hNPMOBMQb1qzZs0MmvueHlJKRmS1BCZYYZoOA2exTFd+dT/eTsuzKSFaPJwkNMDPO++8+fLiMvdA+Z8JJcqPN+9RGnocoZ0PBELjFF2cbjdYIEykvq4wWehd4APb05dBari4gaWCe/p8AT+uFOdT4j7aoJTB7oAGowFurqqqmicBV5QPmgLKX3b7lVbHANmRLLPVVSjnGT6hzFRa44dHHEqIHhQThXC8+YQiqQ66K9rnvakoD1O9DPiAJvSAo8vYjMXFxWZ6U9VFA3IP052fv+5VGntzBW4+SCYl4KtQ/L3tpCBJ0+WpC/hKLgKrvb29DDj41Q4WIvUOcaZHH310lslkGqlPHI77uQd38CgZTBbSVBVKXk+CGYwjS758/ywwS1sIz/oI1uCmmTNnflKaJ7l/OmuQG3migQ9xnvg0W2gaN/2TfYDzoLQDFw5wVYOT/T1XAq7JKacDKuS2csVg1B/unB6W2nkwaiiumEs7rMEBueZEG5zpN9Gt+QKyv+douWQg5yXAkPvtHYO78MxiCZisJXNsVRML7C3HndRN5li1w/WnNPaNDz744Ll0ZpRm8Zhk1wYhAYacjPJBlM7eIgHFUFryxZvPpR6q/Io9DavBJ0yYcJY0T0Qx5U84CDnNrtjb82dQZHqZysefRQPaRltEDc4JRlr7PS1/Ri9HopeAwWRWjLYKQiF/NLnBWgpmocGZY3XYoomCBOybaPXgNKnBVfnk7R8V8qLyvIAcrBoLiqaCXdoYcvXYMeB8KmPfSIBPUVPln7yWQD/kjEEOD7fABsBVfvtGoTIdYoOPHDnSXFhYODmHhyq7noAEgpCPUPyOTiql3QBMoIbsyGo0F04uInYdbW3RTZRbb711AnXZmh3dlr3IhAQYcpooz0RzaWmDTk1r0YLrwS4GwRaJuoMGmXrjOeecI5fHQiLDzKmQF9ILXFXIGYfc8q2jZ4JdBlyFnE9ZHolx1KhR8gJzmMHNw9Ugz8U7nrijWToyZCZFtMEBu7GoqGgiD1j6w08CKuTWUsXv6s65O56GApVdlWM+cnoNbqB3D+JzEdINYwkw5DlnkxvNYJetEdVEETU4Ioy0RLZEzoEPY7r7hh6EvIQ0eQ/FZP/sCpilPgNwKG0VbgyFdzTqCXC8ZFw6KQEAoxgLS3NoPbkR7GosIyxqcBxSgwQcYpCOJWDAOnIrKUbS5AH9M5GcKUt8OiEZcK1HbIMjQiVfAq7JRgb6JADIDQR5tpuuAaMGuGaisAbXIiTgkutwEujX5L2UnJ02uSEIOHdfZVpqcBaH9GNKIKjJQ6yAmOUylYHsa+6cprBZg3MfpA3OkpB+WAkENXmxEnDbs2+e3KABrvU9RINTih56LbMMSAlAAqomL7BRQFOU2SGYgMouOqV1jGHWIrxer50+8iofV8uOQ5a1vVA1OUEecOPtWdlhkxsUH/2saE5lmufBtVifz4erCOmkBGJKIKjJ8V0ETT/GLJPODAG/X8+uOg+O0087BaHB09kJWXd+SSCoyYuUgIceaB/qeXL/AA2uci3a4JB8QGrw/AIwE6NRNbmlcMht8oBftT40ZY2xsw2OsJogAYcopEtUAqomt5Am9w6dJg8ENPNagzysBs/2W7KJCl/mz4wE8OYsg3loNLnKbNAG1+DGqFmDI1LdpA2eGRjytRX19XAEecDr6kMqcyM1BNTrR41ltCxqcAYc6yOlkxIYtASCmhyP9WZ2doVmUXhtL1hWHWtw3lccDkcb1H22L6zROiwDWSmBoCa39mnyDHSRmPV7nG36lliDs1r3t7e31+kzyX0pgcFIQNPkGbrj6be3gV287Z95Vk0U7MCpkdXV1bXyIjMoEPk3eQmokJsKglOIAD1tm6J4Wo7UMsd9PQ+wBse+CvgzzzwjAe+TjvRSIwGGnB4qS02F4WohE8W58zk94CGzKP6XX3652+VyNdN6lFHh6pFxUgKDkQAgDygWxeDzDKZ47DJeV3PvvtfpVQChJgoKs80C+8Xf09NzRJopEIt0qZQAIFfou0GpXoUIVv0uxxHqq8ov+cxzyDShmsFut9elcmCyLikBloAKuZEm71Jsi/vdKrMi4GqTbIMz8cjgw0yK1OB8SKSfagkMgDwVlZMGDzg6oJR9tIFh5lmzwdEMR/pPnjxZiwjppATSJQHVJg/QRaffm3wT9Gvg624GswPgRsXhNLh//fr1u2nRFYCXTkogbRJQbybCXEl2diXgCzh2bthNFQHwAZAz4BgEgEaijz4C29zZ2VkjzRSIRbp0SiAIOT7MgCnExDeyThS/s7uma+vaZqpANFHUbusBZ8i9ra2tWyXgqozknzRLQIMcF56JOiLc19O6lYrB1hmgvVGVCDj2VQ1Ovq+mpmaLBBwikS4TElAhx7vJE55dIWhb6rZQH6G9WYNrXRYBh/ZmDe5buXLlVj85LacMSAmkWQIa5Im0Q4x2bXkUGpzhZo7VWsIBrp4JGzZsaCc7/KDU4olIW+ZNVgL9kMe2x4P2d+dB+86X8NFP1uARAUffWIPDnvHSdOE2CTjEIl0mJRCEPA57nAj3dzXj468qr+SzDa51V9TgiGTAcTZ4yQ7fLAHXZCUDGZSABnlUm5wgba3dDFZpE00Uraf6Bx5YveNM8C5fvnzbJZdc4iwuLqYH7Yavq+ytURq70rRIKIvEGlmZAYswDjZCRBchLUJ0ULeGqYzaQL8AfEj/PA5nz8u/Zw3O2ntAC+EAR0bVnnn33Xe7Gxsb35gyZcqlxhR9mGj/oU7liWfrlPZOd5jRZGfUbK9bmUnPGIYIeEB3B8i1PyUKBHTo+vPFEYrcfpR6orYfR6NZmiUQ8Cs9XU1vbDiyEysI2f5myLVe6wFHAqSlanDyPTt37nz+9NNPTxngv/3DHqW5lV4tkGPO67ErPi+9pgw/mYAGfjyO8zJo+vL6dH2dmc6vb1/fP31/9Pn1+7HK69P15fXt9eUP+LxKR/OB5yk7flrFOfABNehtcCSKgHuvu+66t2n5bGtk7TGgvpg7uQg3BmW22BSTGa8pIwehx+s4L3wxzOXFOM4j+sjHecSwmEcMi3nEsJhHDIt5ENY75IXjMhxWI+P4E6u8Pp3bYV/fHsWDRb/f1Vq3b9XblBzxAhNFowEOte+hlYWO+vr6f6QKcDSaq06F3FQYdeUEow9fDGfLmMU+ieFI/RPziOFU5Y9UT/T4gOJ2tP/D7e7Bmz+hwcNeYKKOcIAjHiaKZqa8+uqr6+l9KYgf9g6QG/sgxwHXbxAQgyCG9fmGal/skxiO1B8xjxhOVf5I9USLV8j+7mjd/Rz1RzRPwGuIiwQ4zBScFaDas3Tp0r0dHR2HpRYPyo8hD+7Jv5mUABj0eeyHjx58Yh+1y4CDVTAb4qIBzpCjEjfNiW+Qd+775dcPeTRdI9NCf+OSlQl98M3RvAFM0sbmCVhNCHAcSah8TYuvXr16PT2MjAql65OAapPjXXzRnP4iCnk5Llw5ToMvhsPlzYU4cQxiOFLfxTxiuC+/3+/xNB9/cz3tito7rHmCIpE0ONJwRrAd7l61alXjkSNHXpBaHKLpd5hZMfELJ3FA9Buy8oESw/p8vC/mEcOcnmu+OAYxHGkcYh4xTPlx38DtaHnhZP3rjZQEDR5xehBF4eIFXDVT1q5d+whp8YhnS7DK4fdXhdyEd/FJl04J+ANef3PDpkeoDTZPkgIcfR2gxe+7776aY8eO/VNq8dDD2A95sjamLE8/eSTggRsuLj2Otn821D5fQ4lxaW8cpWgaHOnQ1pqZQmHXU0899VePxxPWoEeB4ewYchwadhzmw4V4jhPDnJ6oL9YhhuOtRywjhuMtr88n1iGGOZ8YJ4Y5PZKv+H2BthOb/0pl8F5mEfCoFkUswNEHVICLTdVMufPOOw+QFn9TanGIJtTBHjeSucIHCjkQZsfhSOmcL14/2fqSLa/vZ6z6YqXr68M+1p24nK1vHq3++wHaZfMETEaFG2XjARzaWgOcwq4XX3zxYdLiKC9dGAkw5Pqf2czso0OMkRhGXG5u9N5vpb3p/YdpAKy9AR+YjGlJxAs4a3GcPa4lS5bsOnHixGapxUkaEVwQcnqrasYdw80wowMcl/HOJN0gtLfb1bH5yMHHd1FlDDhr75QAjk6yFsdVKyB3bty48UE5owLRRHYa5JgSY8dhniZDPMeJYU5P1BfrEMOR6hHzIBzLcV8j1aePR31cRgxzPjFODPel+xWvv6N5x4OUhCWoYA8MxqW9KV9cJgryAXBocQbcdeONN+6kd4k/J9eoQDyRnQq5se+Fk3yg2UcxDvcdULUmjotcbeQULhtvffr8XC6Sj5a5TORe9KdwXq5PXz5KOn0WUHH2nnyudt/qnVSMtXfMqcH+xuMHHGVYi6sXm2jwpptuWk4PJrfLNSqiSEPDGuShSTImggTUNSdee/uxA2uXUxaGO27bm6uNxwbnvKzF8fOABp2vvfZa89atW/8oLzhZRJF9zVyJnEWmCBKgb14qPZ01f2xv3o03VsE8AXNx295cVSKAo4yoxVXIFy9e/Aw91rZLXnCySCP7Jpo+NNLnPMQvHXAYfjz/UDuXEcNcVowTw5yeal9sQwxHakfMI4bF/HhiyuPq2LV/293PUB6GO2HtjfoHA7g4o4LGnWvWrLnL6XT6pKkCkUZ3gNxAL4HnA4rcCMfrOG+k8rHS420n3nyJthcrPxgK+D2+5oa37qI+qHyRj4vLhLU3xpAo4CjDgOOMUrX4HXfcse/AgQPr6I20SJcuhgQYcvVijS++pN938RpQHD0n1h378Cms99Zrb7CXkBsM4GiAIVenDGnfccMNNzzU0tLSKE2V+OSvmiuYXZFOkwDmvD2e7saa/X99iCLxOBoAF7W3ljfewGABZ1ucpw2d7733XusTTzxxE33+xCNNlfjED3vcqELON2WGr0+WCS03cXtaTmy6qbutppUkyHAnNO+tl/xgAUc9DLmmxWnacAeB/hDdANK3I/cjSCAIebi3d0QokKfRZHcrvZ01D9XtW72DhqjX3mBtUC5ZwGGqaFqcws5LL7109dGjR9+WN4DiPx7DHXLc0HE5Wt7es/m21WCob4PiTOimTjiJJwM46gPg2PiCE2ee/Wc/+9lvyB5vkvY4SSNO12+uxFkgT7LB7vZ6uptq9678DQ3JThsYggkAppgvCg7OJQs4WkUnMH2CMw6dc9ANoJNPPvnkL8ke90p7nCQSpzPS9CFscryHbzhsEEvA7/a2NLzzy46WXSdpV+WH/KQuLFEvu1QAzrY4mypqJ+lVE9u3bdv2Z9jjEnIWd2wfkBsM+W+T9813093K6j/X7l+9nSQjwp3UhaUo5VQAjvoY8gGmysKFC1fSgqxX3G6ckNLFKwEVcu3rY/k5swK729Hb9Mqed29fSXLRmyawCAZ9YSnKOVWAo06GHDTjQgGdti9atOjXdNH5noScpJGAU00VI74+ln+OXv2gOJ0t7x3cduevaXQqJ+TztGDK4IbkUg24aI+rkNNXIrquuOKKG+kBiYNyURZEHr/LR8j99OFXt6v94KH377/R4WjtImkAcBFuMJQS7Q1Jp0NFoHNiBw0Eube2tnbT/PnzFzz3UtMIA76mJV1cEjAYcIhInLgTkuMOZonH3XW8dvdff9zZur+JhtNLGwMO8zal2hviSgfgqBduAOhki7u6u7u3NHWO+yxNidkk5EEhxfM3CHmfSHN0zQq98Fjxunta6w+v+9GphneO0Wj0cKdUc7Nc0wW4qG608AcffNBrMlvfLx0x5XMGo7lAQs6HIbbfLytNnLELZUkOrO2mF2b2nDz64rX1hzccpG7p4YbmBuApd+kCHB3lI8G+2vnOlr0dBYVV+4tKxl1MswWW/gOX8rHlXYUsq+C8ChaeZv8/vOqYvo5hb2l48+d1+9fiNrwId8rmuyMd7HQCLrYJyDXQ20/tOGUxF+6wlU1aYDQWFPGBEwvIcHgJ9MtKE2f4jFkQq9rcnu72xrp//OTIgccx181wY8477XBDBJkGXAO9o2VPm+JzbioZMXWewVRQ2n/g0C3poklgoKyyc57cTxeUXnfHCVrXfU1D7fr9NJ4e2gA4w530OpNoMuK0TAGO9ljlaJB3tVd3u1yNb5ZVzPy40Wyt7L+Y4u5JP5IE+iFnsUbKmfl4zHN7nG3VdXtWXNvU8GYd9QBgZxxujDyTgKM9OAZc9e1dDY6ejoOvl1fNnm0yFY1TaApR/QhoMK/8G0UCGuQGEmUWKHK83jhA89z0gvoPDu1cfn1b864T1H29WZIRzc1iyzTgA+CmTqj7Lkeru6156xsVoy+cQk+fn44DJyHnQxTd1yBXRRk9bzpTsSrQ7/MoLvvJN/a/d9uSno5jLdQew40bOVghmFG4Md5MA4424UJA97rtvub6f71VPupcq9lSNttgNBLj8oZQUFzR/w6UU+ZVOeD2eV2B3u7ax/a9e/PvXI7OTuqxCDcuKDMON6Q2VICjbYacJ/jpHYte/8mjr35gtVUdLCwaPYfmyunDlFKbQ1ixXBByiDRzTl0RGPBiPXd7S8Pbyw68d+/TdAz5YlK8QzkkcEMSQwk42mfI4Wugt53c3uB0nHyttHz6THo4dywOnjRZIK7ojiHPxOw4lg4EYJI4mnfW7V95ff3h9bupd9DarLlhkohTgZk9+/pElS2AA27eVOjt3fW9p4699kr5qFkmc0HZR6TJ0nfEYngDzZUYmQeZrN6ZhEnSeXj1nk2/vr2nsw5vn4LGZrj1i6cG2VLyxYYacIyAz2zW4hro9HPnO3nstZ2FhZX7Cm1j5tCDAEWkyqU2j3HctV+7FJvjWE+CWRKvt6utpeGtX+7f/vv/6zNJGG7McfPFZNpuv8cY/oDkbAAcHRIhF0FXw21N2084HfWv2UonjaHPhEwJaikJ+oAjqdvRINfFD2ZXfSILF5I+Fz2kUP/akT0rlhyv2bCX6mKNDcD1N3CgqIbc4RzPJof+YOoEJx7eioNPl+FDlHSxqdgQnj77h5+oGPeJXxQUlE3Cg7qZ+EmmdnPWYYYjGRec/nMrbnfnsbaT2+6v2f3wZqoPJghDzVOAvNwVDbLCSqbplJTNNsAxKP5hBeR4OBGfSQDkDHpRYWFFyYzzf/Gd4oqpV5JGt+IZxlRqLGorr1zwmdjEmOMZEp/X4erpqFld/f4Djzud7ZghgabGBrDZ1sYsCa/lTqwhKphOly0min6MLCT42KAV2Kbzeb1Ob9Pxf+32utteLSqZOJ4++jRJmi16Efbv95/8rDsi++pzFX3mCM1kvXPkw7X/Vbd31eskc3H6D9pbhBvHJ7mfiv7upjSUjRpcHCD6xyYLa3PW6DBbVM0+4/yffKq88iPXmq0jJuOdf/J2vyjC/nBQk/fviyHRzva6u462N+96qHrng29RHtbUrLUx9cc3bljpsEISq8yKcLYDzkIC5Aw6bHNAzva5CrnZbC6c/pHrLykbefYVZmv5NAk6iy66PwBsV8fhrrYDj1Xv+uOr9GYyBpt9ntcWbe2s1NriiHMFcPSZtTlAhzZn0AE4ww7fOuP86z45ovLcKyzWkecEL0RN0kYnwYguaGP78MJLetl8277O1j2Pffj+n96mPAAZG8BmHxobYPMdSYCdtVqb+qa5XAKcO40+49qBQYc2Z42uAk77qj919tUfqxh1wZXWosrz6cEKslxQbPhOLwZNFKz4I7D9broL2fp+e/OO1TW7H3mPBMNgi75ojgBqvpCkYG64XAQckkW/sYlmCzQ6Ty2KoBeccc53Z5eP/uiXrIWjFpjNRTaD+no0FM1/2DWo6cIRb3D1eh12l7P5jY5TH6yv27cGt9cBsQg1wtDWvIl2dk5obeq75nIVcB4AQ86gs+nCoLNmV7V8YcnY4ikzvr3ANuKMz1mLqi4k0E3q+7nVu6OoIn+cOv9NUyJ4+ACfBKG3t263d9a9XPvh2jecPSdxg4a1M4BmyBlqnvaD1s4ZcyTc0ct1wHlMetBhi7CNziYM+6qmrzrtwtHjJi/6rK1k/OfoiblpAJ1hz0XNzpoai6AANTafu/uwvafh5cajG//ZcmL7KZIJA8xwiz7SoK1ZY+c02DQO1eUL4OJ4grZH0E6HRmetDsAZetE3T5q6eHr5mPPmWQurzjcXls8i0K20VFcx4iWYeA9JFpoyA4CmJatYI0JQu7zOjr0uZ8v7HU073zlW82w1dR7aGPAC5nA+0llj8z2HnDNFaAxhXb4BzoMMUtlvo0Ojs1bXA69qdEqHby4sLLeOm7p4Vln5tAsshRXnFxSMOJseirbgAhXPjAZvmrDYgn7/jRRuPjV+EGLUxbzRBSKWqdJ7RnChGKBPftAt9AMeZ/v7XR2HdzTWPLvX6eyAycFQA2jeGHBOY23NGhuNcEMUzA/HRyo/RhM6ChF0aHbRVhe1O0POceybiovH28ZNW/SR4pJJ55oLiieZzLZJJottPFY2BoHHWnWAT1Wr0owkUn18JJYoHv9xUQiQNd/roJfnNPi89mNed++x3p5jexoPb9zV29uAu4qAlDUx+ww2fI6Dz0CL9nWkzlD23HZ6qef2aKL3HmNl84VBZ83OQEfyOR98lDWOnjB3dFnFOZOttjGTLIWlk81m20RaMlBpUEw2Ay2QoRPARg1SffQXF7F9vtpFaOEgxbSrhuhDAV57gBZ+BBSf3e9ztXq99uMeZ/dRl73pWFf7vqOn6jfBhmYoRe0rwhsuLOZlu5p9tTv5/Gc4Ac7HEWMWN4ZW9AE6Q83Q8z6fHKKvQq+r10DmjrmoZEKx1Ta6yGItK7aYy7AiUvF4u+weV1evy37K4eip7yWzAmBCi4obwwyfta7oI8xAM8TYF/NwWbHevNXWNPYQNxwBF4Uggo4wg8q+CL0IuAg350Ec18H1oi0xjH3RMXiI4zBrVwZcDyxDy1DzPudnn+tjX2x32IQhfOmCEmBZMJDwGXQxLMYBbqSxz5AjDg4+b7wPH9DBMXz6fUCKOEAs+gwv+0gTw9jHBsd+cG+Y/uUDMUyHH3XYLBsGNJIvQq3PgwbEesQGGUDRR1i/Mez6eHEf9WJfOp0EWPi6aLkbQQIsLwYZ2aLFiekRqhwAJkPK8KJMtLhIdcr4PgnwwZECSU4Cejnq91G7Po7BFVvWx+n3xbwyHIcE/h9VLWRYHWXC/QAAAABJRU5ErkJggg==',green:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALgAAAC4CAYAAABQMybHAAAltklEQVR4Ae2dCXQcxZnHR3NoNDp8SD7kU7bxFXCchBhMYoLNmhCcOBBykGw2gYTkPV6AhGXD2sTZJQcJG3jsgw3hscuCsTEsOAQW1sbY+MAHxpYtHzI+5EOy5UMStnWPZkZzab9/j75WTWt6NKO5Z6r82lVdXV1d9e/ffPq6uro7zyBDIhXIi7DyngjLyWJRKhDpCYiy2pwoztrpxSwCb+d1bayFm9f1Yu3+cj2MAgOJH2bXnNnEGiHWppW8d999d/inPvWp6YWFheNMJlOR0WgswdLT06PElFdM+xbn5eWVQDXK76TI7vP57H6/v5PyOxFjobwuh8Nx4dixYye+9rWvtaK4ZqFVNY/TiGUIoQCfsBCbcjaLNVHgJRUQG3/4wx9ali1bNmXYsGEzrFbrdLPZjGUagTyNAB2ZCLXoh3CJoD/p9XqxnOju7j7R1tZ2/LHHHqtbtWqVh47pp0X8AaAZbPmRzvnAJzPXhRBhVoBeunSp7b777ruuuLj4xoKCghsI5s8TcPnpIBT9oNwE/D6Xy7Xdbrd/8Oyzz+5+/PHHndQ2LfA5D3suA85QGwmMPLLQ+b///e/nkIW+0WKxLKBlLuUXpAPQEbTB5fF4KmnZShb+g0ceeaSKLLyb9gPgIvQRVJVdRXIN8CCo77777oI//vGPt5CV/n5+fv5NdGrhK2dDsLvd7k1k3f/n17/+9frly5e7qFM5CXsuAM5QI4a1Nh4/fvza0aNH/4PNZvs2rZfRks2h2el0/u2TTz55dcaMGXuoo7DoolXPajcmmwFnsBWoKysrJ02fPv3v6QLxH2hUY1o2E63XNxqhOUkXqq+eOHHitblz557pBV2EXW/XjM3PRsBFsE21tbXXk7VeCheELhKzsb9Rw0cXqT1wYciqP37FFVd8SBX4aMlK0LPphKMvirWm2FRfX//lESNGLKXRj3m0LoOOAjQas/Py5cuPV1RUbKQiDDrDrrNX5mRnA+Aq2OPHjzfv3r3766WlpUvIDfl85pyG1LeU3Jd9LS0tT1x33XVrzp8/76UWAfKMBz2TAUfbFbgJbAuBfUdZWdkSuvFyZepxydwW0I2lo83NzQD9rwS69mZSxnUsUwFXXZHDhw/PmTJlytNksedknPpp3GCy6FV1dXX/OGvWrCpqpui6pHGr+zct0wBXLDZ1w/TSSy+V3n777b+j+R8/pYtHAC9DrwIO9xHD5c5XDF5fS0ya0MWo3+nwvrBx47nfLLlvKypj0DNmaDFTAEc7GW5zQ0PDD4YPH/4YuSMJmQMSExVpsPPxhjsMHt/FuLWkp8dwqb3dt2zhnD2vUKXsnwPytAc9EwBHG01YDh06NIuGtf5DjoyQGmHC4XMLwmwd/Caft2fnmXr3A3d8Zf9hqgXWHEtaQ57Of9pViz179mwrXeE/MnPmzF0S7sEDGuueJnPevCuusO76sPq6R2bPHm2l+sy0gKG0NZTp2jCG27R27drx8+fPf4lu1NwQ6wnKlf0TZcFF/bwe//Z9uxw/vvfuj89Tftr65ukIOI+QmE+ePPllGgJ8UfraIloDp5MBOFoB37zxQvdPvr5gP24SsW+OsfO0CenkoqhWe8GCBQWXLl36Hd1de1vCnTas9GtIXp5h5LgJ1re3H7z2dwsWjMTUYlwrpZXLki4WXIV73bp1E66//vqVNClK3mLvh1RkGcmy4GJr3B7/zkOVXXfd86PD5yg/bVyWdAAcbVBGSY4cOTKPbtqsJqs9QhRPpqNTIBWAo4U0l+1yw1nXd29duH8nrabFKEuqXRSG20yz/hZPnTp1rYQ7OpjTqTRNUhwxtsK69t3tcxZTuzDCAsOVUiOaSsBxbAhgoZl/d02YMOF1SttokSGDFSCabeVj819/v3LOXdQNCy04xynjLFUHVuGmu5K/HDNmzHN0ux2/eBmyQoEe84gRluc2V13zS+pOSiFPBeAK3PQQQj7NQ36CZgA+Kh9EyAqqgzpBQ4h5w4aZH6URlidwrmljSix5sgFX4F60aJGNXmzzYklJyf1BqsiVrFOgqNh0/5ubJr24aFEp3M+kQ57MCwAF7pEjR1rpBs4KeuD3W1l3NtOkQ6kaRQnXfZfL/+Y3bqz7Ed3f6KZyPIwYbpe4bEuWBVfgphbn19TUPCnhjsu5y6hKCgqM33pr4+QnwQAtSbPkyQCc4bY0NjYupXeQ3JNRZ0Y2Nm4KFBab7tlSdc1SqjBpF56JBhwuEI5hOXfu3N30rOS/xk0tWVFGKjB0mPlfN1bOuRtM0AI2EuomJxJwNBx/iix0QfkNupJ+mtIySAUMpSPyn16z5fPfICnYkicM8kQBznCbq6ur59Pt9+U0FAjYZZAK4J6+aczE/BffWn/1fJIjoXc8EwE44Ea95vXr18+gt0mtpjQmx8sgFVAVIEgKJkzJX/2fq66aQZmAHMzE3ZInCnATPRBcNG/evJU0t2SI2iuZkAoIChiNeUM+O6d45cLbxxVRNv7Cxx3weFeIHwwaar148eJTQ4cO/SmlZUiyAuk4Dh5Ogs5O3wsLPrfnQSoT9zHyeFpw/FhQn+Xo0aPflHCHO6Vym6hASYnpp29v+dw3wQ4tYChuhjdegDPc5jVr1kybPHnyM2IHZFoqMJAC48Zbn/nzi1dNo3Jx9cfjCbh54cKFRfS42Qrpdw90OuV2rQLwx6/9QvGKhQsVfxyQx8WKx6MS/EgUv5vmGTw5ZMgQeadSe/aSvJ5pPrgoj73D91/zr97zEOXFxR+P1YKrrsm+fftupNmBEm7xbMl01AoUlRjvWb1u9o20Y1xclVgBV6w3uSVFNN79JL3LLuoOyR2kAqICYKhisu3JBQvG8tBhTIzGsjNbb8vLL7/8C3oxz3SxoTItFRisAhaLcfqyP435Oe0f86jKYAFnuM2vvPLK5FGjRuHRJBmkAnFToLTM8tCfnpk5mSqMyVWJBXBcWFro6Zw/0Z+Vwrj1TFYkFSAFwNQX5w/5N0rGNCFrMICz9bZ8/PHH+MbkV+UZkQokQoGiQtPX/rb+M7f0Qg5WwV5UYTCAYx/zrbfeWkw3dJ6I6miysFQgSgXGV9ieWHjrqGLajV2VqGqIFnC23ua//OUv99PnriuiOposLBWIUgGLJa9iya8q8HA6Ax6VFY8WcJQ30Sewh9DrHn4WZVtlcanAoBQYXmr62fe+NwGzUnHdFxWz0RRm621ZtmzZT+hF9GWDaq3cSSoQpQImU17ZnfeO+gntFvWwYTSAo6wZN3XKy8vvjbKNsrhUICYFykZa7r1mwUjc/GFXJaL6IgWcrbf5+eef/wH53uUR1S4LSQXipIDZklf+m99N/AFVx4BH5ItHCjjKmehbObaxY8fiDpMMUoGkK0BW/OezZxdH9YasSABn621ZvXr1HWS9Jya9Z/KAUgFSID8/b+KjT02/g5IR++KRAK5Y73HjxuXT8oBUWiqQSgVGlVseoCnZfHdzQH4HKgDrjcX8xhtv/B1NqJqays7JY0sFLPl5U59bVbEQTNLCfOoKEwngGHs0013L78npsLo6yg1JUgAMjhlb8D0wSQvYBOS6YSDAsd30/e9/n54hHrpItxa5QSqQRAWKh5gWffWbY4bSIQF4WIbDbcQvA9vNS5cuvY2es8TVqwxSgZQrYDQabHffU34bNWTAIcNwgGObAjh9P+c70j1J+XmVDehVACyOLs//Dq0y4Loc621g59301FNPTSwsLPyiVFcqkE4K2ArzvvjPv52GIWv2w0P64uEAV6z34sWL76BfjF65dOqzbEsOKQAm5/9diWjFowZcGT2hx9G+nUO6ya5mkAL0WBsDzla8X+tDWWa+uDStWrVqBo19T+u3l8xIawUsplFp3b54NY7mik/703/MxNtpeTSlnxWHk64NKuCf/exn58uLS6086b8+3Pqg4WDNHw0O5yf9Gkuf9+sX6N3twXmaVWwMkUWv+Q7eLVShHk1mv310Kg9Vrt/h/PStQoN/PlVxhBYYa7AbVCwc4PQxzxHXS8ANhkZ7jaGq8W8Gh6ed9MuM4C2ebrD7Jhp6CIJsDr481/UGw4nnqY8MeFB3tYDjF6BY8KKiIjO9qeq6oNI5urL+1L8bOt2XM673PrPf4OjwZDXk/p6e68BqV1cXAx5kxUP54MgzrVixYpbJZCrNuLOagAZnItyQwWQ2GgppXlKeEec8OwON75V+/YErZlHv2A8P6qieBTddeeWVX5LuSZBWGbnCkDs7PQa/PyO7EL7RZI5HTCj+EhXaTwt7IKpfprXgintCBU3kf8+TgIfXNlO2AnJbicVAt7izLoBR2xDLPOoYW/CgP1eiBWf6TXRrPp/877lZp0YOd4ghhyUPNUKRydJYbaa5IyYU5l8+53BRP5hjxYprf9NYNz7zzDOfpl9GSSZ3Wra9vwIMORm9rArUn5Kbfzzt09QphV+xcyEt+Pjx42dK90SUKXvSDDksedYEwnrYyIKZ1J89tOhacN5gpLnfU7Om87Ij/RRgyLPJiFlsZjALC84cK/1GBgdswLqJZg9OzabOcwdl3KcAIC8oNuMtrn2ZGZpCHyxW0xXU/H4Xmgw49xLrRgJ8Sob2VTY7CgVUyLNgnLwXcIXfXgkUpvv54KWlpeaCgoKKKHSSRTNYAQXyIrPB1eXVzOLIrE5ZrcaK0lKbuaXFCbDZYCsuCfcEmcbf/va34ym2cqaMs18BhjyTZ/3TmKB17ncngV1Y8X6AM/XGq65SPsaZ/WdV9jBIAUBuLSSfnPFgIjIoHj2pCFO7xR6oFpy7YRw5cqS8wAw69bmz0gc5cMiwQE0uKrH0G0kRfXDFQbfZbBMyrGuyuXFUQIGc3p/Q7fSRT65O6YjjERJXVX6hCewqHPNRsILAFjyP3j2Iz0XIkMMKBCA3ZdwQosloBLsqyziFogXHBiNNkS3OhrFRdE6GwSsAyPPJkrvJkmeCHVeYNeUBcPbBlc7ziko9AY6XjMsgFVDmkysXnqAjAwIN54NdlWWkRQuOLuRJwCGDDKyA0ZRnsNrM5JOn/zi5yZzHgHPz1VEUZCjkS8BVbWSiVwGGXCEkjVUxGlXA1b85bMHVDAl4Gp/BFDaNIXe7vGk7uEL+iOheK0zzKAqkkxY8hQBlwqEBeX4BJmilZ2uNRuX6UeGYW8gWnNelD85KyDikAgy5uzv9xslNRvUiU217PwtOW7TQq4VlQioABRTIrTQzNc1MeU9eD9gNacHVPzper9dBH3mVj6tJlsMqwJB7yJKnyzg5vTXAITRaYZrHwdV8n8/Xpa7IhFQgjAKAnOZhp83gSo/foGVXGQfHD1D9EcKCh+mT3CQVCFKAIfe6yZKrFAUVSdqK39cjsqtwLfrgaEiPtOBJOx9ZcyBAbs7H3JUUd8mnWPCgn5l4QalskICn+CRl6OEVyMld8brp9VkpMuU9fj+7KCrkIS14v9fpZqjostnJVYDuJJIlJ6RSYMrBrK9HAVyFG71nC45MZZE+eHKhyLajMeQ+jz/phtzvy4MPrrIMbUULzoDbs0102Z/kKgDITRZj0g253+8Huwy40mm24KoCTqezBeZezglXJZGJQSgAyA0EOSx5MgLcfp+7p0V7LLbgTL2/tbX1tLaQXJcKDEYBtuSD2Xcw+zg6u8EuflHMs+KiYAVByTx58mSdvMgMCCL/j12BpEFO9Laed9Yxx70t72ELjnUF8DfffFMC3quOjOKjAEOeyMEVfOyqevtFLeD9RlH8GzZs6Ozu7r5E81FGxqd7shapAI1mwCen5zz93sT45H5Pz6UTey52ktb9XBTor1jv3o1+u91+RropkEWGeCoAyI0EebyHV8Bqt8t7htoKuEMCjn4AcqWAw+E4jQwZpALxVkCBnG7tK5DDZ4nT4nb5wawIuNJ09sFFC+7DSIq04PE+tbI+VoAhj5dPjiHCbrsXgNNTGMEWXBwHVyFvamqq48bIWCqQCAUAeQ8ZcJoBGHP1+KF0NHvALCw4c6zUG8qC+995551DNOkq9iPH3HRZQTYrgJuJmKQVa6CvOffUfNhwiOoRXRSFXwYcx0AGCvjoI7CX2tvba6WbAllkSKQCsUKuXGB2eWsr37twidopuihKs7WAM+Te5ubmSgl4Ik+trJsVYMgHMz0E/ndXm6eS6qI3E+m7KHwsxYLTiq+2tna3BJxlkXGiFQDceDe5EiMd6UIPzLU0OneD2d4FDKtBz4L7li9fXkmzs4IKq3vJhFQgAQow5NFUTYT696w5DwsuuieK/416QgGu/BLWrFnTSn54jbTi0cgty8aqgAo5rj0HWHB7vtvhqTnyUVMrlWYLDrhDAo62YQOsNvwZLw0X7pGAkxIyJFWBgHsy8CHhf9tb3Pj4q8IrxWBXhRs1iBYc6ww4fg1e8sN3ScAhiwzJVoAhJ1dc/2YnNaq5oWsXRQBcdFHU5oo3epAJwBly79NPP73npptuchUVFRWoe+RgwnXRZmh3YBQqu4OuMQuyiX0a6GQHCuhs1D1GX7VBKVhp7APgtfvSS4dcm1bUsQVn6x105FCAo6Diz3z00UedjY2NW6dMmXKL0ag19kHtiHil9nyj4b2dVYaOLvEVFhHvnpKCXs9XDUa3m44dpF1QW7TiB23UWdHdR+cw8DlDBlCgE/S30A5h9tOpLubsaG/r6JWnJ+gNrtbmrRdO7sYMQva/GXK1nVrAsQGaoCDMvufgwYP/N2nSpLgB/sJb6w0tHWhTZgV3t4teidBNjYbkkEhPem2/uCyjpt1fu127f7LLa4+vbZ+2Pdry2vWB9tdu1+6vPV6gvN/vMzTUHv8/Ku2hBaz2gxs1hTLLqIEB995///07aPpss661QS1RhEyEG93LtxbQKxH4+7gQPdLAZRGLad5fzOMyYoxyXEZMi2XEtFhGTItlxLRYBmltQFkE3ofTSmYE/w20v3Y7H4dj7fECrorP42mu2rZhB23VvcDEnuEAh9n30MxC5/nz59+LF+A4aKaGAOT5wbxpO6M9X9jOedqyqVjntujxo21Tostrjxfheldnx3tuu91JxWHBQ15goqpQgCMfFpytuGfTpk3v0PtSkJ/zAZBbLL2QMyRiDIUYCjEtlkllWmyTmNZrk1hGTMervF49YfL99JbNpvrat6k5onsCXvsFPcDhpuBXofjhS5cuPdzW1nZKWvGAfhaGvJ+cMiPRCoBBj8t16tCOTUfoWAw4WAWz/UKoi0wUQmGGHJW4aUx8TVlZ2YP0DR9sz/kAyBG8HsgjQ7IUAOD2jvY1dDwMa0F8hjsk4HoWHO2FyVet+MqVK9+hh5Hl2YQyvQGQm/PJXQkXcKcCge9YcFrJDPFftOVDVJFWWdH2Z4Dy9PpjT92R/e9QH8EiPAwwGtI9oXxdHxzb8ItgP9z90ksvNZ45c+ZdOf8K0vQFC42sKJAzwNoYRfmkiWltOV4Xy4hp3p5psdgHMa3XD7GMmKbyALKrs/3dMx8faKQkLDgAB6MhrTflRww4fi3uV1999QWy4rq/FlSYi0GB3GLJxa4ntc9+r9d/5tjHL9BB2T2JCXA0PsiKP/nkk7Vnz559X1rx/ueVIQ9z8a+OJMsygYGmaHTAXVdnZ+f7x/bsqO0FfEC4cZbC+eDYDmutuimU7v7rX//63x6PR/dPAnbK1QDITcoQYq/fDSHwp5hjMR3I7b9d70+3Xj7XPdj6Yt1f266B6htou7a+3nW6c9lTf/Lwf9PuuJ0suidhPYqBAEdzUAEcecVN+cMf/nCMrPg2acUhTf9goYtOk5ncFT5RKII0B07rbedykcax1hfr/tp2DlTfQNu19dE6Rk4c9o5th3d+cIxW2T0Je3HJ1UQCOKy1Cjilu9etW/c8WXGuQ8YaBVTINflydXAK+H007+TUyedpb7begA9MDuhJRAo4W3H8erqXLFlS3dDQsEtacVJDJ0jIdYSJMhvW29nVuevAtvXVtCsDztY7LoCjSWzF4dgDctfatWufkSMqkEY/AHIzja5gLjMHTgcm9AfyOQ9lOM3bo43FOsS0Xj1iGaQHCtG2D/XxPmKa2yPmiWne3uP3+Zvqjj9D21y0gD0wGJH1pnIDXmSiDAIAD7rYfOihhw7Su8TflnNUFH10/zPTRafJbFZOMp9ojrETp/mEinm6lYbZEG192vLcDr042vZp69fuH247psR2tDS/XbVl/UHaj613RKMnLFEkLgqXZSuuXGzigA8//PDT9GByK/6MyKCvAEOuX0Ju0SoAprzd3a3VO9Y/TdsY7oh9b64vWsDZF8cBXZs3b75UWVn5Z3nByXLqxwHI5c0gfYWCt8B6Nzde+HPj6dN4VhDuCZiL2Pfm2qIBHPuIVlyB/Pbbb3+THmurlhecLKl+DH9cHULkYuyfI45kwX68j5jmfcU8Mc3b4x2LxxDTescRy4hpoTwezXN1dVVvfeuVN6kIwx219Ub1gwGcrbhysYkGrFq16jGXy+WTrgokDR8UyE00iZNPKIojHWngsnr7D7Q90uNEWi7a4w1QHgz5vF5f3ZEDj1ETADdfXEZtvdGFaAHHPgw4flGKFX/00UePHDt2bDW9kRbbZRhAAYYcWMslWAMDPcxgb768mm7qYL631nqDvajCYADHARhytuLOBx544NnLly83SlclMv0BuZFGV2ToU6CH4HY7nI37Nr/3LOXicTSt9e4rHGFqsICzL66Oi+/du7f5tddee5g+f+KRrkpk6pvplr4CObsbORwDKBpy9pyuqX74YkN9M60y3FGNe2uVHyzgqIchV604DRvuI9CfpRtA2uPIdR0FFMjlU1L0pQcvjZo0PHvggw37SCqt9QZrgwqxAg5XRbXilHbdcsstK+vr63fIG0CRnw+GPFf9cbpbaejqaNuxZfXylWCod+G7lmAsJYDjDOLgWPiCE788x4MPPvgb8sc/kf44qRFhCECeez45/O5up/OTqo3v/oakwuvOwBBcADDFfFFycCEWC85HRCMwfIJfHBrnpBtATa+//vqvyB/3Sn+cFIkw4Ja+URxCzHKfHGaZ/tJ76SmdX9FrIJpoVeGHYrDEw4KUHHyIB+BoJxrDrorSSHrVRNWePXuegz8uIY/8BCmQG7P/zQVgAn735aYLz+3fsq6KFBLhjunCUlQ7HoCjPoY8yFVZtGjRcpqQtdGtvLhSPKxMh1MgYMkBefZ65TRJ0NDZ1rpxy2vLl1NHta4JDCaYijnEC3A0hCHnURU02rF48eJ/oYvOvRLy6M6ViVwVoymepye64yeytI8sd1dH+94tb6z4FzDSu/CwYNzgRh/iqSAAF/1xNNhBX4nouPPOOx+iByRq5KQsSB55YMizyRXHiEm3vbNm99o3HnJ2dHSQGgBchBsMxcV6Q+lEOHtonNjAPILcW1dXt3P+/PkLPth/eGgePqclQ0QK4L3synvBs2BKMmYIuhz2c/s2rf1ZY33tJyRAFy0MONzbuFpvCJwIwFEvQhDo5It3d3Z27naYCm6mGXWFPNE9UFT+H04B/vhAgPHM9Mv9fvpglNPZfGjnpntOHzl0lvqrhTuulpv1TBTgogVX0wcOHOiix7j2Dx899is0HJYvIefTMHCc1/uFjUwckcL9EHphpv34gY/uq9nzUU0IuGG5AXjcQ6IAR0MZbI6VxjfV17UVlQw5OqR0xEKah2GRkEd+TlXIIW2GGHK86tjtcjnqjx74pwNb38dteNFyx228W0/FRAIuHhOQq6BfqD1+0WIp2Dds1KgFNCRmkz65KFX4tAp5Bvjk8LndDkfriQN7fn5g6waMdTPcGPNOONxQMtmAq6DTnasWn8e1s7R8wvVkyEv4xKFRMoRXQDUIiiGnz16n4b8eGud2d9kbqnd+cC+9bu0o9chOCwBnuHEzJyF+N9WrhmQBjgOyBVchv9xwobOro3XbqPGTrjVZLGV8MaW2TiZ0FQhATlKyqrolk78B49z0HsGT+zatua/uyMHT1AKAnXS40fNkAo7jITDgStx++aKz+cLZD8onTZ1NryEeA59c+uUBoQb6X4UcBdPAJ8dwJt5CRTMDD+xY88YvGs+caqCWad2SpFhu1i7ZgAfBTY1Q1umdz+7zp45uHXfFjCn0AstJeUYJOZ+ggWLVXUmxKcesQHqWkm6/t2zd+saKJW0Xmy5T2xlu3MjBDMGkwg3tkg04jonQD3S60vbVVh/cPmbyFGu+rXA2+eRkyGGWZBhIAdYpYMST75H30Bg3fcqlp62p4eWNry7/N3rVWju1WYQbF5RJhxu6pQpwHJsh5wsN+nit13+quupA4ZChNSVDh881mkw0wiKtOcQaKEAnCJrMoMwIpJESj6Orlaa8Ltv2v6++QeeQLybFO5QpgRtapBJwHJ8hR6yCfuFUzQX6U7d5RPn4K8kvL5cuC6QaOKiQJ8EfJ2/bgItJR3vbwb1b1v3iaOX2Q9RCWG223HBJxKHAZP/+FMHSBXDAzYsCPV18dp06eGBjecVkk7Ww6DPSZVHO14D/sbsyYMEYCuDOpNfj7mlpOL9yw6oXf996sQFvn4LFZri1k6diOFpsu6YacLSef9lsxVXQ6c+d79ShqoN05/NI0TByWYxwWWjAQPrmYc96nz7xNeWBhxRofNvpbDl7rPpX2/73f97qdUkYboxx88Vkwm6/h+28ZmM6AI4miZCLoCvp86eON9ibWzYPHVk+mlyWKXBZMC7WdyI1vZKrvdqwrLEJArAxSoJvgna0XNpctXntkqOVHx6mWtliA3DtDRwYqpQHkJJOAe3BXFr88PCmSist+OKqjZZCpK+55bYvVEy78pcFRcUT8eRL3zAZbZWhnwIAM5bAw3/dXfaz9SeO/vve99fsovrggjDUPATI011xwPj8smJpeO++6QY4mhUwzwHI8Zg5vrQKyBl0W0FJSfENt/39D0pHj73LYrVayXWR1pwE0guBGYjRMaeOkNBDtc1NDSs/XLP6FVdnJ0ZIYKmxAGz2tTFKwnO5ozsQ7ZjIkC4uiraPLBJiLLAK7NP5vG63t/bQvkMOR8emoWWjx9Fr0CZKt0UrYd96nyvHtkM/xhwudkfsra0fHtz6/j/v2/zuB6S5OPwH6y3CjfMT25+KvubGNZWOFlzsINrHLgtbc7bocFsUyz7vq9+6oXzK9PsKCgsraE6L4rb0nVSxutxOByx5aA3Yz/aRn+1yOOobT598dte6N7dTabbUbLUx9Mc3btjosEEKXXkKc9MdcJYGkDPo8M0BOfvnCuRms7lg7uJv31Q+ruJOa1HxVLzcEv65BJ0lDB0z2LiAJD/7VNOF+pcr1/5tE72uhMHmmMe1RV87La222NNMARxtZmsO0GHNGXQAzrAjtn5x0Te/VD556p0FxSVX4Y1RmIorQSdlhKCAjfFsL1lse+eRptOnXv7ovbd2UBGAjAVgcwyLDbD5jiTATlurTW1TQyYBzo1Gm3HtwKDDmrNFVwCndSW+5uavXzNu8oy7CocMuRpfVgi8hiF3hxcDLgpm/GFilMfg6OjYf+H08ZU0MrKXNGOwxVh0RwA1X0hSMjNCJgIOZdFuLKLbAovOQ4si6PlXz7959tipM28rKhm2wGzNL8TrGHLlopShxoQo3Fr3drsdXZ1tWxtO1byzf9v7uL0OiEWokYa15kX0szPCalPb1ZCpgHMHGHIGnV0XBp0tu2Lli4eNKPrc/C8vKC0v/0phybA5NI5uogldivuSbePpGAkB3JifjU+CODrbqlqamjYc2LZxq73tMm7QsHUG0Aw5Q83DfrDaGeOOMBRinOmAc1+0oPONInZfxFix9BOmXjVq+py5Nw8rG/kVmp47lV+XFvDVM8+NUS11H9R0S91xqq350oYTVZXvnzt15CKJxQAz3GKMbbDWbLEzGmwRDE5nQ8ygIwbksOhs1QE54NbG5qu+cMO0cZOmXW8bMvTqgsLiWQS7FW95hc+ersAHA+1XXmRJlrqbXqxz2NnRvv/CmZMfHtm1/ST1F9YY8ALmUDG2s8WGC5IVYFM/lJAtFpz7wzH6xbADdF4AuBZ4xaJTvrKtoLjYOuvaL80qGzPx8wVDSq622Yo/ZTSbLLhbqjwzqsxPp9JKCMiXqBGaAMQ4UMD1xU0Y8jsMmM2HJ9ZpLprH6bQfc3V07m9uPLvv8J4dh112O1wOhhpA88KA8za21myxldqpfFaFbAWcT5IIOvx00VcXrTtDznkcm4aWlRXOuGbeZ4aXjfm0xVYwMT/fOtFsLRhnwsMYyvCjUQG/76KVD62NtVIHoNWWUiAmoHFRCJAVX5pi+oKdk+zzBbe7+6zH6Trb2tz48fG9O6vbm5txVxGQsiXmmMFGzHmIGWjRvw7dGCqc6UGreqb3J1z70VcAzjFbddGVYbC1sVhW+aFUzPzMqNETJ1YUDyubaLUVVeRbrRNMFnOZyWguzAvAj9fToZ6AmwPLjxUKCk1EMltoir30OJOjhyD2+b0On8fb7O7uPtft7Kq3tzWf/eTs2fr6mmr40AylaH1FeEOlxbLsfnCstCeb/2PNs7mP2r6hz+ICeNmycwwwGWqGnde5jBgjjUWsN4/cHfPQ0lFF9PidzVpUWFRgK8KMSIPL2eXo7qLRuvZWZ3vLxS5yKwAmuwgcM8yI2eqKMdIMNEOMdbEM78t1ckzFciPkIuDimQ0CkjYwqByL8IuAY7u4jcujPqS5XkoGpbEuBhE4TrN1ZcC1wDK0DDWvc3mOuT6OxePmTDrXARdPNGvBcCLWgsvrDDEgRzmOOT9UXTgW5wM6BIZPuw5IkQeIxZjh5RjbxDTWsSBwHFjL0f9Z8BztfthuszaIwy0i1NpyOIBYj3hABlCMkdYuDLs2X1xHvViXQaMAi6/Jlqs6CrBeDDKKhcsTt+tUGQQmQ8rwYp9weXp1yvxeBfjkSEFiU0Cro3YdtWvzGFzxyNo87bpYVqYjUOD/AZrbm7Ts1rpFAAAAAElFTkSuQmCC',red:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALgAAAC4CAYAAABQMybHAAAk/0lEQVR4Ae2dCZxUxZ3Hq8/pnhkGmOEQuQS5VCTxWHEDBlyNkciakMMkxujGuOvHO24IKCae0UQlKwmyroocoqtozGpA4oFiVAQU5IaRcchwDsPczNF39/5/b+bfVL/p7ume6bur+DyqXt31r2//5//q1XvPIJRLpgQMMVYeiDGfyhanBGKdgDirzYvsLLtIPguB0/lc7+vh5vNIvr68Oo8ige6EH6Vo3iSxjODrw1rcm2++2f+MM84YV1hYONRkMhUZjcY+OAKBgOZTXDGVLTYYDH0gNYpvIa/V5/O1+v3+FopvgY+D4tra29uP7N27d98VV1zRiOy6g06DcRyGr1wYCfCEhUnK2yiWiQYvSQG+8ac//all3rx5o/v16ze+oKBgnNlsxjGWQB5LgA5MhrToh1BL0Fd4vV4c+1wu176mpqYvHnnkkf0rVqzwUJt+OuQfALrBmh/hvHc8mfkuCBlmDei5c+fab7nllguLi4svttlsXyeYzyPgrJkgKPpBuQn4LU6n88PW1tZ1ixYt2vjoo486qG964PMe9nwGnKE2EhgG0tDWBx988HzS0BdbLJbpdEymeFsmAB1DH5wej2cTHR+Qhl937733biYN76ZyAFyGPoaqcitLvgEeAvX1119ve/jhhy8nLX211Wq9lKYWtnIuuFa3272WtPv/3nPPPW8tWbLESYPKS9jzAXCGGj60tfGLL764YPDgwT+x2+3fp/MyOnLZ1Tscjj/X1NS8OH78+E9poNDoslbPaTMmlwFnsDWoN23adNq4ceN+TBeIP6FVjbG5THSksdEKTQVdqL64b9++lyZPnlzVCboMe6SiWRufi4DLYJsqKyunkraeCxOELhJzcbxxw0cXqQGYMKTVHz399NM/pgp8dOQk6Lk04RiLpq3JNx04cOAbAwYMmEurH1PoXLkIEqDVmPV1dXWPjhw58l3KwqAz7BFKZU90LgAeBHvYsGHmjRs3/mtpaekcMkPOy55pSH9PyXzZ0tDQ8NiFF1646vDhw17qESDPetCzGXD0XYObwLYQ2FeVlZXNoRsvZ6Yfl+ztAd1Y2lNfXw/QXyHQ9TeTsm5g2Qp40BTZtWvX+aNHj15AGvv8rJN+BneYNPrm/fv3/2LixImbqZuy6ZLBve7atWwDXNPYNAzT0qVLS2fNmvUA7f+4gS4eAbxynRIwHN8ozDseFQZHTW9l4m/3BBa/8nnDfT97vKqBKmPQs2ZpMVsARz8ZbvPRo0ev6d+//yNkjiRlD0hvqUh3ecsrpwtD2+GEdcMfELUNbWLewNniBaqU7XNAnvGgZwPg6KMJx44dOybSstYf1coISSOKsy4tiJLa8ySPX6wvrxN3TLpX7KJaoM1xZDTkmfynPaixJ02aVEBX+PdOmDBhg4K754D2tqTFKKacPVhsOPEnce+kSQK/IjMdYChjFWWmdozhNq1evXrYtGnTltKNmq/3doLypXyyNLgsP49XfPhOpfjZzCcEbKGMtc0zEXBeITFXVFR8g5YAn1O2toxW9+FUAI5ewDY/UC9+PvrXAjeJ2DbH2nnGuEwyUYJae/r06bba2toH6O7a6wrujGGlS0eMBjFw1ADxetMT4oHpZ2lbi3GtlFEmS6Zo8CDca9asGT516tTltClK3WLvglRsEanS4HJvXF6x/v0vxHXfWigOUXzGmCyZADj6oK2S7N69ewrdtFlJWnuALDwVjk8C6QAcPSSTpa6iTvxwwm/EejrNiFWWdJsoDLeZdv3NHDNmzGoFd3wwZ1JuMlkGjBsoVlf9TsykfmGFBYorrUo0nYCjbQjAQjv/rhs+fPjLFLbToVwWS4Boto/sL14++ri4joZhoQNznDbO0tVwEG66K/nLIUOGPEW32/GLVy43JGAeUiKeqvsv8UsaTlohTwfgGtz0EIKV9iE/RjsAH1IPIuQG1SGjCAhDWaF4qHmBeGzwYIG3EaRFk6cacA3uGTNm2OnFNs/16dPn1hChqJOck0CJTdxaeY94bsZkzfxMOeSpvADQ4B44cGAB3cBZRg/8fi/nZjNDBpSuVZRow3d4xGsjHxT/VlsrXJSPlxGjFUlIWqo0uAY39dhaXl4+X8GdkLnLqkrsFvE90uTzwQAdKdPkqQCc4bZUV1fPpXeQ3JhVM6M6mzAJ9LGJG+v/IOZShSm78Ew24DCB0Ibl0KFD19Ozkr9JmLRURVkpgdIi8Zvqx8X1YIIOsJFUMzmZgKPj+FNkoQvK79CqyQIKK6ckIE4pEQsqHxbfIVGwJk8a5MkCnOE2b9++fRrdfl9CS4GAXTklATwiYRpVJp7bfb+YRuJI6h3PZAAOuFGv+a233hpPb5NaSeHkPGJCFSuXnRIgSGwTBomVb/2nGE8jAORgJuGaPFmAm+iB4KIpU6Ysp70lJdk5BarXyZaA0ShKLh4tls+6QBRRW/gLn3DAE10hfjDoaMHx48ef6Nu37w0UVi7FEsjEdfBoImh2iMX97hR3Up6Er5EnUoPjx4L6LHv27PmugjvalKo0WQJ97eKGLx8U3wU7dIChhCneRAHOcJtXrVo1dtSoUQvlAaiwkkB3EqAngxauuk2MpXwJtccTCbj5kksuKaLHzZYpu7u76VTpegnAHr9svFh2yQTNHgfkCdHiiagEPxLN7qbnKOeXlJSoO5X62UvxebbZ4LJ4yB5/muzx2RSXEHu8txo8aJps2bLlYtodqOCWZ0uF45YA7T68cfu94mIqmBBTpbeAa9qbzJIiWu+eTy9Wj3tAqoCSgCwBIETr4/OnjwsuHfaK0d4UZu1tef7552+nF/OMkzuqwkoCPZWA1SzGvXS9uI3K93pVpaeAM9zmF154YdSgQYPwaJJySgIJk8DgvmL2C/8hRlGFvTJVegM4Liwt9HTO78k0KUzYyFRFSgIkATJVCq88S/yOgr3akNUTwFl7W3bu3IlvTH5LzYiSQDIk0KdAXEEbsi7vhBysgr24XE8ARxnzlVdeWUw3dB6LqzWVWUkgTgmMHSgeu3Ky9oFeNlXiqiFewFl7m5988slb6XPXI+NqTWVWEohTAhaTGPnMLIGH0xnwuLR4vIAjv4k+gV1Cr3u4Kc6+quxKAj2SwIA+4qbrpwjsSsV1X1zMxpOZtbdl3rx5P6cX0Zf1qLeqkJJAnBIwmUTZ/TPFz6lY3MuG8QCOvGbc1DnllFNujrOPKruSQK8kQG/Kuple0Yx942yqxFRfrICz9jY/88wz15DtfUpMtatMSgIJkoDZJE5Z9mNxDVXHgMdki8cKOPKZ6Fs59lNPPRV3mJRTEki5BIb0FbdNOj2+N2TFAjhrb8vKlSuvIu09IuUjUw0qCZAErBYx4i/XiasoGLMtHgvgmvYeOnSolY47lKSVBNIpgWH9xR0lJcG7m93y210GaG8c5ldfffVfaEPVmHQOTrWtJEAbsca8f7O4BEzSwXxGFEwsgGPt0Ux3LX+ktsNGlKNKSJEEsJ121CDxIzBJB9gE5BFdd4Aj3XT11VfTM8R9Z0SsRSUoCaRQAn0LxIyrvyb6UpMAPCrD0RLxy0C6ee7cud+m5yzV50VIGMqlXwL0/Kb9nsvEt6kn3S4ZRgMcaRrg9P2cHyjzJP0Tq3rQIQGYKSP6iR/QGQMekeNICdDeOExPPPHEiMLCwq91VK3+VxLIDAkUWcXXnrhaYMma7XDw2sVFA1zT3jNnzryKtHekfF0qVBFKAqmQABFpnDUxRIvHDbi2ekKPo30/FR1WbSgJxCuBwcVBwFmLd6kinGbGLwHxphUrVoynte+xXUqpiIyWQKBoWEb3L1GdozXxsS/9u/Z2Wl5N6aLFYaTrXRDwr371q9PUxaVePJl/3nzef4uaN28S7hNHunQ2EOgSRa/r1rkuEXild1enr6unecJVHktd9OlwaOJp1LPddEApg92QotEANw8YMGCqApwktmen8K9cIURTI8kv810BdXGI72JR73LR9+ND5jvzOx9nD80u11QhVj1DxRjwkBr0gOMXoGnwoqIiM72p6sKQ3Hl64nv0fhGoPZ5Vo8ff7P5+v2jw+Eil5S7kfQKBC8FqW1sbAx6ixRGpd4gzLVu2bKLJZCrVJ+bjebbBzXNkoTsipfRQo0HTWRybWz7BWvqHkYMn0qjYDg8ZoB5w1uCmM8888yJlnoTIKitPGHIj3R3hyc0lHwCPLbRdRB4A56EF5yoc4Igzkf09RQEelFNWBwB5f3okJhfnE2MqNZumgFk6wC4gDzoZcKbfRLfmrWR/Tw7mUoGsl0Ao5DzVueEXmUyThxcW8heUeVDanMmAIwLnxoULF55Nv4w+Wg71X85IgCE3AoEccjScPr8ZderZNCSNX3lo8ioKk28aNmzYhFz8cyYPPF/DHZAbRKPXmzNrK6B6qM0ygbxP6WCOtaUjWYNzgpH2fo/JVwDyYdxmUuH9zWZN3eXKePuYjGAWPDPH2tD0GhwZTLR7cIzS4Jp8cvY/QN6PIG/KAU0OVouMxtPBLh0MuTZ3rMFBPRzOjQT4aO1M/ZfTEmDIc8Emt5s0wDV+OydNY5oBR5ym2ktLS802m21kTs+sGlxQAoC8r4nMFZp9DQAGIct8m9EwstRuh0XCw9DGqAfceP/992MrGrYzKJcnEjgJOdjIUhcQBbcPHQx2wXRwIGyDM/XGs846S22PzdI57k23AXkJmbAnfNm5dwUAn1mkbe3+ohNwRAVYgwcBHzhwoLrA7A0pWVxWg5xe5Wo8qQCzZjQAuNRs7rKSwhocAwHsRrvdPhwnyuWnBAB5H9LkLZomzy4ZFJmNYFfjmHuu1+AGevdgMScqPz8loEGuafLsGr/ZYAC7bI3A1x6751EgwkhbZIvVGjiLJH99QF5Mmrw1SzQ5mKVFcAAOpa3BjdnjkyD1BDheMq6ckoDQNDntQsQSYjY4ghzsBllGWLbBMQaDAhxiUI4lYCLNWEzmiqbJM/zBIKvByIBz9zUNzica+QpwFofyWQIMObGe0c4kAgx4sKeswYMRCvCMnsO0dY4hb/P5M/YZT7NJ0+AsI41pXkVBJCKUicLiUX4XCQDyIhNWyYP6sEuedEZE0+DcLwU4S0L5YSXAkLdrmjxslrRFGmOxwal3bLakraOq4cyWACAv1DR5ZvWTVlHArmaJcM/YRAn+zfF6ve2cqHwlgUgSYMi7rDNTASYs1b7PH5DZ1Zjm/gXH4fP52oInKqAkEEUCgJz2YWeMRU6Xv3p2NZWO1c3gCqfS4FFmVCV1kQBD7qS3aKX7LXE+v1/W4BrXbKJwxwNKg7MolB+rBAC5jd69Ql5anS8goMGDyhqdkS8otQQFeFrnKGsb1zQ5Qa5p8jSNwm8ImihByMNq8EC6/9akSUCq2d5JAK+H0zR576rpUWkwSyuXETW4Zq9QzQFlg/dIvqpQpwQYche9vDvVb7X1BgRs8CDL6JKswbUEAry1s6/KUxLokQQAeQFtQUz1HU96FzrYZcC1vss2uBbhcDgaoO7VnvAeza0q1CmBDsiFcPlTIxJQ7aTXoetbYw3O1PsbGxv/oc+kzpUEeiKBk5q8J6XjL9Pk9YBd/KSYZ81EwQmcFllRUbFfXWR2CET933sJAHKrZq4k9w4nelrldOwnLwg3wqzBka4lvPbaawpwSEO5hEkgCHkS18kB72v1zXrAg+vgTL3/7bffbnG5XLVms3lgwkaoKsp7CQByC0nBo+nRxIvD7ffXrjve1EI1dzFR0FoQcGRobW2tUmYKxKJcIiWgQU6gJ1qRg9U2X6CK+gq4wwKOcQByLUN7e/s/EKGckkCiJQDI6fUOCd9x2O7zgVkZcK3rbIPLGtyHlRSlwRM9tao+loAMOcf1xge8TT4vAPfREaLB5XXwIOTHjh3b35sGVVklge4kAMhhqngTsC0E9dR6fGA2BG70IZwG97/xxhs7aNMVgFdOSSBpEsDNxA5zpXdWuY/MjVW1zTuoowA8BHIGHIMA0Ej00Udga5ubmyuVmQKxKJdMCQByE/ENfd6Tf6C2xR+ofPFITS31UzZRtG7rAWfIvfX19ZsU4MmcWlU3SyAIeQ8UOYCt93g3keelI0R7o34ZcJxrGpx8X2Vl5UYFOESiXCokAMgBI3lxHTDkqxyujVQU2ps1eLDLMuD4MbAG9y1ZsmSTn1wwpwooCSRZAgx5PM3Qg3L+JTX10OAMN3OsVRMOcO2XsGrVqkayw8uVFo9H3CpvbyXAkMNa6e7AQ6DNXl/5W8fqGyk7a/CIgKNvrMFhz3hpufBTBTjEolwqJQDIAXd3DrDWuj34+KvGK/lsgweLyhockQw4fg1essM3KMCDslKBFEqAIY+mxdGdynbPBvIAuGyiIElz8o0eRLB6xy/Bu2DBgk8vvfRSZ1FRkU3Lnaf/VRaVCM/xmpwffSRlBijCuUjxyBsxLUJCpMfbkB39AvD6/jn8fufjh46wBmftHdJCOMCRUbNnPvnkk5bq6uoPRo8efbmRnphOhGvbWiGO/c9fhaeuORHVpaQOt+8rwlmCb7uHyC6k7UgpUctEKBStTEijnSf6iZfzRGhCyxJvO3K96Q7T42mi2nnig21N5dhByPY3Qx7snh5wJEAmmgYn37Nt27a/nnbaaQkDfP+dTwp3dT3aySrn9HtEu9+r2YYQUCw2IgbIeRk0lOO4cOmIk12q88ttI8x9jdR/fX79eXfl9en68pHG7w34xW5nzV8pv4cOeQ08pIpwahltMuDeW2+99SPaPlsfTUuE1NjNSTbCjSEVGS2i0NihD2KFG+U4L3w5jDQ4OY7zyL6cRw7LeeSwnEcOy3nksJwHYb1DXjguw2EtMob/uiuvT+d22Ne3h3iw6Az46he37PyITiNeYKJsNMCh9j20s9Bx+PDhvyUKcDSarQ6Q2wnyaNf4nMa3nTFWjsuEcXNfYu1fsvP3RCbQwLU+598a3W4HBaHBw15gou5wgCMeGpy1uGft2rVv0OskEJ/3DpDbjCYNWoZE9iEghkIOy3nSGZb7JIcj9UnOI4cTlT9SPdHiAeZ2Z93r5MnmCaK7uEiA40eCXwWo9sydO3dXU1PTl0qLd8iPIe84U/+nUgJgsC3g+XJJ8+7d1C4DDlbBbBcX7iITmZCZIUclbloTX1VWVnYnfcMH6XnvADmcKwDZKpcqCUBN13jbVpHnpoPNE+a1SzciaXBkRF1BLb58+fI36GFkVKhcpwQ0Td7lS4xKPMmUgFv4PG+3HXmD2pC1d1jzBP2IBjh+FSgIM8W9dOnS6qqqqjfV/iuShuSwsmJTkEsSSV4Qa9+1Pseb77ZWVVMr0OBgE4yC1bAuVsA1M+XFF19cTFo84q8lbAt5EKkgT80kuwMB/7q2I4upNTZPegU4eh2ixefPn1958ODBd5QW7zqhDHm0q3+V1nMJkPIW9f72d149UVHZCXi3cGOWomlwpENbB80UCrteeeWVZz0eT8Q/CSiUr64DciwhnnQcjnbjArk5PV6fy3KL+va6q6+35fX1d1dfd+n6+vjcL/yBjx3Vz1J5Fx2yeRLVougOcPQHFeBiUzNTfvvb3+4lLf53pcUhmq4ON4IKDB2QY3Lg2JfDPHFyHMLxOq67p/X1try+v93V1126vj6cd9jezr+vaCrfS6dsnoDJqHCjbCyAQ1sHAaewa82aNc+QFkd55cJIQA85w5cKH91hiORwKtpOVhs+4nij89gzNB7W3oAPTHZrScQKOGtx/Hpcc+bM2X706NENSouTNCI4QG4lTZ5qx3AzbGif41Ldl0S0B+1d73dtWNy4ezvVx4Cz9k4I4Ogna3EY9oDcuXr16oVqRQWiiexOavKTiOEyC44vtzisRXbGcxznicfnsrHWp8/P5SL5+v531zd9/fry3aV7aOVkk+P4QsrnpAPsgcGYtDfli8lEQT4ADi3OgLtmz569jd4l/rraowLxRHY2TZPjY6kd/5CTJ1kOR0qPXHP4FK471vr0+blcJF/uc/gehMbq69eXj5buoy2xR31trz/duGMblWPtHdPqCfciFhOF87IW1y420eBdd921gB5MblR7VFhE4X2GPHyqig0ngY49J97GxU27FlA6wx2z7c11xgs42+Jo0Pnee+/Vbtq06U/qgpPFGdkH5FhdUS42CeD5qb2exj997qzFG6tgnoC5mG1vbiUewFFG1uIa5LNmzXqNHmvbri44WaSR/QLaZstLiJyLrXP4sRwox2XkMJeV4+Qwpyfal9uQw5HakfPIYTk/tHej37X9vuMbX6M8DHfc2hv19wRw1uLaxSY6sGLFikecTifegYg6lYsiAUCO1RWeUGRFOFbHeSOV7y491nZizRdve93lB0Nu+qD8O22HH6E+AG6+uIxbe2MM8QKOMgw4flGaFn/ooYd27927dyW9kRbpynUjgSDkeP+HOkJkEKBfwCF/68oXmvdgv7dee4O9uFxPAEcDDDlrcccdd9yxqK6urlqZKrHJH5BbeqRfYqs/G3NhzftEwF39ZNPORdR/PI6m195xD6ungLMtzsuGzs8++6z+pZdeuos+f0JLl8pUiWUmGHL82c73A69hcwm/5/3WQ3eVOxrw2gWGO651b73cewo46mHIg1qclg23EOiL6AaQvh11HkECgNysNDltdPKLfe6GRU837d5CotJr7x5rzN4CDlMlqMUp7Lz88suXHzhw4CN1AygC0WGi8x1y3NCp8To++lXN+uVgqPPgu5ZgLC2AY6rQOA6+4MQvr/3OO++8j+zxGmWPkzRidJq5YuiNvomxoQzLBru72e+pWdS46z7qWjsdYAgmAJhivijYM5cIiaITWD7BLw6dc9ANoGMvv/zy3WSP0zeGevzjo6ryy2H50EKQR7pNnmvx0MvugN/7vuPw3Vucx47RbGv8kA+WeFmwVxAkAnAQjM6wqaJ1kl41sfnTTz99Cva4gjz2OQLk+DBTrjswAbt7r6fhqacbdm6m8cpw9+rCUpZdIgBHfQx5iKkyY8aMJbQh6123Gz9I5WKVwElNnrurK16C+4i39d05NeuXkFz0pgkUZkL+9CcKcMwdQw6acaGATrfPnDnz13TR+ZmCnKQRh4OpYs5Rm9yjXVS2f3ZX3YZfk0g0TsjnZcGEwQ1xJxpw2R7XIKevRJy49tprZ9MDEuVqUxZEHrtjyHNpjRwrJvU+R/nDjZtn13scJ0gaAFyGGwwlRHtD0snY3obOyR00EOTe/fv3r582bdr0pmXv9MVXbpWLTQImklWHQGWRxlY203IB7kaf69CC5p037XDU4osCbXQw4DBvE6q9Mf5kAI564UJAJ1vc1dLSsnFUZctltKOuUEHeIaRY/gfkcBBotq6k+KnzJwKe+mUnym9c13roIA1FD3dCNTfkBZcswGV1Ewxv3bq1rcBk+Xycpd836c+vVUHeMQmx/M+yCgozlkIZkoe2mYrWgKf19ROVt/y55cty6pYebmhuAJ5wlyzA0VGeC/a1zm9z1jaVme17hluKL6HVAgtPXMJHloMVsqxCBJrh4+yA292+tv3Ifz7btAu34WW4E7beHUkMyQRcbhNzEpyXTY5jx+kJly2jrSXTSZPbeeLkAiocXgIsq6Aww2fLiFjY3Cf8nsbX2/bf9mzjLqx1M9xY80463BBCqgEPgr7VWdvQbvCuH28tnUo2eR+eOHRKuegSCMqKTHOY55l44F0mDQHn0eXNX9z8yomKPTSiVjoAOMONmzlJsbup3qBLFeBokJVOEPJyV2PLUW/738+2DbjAZjCV8cVUsHcqEFECgDwoyIi50pOAde46n6NiYePuW9a2HfgH9QJgpxxujD6VgKM9OJ4XzT/gOeHY7W5Yd65t0CS70TRE24nRuWrQkV39H0kCDHmmrK1gZnH7/ZjXsfWRhs23b3HUHKW+682SlGhullmqAQ+Bmzqhndd6He5PHDUfTC48ZXShwXyagpynp3ufzRUIMp0OuwLpWUq6/d72wd21G+fsdzfVUX8YbtzIwQ7BlMINeaQacLQJ1wX0Fr/b9zfnwQ/PKxhUUGKyTjIJo4Enr6OI+j+SBGQ5YcU81Qfgdga8gQpP0/O/qP/4d41eB77yK8ONC8qUww15pQtwtM2Q84VGwEsbyN9srdo60FRYPsRin2wxmOzYS4AHc5WLLoGT5kr0fIlMxY5AvL+k2e9ufK/98Lz7aje9SnPIF5PyHcq0wI2xphNwtM+Qww+CvsFRfaTa2/beuILSM+0G0ynKZIGounephJxNkhpf+7aFjTtvp5WSHdRDaG3W3DBJ5KVAzHHKXaYADrj50KCv8rS0rXFUvXtOwSBTX5P1K8pkiY0NNleSSRNu3sAkKfc0L7+j9sMH97ua8fYpaGyGW795KrbOJyFXugHHkHgu4DPkmjanP3e+Na1V2waa7buHmAsn0/ZRu7YXQ5ksUVE4adIlducKcU0mCW7euBvWOo7c/UDtxr90miQMN9a4+WIyabffow5el5gJgKNLMuQy6Fp4g+PY0cNksoyylgymz4SM7nioS9nmurkMOT0JeUh0j05ga/toiuj78OKQr/W9RY3b57x64stdVBlrbACuv4EDJZV2l2lXb+gPrivxw8OXVgvosNFhp6MQ4TvKzvnni+yn/rLUaB2BJ1/4TzKlKRdGArCVe+PY1m70uw9+7Kz+wx/rt26g+mCCMNS8BMjbXbW/vr1pM5FlMw1wjA19wgHI8SVmKx2AnEG39zfbiu8vu+CasdZ+19HHWAvM2ESqzBYSUXgHDRwv5rxC0ub3uCrI1n6w/tMXGr1OrJBAU+MA2GxrY5WE93LH2xQVTZ7LFBNFP0IWEnwc0Aps0/mcfq/3rbYDO+r9zrUjLMVDaePWCGW26EV48px//Kw5ovl4wxSbI/Ty+Y+fa97zq0WNO9aRzOXlP2hvGW7MT0aYJCdH3RHCWDPZoX9ssrA2Z40Os0XT7HMGnP/1C2yDbulrtI7E64nx7lae1EweXKr7Bq0cybGd7SI7m9a1D3zmqln0WN3nH1J+1tSstbH0xzduWOlErjhSgymKz3TAWQyAnEGHbQ7I2T7XIDebzba7+p1z6STbgGv7GwvGKNBZdNF9GWx6J/eXO5x1z/++aetaejMZg80+r2vLtnZGam15xNkCOPrM2hygQ5sz6ACcYYdf8Kuy8y86zz7g2jKj7SwFOkkkjJPBJlNv9xZH3fOP12/+iLICZBwAm31obIDNdyQBdsZqbepb0GUT4Nxp9BnXDgw6tDlrdA1wOtf828rO+afJtkHXDTLZz7XiNQxUBIXz1XwB1KASa9n0Rilx3Of4fJPz+PKF9Vs/o2gGW/ZlcwRQ84UkBbPDZSPgkKzGKfmy2QKNzkuLMujWG0rPmnRhwZBvDzbbp9sN5kLAni8XpQy1n9AG1I6At51edPnBRlf1G4sbduP2OiCWoUYY2poP2c7OCq1NfQ+6bAWcB4D+A3IGnU0XBp01u6blh5qLi27od8b0Mdb+3xxosp9PoJvwch3Anmvr6Vi/BtRegprA9tX6HJu/dDe+vbhp7wf0RincoGHtDKAZcoaal/2gtbPGHKG+dnHZDjgPSA86TBi20dmEYV/T9FMKTx00q3j0ZSOsfb5ZYrCO0UyYLNbssqbuhBpfS/jyoLvl7f9r3f/O+vajx0kmDDDDLftIg7ZmjZ3VYNM4NJcrgMvjgTbHuAA5NDprdQDO0Mu++Yf9xo2dXDB4Kmn1c/uZCibShWkBPi+CR+gy1ZSRgcbmJzxJQ0t8riafaxdp6883uWo+Xtm0r4LGDG0MeAFzOB/prLFhguQE2DQOzeUa4PK4WKsDdD4Ath54TaNTvJbWz2wr+FHfsRMnWErPG2iyndvfVHAGwW7BBSqA7/jX0QwLL1kXrYAYjg1f+LhMBNC4UCSoPfSmqL21Pufn5Z6GLS83V+xq8jphcjDUAJoPBpzTWFuzxu6ongrkkuM5yqUxyWPB+Bh0va0ua3eGnOPYNw21FRX+oHDcV06zlpxdQvtfCg2mEYVGy1CrMNpZw7Mvwy93AmG9oBlafT6GGPYzQGbfLfyOdr/nSHvAd5B28x2scp/Y+Wr7vu1HnG24qwhIWROzz2DD5zj4DLRsX0fqDmXPbqeXe3aPJnrvGXT2WavLpgyDrfflvNoP5eLiYYMmWctGDjEVj+hrtowsMliG01cayugppEK6k2qnbWCFlNGMxhh81vRsXkAbgywizUuvWWinW+QOT8DX7vL76tsCnkPNXs+Bal/rwR3u+gPrWg/DhmYoZe0rwxsuLOdl84P96BLLgdR8Apynq4O5DqWKMOAFtLIPwBlqhp3P9Xk14DvrCKmbzB3zSGtx0RBjob2fuaCoj8GKHZGiJeBub/K62qr97Y4D7tY2MisAZofyPukzzPBZ68o+wgw0Q4xzOQ+X1ddN2fLD5SPg8syGAEkJMqx6kGXA9WlcDvUhzPWiLTmMc9kxeIjjMGtXBlwPLEPLUPM552ef62NfbjdvwhC+ch0SYFkwkPD14PI5QwzokY99jg9XF1rheEAHx/DpzwEp4gCx7DO87CNNDuMcBxz7HWd5+j8LPE+HH3XYLBv40Q4Zan0+NCDXIzfIAMo+wvqDYdfHy+eoF+fK6STAwtdFq9MIEmB5McjIFi1OTo9QZQiYDCnDizLR4iLVqeI7JcCTowTSOwno5ag/R+36OAZXblkfpz+X86pwDBL4fwN/IZwMBwH5AAAAAElFTkSuQmCC',yellow:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALcAAAC4CAYAAAChOH1KAAAlaElEQVR4Ae2dCZhUxbXHTy+zL8ywDDsSVhEVJQoCkoSIIr4kvohLxO2ZfC8an0mQrCQm+uJ7qHkv5hE/xSQaNokBogkxigaUuLDIpsiOMA4MOwyz7zPd7/yLOZfqnu7p7umeXut83+2qW7du3apTv3v63Lr31rWRkUhowOZViPc6Nutpbq/8WPVO8173sYtJ6kgDusI7yme2nYdTdIZQj0NH1vrgwYNtc+bMyb344otzCgsL87KysnLT0tKym5ub6+rr62vKy8urd+7cWfv444/XlJSUAGSB2VfoKw3HM9KBBqQzOsiSspsEXgmhCMTtDGT2TTfdNDwvL28kQzvC6XSOcDgcQ2w2Wzfenme323M5nuN2uwPql/O5OF+dy+Wq4X2rOV7Z2tpa3NLSsp9Pgv3V1dX7XnnllU/4RKnj7S5edNARl4WjRnQNBFS+njnJ4wKxHtp37NgxpG/fvlPY6l7CAI/kZTgv/YMBN1L64hPAzcAf5eUTXvax9d9x/PjxtZdcckkxH0OAF8gljNThE7acVIdbQLZzDyJuX7du3YChQ4dOycnJ+QJb5M+zFR4Qr73L1v4IW/h3amtr/3nw4MG1kyZNOsJ1FdglBOwpKakItwfQTz31VN4dd9wxnd2LL7J1/hzDPCxRSWDYD7BVf5fdmbeXLl26avbs2dXcFsCdkqCnCtwCNEL7gAEDnBs2bPh8QUHBnenp6TdyWi4vySY1TU1NKysqKl6cMGHCO0eOHGnhBuqQJ71FT3a4FczcqQgdu3btGtWvX787MzMzv8YWun+y0eyvPWzRjzY0NPzp2LFjL44ePXoP52vlRbfo/nZN6PRkhdvyoX/7299245GNe9iHvoMvBC9P6N6KQOX5gvRD9tGX8gjMovvuu6+SixRrjjCpJJngRluwAGz78uXLu0+dOvXbDPW3eL2QFyOeGihnyOevWbPm6VtvvfUsbwLcAnpSuCzJALcH1KtXr+4zduzYWbm5uf/OnZWMvrQnouGv1bD8ftu2bf937bXXnmgDPCkgT3S4lZXmDrGvX79+0EUXXTSbRz3u5fXM8Ps85Upo4FGWBbt3735q4sSJh7n1YskRJqQkKtyoN8B2vPzyyz2uueaaX2RnZ9/NN1bSE7IX4qjSfMOoqa6ubvFbb7318xkzZpRx1XDxKZY8jmoauCqJBjfqi8WB4bzNmzf/W/fu3R/j9R6Bm5o6OWyuErK1fMiKwuhfJ8VNZWUVtT/77MTHFrYNI8oIS8L444kEt7ggju3bt182bNiweXwHcXwnuy5pdwPYzrofMdiR8SaaW9wffFLc+N3RE/7xEStNrHhkCu/iXkgEuFFHBfb8+fMLb7vttkf4YvGb7II4u1g3CVm8vXEpORtfiGzdbbaWmpqW3724ou4/v/WDj8u5cMAd965KvMMt1tp56NCh24qKip7gmy99IttzyVWao3ERYekKcbnpxKmy5h/3HbVpGZcvdzzj1ooDnngUnHQOLI8++mhBZWXlC3369FlowI5tV9lt1KdPz7SFdaUTXnj00REF0kccxqWRjMdKWWBv2rTpUn7YfwnfWRwZ225NnKN3peXWtdDion0799TedfkXPvqY0+GLywWnni2m8Xiz3KgPLLbz6NGj3xgzZsw7BuyY8uH34E47jRxzUc47J/eN/wb6ixf0W1zxFC+VEWvtnDt3biE/ybagZ8+ez7CysngxEqcasNkoq6i785m6w1ctmDt3GB5xEMjjwiOIh0qgDjjJMG49hp9ae5Gt9fA47c+4r1a03BJvRbS43J/s3FN3R5ubIhebMR0Tj7XlFoudtm/fvmsuvfTSNQZsb2wSY91ptw0fMzrnrYObr7iGa5zGC9yUmBrPWMItYGOY7xZ+W/wvrIw8XowkqAa4Q/M+MzjjL0d2jL+FmxBzFyVWcOO4OLPT+AH6b/ELuAs5bp4LYSUkujDg6f37Ohee3ncVHjUWCx4TzmJxUAE7/eTJk4/06NHjKb7bGIt6JDpH8Vt/N9l7dnc8dfaTcY9wJWG0YjKSEm2oFNh80ZhRVlb2NL/D+KP47SFTs3A1UFiQ9qOakglPjx7dKyMWgEcTbgX2+PHjs3j6hCX8fMjXw1We2T/+NZCTY//65jeGLRk/vjuGdaNqwaN1NavA5salnz179jl+9evO+O+WxKxhrIYCA2mrtq71xdwLNt7P+Zp4kacLA+0W1vZoWG4BO4197McM2GH1V8LunJPtuLP84FWPcQOidpHZ1XCjfCxppaWl32Ef+6GE7R1T8bA1UJDveOjUnvHfAQ+8CBthl+uvgK6EGy6PAru4uPj23r17z/VXCZOeOhro1cs5t3T7uNu5xQJ4l7nGXQU3KqzGsfmF0+v79+8/P5oTR6YOKgnYUjfZ+vdLm7/vg7HXtwEOTroE8K6AWyy2kx9ZHTdkyJAlbY1IwJ4wVe4KDTAgacMHZy3Z9vbl47h83MkEhxEHvCvgRpnOefPmFfF49lLMU83rRowGPDRgs1POpRdlLZ33xJAi3iCAe+QJdyXSZ4sCmyuVwY+truA5RKaFW0Gzf2gaiNehQH+tqKt3vZkzaAOeRWnkRZ4m9Jc9pPRIWm6cKMrPPnz48HcN2CH1Q8pmzs6yTzux+8rvsgJkiDBiBjdScAvY8LOv4hd58UyBEaOBoDRQ1DPtEfa/r+LMEX2SMFJwoxzHE0880Yv97AXsZ6OSRowGgtIAeLl0VNaCJx4d0ot3wL9/RLiMxF8AKgKY4WcvY3dkOseNxEgDieZz62qqq29dlTNo422cFhH/O9wzBCeHgptfOHjAgK13lYmHqoHsLMf0ozvHPcD7yehJWMY3HLgtsBcvXnwB34F8ONTGmPxGA94a6FuU9vDiZy6+gNPDBjxcuNXoyA033PA4+01mLmzvnjLrIWuA36jP/dcb8h7nHcMePeks3JbV3rp167X8sVF8NMmI0UBENJCXa7/xo3fGXsuFhWW9Ows39nNed911uRdeeOEvI9IiU4jRgKaBi0Zk/vK663rDGxDAta3BRTsDt2W1n3/++Vk8jfDQ4A5lchkNBK+BNKdt6OJfD5rFewjcIV9chgq3BTZ/UGkY36wxz2cH318mZ4ga4Js7Dy1fMHpYZwHvDNzqIpI/1fEkX0Sab8+E2GEme/AasNltmdO/kP8k79Gpi8tQ4Las9rvvvjuBXxe7LvhqmpxGA53TQE6O7bp1r4+RW/PgNWj3JFS4ldXmW+zfY6vdudqavYwGQtAAOONb89/nXUK23sHCbVnt119//TKelmFqCPUzWY0GwtJAbq596j9eueQyLiSki8tQ4IbVdl555ZWzOTRmO6zuMjuHpgGbbfxlOeAOcIPDoPgLBm7LavM3H0fl5+d/KbSKmdxGA+FrID/P/qWXXxw1iksK2noHC7ey2pMnT8bQXzD7hN8aU4LRgIcGbPYpV3UDf0Fb70CgitV2LFq0aAhb7RkexzMrRgNR1ADPezJj0fyLhvAhYWzBbofuSbBwO6dOnfogX7miUCNGAzHRAA+cOP5lSt6DfPCgXJNg4HawO5LDs0XdFJMWmYMaDWgaKChw3DR5ck/MqBDwwrIjuMUlwTQN0/lzHvjuoBGjgZhqwG6ngmfnDsTbXgGtd0dwY5u6kBwwYMCt5qZNTPvUHLxNA+BwYP/0W3lVLiz9MuxvA6w2FsecOXN68fPaX2wr2wRGAzHXQF6O44tzZlsvEwur7erVEdzY5rz77rtv5s9S49anEaOBuNCA3W5L+/rt3W/mynTomnQEt3JJ+JvrmA3IiNFAXGmgX1FawC+m+YJbzLxjyZIlI/mNdtzTN2I0EFcayMqyXfbS7y4cyZWSURNw6yH+4MYOjokTJ95iLiQ99BX3K271Tx331Qy7guBy0vg8WG/FKoft4IbP4i3IpPztwsLCz3tvNOvxrYEW23iqKPs9VxKfnUlc4fncPSrvtUpYb2lygU+/frc33JZLcs899xSwS3KpxxFSdMVWv4dsle+Qzd0c9xqAGevm/AJVVBSTy+ViCDwhQQN8JLVLc1P7/bz39VXOuTye+/rK5zvNcz+U1ZG4XO5Lb5teWbBs1QHMUCXsWoV4w42yYLUd99133yQ2/dBVSoutbhc5997MmkscS4hOK2hxU1mlb7h9daj3f7r3uq99Yp3GJ67jnqktk5atopVcF3Dr0UnecKNNCu5+/fpNNv42m4PyN8jWdDTW/Rjy8TF22yPLTWeriFyWLQu5mLjeAbD26eaezMHfeQG3SLJaiwRdsK7g5icAJ+kbUjVuc+OziYkpPD0Cdc/nDk0EM9xJFedn2ybyrvizEnatknS4oQIsjlmzZvXMzs6+0MplIgmrAQHcwT0tHZxMYXaGe9QDX03vCW55kaap/vIFt33mzJlXt2VUmcxPYmsAgBfmsWkD4Nz9SbbYvnq1G7yC5Q7hRgYH35W82vjbiQ20d+11wL23JfI6OO1TSIBbXBMArsTbciu4eU4Sc1dSNJREoQKcZ9+DBY+U4F8AIv8GEleJUfrJyiTw2g5uGS0R2hXcPL79mSjVyxwmyhpwwkXJdVNFTeRGUQRwNEXiEkajedkZBF4FblUN/nHr5zDi9p/85Cd92NSzh2YkWTUAwAtgwcWkJXhD+UTKm3VLWh9uhmJYmiNwo5lY7Pw8yXDZaMLk1YAArkZRuOdhaRN5mXSxDdyCZ2FZrUgPKrj55s1QczEpKknuEIB347cRYcGFiEQMUf++3V1DubcEbtVx7Sw3v3UzLLm71LRO14AADqudyJKbaQO3ArdqjQ434naeB3CIsdyJ3M2h110Aj+QoSui16Pwe4DUnm4ZwCYphDhXcGC2Rcxahg0dKkMlIimkAgOdnu6mqzvdTg/Gujqx0G7jFiInFM0iHIME+atSo9MzMzAEqxfyknAbOAc4gMBWJdnGZke4eMOozmengmBcFuA63bdq0aYV4jDDletU02NIAAM/LOge3lZgYEceUMa2FXFWAbcEtKzaen4RHP42kugYE8M6Mg8uFqVh+6FLSfOlVtnU2v+yHcFCRG/xaPOt3KG29evUyN2989UAKpgHwXH4evKZee0A6SD0IsMgucQl9FaFvk7iEgfLr27vnucGvwK38E9lu42FAY7lFGyYkZcGz2YkFLgkg+TkOsdyqtjJaomjnZ7gN3AnQidGsosOhWXDrHZdo1iC4YwHgzEzfbglKsBm4g1NkquUSwGsb4neYEG5MTjp5WG6P0RIeBswxN3BSDd3g2gvAc/irox35wsGV1DW5UK/0DDemNlZeCI5ijQkikT91jY1GjAZ8asAX4AI7Qj3us4BOJOpl6nFfRaU77AI3Ntv00RK+gDBw+1KaSTuvgXOAu6mOZwqRuUcEOuSSuITn9+x8TC9L4hLqpTqdynIjCdbbc+6t1tbWFiQaMRroSAMAnF/MpXoA3lHGKG9rddk8+BWfG9WwNTU11fqaoSjKdTSHSwANAPCsjDYTGQf1xb9IYzPVclWU1UaVdLipoaEBG40YDQSlAR1wuYrzDlGQRZuPUmWb937+1r3L0/fnuQM9+NXhdhu4fWjfJHWoAQtwocwrtyQHC6vX7u1WvctDBkmrb7YBbstTErhVQl1dHb82asRoIDQNAHA8j+frIi+0ksLLzRe5wq/iGaMlQrq7oqLCw6yHdyizdypp4JwFd1MDzz4noyjRbD9OrMpaD8vtlqFAAO4uLy8X8qNZL3OsJNEAf6uGLfg5wKPdJMBdXuMCv4plHF/cElWX06dPV5vREqUK89NJDZwDPPouCv4tTpVTtV5tgVvRvnv37hoDt64eE++MBgB4Bs+hDGvqvaA8pIlIXPIhXdIkjx7KNskvIa4q9xyyA24Py40ViHvlypXVPNbNMzobMRoITwMW4F7FeMOJzZKmxwVa71DPg7hIczNVvba+SdwSJFszTgntbh4xKTHWW1RmwnA0AMDTYcG5kK5ccAXLIyUlfBiLY9Rb3BLEscFVW1tbghUjRgOR0IAFuOaKRKJc7zJqG2wlnObiRTwRBbfQjg0uHg781Fhu1oSRiGkAgKfxuJy3ixGpdVS0qtb9KQeKYQ4V02K5BXA3j5gUI7MRo4FIakAAj2SZelmnKuggr1scYxvg1hNaecTkoLHcUI2RSGtAAI+UxZZyUM89h1wwyviamcWzWG5sVyZ94cKFn/L3CxE3YjQQcQ0AcCfPjAMwIyVMq2vhasenXJ5iWMoVuIV2165duxp4xOSYZDCh0UCkNaADLtY3nLC+yXZs14EmfsPTuqAEz9ZoiQU3p7XW1NQY1wTaMdJlGsC7urDg4Qpc6JoGN/xtuCSw3MKyB9xi0l0nTpzYbPzucNVu9g+kAQE8lDFwlOnh0TDKJ8tsmznZ4pfjHpYb+yABGVq3bNmywbjdUImRrtYAAHeE4IML2HJC4OvIW/e3buB66pZbVbudz41MP/3pT3fziwvmNnxX96wpX2kAgHd2ZtnGFqr68QuO3eCWF59uCQ5iWe7q6uqms2fPbjWuCdRiJBoaEMBDORb4LKugLYwrvmGuw62KEcuNFQtujrccO3bsAwO30pH5iZIGBPBgR05QrWNltk0c4K33gHADcGRq2bBhw3rjd7MmjERVAwAccAcj8LfX7Wxdz3kFbvCLRYleDOIYnOEX9tWca93OnDmznmd+7aFypuiP48jjhMVIdDUQjNdQVecuK7iheSLXrJIXPO7KM6ko46wAl9fMOE0Rj0Q1YsJhC8O9mT+Vfb09Ub8EhFaFKc2taVReYRmDMEszu4eigY4Ad7HZPnyKMAQoVtvjYhLH0eHGusCNHVr27du3euDAgRGF21axm2zH1pLN3Yzjxb3YG89Qel02PzIM3bUXf9jjtSdf4i8def3s4veFW39l+StHHaODjaGW5zd/R8fw08pQy2ppddOuva2rGVPFKrdN4EYzlehuCRKwDuB5Pk/KGzlyZM/169e/z5/vi8gXFwC28x9fZrDh1ieOVNW7cBcscSqcAjWtbXRXf/l/K6/ed6rpDDcXr5fh9jtAtzrKl+XGRtDXzJa77siRI6tHjBhxUyRcE9vhV8lWe4SLTizJR3XZLtRiwMlIzDWAx/qOn6HV+04Rf1iQ4AKAV3Brgc1x6/Y74iIw71hwFjTxqMlKniBTtoUV2lyJS0c+f+GLJzc3EgcaYI+EthyilVwVAAVOhVmP2unj3LJBLLfyZe6///5NVVVVRzty7mXHZA8BeC6PJcF3M0tsdADbzF94OPq9P5OMb4NTsdweCPqDWwCHyW8uKSl5zcB9Tm95fDWSg8FSIzHRAC48SyvoNT64YpNDARvMeogvuJEBZh474axo5ikf/trM784bOacBATzYO2kmH1t5/quLxNLCCK/aSX8Fl7yI1Qav7cQf3DgLLL/7ySefLC4rK9turPd5/QHwbOODn1dIFGKw2uW1tP3/3qZiPpzub7ez2qhOMHDj7GjasWPHSy1qSBG7GYEGlAVnwI3/HR0dtLK53XWCXmLVC9hgE0Y4JLg5v9oBO8L8N82cOfM1nvah1FhvqOa85BoLfl4ZXRiD1a6sp9L7lil/G3CDS79goyr+LDe24Wyw/G5+9axh+/btf4jUsCAOkCwigEfCpzRl+PbN8ZDUzhP0h5oadbNG97d9Wm2wFQhuAVxZ729+85t/raysPGmsd/vTEoBn8dRhRiKvAWW1G+jk7OXqQlKstt9REqlBR3AjD8w+CgHcjUePHq3duXPnImO9WRs+xFhw31Y33H8jWO29J2jR0Qr1QSc8+QcewSX49CuB4IblRgHqopLDxm9/+9sr+E2dMmO9fesUY+DGgvvWTWdSYbVrmqjsxytpBfjjRS4mO/S3caxAcCOPWG8FOD9vUrVnz54XjfWGanyLAG5GUcIfRcFzJPtP0ov7jhPe6RWwA1pt9EwwcIv1Vn4379M4Z86cl9h6VxrrDRX6FgW4GQf3rZwgU2G1qxup8ud/V8N/YrXBYUCrjUMEAzfyifVWvvfGjRvLN2/e/LS5awnV+Bfc5MnCOHiE7s6lWjktTN22Unp6awmVs5aD9rWlR4KF29t6N8yYMWMFT96z07xnKar0HQLwTDOK4ls5HaTCHTlVTTvvWqR8bTyrLaMkQVltFB0s3MjrYb358yL1y5Ytm8vzm7iMewL1+BcB3PjgwfnguMPC85G4Xt5Gc3nShnrWbMhWG70RCtztrPfDDz/88f79+/9sLi79gy1bBHBZN6F/DeA2+4Ez9OdfvE4fc65OWW2UHgrcyC/WG38ROJsavv/97/+Gb8ufNdYb6ulY4H/DRUk13zmU9kKDlY109sd/pd9wFGDLhWRQIyTYXyRUuGG9cRAMC+Kg9e+9914ZX2D+mt0UXjUSSAMAPMP75b5AO6XQ9iama0sJ/XrjQSrjZotLAt7AHfgLWkKFGwUL4GrkhNfr+eJyJd+93Gbck+D0LoCHYtFSIS/uRJ6oom23v6BeIROwwVnIYKMnOgs33BPrriXHG+bNm/cIv45WY0ZPoNbAIoAHznk+By5IIXJhKnGV2JYuaXpe2R4o1PfR4/720/PocX/5O0rH6EhlA9U88096hPPp7gg4A28hWW0cqzNwYz/xvS3r/dxzzx1cvXr1L3j0hOfZCLkeKDPlBP43XBSAEcwCBQlEelz21dP0uGwPFOr76HF/++l59Li//P7S20ZHaO0++sXv31cfbvK22uAtZOks3DgQDijWG2da/V133fXm3r17l5ubO1BPcALA01PcB29mp4OnaVj+jcX0JmsNYMsIiVjt4JTplSscuGGeAbhYb1So7pZbbvnV8ePH9xr/20vTHaxaFpxNWyr41nob4WefrKG9dy6kX4EfXsQlAVfgq9NuQAS+SsKHPy829rt5gquWDydMmPCVjIyMdMzaKWI/8S5hMdJeA+r7MNyN6GwR0Zy/v/NIp+O4ckw9LsfR0/S4bA81xAx1VQ1U+8s19K1/7qVjXGYtL7Dc8oCUpg0cMTQJx3LjSDi4t3tSN3/+fPjfjxn/O7TOyGAXJQ2f0ODdsEAkPLfWtb9yLH/HD7Q9lNrhsqyBnY639tJjv39X+dlitQXssKw26hIu3ChDABf3BGdeHfvfq/jR2BVm/BsqCl4E8OD3SMycGM/ec4JW3LuYVnELADa4wb2TsN0RLkNJJOBGQTjLMBbpAfj06dOfLC4uft8ADhUFLwAcF5m6b5pMcVxAlpyl9298jp5krXiDDY7AU9gSKbhREVhwffSkjt+3rLn55pt/WFpa+rEZQQmtrwA3XJRkE4B9pJw+/trz9MPKOjVhvLc7Ao4iIpGGW/xv/L2o0ZMDBw5U8HyDD/HjscUteEDXSNAaEMCTxWrjgaiT1VT84Ev00IFTVMGKELDBiwz7RQzurrYNqqKHDh1q4tvzGyZfmHVNbsUHufz5byNBasDRZn7kvpiuOokj9LXgEJJHj/vKK/kk7Ex+7KOLlIUQdyBP19CJOa/Q/W/soSOchJERwB1RP5vLs6Qr4PZ55vHFZb2r1b1lXNHRa/muXKYB3OqDgBFfgOvg+CtAz6PHuyo/jqEvOA7WYbF5GrSKX71NDyzaQAc4SYb88O+O67SI+dlcliVdATcKB+CyyMFsH+w6WsnTAO+8pD9dx4CnGcBFNYFDAVwfBw+8V+xzAGyeKar+D+vpu798k7ZzjWCtxR3Rh/0iXtmugluvqECO0MbPD5zpmUs7RvamKQx4Rgp/S0rXUVBxAVwpkk1ivPviAPtsPVUv2Uizfvaq+jgToBarDbBhsdGcLpFowo0GqIas3kOnud0fjBlAk/nWc450Wpe0MMkKFV3BB9ddgHiLtzC27GOfmvcWPTj3DfqIuwFQY4ErolvshIab22KdnWiIasyGYqrkZwreu/ICmsivYBVIpyGzkY41IP92cpHZce7ob23icY/jVXToZ3+jB55fR59wDfCNSN1iR3xkxFcro2G55bhyhlqAf3yEanccp7WfG05j+XszRQAcf7VGAmsgHgHHyQawedqzXQ8up/949WNrVEQHO2J3IANpKZpwS10EbhV+eoYaV++lt68dRaPyM2mAAVzUFDgUwJEz1v436oBb6p+W0cZbX6CHNn1KpzkJUMPP1h+GYo/U+ifnaNdJtOHWwZZGus/UUMufPqS114+mfvkZNNxpLHjQPS6Ax9JFwRh2Hdtjnqzy9WnP0k9Ky9QNmpiCDQVGG27pNB1yxF31jeT63Xu07ooLqLx3N7oy3UFO6TjZyYS+NaAPqUbbgquhvkZq5FGwX13/ND3L/YgPnsLH9jXch76OmsQKbjRQQd0WWrAv30r7bXbaOLIPXZHppG7GTQmOBQ/AeZeuHj1B7/HEOXSikg4/vZZmzV5Ba/mwsNbiX8uoiNygQR9HVWIJtzQUjYaLYrkp6w5QOfvhb04aSn3YDx9m3BRRVcehAN7VFCk3hAfz9p6kN29fQD9Y+REd4poJ2GKx9TuPXV0ln4qJNdxotPeiQD9dTc3sprw39gI60zufxsFNkb9cny0xiUoDMtrUFTTBr1e30huo8e399D/TfkPPcj9V8oF1/1qeFRGLHbOeiTXcaLj0g1hvPXSv2EqfuG20bngRXc43fAod/H8rHRgzrcX5gS39tOlKjEI4IcDGmzPHKql43ts0i7/g+y6rQe44yoiIgC19GFNNwTWLF0FdcLJh4cf1Cd/p5Q9SqyW7ex7lLL2X7vjsILq3WyZ/vIBzWZ3ImYy01wDch3AFUOMZbJ5TpH7rYVrAs64uPVvtYan1N2hgrbGIwQr38GHtHw+WW28AlCKLnP0IW+ubyLX0A9pxqIzWXNib+vLk7oPlYtNArqvwfDwcvYgLUsu2eP9pemfOSvrBwyvpHe4HuCAyGgKwvZ/siwuwoYV4styojwieYsaCGT14dj1lxfl7YZYlz3j2drr6Xy6m2T3zqD+PqpAZNmTt+BGAiiVYgcWHC8L3H46+toOeenAZvc/7wuUAzAI01vVnRCLwP8ElRlDiFW40EXUTwAVyAG4tA3tR3oI76J4xA+mOvHTKgKtiIIfq2kswcANquCDVTdTIj0YsvXcpLSo9rcatYZ31RaDmU8Aa5Wp/0BinxDPcUA3qhwXuEwCHLw5LbgGO+MyraNCDk+nuEb1pOrsr6TyyYiBnxXiLP8ABNW6dswvStP8UrXrmPVr8x410mPfXgUYcUGOID1CLbx3CfwLvFUWJd7hFFagnrLhALq4KLjoF9IyvXkb9Zk+lmSOK6Cv8XfZMfl7cQC4a9BECatyIqW6gBob6b0+toT/+5SM1OQ5cDgEbcd0FAdRwQeIWaq6bkkSBG5VFXQVyWHFxVQC4QK7iU4ZTr4e/RLeN7kdfzcugXAU57xnOBRYfIykE1htv8yioG6lm1zH6y3/9nZat/UQ96CQgA2yJ+3JB4h5sdFYiwS1wCeDe/jjAFosOa57+2c9Q4X9/mW4Z3Zdm8J3OQszJJ3c7Uwl0AI0Fkw80sFPBU5iV7zpOL//0VVqx9VP1pTAALEAjrltq8asTwlpz3S1JRLil8gI5XBUs8MdlfFwgV8AX5lHW4zfSxCsG0vUDu9NEfnY8Xax5Ml+Awu0QK13bRE2lZ2n9llJ6g4f11pdXW4+h6hYacfjUcus8YVwQrnM7SWS40RjUXyAXn1wgB+ACucTTxw2mbj+cRlNH9aZp/QroYobcpmZ3QkFcUiJbdLHQ8Bnw0gC7Hu5jFbRzDz8Dwi/nrtlUom6VwzLLIhYa6zrUsNJiqRPCBeH6tpNEh1sa5AtyfXQFcAN6gVydAHdNoAF3j6PpQ3rQlIIcGoxRFoCubg5x5niHXYcZz3wAaIx6VNRSSXEZrV28iVYt2UBHuCkCrkCNdT0O10OsdMJDzW1Rkixw6+0R0MVd0V0WuQgV0MXKO798CRV9bRxdMbQHje3TjS7n0Za+cF0wdq7DjgPFwroDZIgCmkPAjDHpttGO4/zo6YcHy2jbnzbRlld30CnOAmB1qAVoPR1Ay4IjyMLRxJdkg1vvEbQNroq4KwI7ABeovUNsQz7nzHHU78YxdMWQnjSWn0q8LDuNemIObVyQAnbrwpQzQ3Tg9fi5rYF/BV7klLgijX9wIQiYEeKtcn7r5czJKvqo+AxtW7mdtvxxkxq+E+urwytwSyh5BGgu0XI/AlcywXIkM9zSFWLJBXSEFsQcB+BYF+glriBvS7dPGU6FUy+iwcOKaFBRPg3qlkUD89NpIFv4fmzdnQAez1OLK6POLK91bBPLq0IGFxd8AjHSsN5mlVt4/PlYVROV8qQ2paeq6DDPr3d4zW4q4WE7fAsdYAJWAVbiANk7DpiRJjAjVIflMGkFfZAqgrbqC+AF6Ahl8QU20mS7vo86WXIzyfm1K6jfZQNpQEEm5fP0w1lZaZTNw47Z7L9ns4XPZl8+i61+NsOdwQA3svWtY9+4ni1xHfvJdTw8V1fPS2Mz1Vc0UNVHpXTkT1voWE2DB5AAFFCK1RVgBWR9Xc8j+wjMEnJRyS2pBLfekzrkiCtQOdThFaB9wS0nhYRShne5so5jIy4CwCACmncolhWQCpwIJS7wAmyJ+8rrXS5nTx3RFZ46rfZsqQCohwK7Hgr4HaXpZUgcR9PjWBfo9LikIRSQBWZ93V8a0vUyJI5jpKRA6UY8NSAgeoeAGmmBQu/9UDrSvAXwQQRCPRRQA4X6PhI/V6r59al0oxZPDQisSPUVlzQ9lLx6iLi3AEiIHgqk3qHk886rCjA/7TWADjESugZ0vUncO5RSJV3W9VBAlTRZ9w6xXdIkrwkDaKAjxQfY1WwOoIFQdGvADaDMzmz+f6SMYEX4z7hMAAAAAElFTkSuQmCC'};return{FaviconsByHue,};});'use strict';Polymer({is:'tr-ui-b-info-bar-group',ready(){this.messages_=[];},clearMessages(){this.messages_=[];this.updateContents_();},addMessage(text,opt_buttons){opt_buttons=opt_buttons||[];for(let i=0;i<opt_buttons.length;i++){if(opt_buttons[i].buttonText===undefined){throw new Error('buttonText must be provided');}
+if(opt_buttons[i].onClick===undefined){throw new Error('onClick must be provided');}}
+this.messages_.push({text,buttons:opt_buttons||[]});this.updateContents_();},updateContents_(){Polymer.dom(this.$.messages).textContent='';this.messages_.forEach(function(message){const bar=document.createElement('tr-ui-b-info-bar');bar.message=message.text;bar.visible=true;message.buttons.forEach(function(button){bar.addButton(button.buttonText,button.onClick);},this);Polymer.dom(this.$.messages).appendChild(bar);},this);}});'use strict';Polymer({is:'tr-ui-b-toolbar-button'});'use strict';tr.exportTo('tr.ui',function(){const Task=tr.b.Task;function FindController(brushingStateController){this.brushingStateController_=brushingStateController;this.filterHits_=[];this.currentHitIndex_=-1;this.activePromise_=Promise.resolve();this.activeTask_=undefined;}
+FindController.prototype={__proto__:Object.prototype,get model(){return this.brushingStateController_.model;},get brushingStateController(){return this.brushingStateController_;},enqueueOperation_(operation){let task;if(operation instanceof tr.b.Task){task=operation;}else{task=new tr.b.Task(operation,this);}
+if(this.activeTask_){this.activeTask_=this.activeTask_.enqueue(task);}else{this.activeTask_=task;this.activePromise_=Task.RunWhenIdle(this.activeTask_);this.activePromise_.then(function(){this.activePromise_=undefined;this.activeTask_=undefined;}.bind(this));}},startFiltering(filterText){const sc=this.brushingStateController_;if(!sc)return;this.enqueueOperation_(function(){this.filterHits_=[];this.currentHitIndex_=-1;}.bind(this));let stateFromString;try{stateFromString=sc.uiStateFromString(filterText);}catch(e){this.enqueueOperation_(function(){const overlay=new tr.ui.b.Overlay();Polymer.dom(overlay).textContent=e.message;overlay.title='UI State Navigation Error';overlay.visible=true;});return this.activePromise_;}
+if(stateFromString!==undefined){this.enqueueOperation_(sc.navToPosition.bind(this,stateFromString,true));}else{if(filterText.length===0){this.enqueueOperation_(sc.findTextCleared.bind(sc));}else{const filter=new tr.c.FullTextFilter(filterText);const filterHitSet=new tr.model.EventSet();this.enqueueOperation_(sc.addAllEventsMatchingFilterToSelectionAsTask(filter,filterHitSet));this.enqueueOperation_(function(){this.filterHits_=filterHitSet.toArray();sc.findTextChangedTo(filterHitSet);}.bind(this));}}
+return this.activePromise_;},get filterHits(){return this.filterHits_;},get currentHitIndex(){return this.currentHitIndex_;},find_(dir){const firstHit=this.currentHitIndex_===-1;if(firstHit&&dir<0){this.currentHitIndex_=0;}
+const N=this.filterHits.length;this.currentHitIndex_=(this.currentHitIndex_+dir+N)%N;if(!this.brushingStateController_)return;this.brushingStateController_.findFocusChangedTo(new tr.model.EventSet(this.filterHits[this.currentHitIndex]));},findNext(){this.find_(1);},findPrevious(){this.find_(-1);}};return{FindController,};});'use strict';tr.exportTo('tr.ui.b',function(){function TimingTool(viewport,targetElement){this.viewport_=viewport;this.onMouseMove_=this.onMouseMove_.bind(this);this.onDblClick_=this.onDblClick_.bind(this);this.targetElement_=targetElement;this.isMovingLeftEdge_=false;}
+TimingTool.prototype={onEnterTiming(e){this.targetElement_.addEventListener('mousemove',this.onMouseMove_);this.targetElement_.addEventListener('dblclick',this.onDblClick_);},onBeginTiming(e){if(!this.isTouchPointInsideTrackBounds_(e.clientX,e.clientY)){return;}
+const pt=this.getSnappedToEventPosition_(e);this.mouseDownAt_(pt.x,pt.y);this.updateSnapIndicators_(pt);},updateSnapIndicators_(pt){if(!pt.snapped)return;const ir=this.viewport_.interestRange;if(ir.min===pt.x){ir.leftSnapIndicator=new tr.ui.SnapIndicator(pt.y,pt.height);}
+if(ir.max===pt.x){ir.rightSnapIndicator=new tr.ui.SnapIndicator(pt.y,pt.height);}},onUpdateTiming(e){const pt=this.getSnappedToEventPosition_(e);this.mouseMoveAt_(pt.x,pt.y,true);this.updateSnapIndicators_(pt);},onEndTiming(e){this.mouseUp_();},onExitTiming(e){this.targetElement_.removeEventListener('mousemove',this.onMouseMove_);this.targetElement_.removeEventListener('dblclick',this.onDblClick_);},onMouseMove_(e){if(e.button)return;const worldX=this.getWorldXFromEvent_(e);this.mouseMoveAt_(worldX,e.clientY,false);},onDblClick_(e){},isTouchPointInsideTrackBounds_(clientX,clientY){if(!this.viewport_||!this.viewport_.modelTrackContainer||!this.viewport_.modelTrackContainer.canvas){return false;}
+const canvas=this.viewport_.modelTrackContainer.canvas;const canvasRect=canvas.getBoundingClientRect();if(clientX>=canvasRect.left&&clientX<=canvasRect.right&&clientY>=canvasRect.top&&clientY<=canvasRect.bottom){return true;}
+return false;},mouseDownAt_(worldX,y){const ir=this.viewport_.interestRange;const dt=this.viewport_.currentDisplayTransform;const pixelRatio=window.devicePixelRatio||1;const nearnessThresholdWorld=dt.xViewVectorToWorld(6*pixelRatio);if(ir.isEmpty){ir.setMinAndMax(worldX,worldX);ir.rightSelected=true;this.isMovingLeftEdge_=false;return;}
 if(Math.abs(worldX-ir.min)<nearnessThresholdWorld){ir.leftSelected=true;ir.min=worldX;this.isMovingLeftEdge_=true;return;}
 if(Math.abs(worldX-ir.max)<nearnessThresholdWorld){ir.rightSelected=true;ir.max=worldX;this.isMovingLeftEdge_=false;return;}
-ir.setMinAndMax(worldX,worldX);ir.rightSelected=true;this.isMovingLeftEdge_=false;},mouseMoveAt_:function(worldX,y,mouseDown){var ir=this.viewport_.interestRange;if(mouseDown){this.updateMovingEdge_(worldX);return;}
-var ir=this.viewport_.interestRange;var dt=this.viewport_.currentDisplayTransform;var pixelRatio=window.devicePixelRatio||1;var nearnessThresholdWorld=dt.xViewVectorToWorld(6*pixelRatio);if(Math.abs(worldX-ir.min)<nearnessThresholdWorld){ir.leftSelected=true;ir.rightSelected=false;return;}
+ir.setMinAndMax(worldX,worldX);ir.rightSelected=true;this.isMovingLeftEdge_=false;},mouseMoveAt_(worldX,y,mouseDown){if(mouseDown){this.updateMovingEdge_(worldX);return;}
+const ir=this.viewport_.interestRange;const dt=this.viewport_.currentDisplayTransform;const pixelRatio=window.devicePixelRatio||1;const nearnessThresholdWorld=dt.xViewVectorToWorld(6*pixelRatio);if(Math.abs(worldX-ir.min)<nearnessThresholdWorld){ir.leftSelected=true;ir.rightSelected=false;return;}
 if(Math.abs(worldX-ir.max)<nearnessThresholdWorld){ir.leftSelected=false;ir.rightSelected=true;return;}
-ir.leftSelected=false;ir.rightSelected=false;return;},updateMovingEdge_:function(newWorldX){var ir=this.viewport_.interestRange;var a=ir.min;var b=ir.max;if(this.isMovingLeftEdge_)
-a=newWorldX;else
-b=newWorldX;if(a<=b)
-ir.setMinAndMax(a,b);else
-ir.setMinAndMax(b,a);if(ir.min==newWorldX){this.isMovingLeftEdge_=true;ir.leftSelected=true;ir.rightSelected=false;}else{this.isMovingLeftEdge_=false;ir.leftSelected=false;ir.rightSelected=true;}},mouseUp_:function(){var dt=this.viewport_.currentDisplayTransform;var ir=this.viewport_.interestRange;ir.leftSelected=false;ir.rightSelected=false;var pixelRatio=window.devicePixelRatio||1;var minWidthValue=dt.xViewVectorToWorld(2*pixelRatio);if(ir.range<minWidthValue)
-ir.reset();},getWorldXFromEvent_:function(e){var pixelRatio=window.devicePixelRatio||1;var canvas=this.viewport_.modelTrackContainer.canvas;var worldOffset=canvas.getBoundingClientRect().left;var viewX=(e.clientX-worldOffset)*pixelRatio;return this.viewport_.currentDisplayTransform.xViewToWorld(viewX);},getSnappedToEventPosition_:function(e){var pixelRatio=window.devicePixelRatio||1;var EVENT_SNAP_RANGE=16*pixelRatio;var modelTrackContainer=this.viewport_.modelTrackContainer;var modelTrackContainerRect=modelTrackContainer.getBoundingClientRect();var viewport=this.viewport_;var dt=viewport.currentDisplayTransform;var worldMaxDist=dt.xViewVectorToWorld(EVENT_SNAP_RANGE);var worldX=this.getWorldXFromEvent_(e);var mouseY=e.clientY;var selection=new tr.model.EventSet();modelTrackContainer.addClosestEventToSelection(worldX,worldMaxDist,mouseY,mouseY,selection);if(!selection.length){modelTrackContainer.addClosestEventToSelection(worldX,worldMaxDist,modelTrackContainerRect.top,modelTrackContainerRect.bottom,selection);}
-var minDistX=worldMaxDist;var minDistY=Infinity;var pixWidth=dt.xViewVectorToWorld(1);var result={x:worldX,y:mouseY-modelTrackContainerRect.top,height:0,snapped:false};var eventBounds=new tr.b.Range();for(var i=0;i<selection.length;i++){var event=selection[i];var track=viewport.trackForEvent(event);var trackRect=track.getBoundingClientRect();eventBounds.reset();event.addBoundsToRange(eventBounds);var eventX;if(Math.abs(eventBounds.min-worldX)<Math.abs(eventBounds.max-worldX)){eventX=eventBounds.min;}else{eventX=eventBounds.max;}
-var distX=eventX-worldX;var eventY=trackRect.top;var eventHeight=trackRect.height;var distY=Math.abs(eventY+eventHeight/2-mouseY);if((distX<=minDistX||Math.abs(distX-minDistX)<pixWidth)&&distY<minDistY){minDistX=distX;minDistY=distY;result.x=eventX;result.y=eventY+
+ir.leftSelected=false;ir.rightSelected=false;return;},updateMovingEdge_(newWorldX){const ir=this.viewport_.interestRange;let a=ir.min;let b=ir.max;if(this.isMovingLeftEdge_){a=newWorldX;}else{b=newWorldX;}
+if(a<=b){ir.setMinAndMax(a,b);}else{ir.setMinAndMax(b,a);}
+if(ir.min===newWorldX){this.isMovingLeftEdge_=true;ir.leftSelected=true;ir.rightSelected=false;}else{this.isMovingLeftEdge_=false;ir.leftSelected=false;ir.rightSelected=true;}},mouseUp_(){const dt=this.viewport_.currentDisplayTransform;const ir=this.viewport_.interestRange;ir.leftSelected=false;ir.rightSelected=false;const pixelRatio=window.devicePixelRatio||1;const minWidthValue=dt.xViewVectorToWorld(2*pixelRatio);if(ir.range<minWidthValue){ir.reset();}},getWorldXFromEvent_(e){const pixelRatio=window.devicePixelRatio||1;const canvas=this.viewport_.modelTrackContainer.canvas;const worldOffset=canvas.getBoundingClientRect().left;const viewX=(e.clientX-worldOffset)*pixelRatio;return this.viewport_.currentDisplayTransform.xViewToWorld(viewX);},getSnappedToEventPosition_(e){const pixelRatio=window.devicePixelRatio||1;const EVENT_SNAP_RANGE=16*pixelRatio;const modelTrackContainer=this.viewport_.modelTrackContainer;const modelTrackContainerRect=modelTrackContainer.getBoundingClientRect();const viewport=this.viewport_;const dt=viewport.currentDisplayTransform;const worldMaxDist=dt.xViewVectorToWorld(EVENT_SNAP_RANGE);const worldX=this.getWorldXFromEvent_(e);const mouseY=e.clientY;const selection=new tr.model.EventSet();modelTrackContainer.addClosestEventToSelection(worldX,worldMaxDist,mouseY,mouseY,selection);if(!selection.length){modelTrackContainer.addClosestEventToSelection(worldX,worldMaxDist,modelTrackContainerRect.top,modelTrackContainerRect.bottom,selection);}
+let minDistX=worldMaxDist;let minDistY=Infinity;const pixWidth=dt.xViewVectorToWorld(1);const result={x:worldX,y:mouseY-modelTrackContainerRect.top,height:0,snapped:false};const eventBounds=new tr.b.math.Range();for(const event of selection){const track=viewport.trackForEvent(event);const trackRect=track.getBoundingClientRect();eventBounds.reset();event.addBoundsToRange(eventBounds);let eventX;if(Math.abs(eventBounds.min-worldX)<Math.abs(eventBounds.max-worldX)){eventX=eventBounds.min;}else{eventX=eventBounds.max;}
+const distX=eventX-worldX;const eventY=trackRect.top;const eventHeight=trackRect.height;const distY=Math.abs(eventY+eventHeight/2-mouseY);if((distX<=minDistX||Math.abs(distX-minDistX)<pixWidth)&&distY<minDistY){minDistX=distX;minDistY=distY;result.x=eventX;result.y=eventY+
 modelTrackContainer.scrollTop-modelTrackContainerRect.top;result.height=eventHeight;result.snapped=true;}}
-return result;}};return{TimingTool:TimingTool};});'use strict';tr.exportTo('tr.ui',function(){var kDefaultPanAnimationDurationMs=100.0;function TimelineDisplayTransformPanAnimation(deltaX,deltaY,opt_durationMs){this.deltaX=deltaX;this.deltaY=deltaY;if(opt_durationMs===undefined)
-this.durationMs=kDefaultPanAnimationDurationMs;else
-this.durationMs=opt_durationMs;this.startPanX=undefined;this.startPanY=undefined;this.startTimeMs=undefined;}
-TimelineDisplayTransformPanAnimation.prototype={__proto__:tr.ui.b.Animation.prototype,get affectsPanY(){return this.deltaY!==0;},canTakeOverFor:function(existingAnimation){return existingAnimation instanceof TimelineDisplayTransformPanAnimation;},takeOverFor:function(existing,timestamp,target){var remainingDeltaXOnExisting=existing.goalPanX-target.panX;var remainingDeltaYOnExisting=existing.goalPanY-target.panY;var remainingTimeOnExisting=timestamp-(existing.startTimeMs+existing.durationMs);remainingTimeOnExisting=Math.max(remainingTimeOnExisting,0);this.deltaX+=remainingDeltaXOnExisting;this.deltaY+=remainingDeltaYOnExisting;this.durationMs+=remainingTimeOnExisting;},start:function(timestamp,target){this.startTimeMs=timestamp;this.startPanX=target.panX;this.startPanY=target.panY;},tick:function(timestamp,target){var percentDone=(timestamp-this.startTimeMs)/this.durationMs;percentDone=tr.b.clamp(percentDone,0,1);target.panX=tr.b.lerp(percentDone,this.startPanX,this.goalPanX);if(this.affectsPanY)
-target.panY=tr.b.lerp(percentDone,this.startPanY,this.goalPanY);return timestamp>=this.startTimeMs+this.durationMs;},get goalPanX(){return this.startPanX+this.deltaX;},get goalPanY(){return this.startPanY+this.deltaY;}};function TimelineDisplayTransformZoomToAnimation(goalFocalPointXWorld,goalFocalPointXView,goalFocalPointY,zoomInRatioX,opt_durationMs){this.goalFocalPointXWorld=goalFocalPointXWorld;this.goalFocalPointXView=goalFocalPointXView;this.goalFocalPointY=goalFocalPointY;this.zoomInRatioX=zoomInRatioX;if(opt_durationMs===undefined)
-this.durationMs=kDefaultPanAnimationDurationMs;else
-this.durationMs=opt_durationMs;this.startTimeMs=undefined;this.startScaleX=undefined;this.goalScaleX=undefined;this.startPanY=undefined;}
-TimelineDisplayTransformZoomToAnimation.prototype={__proto__:tr.ui.b.Animation.prototype,get affectsPanY(){return this.startPanY!=this.goalFocalPointY;},canTakeOverFor:function(existingAnimation){return false;},takeOverFor:function(existingAnimation,timestamp,target){this.goalScaleX=target.scaleX*this.zoomInRatioX;},start:function(timestamp,target){this.startTimeMs=timestamp;this.startScaleX=target.scaleX;this.goalScaleX=this.zoomInRatioX*target.scaleX;this.startPanY=target.panY;},tick:function(timestamp,target){var percentDone=(timestamp-this.startTimeMs)/this.durationMs;percentDone=tr.b.clamp(percentDone,0,1);target.scaleX=tr.b.lerp(percentDone,this.startScaleX,this.goalScaleX);if(this.affectsPanY){target.panY=tr.b.lerp(percentDone,this.startPanY,this.goalFocalPointY);}
-target.xPanWorldPosToViewPos(this.goalFocalPointXWorld,this.goalFocalPointXView);return timestamp>=this.startTimeMs+this.durationMs;}};return{TimelineDisplayTransformPanAnimation:TimelineDisplayTransformPanAnimation,TimelineDisplayTransformZoomToAnimation:TimelineDisplayTransformZoomToAnimation};});'use strict';tr.exportTo('tr.ui.tracks',function(){var DrawType={GENERAL_EVENT:1,INSTANT_EVENT:2,BACKGROUND:3,GRID:4,FLOW_ARROWS:5,MARKERS:6,HIGHLIGHTS:7,ANNOTATIONS:8};var DrawingContainer=tr.ui.b.define('drawing-container',tr.ui.tracks.Track);DrawingContainer.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('drawing-container');this.canvas_=document.createElement('canvas');this.canvas_.className='drawing-container-canvas';this.canvas_.style.left=tr.ui.b.constants.HEADING_WIDTH+'px';this.appendChild(this.canvas_);this.ctx_=this.canvas_.getContext('2d');this.viewportChange_=this.viewportChange_.bind(this);this.viewport.addEventListener('change',this.viewportChange_);},get canvas(){return this.canvas_;},context:function(){return this.ctx_;},viewportChange_:function(){this.invalidate();},invalidate:function(){if(this.rafPending_)
-return;this.rafPending_=true;tr.b.requestPreAnimationFrame(this.preDraw_,this);},preDraw_:function(){this.rafPending_=false;this.updateCanvasSizeIfNeeded_();tr.b.requestAnimationFrameInThisFrameIfPossible(this.draw_,this);},draw_:function(){this.ctx_.clearRect(0,0,this.canvas_.width,this.canvas_.height);var typesToDraw=[DrawType.BACKGROUND,DrawType.HIGHLIGHTS,DrawType.GRID,DrawType.INSTANT_EVENT,DrawType.GENERAL_EVENT,DrawType.MARKERS,DrawType.ANNOTATIONS,DrawType.FLOW_ARROWS];for(var idx in typesToDraw){for(var i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track))
-continue;this.children[i].drawTrack(typesToDraw[idx]);}}
-var pixelRatio=window.devicePixelRatio||1;var bounds=this.canvas_.getBoundingClientRect();var dt=this.viewport.currentDisplayTransform;var viewLWorld=dt.xViewToWorld(0);var viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);this.viewport.drawGridLines(this.ctx_,viewLWorld,viewRWorld);},updateCanvasSizeIfNeeded_:function(){var visibleChildTracks=tr.b.asArray(this.children).filter(this.visibleFilter_);var thisBounds=this.getBoundingClientRect();var firstChildTrackBounds=visibleChildTracks[0].getBoundingClientRect();var lastChildTrackBounds=visibleChildTracks[visibleChildTracks.length-1].getBoundingClientRect();var innerWidth=firstChildTrackBounds.width-
-tr.ui.b.constants.HEADING_WIDTH;var innerHeight=lastChildTrackBounds.bottom-firstChildTrackBounds.top;var pixelRatio=window.devicePixelRatio||1;if(this.canvas_.width!=innerWidth*pixelRatio){this.canvas_.width=innerWidth*pixelRatio;this.canvas_.style.width=innerWidth+'px';}
-if(this.canvas_.height!=innerHeight*pixelRatio){this.canvas_.height=innerHeight*pixelRatio;this.canvas_.style.height=innerHeight+'px';}},visibleFilter_:function(element){if(!(element instanceof tr.ui.tracks.Track))
-return false;return window.getComputedStyle(element).display!=='none';},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){for(var i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track))
-continue;var trackClientRect=this.children[i].getBoundingClientRect();var a=Math.max(loY,trackClientRect.top);var b=Math.min(hiY,trackClientRect.bottom);if(a<=b){this.children[i].addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);}}
-tr.ui.tracks.Track.prototype.addClosestEventToSelection.apply(this,arguments);},addEventsToTrackMap:function(eventToTrackMap){for(var i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track))
-continue;this.children[i].addEventsToTrackMap(eventToTrackMap);}}};return{DrawingContainer:DrawingContainer,DrawType:DrawType};});'use strict';tr.exportTo('tr.model',function(){var SelectableItem=tr.model.SelectableItem;var SelectionState=tr.model.SelectionState;function ProxySelectableItem(modelItem){SelectableItem.call(this,modelItem);};ProxySelectableItem.prototype={__proto__:SelectableItem.prototype,get selectionState(){var modelItem=this.modelItem_;if(modelItem===undefined)
-return SelectionState.NONE;return modelItem.selectionState;}};return{ProxySelectableItem:ProxySelectableItem};});'use strict';tr.exportTo('tr.ui.tracks',function(){var EventPresenter=tr.ui.b.EventPresenter;var SelectionState=tr.model.SelectionState;var LetterDotTrack=tr.ui.b.define('letter-dot-track',tr.ui.tracks.Track);LetterDotTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('letter-dot-track');this.items_=undefined;this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},get items(){return this.items_;},set items(items){this.items_=items;this.invalidateDrawingContainer();},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},get dumpRadiusView(){return 7*(window.devicePixelRatio||1);},draw:function(type,viewLWorld,viewRWorld){if(this.items_===undefined)
-return;switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawLetterDots_(viewLWorld,viewRWorld);break;}},drawLetterDots_:function(viewLWorld,viewRWorld){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var height=bounds.height*pixelRatio;var halfHeight=height*0.5;var twoPi=Math.PI*2;var dt=this.viewport.currentDisplayTransform;var dumpRadiusView=this.dumpRadiusView;var itemRadiusWorld=dt.xViewVectorToWorld(height);var items=this.items_;var loI=tr.b.findLowIndexInSortedArray(items,function(item){return item.start;},viewLWorld);var oldFont=ctx.font;ctx.font='400 '+Math.floor(9*pixelRatio)+'px Arial';ctx.strokeStyle='rgb(0,0,0)';ctx.textBaseline='middle';ctx.textAlign='center';var drawItems=function(selected){for(var i=loI;i<items.length;++i){var item=items[i];var x=item.start;if(x-itemRadiusWorld>viewRWorld)
-break;if(item.selected!==selected)
-continue;var xView=dt.xWorldToView(x);ctx.fillStyle=EventPresenter.getSelectableItemColorAsString(item);ctx.beginPath();ctx.arc(xView,halfHeight,dumpRadiusView+0.5,0,twoPi);ctx.fill();if(item.selected){ctx.lineWidth=3;ctx.strokeStyle='rgb(100,100,0)';ctx.stroke();ctx.beginPath();ctx.arc(xView,halfHeight,dumpRadiusView,0,twoPi);ctx.lineWidth=1.5;ctx.strokeStyle='rgb(255,255,0)';ctx.stroke();}else{ctx.lineWidth=1;ctx.strokeStyle='rgb(0,0,0)';ctx.stroke();}
-ctx.fillStyle='rgb(255, 255, 255)';ctx.fillText(item.dotLetter,xView,halfHeight);}};drawItems(false);drawItems(true);ctx.lineWidth=1;ctx.font=oldFont;},addEventsToTrackMap:function(eventToTrackMap){if(this.items_===undefined)
-return;this.items_.forEach(function(item){item.addToTrackMap(eventToTrackMap,this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){if(this.items_===undefined)
-return;var itemRadiusWorld=viewPixWidthWorld*this.dumpRadiusView;tr.b.iterateOverIntersectingIntervals(this.items_,function(x){return x.start-itemRadiusWorld;},function(x){return 2*itemRadiusWorld;},loWX,hiWX,function(item){item.addToSelection(selection);}.bind(this));},addEventNearToProvidedEventToSelection:function(event,offset,selection){if(this.items_===undefined)
-return;var items=this.items_;var index=tr.b.findFirstIndexInArray(items,function(item){return item.modelItem===event;});if(index===-1)
-return false;var newIndex=index+offset;if(newIndex>=0&&newIndex<items.length){items[newIndex].addToSelection(selection);return true;}
-return false;},addAllEventsMatchingFilterToSelection:function(filter,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){if(this.items_===undefined)
-return;var item=tr.b.findClosestElementInSortedArray(this.items_,function(x){return x.start;},worldX,worldMaxDist);if(!item)
-return;item.addToSelection(selection);}};function LetterDot(modelItem,dotLetter,colorId,start){tr.model.ProxySelectableItem.call(this,modelItem);this.dotLetter=dotLetter;this.colorId=colorId;this.start=start;};LetterDot.prototype={__proto__:tr.model.ProxySelectableItem.prototype};return{LetterDotTrack:LetterDotTrack,LetterDot:LetterDot};});'use strict';tr.exportTo('tr.ui.tracks',function(){var AlertTrack=tr.ui.b.define('alert-track',tr.ui.tracks.LetterDotTrack);AlertTrack.prototype={__proto__:tr.ui.tracks.LetterDotTrack.prototype,decorate:function(viewport){tr.ui.tracks.LetterDotTrack.prototype.decorate.call(this,viewport);this.heading='Alerts';this.alerts_=undefined;},get alerts(){return this.alerts_;},set alerts(alerts){this.alerts_=alerts;if(alerts===undefined){this.items=undefined;return;}
-this.items=this.alerts_.map(function(alert){return new tr.ui.tracks.LetterDot(alert,String.fromCharCode(9888),alert.colorId,alert.start);});}};return{AlertTrack:AlertTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var Task=tr.b.Task;var ContainerTrack=tr.ui.b.define('container-track',tr.ui.tracks.Track);ContainerTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);},detach:function(){this.textContent='';},get tracks_(){var tracks=[];for(var i=0;i<this.children.length;i++){if(this.children[i]instanceof tr.ui.tracks.Track)
-tracks.push(this.children[i]);}
-return tracks;},drawTrack:function(type){this.tracks_.forEach(function(track){track.drawTrack(type);});},addIntersectingEventsInRangeToSelection:function(loVX,hiVX,loY,hiY,selection){for(var i=0;i<this.tracks_.length;i++){var trackClientRect=this.tracks_[i].getBoundingClientRect();var a=Math.max(loY,trackClientRect.top);var b=Math.min(hiY,trackClientRect.bottom);if(a<=b)
-this.tracks_[i].addIntersectingEventsInRangeToSelection(loVX,hiVX,loY,hiY,selection);}
-tr.ui.tracks.Track.prototype.addIntersectingEventsInRangeToSelection.apply(this,arguments);},addEventsToTrackMap:function(eventToTrackMap){for(var i=0;i<this.children.length;++i)
-this.children[i].addEventsToTrackMap(eventToTrackMap);},addAllEventsMatchingFilterToSelection:function(filter,selection){for(var i=0;i<this.tracks_.length;i++)
-this.tracks_[i].addAllEventsMatchingFilterToSelection(filter,selection);},addAllEventsMatchingFilterToSelectionAsTask:function(filter,selection){var task=new Task();for(var i=0;i<this.tracks_.length;i++){task.subTask(function(i){return function(){this.tracks_[i].addAllEventsMatchingFilterToSelection(filter,selection);}}(i),this);}
-return task;},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){for(var i=0;i<this.tracks_.length;i++){var trackClientRect=this.tracks_[i].getBoundingClientRect();var a=Math.max(loY,trackClientRect.top);var b=Math.min(hiY,trackClientRect.bottom);if(a<=b){this.tracks_[i].addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);}}
-tr.ui.tracks.Track.prototype.addClosestEventToSelection.apply(this,arguments);},addContainersToTrackMap:function(containerToTrackMap){this.tracks_.forEach(function(track){track.addContainersToTrackMap(containerToTrackMap);});},clearTracks_:function(){this.tracks_.forEach(function(track){this.removeChild(track);},this);}};return{ContainerTrack:ContainerTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ChartAxis(opt_min,opt_max){this.guid_=tr.b.GUID.allocate();this.bounds=new tr.b.Range();if(opt_min!==undefined)
-this.bounds.addValue(opt_min);if(opt_max!==undefined)
-this.bounds.addValue(opt_max);};ChartAxis.prototype={get guid(){return this.guid_;},valueToUnitRange:function(value){if(this.bounds.isEmpty)
-throw new Error('Chart axis bounds are empty');var bounds=this.bounds;if(bounds.range===0)
-return 0;return(value-bounds.min)/bounds.range;},autoSetFromSeries:function(series,opt_config){var range=new tr.b.Range();series.forEach(function(s){range.addRange(s.range);},this);this.autoSetFromRange(range,opt_config);},autoSetFromRange:function(range,opt_config){if(range.isEmpty)
-return;var bounds=this.bounds;if(bounds.isEmpty){bounds.addRange(range);return;}
-if(!opt_config)
-return;var useRangeMin=(opt_config.expandMin&&range.min<bounds.min||opt_config.shrinkMin&&range.min>bounds.min);var useRangeMax=(opt_config.expandMax&&range.max>bounds.max||opt_config.shrinkMax&&range.max<bounds.max);if(!useRangeMin&&!useRangeMax)
-return;if(useRangeMin&&useRangeMax){bounds.min=range.min;bounds.max=range.max;return;}
-if(useRangeMin){bounds.min=Math.min(range.min,bounds.max);}else{bounds.max=Math.max(range.max,bounds.min);}}};return{ChartAxis:ChartAxis};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ChartPoint(modelItem,x,y,opt_yBase){tr.model.ProxySelectableItem.call(this,modelItem);this.x=x;this.y=y;this.yBase=opt_yBase;};ChartPoint.prototype={__proto__:tr.model.ProxySelectableItem.prototype};return{ChartPoint:ChartPoint};});'use strict';tr.exportTo('tr.ui.tracks',function(){var EventPresenter=tr.ui.b.EventPresenter;var SelectionState=tr.model.SelectionState;var ChartSeriesType={LINE:0,AREA:1};var DEFAULT_RENDERING_CONFIG={chartType:ChartSeriesType.LINE,selectedPointSize:4,unselectedPointSize:3,colorId:0,lineWidth:1,skipDistance:1,unselectedPointDensityTransparent:0.10,unselectedPointDensityOpaque:0.05,backgroundOpacity:0.5};var LAST_POINT_WIDTH=16;var ChartSeriesComponent={BACKGROUND:0,LINE:1,DOTS:2};function ChartSeries(points,axis,opt_renderingConfig){this.points=points;this.axis=axis;this.useRenderingConfig_(opt_renderingConfig);}
-ChartSeries.prototype={useRenderingConfig_:function(opt_renderingConfig){var config=opt_renderingConfig||{};tr.b.iterItems(DEFAULT_RENDERING_CONFIG,function(key,defaultValue){var value=config[key];if(value===undefined)
-value=defaultValue;this[key+'_']=value;},this);this.topPadding=this.bottomPadding=Math.max(this.selectedPointSize_,this.unselectedPointSize_)/2;},get range(){var range=new tr.b.Range();this.points.forEach(function(point){range.addValue(point.y);},this);return range;},draw:function(ctx,transform,highDetails){if(this.points===undefined||this.points.length===0)
-return;if(this.chartType_===ChartSeriesType.AREA){this.drawComponent_(ctx,transform,ChartSeriesComponent.BACKGROUND,highDetails);}
+return result;}};return{TimingTool,};});'use strict';tr.exportTo('tr.ui',function(){const kDefaultPanAnimationDurationMs=100.0;const lerp=tr.b.math.lerp;function TimelineDisplayTransformPanAnimation(deltaX,deltaY,opt_durationMs){this.deltaX=deltaX;this.deltaY=deltaY;if(opt_durationMs===undefined){this.durationMs=kDefaultPanAnimationDurationMs;}else{this.durationMs=opt_durationMs;}
+this.startPanX=undefined;this.startPanY=undefined;this.startTimeMs=undefined;}
+TimelineDisplayTransformPanAnimation.prototype={__proto__:tr.ui.b.Animation.prototype,get affectsPanY(){return this.deltaY!==0;},canTakeOverFor(existingAnimation){return existingAnimation instanceof TimelineDisplayTransformPanAnimation;},takeOverFor(existing,timestamp,target){const remainingDeltaXOnExisting=existing.goalPanX-target.panX;const remainingDeltaYOnExisting=existing.goalPanY-target.panY;let remainingTimeOnExisting=timestamp-(existing.startTimeMs+existing.durationMs);remainingTimeOnExisting=Math.max(remainingTimeOnExisting,0);this.deltaX+=remainingDeltaXOnExisting;this.deltaY+=remainingDeltaYOnExisting;this.durationMs+=remainingTimeOnExisting;},start(timestamp,target){this.startTimeMs=timestamp;this.startPanX=target.panX;this.startPanY=target.panY;},tick(timestamp,target){let percentDone=(timestamp-this.startTimeMs)/this.durationMs;percentDone=tr.b.math.clamp(percentDone,0,1);target.panX=lerp(percentDone,this.startPanX,this.goalPanX);if(this.affectsPanY){target.panY=lerp(percentDone,this.startPanY,this.goalPanY);}
+return timestamp>=this.startTimeMs+this.durationMs;},get goalPanX(){return this.startPanX+this.deltaX;},get goalPanY(){return this.startPanY+this.deltaY;}};function TimelineDisplayTransformZoomToAnimation(goalFocalPointXWorld,goalFocalPointXView,goalFocalPointY,zoomInRatioX,opt_durationMs){this.goalFocalPointXWorld=goalFocalPointXWorld;this.goalFocalPointXView=goalFocalPointXView;this.goalFocalPointY=goalFocalPointY;this.zoomInRatioX=zoomInRatioX;if(opt_durationMs===undefined){this.durationMs=kDefaultPanAnimationDurationMs;}else{this.durationMs=opt_durationMs;}
+this.startTimeMs=undefined;this.startScaleX=undefined;this.goalScaleX=undefined;this.startPanY=undefined;}
+TimelineDisplayTransformZoomToAnimation.prototype={__proto__:tr.ui.b.Animation.prototype,get affectsPanY(){return this.startPanY!==this.goalFocalPointY;},canTakeOverFor(existingAnimation){return false;},takeOverFor(existingAnimation,timestamp,target){this.goalScaleX=target.scaleX*this.zoomInRatioX;},start(timestamp,target){this.startTimeMs=timestamp;this.startScaleX=target.scaleX;this.goalScaleX=this.zoomInRatioX*target.scaleX;this.startPanY=target.panY;},tick(timestamp,target){let percentDone=(timestamp-this.startTimeMs)/this.durationMs;percentDone=tr.b.math.clamp(percentDone,0,1);target.scaleX=lerp(percentDone,this.startScaleX,this.goalScaleX);if(this.affectsPanY){target.panY=lerp(percentDone,this.startPanY,this.goalFocalPointY);}
+target.xPanWorldPosToViewPos(this.goalFocalPointXWorld,this.goalFocalPointXView);return timestamp>=this.startTimeMs+this.durationMs;}};return{TimelineDisplayTransformPanAnimation,TimelineDisplayTransformZoomToAnimation,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const DrawType={GENERAL_EVENT:1,INSTANT_EVENT:2,BACKGROUND:3,GRID:4,FLOW_ARROWS:5,MARKERS:6,HIGHLIGHTS:7,ANNOTATIONS:8};const MAX_OVERSIZE_MULTIPLE=3.0;const REDRAW_SLOP=(MAX_OVERSIZE_MULTIPLE-1)/2;const DrawingContainer=tr.ui.b.define('drawing-container',tr.ui.tracks.Track);DrawingContainer.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('drawing-container');this.canvas_=document.createElement('canvas');this.canvas_.className='drawing-container-canvas';this.canvas_.style.left=tr.ui.b.constants.HEADING_WIDTH+'px';Polymer.dom(this).appendChild(this.canvas_);this.ctx_=this.canvas_.getContext('2d');this.offsetY_=0;this.viewportChange_=this.viewportChange_.bind(this);this.viewport.addEventListener('change',this.viewportChange_);window.addEventListener('resize',this.windowResized_.bind(this));this.addEventListener('scroll',this.scrollChanged_.bind(this));},get canvas(){return this.canvas_;},context(){return this.ctx_;},viewportChange_(){this.invalidate();},windowResized_(){this.invalidate();},scrollChanged_(){if(this.updateOffsetY_()){this.invalidate();}},invalidate(){if(this.rafPending_)return;this.rafPending_=true;tr.b.requestPreAnimationFrame(this.preDraw_,this);},preDraw_(){this.rafPending_=false;this.updateCanvasSizeIfNeeded_();tr.b.requestAnimationFrameInThisFrameIfPossible(this.draw_,this);},draw_(){this.ctx_.clearRect(0,0,this.canvas_.width,this.canvas_.height);const typesToDraw=[DrawType.BACKGROUND,DrawType.HIGHLIGHTS,DrawType.GRID,DrawType.INSTANT_EVENT,DrawType.GENERAL_EVENT,DrawType.MARKERS,DrawType.ANNOTATIONS,DrawType.FLOW_ARROWS];for(const idx in typesToDraw){for(let i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track)){continue;}
+this.children[i].drawTrack(typesToDraw[idx]);}}
+const pixelRatio=window.devicePixelRatio||1;const bounds=this.canvas_.getBoundingClientRect();const dt=this.viewport.currentDisplayTransform;const viewLWorld=dt.xViewToWorld(0);const viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);const viewHeight=bounds.height*pixelRatio;this.viewport.drawGridLines(this.ctx_,viewLWorld,viewRWorld,viewHeight);},updateOffsetY_(){const maxYDelta=window.innerHeight*REDRAW_SLOP;let newOffset=this.scrollTop-maxYDelta;if(Math.abs(newOffset-this.offsetY_)<=maxYDelta)return false;const maxOffset=this.scrollHeight-
+this.canvas_.getBoundingClientRect().height;newOffset=Math.max(0,Math.min(newOffset,maxOffset));if(newOffset!==this.offsetY_){this.offsetY_=newOffset;return true;}
+return false;},updateCanvasSizeIfNeeded_(){const visibleChildTracks=Array.from(this.children).filter(this.visibleFilter_);if(visibleChildTracks.length===0){return;}
+const thisBounds=this.getBoundingClientRect();const firstChildTrackBounds=visibleChildTracks[0].getBoundingClientRect();const lastChildTrackBounds=visibleChildTracks[visibleChildTracks.length-1].getBoundingClientRect();const innerWidth=firstChildTrackBounds.width-
+tr.ui.b.constants.HEADING_WIDTH;const innerHeight=Math.min(lastChildTrackBounds.bottom-firstChildTrackBounds.top,Math.floor(window.innerHeight*MAX_OVERSIZE_MULTIPLE));const pixelRatio=window.devicePixelRatio||1;if(this.canvas_.width!==innerWidth*pixelRatio){this.canvas_.width=innerWidth*pixelRatio;this.canvas_.style.width=innerWidth+'px';}
+if(this.canvas_.height!==innerHeight*pixelRatio){this.canvas_.height=innerHeight*pixelRatio;this.canvas_.style.height=innerHeight+'px';}
+if(this.canvas_.top!==this.offsetY_){this.canvas_.top=this.offsetY_;this.canvas_.style.top=this.offsetY_+'px';}},visibleFilter_(element){if(!(element instanceof tr.ui.tracks.Track))return false;return window.getComputedStyle(element).display!=='none';},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){for(let i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track)){continue;}
+const trackClientRect=this.children[i].getBoundingClientRect();const a=Math.max(loY,trackClientRect.top);const b=Math.min(hiY,trackClientRect.bottom);if(a<=b){this.children[i].addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);}}
+tr.ui.tracks.Track.prototype.addClosestEventToSelection.apply(this,arguments);},addEventsToTrackMap(eventToTrackMap){for(let i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track)){continue;}
+this.children[i].addEventsToTrackMap(eventToTrackMap);}}};return{DrawingContainer,DrawType,};});'use strict';tr.exportTo('tr.model',function(){const SelectableItem=tr.model.SelectableItem;const SelectionState=tr.model.SelectionState;function ProxySelectableItem(modelItem){SelectableItem.call(this,modelItem);}
+ProxySelectableItem.prototype={__proto__:SelectableItem.prototype,get selectionState(){const modelItem=this.modelItem_;if(modelItem===undefined){return SelectionState.NONE;}
+return modelItem.selectionState;}};return{ProxySelectableItem,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const EventPresenter=tr.ui.b.EventPresenter;const SelectionState=tr.model.SelectionState;const LetterDotTrack=tr.ui.b.define('letter-dot-track',tr.ui.tracks.Track);LetterDotTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('letter-dot-track');this.items_=undefined;this.heading_=document.createElement('tr-ui-b-heading');Polymer.dom(this).appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},get items(){return this.items_;},set items(items){this.items_=items;this.invalidateDrawingContainer();},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},get dumpRadiusView(){return 7*(window.devicePixelRatio||1);},draw(type,viewLWorld,viewRWorld,viewHeight){if(this.items_===undefined)return;switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawLetterDots_(viewLWorld,viewRWorld);break;}},drawLetterDots_(viewLWorld,viewRWorld){const ctx=this.context();const pixelRatio=window.devicePixelRatio||1;const bounds=this.getBoundingClientRect();const height=bounds.height*pixelRatio;const halfHeight=height*0.5;const twoPi=Math.PI*2;const dt=this.viewport.currentDisplayTransform;const dumpRadiusView=this.dumpRadiusView;const itemRadiusWorld=dt.xViewVectorToWorld(height);const items=this.items_;const loI=tr.b.findLowIndexInSortedArray(items,function(item){return item.start;},viewLWorld);const oldFont=ctx.font;ctx.font='400 '+Math.floor(9*pixelRatio)+'px Arial';ctx.strokeStyle='rgb(0,0,0)';ctx.textBaseline='middle';ctx.textAlign='center';const drawItems=function(selected){for(let i=loI;i<items.length;++i){const item=items[i];const x=item.start;if(x-itemRadiusWorld>viewRWorld)break;if(item.selected!==selected)continue;const xView=dt.xWorldToView(x);ctx.fillStyle=EventPresenter.getSelectableItemColorAsString(item);ctx.beginPath();ctx.arc(xView,halfHeight,dumpRadiusView+0.5,0,twoPi);ctx.fill();if(item.selected){ctx.lineWidth=3;ctx.strokeStyle='rgb(100,100,0)';ctx.stroke();ctx.beginPath();ctx.arc(xView,halfHeight,dumpRadiusView,0,twoPi);ctx.lineWidth=1.5;ctx.strokeStyle='rgb(255,255,0)';ctx.stroke();}else{ctx.lineWidth=1;ctx.strokeStyle='rgb(0,0,0)';ctx.stroke();}
+ctx.fillStyle='rgb(255, 255, 255)';ctx.fillText(item.dotLetter,xView,halfHeight);}};drawItems(false);drawItems(true);ctx.lineWidth=1;ctx.font=oldFont;},addEventsToTrackMap(eventToTrackMap){if(this.items_===undefined)return;this.items_.forEach(function(item){item.addToTrackMap(eventToTrackMap,this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection){if(this.items_===undefined)return;const itemRadiusWorld=viewPixWidthWorld*this.dumpRadiusView;tr.b.iterateOverIntersectingIntervals(this.items_,function(x){return x.start-itemRadiusWorld;},function(x){return 2*itemRadiusWorld;},loWX,hiWX,function(item){item.addToSelection(selection);}.bind(this));},addEventNearToProvidedEventToSelection(event,offset,selection){if(this.items_===undefined)return;const index=this.items_.findIndex(item=>item.modelItem===event);if(index===-1)return false;const newIndex=index+offset;if(newIndex>=0&&newIndex<this.items_.length){this.items_[newIndex].addToSelection(selection);return true;}
+return false;},addAllEventsMatchingFilterToSelection(filter,selection){},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){if(this.items_===undefined)return;const item=tr.b.findClosestElementInSortedArray(this.items_,function(x){return x.start;},worldX,worldMaxDist);if(!item)return;item.addToSelection(selection);}};function LetterDot(modelItem,dotLetter,colorId,start){tr.model.ProxySelectableItem.call(this,modelItem);this.dotLetter=dotLetter;this.colorId=colorId;this.start=start;}
+LetterDot.prototype={__proto__:tr.model.ProxySelectableItem.prototype};return{LetterDotTrack,LetterDot,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const AlertTrack=tr.ui.b.define('alert-track',tr.ui.tracks.LetterDotTrack);AlertTrack.prototype={__proto__:tr.ui.tracks.LetterDotTrack.prototype,decorate(viewport){tr.ui.tracks.LetterDotTrack.prototype.decorate.call(this,viewport);this.heading='Alerts';this.alerts_=undefined;},get alerts(){return this.alerts_;},set alerts(alerts){this.alerts_=alerts;if(alerts===undefined){this.items=undefined;return;}
+this.items=this.alerts_.map(function(alert){return new tr.ui.tracks.LetterDot(alert,String.fromCharCode(9888),alert.colorId,alert.start);});}};return{AlertTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const Task=tr.b.Task;const ContainerTrack=tr.ui.b.define('container-track',tr.ui.tracks.Track);ContainerTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);},detach(){Polymer.dom(this).textContent='';},get tracks_(){const tracks=[];for(let i=0;i<this.children.length;i++){if(this.children[i]instanceof tr.ui.tracks.Track){tracks.push(this.children[i]);}}
+return tracks;},drawTrack(type){this.tracks_.forEach(function(track){track.drawTrack(type);});},addIntersectingEventsInRangeToSelection(loVX,hiVX,loY,hiY,selection){for(let i=0;i<this.tracks_.length;i++){const trackClientRect=this.tracks_[i].getBoundingClientRect();const a=Math.max(loY,trackClientRect.top);const b=Math.min(hiY,trackClientRect.bottom);if(a<=b){this.tracks_[i].addIntersectingEventsInRangeToSelection(loVX,hiVX,loY,hiY,selection);}}
+tr.ui.tracks.Track.prototype.addIntersectingEventsInRangeToSelection.apply(this,arguments);},addEventsToTrackMap(eventToTrackMap){for(const track of this.tracks_){track.addEventsToTrackMap(eventToTrackMap);}},addAllEventsMatchingFilterToSelection(filter,selection){for(let i=0;i<this.tracks_.length;i++){this.tracks_[i].addAllEventsMatchingFilterToSelection(filter,selection);}},addAllEventsMatchingFilterToSelectionAsTask(filter,selection){const task=new Task();for(let i=0;i<this.tracks_.length;i++){task.subTask(function(i){return function(){this.tracks_[i].addAllEventsMatchingFilterToSelection(filter,selection);};}(i),this);}
+return task;},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){for(let i=0;i<this.tracks_.length;i++){const trackClientRect=this.tracks_[i].getBoundingClientRect();const a=Math.max(loY,trackClientRect.top);const b=Math.min(hiY,trackClientRect.bottom);if(a<=b){this.tracks_[i].addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);}}
+tr.ui.tracks.Track.prototype.addClosestEventToSelection.apply(this,arguments);},addContainersToTrackMap(containerToTrackMap){this.tracks_.forEach(function(track){track.addContainersToTrackMap(containerToTrackMap);});},clearTracks_(){this.tracks_.forEach(function(track){Polymer.dom(this).removeChild(track);},this);}};return{ContainerTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ChartPoint(modelItem,x,y,opt_yBase){tr.model.ProxySelectableItem.call(this,modelItem);this.x=x;this.y=y;this.dotLetter=undefined;this.yBase=opt_yBase;}
+ChartPoint.prototype={__proto__:tr.model.ProxySelectableItem.prototype,};return{ChartPoint,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ColorScheme=tr.b.ColorScheme;const EventPresenter=tr.ui.b.EventPresenter;const SelectionState=tr.model.SelectionState;const ChartSeriesType={LINE:0,AREA:1};const DEFAULT_RENDERING_CONFIG={chartType:ChartSeriesType.LINE,selectedPointSize:4,unselectedPointSize:3,solidSelectedDots:false,colorId:0,lineWidth:1,skipDistance:1,unselectedPointDensityTransparent:0.10,unselectedPointDensityOpaque:0.05,backgroundOpacity:0.5,stepGraph:true};const LAST_POINT_WIDTH=16;const DOT_LETTER_RADIUS_PX=7;const DOT_LETTER_RADIUS_PADDING_PX=0.5;const DOT_LETTER_SELECTED_OUTLINE_WIDTH_PX=3;const DOT_LETTER_SELECTED_OUTLINE_DETAIL_WIDTH_PX=1.5;const DOT_LETTER_UNSELECTED_OUTLINE_WIDTH_PX=1;const DOT_LETTER_FONT_WEIGHT=400;const DOT_LETTER_FONT_SIZE_PX=9;const DOT_LETTER_FONT='Arial';const ChartSeriesComponent={BACKGROUND:0,LINE:1,DOTS:2};function ChartSeries(points,seriesYAxis,opt_renderingConfig){this.points=points;this.seriesYAxis=seriesYAxis;this.useRenderingConfig_(opt_renderingConfig);}
+ChartSeries.prototype={useRenderingConfig_(opt_renderingConfig){const config=opt_renderingConfig||{};for(const[key,defaultValue]of
+Object.entries(DEFAULT_RENDERING_CONFIG)){let value=config[key];if(value===undefined){value=defaultValue;}
+this[key+'_']=value;}
+this.topPadding=this.bottomPadding=Math.max(this.selectedPointSize_,this.unselectedPointSize_)/2;},get range(){const range=new tr.b.math.Range();this.points.forEach(function(point){range.addValue(point.y);},this);return range;},draw(ctx,transform,highDetails){if(this.points===undefined||this.points.length===0){return;}
+if(this.chartType_===ChartSeriesType.AREA){this.drawComponent_(ctx,transform,ChartSeriesComponent.BACKGROUND,highDetails);}
 if(this.chartType_===ChartSeriesType.LINE||highDetails){this.drawComponent_(ctx,transform,ChartSeriesComponent.LINE,highDetails);}
-this.drawComponent_(ctx,transform,ChartSeriesComponent.DOTS,highDetails);},drawComponent_:function(ctx,transform,component,highDetails){var extraPixels=0;if(component===ChartSeriesComponent.DOTS){extraPixels=Math.max(this.selectedPointSize_,this.unselectedPointSize_);}
-var leftViewX=transform.leftViewX-extraPixels*transform.pixelRatio;var rightViewX=transform.rightViewX+
-extraPixels*transform.pixelRatio;var leftTimestamp=transform.leftTimestamp-extraPixels;var rightTimestamp=transform.rightTimestamp+extraPixels;var firstVisibleIndex=tr.b.findLowIndexInSortedArray(this.points,function(point){return point.x;},leftTimestamp);var lastVisibleIndex=tr.b.findLowIndexInSortedArray(this.points,function(point){return point.x;},rightTimestamp);if(lastVisibleIndex>=this.points.length||this.points[lastVisibleIndex].x>rightTimestamp){lastVisibleIndex--;}
-var viewSkipDistance=this.skipDistance_*transform.pixelRatio;var circleRadius;var squareSize;var squareHalfSize;var squareOpacity;switch(component){case ChartSeriesComponent.DOTS:ctx.strokeStyle=EventPresenter.getCounterSeriesColor(this.colorId_,SelectionState.NONE);ctx.lineWidth=transform.pixelRatio;circleRadius=(this.selectedPointSize_/2)*transform.pixelRatio;squareSize=this.unselectedPointSize_*transform.pixelRatio;squareHalfSize=squareSize/2;if(!highDetails){squareOpacity=0;break;}
-var visibleIndexRange=lastVisibleIndex-firstVisibleIndex;if(visibleIndexRange<=0){squareOpacity=1;break;}
-var visibleViewXRange=transform.worldXToViewX(this.points[lastVisibleIndex].x)-
+this.drawComponent_(ctx,transform,ChartSeriesComponent.DOTS,highDetails);},drawComponent_(ctx,transform,component,highDetails){let extraPixels=0;if(component===ChartSeriesComponent.DOTS){extraPixels=Math.max(this.selectedPointSize_,this.unselectedPointSize_);}
+const pixelRatio=transform.pixelRatio;const leftViewX=transform.leftViewX-extraPixels*pixelRatio;const rightViewX=transform.rightViewX+extraPixels*pixelRatio;const leftTimestamp=transform.leftTimestamp-extraPixels;const rightTimestamp=transform.rightTimestamp+extraPixels;const firstVisibleIndex=tr.b.findLowIndexInSortedArray(this.points,function(point){return point.x;},leftTimestamp);let lastVisibleIndex=tr.b.findLowIndexInSortedArray(this.points,function(point){return point.x;},rightTimestamp);if(lastVisibleIndex>=this.points.length||this.points[lastVisibleIndex].x>rightTimestamp){lastVisibleIndex--;}
+const viewSkipDistance=this.skipDistance_*pixelRatio;let selectedCircleRadius;let letterDotRadius;let squareSize;let squareHalfSize;let squareOpacity;let unselectedSeriesColor;let currentStateSeriesColor;ctx.save();ctx.font=DOT_LETTER_FONT_WEIGHT+' '+
+Math.floor(DOT_LETTER_FONT_SIZE_PX*pixelRatio)+'px '+
+DOT_LETTER_FONT;ctx.textBaseline='middle';ctx.textAlign='center';switch(component){case ChartSeriesComponent.DOTS:{selectedCircleRadius=(this.selectedPointSize_/2)*pixelRatio;letterDotRadius=Math.max(selectedCircleRadius,DOT_LETTER_RADIUS_PX*pixelRatio);squareSize=this.unselectedPointSize_*pixelRatio;squareHalfSize=squareSize/2;unselectedSeriesColor=EventPresenter.getCounterSeriesColor(this.colorId_,SelectionState.NONE);if(!highDetails){squareOpacity=0;break;}
+const visibleIndexRange=lastVisibleIndex-firstVisibleIndex;if(visibleIndexRange<=0){squareOpacity=1;break;}
+const visibleViewXRange=transform.worldXToViewX(this.points[lastVisibleIndex].x)-
 transform.worldXToViewX(this.points[firstVisibleIndex].x);if(visibleViewXRange===0){squareOpacity=1;break;}
-var density=visibleIndexRange/visibleViewXRange;var clampedDensity=tr.b.clamp(density,this.unselectedPointDensityOpaque_,this.unselectedPointDensityTransparent_);var densityRange=this.unselectedPointDensityTransparent_-
-this.unselectedPointDensityOpaque_;squareOpacity=(this.unselectedPointDensityTransparent_-clampedDensity)/densityRange;break;case ChartSeriesComponent.LINE:ctx.strokeStyle=EventPresenter.getCounterSeriesColor(this.colorId_,SelectionState.NONE);ctx.lineWidth=this.lineWidth_*transform.pixelRatio;break;case ChartSeriesComponent.BACKGROUND:break;default:throw new Error('Invalid component: '+component);}
-var previousViewX=undefined;var previousViewY=undefined;var previousViewYBase=undefined;var lastSelectionState=undefined;var baseSteps=undefined;var startIndex=Math.max(firstVisibleIndex-1,0);for(var i=startIndex;i<this.points.length;i++){var currentPoint=this.points[i];var currentViewX=transform.worldXToViewX(currentPoint.x);if(currentViewX>rightViewX){if(previousViewX!==undefined){previousViewX=currentViewX=rightViewX;if(component===ChartSeriesComponent.BACKGROUND||component===ChartSeriesComponent.LINE){ctx.lineTo(currentViewX,previousViewY);}}
+const density=visibleIndexRange/visibleViewXRange;const clampedDensity=tr.b.math.clamp(density,this.unselectedPointDensityOpaque_,this.unselectedPointDensityTransparent_);const densityRange=this.unselectedPointDensityTransparent_-
+this.unselectedPointDensityOpaque_;squareOpacity=(this.unselectedPointDensityTransparent_-clampedDensity)/densityRange;break;}
+case ChartSeriesComponent.LINE:ctx.strokeStyle=EventPresenter.getCounterSeriesColor(this.colorId_,SelectionState.NONE);ctx.lineWidth=this.lineWidth_*pixelRatio;break;case ChartSeriesComponent.BACKGROUND:break;default:throw new Error('Invalid component: '+component);}
+let previousViewX=undefined;let previousViewY=undefined;let previousViewYBase=undefined;let lastSelectionState=undefined;let baseSteps=undefined;const startIndex=Math.max(firstVisibleIndex-1,0);let currentViewX;for(let i=startIndex;i<this.points.length;i++){const currentPoint=this.points[i];currentViewX=transform.worldXToViewX(currentPoint.x);if(currentViewX>rightViewX){if(previousViewX!==undefined){previousViewX=currentViewX=rightViewX;if(component===ChartSeriesComponent.BACKGROUND||component===ChartSeriesComponent.LINE){ctx.lineTo(currentViewX,previousViewY);}}
 break;}
-if(i+1<this.points.length){var nextPoint=this.points[i+1];var nextViewX=transform.worldXToViewX(nextPoint.x);if(previousViewX!==undefined&&nextViewX-previousViewX<=viewSkipDistance&&nextViewX<rightViewX){continue;}
+if(i+1<this.points.length){const nextPoint=this.points[i+1];const nextViewX=transform.worldXToViewX(nextPoint.x);if(previousViewX!==undefined&&nextViewX-previousViewX<=viewSkipDistance&&nextViewX<rightViewX){continue;}
 if(currentViewX<leftViewX){currentViewX=leftViewX;}}
 if(previousViewX!==undefined&&currentViewX-previousViewX<viewSkipDistance){currentViewX=previousViewX+viewSkipDistance;}
-var currentViewY=Math.round(transform.worldYToViewY(currentPoint.y));var currentViewYBase;if(currentPoint.yBase===undefined){currentViewYBase=transform.outerBottomViewY;}else{currentViewYBase=Math.round(transform.worldYToViewY(currentPoint.yBase));}
-var currentSelectionState=currentPoint.selectionState;switch(component){case ChartSeriesComponent.DOTS:if(currentSelectionState!==lastSelectionState){if(currentSelectionState===SelectionState.SELECTED){ctx.fillStyle=EventPresenter.getCounterSeriesColor(this.colorId_,currentSelectionState);}else if(squareOpacity>0){ctx.fillStyle=EventPresenter.getCounterSeriesColor(this.colorId_,currentSelectionState,squareOpacity);}}
-if(currentSelectionState===SelectionState.SELECTED){ctx.beginPath();ctx.arc(currentViewX,currentViewY,circleRadius,0,2*Math.PI);ctx.fill();ctx.stroke();}else if(squareOpacity>0){ctx.fillRect(currentViewX-squareHalfSize,currentViewY-squareHalfSize,squareSize,squareSize);}
-break;case ChartSeriesComponent.LINE:if(previousViewX===undefined){ctx.beginPath();ctx.moveTo(currentViewX,currentViewY);}else{ctx.lineTo(currentViewX,previousViewY);}
-ctx.lineTo(currentViewX,currentViewY);break;case ChartSeriesComponent.BACKGROUND:if(previousViewX!==undefined)
-ctx.lineTo(currentViewX,previousViewY);if(currentSelectionState!==lastSelectionState){if(previousViewX!==undefined){var previousBaseStepViewX=currentViewX;for(var j=baseSteps.length-1;j>=0;j--){var baseStep=baseSteps[j];var baseStepViewX=baseStep.viewX;var baseStepViewY=baseStep.viewY;ctx.lineTo(previousBaseStepViewX,baseStepViewY);ctx.lineTo(baseStepViewX,baseStepViewY);previousBaseStepViewX=baseStepViewX;}
+const currentViewY=Math.round(transform.worldYToViewY(currentPoint.y));let currentViewYBase;if(currentPoint.yBase===undefined){currentViewYBase=transform.outerBottomViewY;}else{currentViewYBase=Math.round(transform.worldYToViewY(currentPoint.yBase));}
+const currentSelectionState=currentPoint.selectionState;if(currentSelectionState!==lastSelectionState){const opacity=currentSelectionState===SelectionState.SELECTED?1:squareOpacity;currentStateSeriesColor=EventPresenter.getCounterSeriesColor(this.colorId_,currentSelectionState,opacity);}
+switch(component){case ChartSeriesComponent.DOTS:if(currentPoint.dotLetter){ctx.fillStyle=unselectedSeriesColor;ctx.strokeStyle=ColorScheme.getColorForReservedNameAsString('black');ctx.beginPath();ctx.arc(currentViewX,currentViewY,letterDotRadius+DOT_LETTER_RADIUS_PADDING_PX,0,2*Math.PI);ctx.fill();if(currentSelectionState===SelectionState.SELECTED){ctx.lineWidth=DOT_LETTER_SELECTED_OUTLINE_WIDTH_PX;ctx.strokeStyle=ColorScheme.getColorForReservedNameAsString('olive');ctx.stroke();ctx.beginPath();ctx.arc(currentViewX,currentViewY,letterDotRadius,0,2*Math.PI);ctx.lineWidth=DOT_LETTER_SELECTED_OUTLINE_DETAIL_WIDTH_PX;ctx.strokeStyle=ColorScheme.getColorForReservedNameAsString('yellow');ctx.stroke();}else{ctx.lineWidth=DOT_LETTER_UNSELECTED_OUTLINE_WIDTH_PX;ctx.strokeStyle=ColorScheme.getColorForReservedNameAsString('black');ctx.stroke();}
+ctx.fillStyle=ColorScheme.getColorForReservedNameAsString('white');ctx.fillText(currentPoint.dotLetter,currentViewX,currentViewY);}else{ctx.strokeStyle=unselectedSeriesColor;ctx.lineWidth=pixelRatio;if(currentSelectionState===SelectionState.SELECTED){if(this.solidSelectedDots_){ctx.fillStyle=ctx.strokeStyle;}else{ctx.fillStyle=currentStateSeriesColor;}
+ctx.beginPath();ctx.arc(currentViewX,currentViewY,selectedCircleRadius,0,2*Math.PI);ctx.fill();ctx.stroke();}else if(squareOpacity>0){ctx.fillStyle=currentStateSeriesColor;ctx.fillRect(currentViewX-squareHalfSize,currentViewY-squareHalfSize,squareSize,squareSize);}}
+break;case ChartSeriesComponent.LINE:if(previousViewX===undefined){ctx.beginPath();ctx.moveTo(currentViewX,currentViewY);}else if(this.stepGraph_){ctx.lineTo(currentViewX,previousViewY);}
+ctx.lineTo(currentViewX,currentViewY);break;case ChartSeriesComponent.BACKGROUND:if(previousViewX!==undefined&&this.stepGraph_){ctx.lineTo(currentViewX,previousViewY);}else{ctx.lineTo(currentViewX,currentViewY);}
+if(currentSelectionState!==lastSelectionState){if(previousViewX!==undefined){let previousBaseStepViewX=currentViewX;for(let j=baseSteps.length-1;j>=0;j--){const baseStep=baseSteps[j];const baseStepViewX=baseStep.viewX;const baseStepViewY=baseStep.viewY;ctx.lineTo(previousBaseStepViewX,baseStepViewY);ctx.lineTo(baseStepViewX,baseStepViewY);previousBaseStepViewX=baseStepViewX;}
 ctx.closePath();ctx.fill();}
 ctx.beginPath();ctx.fillStyle=EventPresenter.getCounterSeriesColor(this.colorId_,currentSelectionState,this.backgroundOpacity_);ctx.moveTo(currentViewX,currentViewYBase);baseSteps=[];}
 if(currentViewYBase!==previousViewYBase||currentSelectionState!==lastSelectionState){baseSteps.push({viewX:currentViewX,viewY:currentViewYBase});}
 ctx.lineTo(currentViewX,currentViewY);break;default:throw new Error('Not reachable');}
 previousViewX=currentViewX;previousViewY=currentViewY;previousViewYBase=currentViewYBase;lastSelectionState=currentSelectionState;}
-if(previousViewX!==undefined){switch(component){case ChartSeriesComponent.DOTS:break;case ChartSeriesComponent.LINE:ctx.stroke();break;case ChartSeriesComponent.BACKGROUND:var previousBaseStepViewX=currentViewX;for(var j=baseSteps.length-1;j>=0;j--){var baseStep=baseSteps[j];var baseStepViewX=baseStep.viewX;var baseStepViewY=baseStep.viewY;ctx.lineTo(previousBaseStepViewX,baseStepViewY);ctx.lineTo(baseStepViewX,baseStepViewY);previousBaseStepViewX=baseStepViewX;}
-ctx.closePath();ctx.fill();break;default:throw new Error('Not reachable');}}},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){var points=this.points;function getPointWidth(point,i){if(i===points.length-1)
-return LAST_POINT_WIDTH*viewPixWidthWorld;var nextPoint=points[i+1];return nextPoint.x-point.x;}
+if(previousViewX!==undefined){switch(component){case ChartSeriesComponent.DOTS:break;case ChartSeriesComponent.LINE:ctx.stroke();break;case ChartSeriesComponent.BACKGROUND:{let previousBaseStepViewX=currentViewX;for(let j=baseSteps.length-1;j>=0;j--){const baseStep=baseSteps[j];const baseStepViewX=baseStep.viewX;const baseStepViewY=baseStep.viewY;ctx.lineTo(previousBaseStepViewX,baseStepViewY);ctx.lineTo(baseStepViewX,baseStepViewY);previousBaseStepViewX=baseStepViewX;}
+ctx.closePath();ctx.fill();break;}
+default:throw new Error('Not reachable');}}
+ctx.restore();},addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection){const points=this.points;function getPointWidth(point,i){if(i===points.length-1){return LAST_POINT_WIDTH*viewPixWidthWorld;}
+const nextPoint=points[i+1];return nextPoint.x-point.x;}
 function selectPoint(point){point.addToSelection(selection);}
-tr.b.iterateOverIntersectingIntervals(this.points,function(point){return point.x},getPointWidth,loWX,hiWX,selectPoint);},addEventNearToProvidedEventToSelection:function(event,offset,selection){if(this.points===undefined)
-return false;var index=tr.b.findFirstIndexInArray(this.points,function(point){return point.modelItem===event;},this);if(index===-1)
-return false;var newIndex=index+offset;if(newIndex<0||newIndex>=this.points.length)
-return false;this.points[newIndex].addToSelection(selection);return true;},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){if(this.points===undefined)
-return;var item=tr.b.findClosestElementInSortedArray(this.points,function(point){return point.x},worldX,worldMaxDist);if(!item)
-return;item.addToSelection(selection);}};return{ChartSeries:ChartSeries,ChartSeriesType:ChartSeriesType};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ChartTransform(displayTransform,axis,trackWidth,trackHeight,topPadding,bottomPadding,pixelRatio){this.pixelRatio=pixelRatio;this.leftViewX=0;this.rightViewX=trackWidth;this.leftTimestamp=displayTransform.xViewToWorld(this.leftViewX);this.rightTimestamp=displayTransform.xViewToWorld(this.rightViewX);this.displayTransform_=displayTransform;this.outerTopViewY=0;this.innerTopViewY=topPadding;this.innerBottomViewY=trackHeight-bottomPadding;this.outerBottomViewY=trackHeight;this.axis_=axis;this.innerHeight_=this.innerBottomViewY-this.innerTopViewY;};ChartTransform.prototype={worldXToViewX:function(worldX){return this.displayTransform_.xWorldToView(worldX);},viewXToWorldX:function(viewX){return this.displayTransform_.xViewToWorld(viewX);},worldYToViewY:function(worldY){var innerHeightCoefficient=1-this.axis_.valueToUnitRange(worldY);return innerHeightCoefficient*this.innerHeight_+this.innerTopViewY;}};return{ChartTransform:ChartTransform};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ChartTrack=tr.ui.b.define('chart-track',tr.ui.tracks.Track);ChartTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('chart-track');this.series_=undefined;this.axisGuidToAxisData_=undefined;this.topPadding_=undefined;this.bottomPadding_=undefined;this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},get series(){return this.series_;},set series(series){this.series_=series;this.calculateAxisDataAndPadding_();this.invalidateDrawingContainer();},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;this.invalidateDrawingContainer();},get hasVisibleContent(){return!!this.series&&this.series.length>0;},calculateAxisDataAndPadding_:function(){if(!this.series_){this.axisGuidToAxisData_=undefined;this.topPadding_=undefined;this.bottomPadding_=undefined;return;}
-var axisGuidToAxisData={};var topPadding=0;var bottomPadding=0;this.series_.forEach(function(series){var axis=series.axis;var axisGuid=axis.guid;if(!(axisGuid in axisGuidToAxisData)){axisGuidToAxisData[axisGuid]={axis:axis,series:[]};}
-axisGuidToAxisData[axisGuid].series.push(series);topPadding=Math.max(topPadding,series.topPadding);bottomPadding=Math.max(bottomPadding,series.bottomPadding);},this);this.axisGuidToAxisData_=axisGuidToAxisData;this.topPadding_=topPadding;this.bottomPadding_=bottomPadding;},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawChart_(viewLWorld,viewRWorld);break;}},drawChart_:function(viewLWorld,viewRWorld){if(!this.series_)
-return;var ctx=this.context();var displayTransform=this.viewport.currentDisplayTransform;var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var highDetails=this.viewport.highDetails;var width=bounds.width*pixelRatio;var height=bounds.height*pixelRatio;var topPadding=this.topPadding_*pixelRatio;var bottomPadding=this.bottomPadding_*pixelRatio;ctx.save();ctx.beginPath();ctx.rect(0,0,width,height);ctx.clip();this.series_.forEach(function(series){var chartTransform=new tr.ui.tracks.ChartTransform(displayTransform,series.axis,width,height,topPadding,bottomPadding,pixelRatio);series.draw(ctx,chartTransform,highDetails);},this);ctx.restore();},addEventsToTrackMap:function(eventToTrackMap){this.series_.forEach(function(series){series.points.forEach(function(point){point.addToTrackMap(eventToTrackMap,this);},this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){this.series_.forEach(function(series){series.addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection);},this);},addEventNearToProvidedEventToSelection:function(event,offset,selection){var foundItem=false;this.series_.forEach(function(series){foundItem=foundItem||series.addEventNearToProvidedEventToSelection(event,offset,selection);},this);return foundItem;},addAllEventsMatchingFilterToSelection:function(filter,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){this.series_.forEach(function(series){series.addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);},this);},autoSetAllAxes:function(opt_config){tr.b.iterItems(this.axisGuidToAxisData_,function(axisGuid,axisData){var axis=axisData.axis;var series=axisData.series;axis.autoSetFromSeries(series,opt_config);},this);},autoSetAxis:function(axis,opt_config){var series=this.axisGuidToAxisData_[axis.guid].series;axis.autoSetFromSeries(series,opt_config);}};return{ChartTrack:ChartTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ColorScheme=tr.b.ColorScheme;var ChartTrack=tr.ui.tracks.ChartTrack;var PowerSeriesTrack=tr.ui.b.define('power-series-track',ChartTrack);PowerSeriesTrack.prototype={__proto__:ChartTrack.prototype,decorate:function(viewport){ChartTrack.prototype.decorate.call(this,viewport);this.classList.add('power-series-track');this.heading='Power';this.powerSeries_=undefined;},set powerSeries(powerSeries){this.powerSeries_=powerSeries;this.series=this.buildChartSeries_();this.autoSetAllAxes({expandMax:true});},get hasVisibleContent(){return(this.powerSeries_&&this.powerSeries_.samples.length>0);},addContainersToTrackMap:function(containerToTrackMap){containerToTrackMap.addContainer(this.powerSeries_,this);},buildChartSeries_:function(){if(!this.hasVisibleContent)
-return[];var axis=new tr.ui.tracks.ChartAxis(0,undefined);var pts=this.powerSeries_.samples.map(function(smpl){return new tr.ui.tracks.ChartPoint(smpl,smpl.start,smpl.power);});var renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:ColorScheme.getColorIdForGeneralPurposeString(this.heading)};return[new tr.ui.tracks.ChartSeries(pts,axis,renderingConfig)];}};return{PowerSeriesTrack:PowerSeriesTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SpacingTrack=tr.ui.b.define('spacing-track',tr.ui.tracks.Track);SpacingTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('spacing-track');this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},addAllEventsMatchingFilterToSelection:function(filter,selection){}};return{SpacingTrack:SpacingTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ContainerTrack=tr.ui.tracks.ContainerTrack;var DeviceTrack=tr.ui.b.define('device-track',ContainerTrack);DeviceTrack.prototype={__proto__:ContainerTrack.prototype,decorate:function(viewport){ContainerTrack.prototype.decorate.call(this,viewport);this.classList.add('device-track');this.device_=undefined;this.powerSeriesTrack_=undefined;},get device(){return this.device_;},set device(device){this.device_=device;this.updateContents_();},get powerSeriesTrack(){return this.powerSeriesTrack_;},get hasVisibleContent(){return(this.powerSeriesTrack_&&this.powerSeriesTrack_.hasVisibleContent);},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.ContainerTrack.prototype.addContainersToTrackMap.call(this,containerToTrackMap);containerToTrackMap.addContainer(this.device,this);},addEventsToTrackMap:function(eventToTrackMap){this.tracks_.forEach(function(track){track.addEventsToTrackMap(eventToTrackMap);});},appendPowerSeriesTrack_:function(){this.powerSeriesTrack_=new tr.ui.tracks.PowerSeriesTrack(this.viewport);this.powerSeriesTrack_.powerSeries=this.device.powerSeries;if(this.powerSeriesTrack_.hasVisibleContent){this.appendChild(this.powerSeriesTrack_);this.appendChild(new tr.ui.tracks.SpacingTrack(this.viewport));}},updateContents_:function(){this.clearTracks_();this.appendPowerSeriesTrack_();}};return{DeviceTrack:DeviceTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ColorScheme=tr.b.ColorScheme;var DISPLAYED_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.DISPLAYED_SIZE_NUMERIC_NAME;var LIGHT=tr.model.ContainerMemoryDump.LevelOfDetail.LIGHT;var DETAILED=tr.model.ContainerMemoryDump.LevelOfDetail.DETAILED;function addDictionary(dstDict,srcDict){tr.b.iterItems(srcDict,function(key,value){var existingValue=dstDict[key];if(existingValue===undefined)
-existingValue=0;dstDict[key]=existingValue+value;});}
-function getProcessMemoryDumpAllocatorSizes(processMemoryDump){var allocatorDumps=processMemoryDump.memoryAllocatorDumps;if(allocatorDumps===undefined)
-return{};var allocatorSizes={};allocatorDumps.forEach(function(allocatorDump){if(allocatorDump.fullName==='tracing')
-return;var allocatorSize=allocatorDump.numerics[DISPLAYED_SIZE_NUMERIC_NAME];if(allocatorSize===undefined)
-return;var allocatorSizeValue=allocatorSize.value;if(allocatorSizeValue===undefined)
-return;allocatorSizes[allocatorDump.fullName]=allocatorSizeValue;});return allocatorSizes;};function getGlobalMemoryDumpAllocatorSizes(globalMemoryDump){var globalAllocatorSizes={};tr.b.iterItems(globalMemoryDump.processMemoryDumps,function(pid,processMemoryDump){addDictionary(globalAllocatorSizes,getProcessMemoryDumpAllocatorSizes(processMemoryDump));});return globalAllocatorSizes;}
-function buildAllocatedMemoryChartSeries(memoryDumps,memoryDumpToAllocatorSizesFn){var allocatorNameToPoints={};var dumpsData=memoryDumps.map(function(memoryDump){var allocatorSizes=memoryDumpToAllocatorSizesFn(memoryDump);tr.b.iterItems(allocatorSizes,function(allocatorName){allocatorNameToPoints[allocatorName]=[];});return{dump:memoryDump,sizes:allocatorSizes};});if(Object.keys(allocatorNameToPoints).length===0)
-return undefined;dumpsData.forEach(function(dumpData){var memoryDump=dumpData.dump;var allocatorSizes=dumpData.sizes;tr.b.iterItems(allocatorNameToPoints,function(allocatorName,points){var allocatorSize=allocatorSizes[allocatorName]||0;points.push(new tr.ui.tracks.ChartPoint(memoryDump,memoryDump.start,allocatorSize));});});var axis=new tr.ui.tracks.ChartAxis(0);var series=[];tr.b.iterItems(allocatorNameToPoints,function(allocatorName,points){var colorId=ColorScheme.getColorIdForGeneralPurposeString(allocatorName);var renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.LINE,colorId:colorId};series.push(new tr.ui.tracks.ChartSeries(points,axis,renderingConfig));});return series;}
-function buildMemoryLetterDots(memoryDumps){var lightMemoryColorId=ColorScheme.getColorIdForReservedName('light_memory_dump');var detailedMemoryColorId=ColorScheme.getColorIdForReservedName('detailed_memory_dump');return memoryDumps.map(function(memoryDump){var memoryColorId;switch(memoryDump.levelOfDetail){case DETAILED:memoryColorId=detailedMemoryColorId;break;case LIGHT:default:memoryColorId=lightMemoryColorId;}
+tr.b.iterateOverIntersectingIntervals(this.points,function(point){return point.x;},getPointWidth,loWX,hiWX,selectPoint);},addEventNearToProvidedEventToSelection(event,offset,selection){if(this.points===undefined)return false;const index=this.points.findIndex(point=>point.modelItem===event);if(index===-1)return false;const newIndex=index+offset;if(newIndex<0||newIndex>=this.points.length)return false;this.points[newIndex].addToSelection(selection);return true;},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){if(this.points===undefined)return;const item=tr.b.findClosestElementInSortedArray(this.points,function(point){return point.x;},worldX,worldMaxDist);if(!item)return;item.addToSelection(selection);}};return{ChartSeries,ChartSeriesType,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ColorScheme=tr.b.ColorScheme;const IDEAL_MAJOR_MARK_HEIGHT_PX=30;const AXIS_LABLE_MARGIN_PX=10;const AXIS_LABLE_FONT_SIZE_PX=9;const AXIS_LABLE_FONT='Arial';function ChartSeriesYAxis(opt_min,opt_max){this.guid_=tr.b.GUID.allocateSimple();this.bounds=new tr.b.math.Range();if(opt_min!==undefined)this.bounds.addValue(opt_min);if(opt_max!==undefined)this.bounds.addValue(opt_max);}
+ChartSeriesYAxis.prototype={get guid(){return this.guid_;},valueToUnitRange(value){if(this.bounds.isEmpty){throw new Error('Chart series y-axis bounds are empty');}
+const bounds=this.bounds;if(bounds.range===0)return 0;return(value-bounds.min)/bounds.range;},unitRangeToValue(unitRange){if(this.bounds.isEmpty){throw new Error('Chart series y-axis bounds are empty');}
+return unitRange*this.bounds.range+this.bounds.min;},autoSetFromSeries(series,opt_config){const range=new tr.b.math.Range();series.forEach(function(s){range.addRange(s.range);},this);this.autoSetFromRange(range,opt_config);},autoSetFromRange(range,opt_config){if(range.isEmpty)return;const bounds=this.bounds;if(bounds.isEmpty){bounds.addRange(range);return;}
+if(!opt_config)return;const useRangeMin=(opt_config.expandMin&&range.min<bounds.min||opt_config.shrinkMin&&range.min>bounds.min);const useRangeMax=(opt_config.expandMax&&range.max>bounds.max||opt_config.shrinkMax&&range.max<bounds.max);if(!useRangeMin&&!useRangeMax)return;if(useRangeMin&&useRangeMax){bounds.min=range.min;bounds.max=range.max;return;}
+if(useRangeMin){bounds.min=Math.min(range.min,bounds.max);}else{bounds.max=Math.max(range.max,bounds.min);}},majorMarkHeightWorld_(transform,pixelRatio){const idealMajorMarkHeightPx=IDEAL_MAJOR_MARK_HEIGHT_PX*pixelRatio;const idealMajorMarkHeightWorld=transform.vectorToWorldDistance(idealMajorMarkHeightPx);return tr.b.math.preferredNumberLargerThanMin(idealMajorMarkHeightWorld);},draw(ctx,transform,showYAxisLabels,showYGridLines){if(!showYAxisLabels&&!showYGridLines)return;const pixelRatio=transform.pixelRatio;const viewTop=transform.outerTopViewY;const worldTop=transform.viewYToWorldY(viewTop);const viewBottom=transform.outerBottomViewY;const viewHeight=viewBottom-viewTop;const viewLeft=transform.leftViewX;const viewRight=transform.rightViewX;const labelLeft=transform.leftYLabel;ctx.save();ctx.lineWidth=pixelRatio;ctx.fillStyle=ColorScheme.getColorForReservedNameAsString('black');ctx.textAlign='left';ctx.textBaseline='center';ctx.font=(AXIS_LABLE_FONT_SIZE_PX*pixelRatio)+'px '+AXIS_LABLE_FONT;ctx.beginPath();ctx.strokeStyle=ColorScheme.getColorForReservedNameAsString('black');tr.ui.b.drawLine(ctx,viewLeft,viewTop,viewLeft,viewBottom,viewLeft);ctx.stroke();ctx.closePath();ctx.beginPath();ctx.strokeStyle=ColorScheme.getColorForReservedNameAsString('grey');const majorMarkHeight=this.majorMarkHeightWorld_(transform,pixelRatio);const maxMajorMark=Math.max(transform.viewYToWorldY(viewTop),Math.abs(transform.viewYToWorldY(viewBottom)));for(let curWorldY=0;curWorldY<=maxMajorMark;curWorldY+=majorMarkHeight){const roundedUnitValue=Math.floor(curWorldY*1000000)/1000000;const curViewYPositive=transform.worldYToViewY(curWorldY);if(curViewYPositive>=viewTop){if(showYAxisLabels){ctx.fillText(roundedUnitValue,viewLeft+AXIS_LABLE_MARGIN_PX,curViewYPositive-AXIS_LABLE_MARGIN_PX);}
+if(showYGridLines){tr.ui.b.drawLine(ctx,viewLeft,curViewYPositive,viewRight,curViewYPositive);}}
+const curViewYNegative=transform.worldYToViewY(-1*curWorldY);if(curViewYNegative<=viewBottom){if(showYAxisLabels){ctx.fillText(roundedUnitValue,viewLeft+AXIS_LABLE_MARGIN_PX,curViewYNegative-AXIS_LABLE_MARGIN_PX);}
+if(showYGridLines){tr.ui.b.drawLine(ctx,viewLeft,curViewYNegative,viewRight,curViewYNegative);}}}
+ctx.stroke();ctx.restore();}};return{ChartSeriesYAxis,};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ChartTransform(displayTransform,axis,trackWidth,trackHeight,topPadding,bottomPadding,pixelRatio){this.pixelRatio=pixelRatio;this.leftViewX=0;this.rightViewX=trackWidth;this.leftTimestamp=displayTransform.xViewToWorld(this.leftViewX);this.rightTimestamp=displayTransform.xViewToWorld(this.rightViewX);this.displayTransform_=displayTransform;this.outerTopViewY=0;this.innerTopViewY=topPadding;this.innerBottomViewY=trackHeight-bottomPadding;this.outerBottomViewY=trackHeight;this.axis_=axis;this.innerHeight_=this.innerBottomViewY-this.innerTopViewY;}
+ChartTransform.prototype={worldXToViewX(worldX){return this.displayTransform_.xWorldToView(worldX);},viewXToWorldX(viewX){return this.displayTransform_.xViewToWorld(viewX);},vectorToWorldDistance(viewY){return this.axis_.bounds.range*Math.abs(viewY/this.innerHeight_);},viewYToWorldY(viewY){return this.axis_.unitRangeToValue(1-(viewY-this.innerTopViewY)/this.innerHeight_);},worldYToViewY(worldY){const innerHeightCoefficient=1-this.axis_.valueToUnitRange(worldY);return innerHeightCoefficient*this.innerHeight_+this.innerTopViewY;}};return{ChartTransform,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ChartTrack=tr.ui.b.define('chart-track',tr.ui.tracks.Track);ChartTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('chart-track');this.series_=undefined;this.axes_=undefined;this.axisGuidToAxisData_=undefined;this.topPadding_=undefined;this.bottomPadding_=undefined;this.showYAxisLabels_=undefined;this.showGridLines_=undefined;this.heading_=document.createElement('tr-ui-b-heading');Polymer.dom(this).appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},get series(){return this.series_;},set series(series){this.series_=series;this.calculateAxisDataAndPadding_();this.invalidateDrawingContainer();},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;this.invalidateDrawingContainer();},get showYAxisLabels(){return this.showYAxisLabels_;},set showYAxisLabels(showYAxisLabels){this.showYAxisLabels_=showYAxisLabels;this.invalidateDrawingContainer();},get showGridLines(){return this.showGridLines_;},set showGridLines(showGridLines){this.showGridLines_=showGridLines;this.invalidateDrawingContainer();},get hasVisibleContent(){return!!this.series&&this.series.length>0;},calculateAxisDataAndPadding_(){if(!this.series_){this.axes_=undefined;this.axisGuidToAxisData_=undefined;this.topPadding_=undefined;this.bottomPadding_=undefined;return;}
+const axisGuidToAxisData={};let topPadding=0;let bottomPadding=0;this.series_.forEach(function(series){const seriesYAxis=series.seriesYAxis;const axisGuid=seriesYAxis.guid;if(!(axisGuid in axisGuidToAxisData)){axisGuidToAxisData[axisGuid]={axis:seriesYAxis,series:[]};if(!this.axes_)this.axes_=[];this.axes_.push(seriesYAxis);}
+axisGuidToAxisData[axisGuid].series.push(series);topPadding=Math.max(topPadding,series.topPadding);bottomPadding=Math.max(bottomPadding,series.bottomPadding);},this);this.axisGuidToAxisData_=axisGuidToAxisData;this.topPadding_=topPadding;this.bottomPadding_=bottomPadding;},draw(type,viewLWorld,viewRWorld,viewHeight){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawChart_(viewLWorld,viewRWorld);break;}},drawChart_(viewLWorld,viewRWorld){if(!this.series_)return;const ctx=this.context();const displayTransform=this.viewport.currentDisplayTransform;const pixelRatio=window.devicePixelRatio||1;const bounds=this.getBoundingClientRect();const highDetails=this.viewport.highDetails;const width=bounds.width*pixelRatio;const height=bounds.height*pixelRatio;const topPadding=this.topPadding_*pixelRatio;const bottomPadding=this.bottomPadding_*pixelRatio;ctx.save();ctx.beginPath();ctx.rect(0,0,width,height);ctx.clip();if(this.axes_){if((this.showGridLines_||this.showYAxisLabels_)&&this.axes_.length>1){throw new Error('Only one axis allowed when showing grid lines.');}
+for(const yAxis of this.axes_){const chartTransform=new tr.ui.tracks.ChartTransform(displayTransform,yAxis,width,height,topPadding,bottomPadding,pixelRatio);yAxis.draw(ctx,chartTransform,this.showYAxisLabels_,this.showGridLines_);}}
+for(const series of this.series){const chartTransform=new tr.ui.tracks.ChartTransform(displayTransform,series.seriesYAxis,width,height,topPadding,bottomPadding,pixelRatio);series.draw(ctx,chartTransform,highDetails);}
+ctx.restore();},addEventsToTrackMap(eventToTrackMap){this.series_.forEach(function(series){series.points.forEach(function(point){point.addToTrackMap(eventToTrackMap,this);},this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection){this.series_.forEach(function(series){series.addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection);},this);},addEventNearToProvidedEventToSelection(event,offset,selection){let foundItem=false;this.series_.forEach(function(series){foundItem=foundItem||series.addEventNearToProvidedEventToSelection(event,offset,selection);},this);return foundItem;},addAllEventsMatchingFilterToSelection(filter,selection){},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){this.series_.forEach(function(series){series.addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);},this);},autoSetAllAxes(opt_config){for(const axisData of Object.values(this.axisGuidToAxisData_)){const seriesYAxis=axisData.axis;const series=axisData.series;seriesYAxis.autoSetFromSeries(series,opt_config);}},autoSetAxis(seriesYAxis,opt_config){const series=this.axisGuidToAxisData_[seriesYAxis.guid].series;seriesYAxis.autoSetFromSeries(series,opt_config);}};return{ChartTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ColorScheme=tr.b.ColorScheme;const ChartTrack=tr.ui.tracks.ChartTrack;const CpuUsageTrack=tr.ui.b.define('cpu-usage-track',ChartTrack);CpuUsageTrack.prototype={__proto__:ChartTrack.prototype,decorate(viewport){ChartTrack.prototype.decorate.call(this,viewport);this.classList.add('cpu-usage-track');this.heading='CPU usage';this.cpuUsageSeries_=undefined;},initialize(model){if(model!==undefined){this.cpuUsageSeries_=model.device.cpuUsageSeries;}else{this.cpuUsageSeries_=undefined;}
+this.series=this.buildChartSeries_();this.autoSetAllAxes({expandMax:true});},get hasVisibleContent(){return!!this.cpuUsageSeries_&&this.cpuUsageSeries_.samples.length>0;},addContainersToTrackMap(containerToTrackMap){containerToTrackMap.addContainer(this.series_,this);},buildChartSeries_(yAxis,color){if(!this.hasVisibleContent)return[];yAxis=new tr.ui.tracks.ChartSeriesYAxis(0,undefined);const usageSamples=this.cpuUsageSeries_.samples;const pts=new Array(usageSamples.length+1);for(let i=0;i<usageSamples.length;i++){pts[i]=new tr.ui.tracks.ChartPoint(undefined,usageSamples[i].start,usageSamples[i].usage);}
+pts[usageSamples.length]=new tr.ui.tracks.ChartPoint(undefined,usageSamples[usageSamples.length-1].start,0);const renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:color};return[new tr.ui.tracks.ChartSeries(pts,yAxis,renderingConfig)];},};return{CpuUsageTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ColorScheme=tr.b.ColorScheme;const ChartTrack=tr.ui.tracks.ChartTrack;const PowerSeriesTrack=tr.ui.b.define('power-series-track',ChartTrack);PowerSeriesTrack.prototype={__proto__:ChartTrack.prototype,decorate(viewport){ChartTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('power-series-track');this.heading='Power';this.powerSeries_=undefined;},set powerSeries(powerSeries){this.powerSeries_=powerSeries;this.series=this.buildChartSeries_();this.autoSetAllAxes({expandMax:true});},get hasVisibleContent(){return(this.powerSeries_&&this.powerSeries_.samples.length>0);},addContainersToTrackMap(containerToTrackMap){containerToTrackMap.addContainer(this.powerSeries_,this);},buildChartSeries_(){if(!this.hasVisibleContent)return[];const seriesYAxis=new tr.ui.tracks.ChartSeriesYAxis(0,undefined);const pts=this.powerSeries_.samples.map(function(smpl){return new tr.ui.tracks.ChartPoint(smpl,smpl.start,smpl.powerInW);});const renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:ColorScheme.getColorIdForGeneralPurposeString(this.heading)};return[new tr.ui.tracks.ChartSeries(pts,seriesYAxis,renderingConfig)];}};return{PowerSeriesTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const SpacingTrack=tr.ui.b.define('spacing-track',tr.ui.tracks.Track);SpacingTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('spacing-track');this.heading_=document.createElement('tr-ui-b-heading');Polymer.dom(this).appendChild(this.heading_);},addAllEventsMatchingFilterToSelection(filter,selection){}};return{SpacingTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ContainerTrack=tr.ui.tracks.ContainerTrack;const DeviceTrack=tr.ui.b.define('device-track',ContainerTrack);DeviceTrack.prototype={__proto__:ContainerTrack.prototype,decorate(viewport){ContainerTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('device-track');this.device_=undefined;this.powerSeriesTrack_=undefined;},get device(){return this.device_;},set device(device){this.device_=device;this.updateContents_();},get powerSeriesTrack(){return this.powerSeriesTrack_;},get hasVisibleContent(){return(this.powerSeriesTrack_&&this.powerSeriesTrack_.hasVisibleContent);},addContainersToTrackMap(containerToTrackMap){tr.ui.tracks.ContainerTrack.prototype.addContainersToTrackMap.call(this,containerToTrackMap);containerToTrackMap.addContainer(this.device,this);},addEventsToTrackMap(eventToTrackMap){this.tracks_.forEach(function(track){track.addEventsToTrackMap(eventToTrackMap);});},appendPowerSeriesTrack_(){this.powerSeriesTrack_=new tr.ui.tracks.PowerSeriesTrack(this.viewport);this.powerSeriesTrack_.powerSeries=this.device.powerSeries;if(this.powerSeriesTrack_.hasVisibleContent){Polymer.dom(this).appendChild(this.powerSeriesTrack_);Polymer.dom(this).appendChild(new tr.ui.tracks.SpacingTrack(this.viewport));}},updateContents_(){this.clearTracks_();this.appendPowerSeriesTrack_();}};return{DeviceTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ColorScheme=tr.b.ColorScheme;const DISPLAYED_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.DISPLAYED_SIZE_NUMERIC_NAME;const BACKGROUND=tr.model.ContainerMemoryDump.LevelOfDetail.BACKGROUND;const LIGHT=tr.model.ContainerMemoryDump.LevelOfDetail.LIGHT;const DETAILED=tr.model.ContainerMemoryDump.LevelOfDetail.DETAILED;const SYSTEM_MEMORY_CHART_RENDERING_CONFIG={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:ColorScheme.getColorIdForGeneralPurposeString('systemMemory'),backgroundOpacity:0.8};const SYSTEM_MEMORY_SERIES_NAMES=['Used (KB)','Swapped (KB)'];function extractGlobalMemoryDumpUsedSizes(globalMemoryDump,addSize){for(const[pid,pmd]of
+Object.entries(globalMemoryDump.processMemoryDumps)){const mostRecentVmRegions=pmd.mostRecentVmRegions;if(mostRecentVmRegions===undefined)continue;addSize(pid,mostRecentVmRegions.byteStats.proportionalResident||0,pmd.process.userFriendlyName);}}
+function extractProcessMemoryDumpAllocatorSizes(processMemoryDump,addSize){const allocatorDumps=processMemoryDump.memoryAllocatorDumps;if(allocatorDumps===undefined)return;allocatorDumps.forEach(function(allocatorDump){if(allocatorDump.fullName==='tracing')return;const allocatorSize=allocatorDump.numerics[DISPLAYED_SIZE_NUMERIC_NAME];if(allocatorSize===undefined)return;const allocatorSizeValue=allocatorSize.value;if(allocatorSizeValue===undefined)return;addSize(allocatorDump.fullName,allocatorSizeValue);});}
+function extractGlobalMemoryDumpAllocatorSizes(globalMemoryDump,addSize){for(const pmd of Object.values(globalMemoryDump.processMemoryDumps)){extractProcessMemoryDumpAllocatorSizes(pmd,addSize);}}
+function buildMemoryChartSeries(memoryDumps,dumpSizeExtractor){const dumpCount=memoryDumps.length;const idToTimestampToPoint={};const idToName={};memoryDumps.forEach(function(dump,index){dumpSizeExtractor(dump,function addSize(id,size,opt_name){let timestampToPoint=idToTimestampToPoint[id];if(timestampToPoint===undefined){idToTimestampToPoint[id]=timestampToPoint=new Array(dumpCount);for(let i=0;i<dumpCount;i++){const modelItem=memoryDumps[i];timestampToPoint[i]=new tr.ui.tracks.ChartPoint(modelItem,modelItem.start,0);}}
+timestampToPoint[index].y+=size;if(opt_name!==undefined)idToName[id]=opt_name;});});const ids=Object.keys(idToTimestampToPoint);if(ids.length===0)return undefined;ids.sort();for(let i=0;i<dumpCount;i++){let baseSize=0;for(let j=ids.length-1;j>=0;j--){const point=idToTimestampToPoint[ids[j]][i];point.yBase=baseSize;point.y+=baseSize;baseSize=point.y;}}
+const seriesYAxis=new tr.ui.tracks.ChartSeriesYAxis(0);const series=ids.map(function(id){const colorId=ColorScheme.getColorIdForGeneralPurposeString(idToName[id]||id);const renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId,backgroundOpacity:0.8};return new tr.ui.tracks.ChartSeries(idToTimestampToPoint[id],seriesYAxis,renderingConfig);});series.reverse();return series;}
+function buildMemoryLetterDots(memoryDumps){const backgroundMemoryColorId=ColorScheme.getColorIdForReservedName('background_memory_dump');const lightMemoryColorId=ColorScheme.getColorIdForReservedName('light_memory_dump');const detailedMemoryColorId=ColorScheme.getColorIdForReservedName('detailed_memory_dump');return memoryDumps.map(function(memoryDump){let memoryColorId;switch(memoryDump.levelOfDetail){case BACKGROUND:memoryColorId=backgroundMemoryColorId;break;case DETAILED:memoryColorId=detailedMemoryColorId;break;case LIGHT:default:memoryColorId=lightMemoryColorId;}
 return new tr.ui.tracks.LetterDot(memoryDump,'M',memoryColorId,memoryDump.start);});}
-function buildGlobalUsedMemoryChartSeries(globalMemoryDumps){var containsVmRegions=globalMemoryDumps.some(function(globalDump){for(var pid in globalDump.processMemoryDumps)
-if(globalDump.processMemoryDumps[pid].mostRecentVmRegions)
-return true;return false;});if(!containsVmRegions)
-return undefined;var pidToProcess={};globalMemoryDumps.forEach(function(globalDump){tr.b.iterItems(globalDump.processMemoryDumps,function(pid,processDump){pidToProcess[pid]=processDump.process;});});var pidToPoints={};tr.b.iterItems(pidToProcess,function(pid,process){pidToPoints[pid]=[];});globalMemoryDumps.forEach(function(globalDump){var pssBase=0;tr.b.iterItems(pidToPoints,function(pid,points){var processMemoryDump=globalDump.processMemoryDumps[pid];var cumulativePss=pssBase;if(processMemoryDump!==undefined){var vmRegions=processMemoryDump.mostRecentVmRegions;if(vmRegions!==undefined)
-cumulativePss+=vmRegions.byteStats.proportionalResident||0;}
-points.push(new tr.ui.tracks.ChartPoint(globalDump,globalDump.start,cumulativePss,pssBase));pssBase=cumulativePss;});});var axis=new tr.ui.tracks.ChartAxis(0);var series=[];tr.b.iterItems(pidToPoints,function(pid,points){var process=pidToProcess[pid];var colorId=ColorScheme.getColorIdForGeneralPurposeString(process.userFriendlyName);var renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:colorId,backgroundOpacity:0.8};series.push(new tr.ui.tracks.ChartSeries(points,axis,renderingConfig));});series.reverse();return series;}
-function buildProcessAllocatedMemoryChartSeries(processMemoryDumps){return buildAllocatedMemoryChartSeries(processMemoryDumps,getProcessMemoryDumpAllocatorSizes);}
-function buildGlobalAllocatedMemoryChartSeries(globalMemoryDumps){return buildAllocatedMemoryChartSeries(globalMemoryDumps,getGlobalMemoryDumpAllocatorSizes);}
-return{buildMemoryLetterDots:buildMemoryLetterDots,buildGlobalUsedMemoryChartSeries:buildGlobalUsedMemoryChartSeries,buildProcessAllocatedMemoryChartSeries:buildProcessAllocatedMemoryChartSeries,buildGlobalAllocatedMemoryChartSeries:buildGlobalAllocatedMemoryChartSeries};});'use strict';tr.exportTo('tr.ui.tracks',function(){var USED_MEMORY_TRACK_HEIGHT=50;var ALLOCATED_MEMORY_TRACK_HEIGHT=50;var GlobalMemoryDumpTrack=tr.ui.b.define('global-memory-dump-track',tr.ui.tracks.ContainerTrack);GlobalMemoryDumpTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.memoryDumps_=undefined;},get memoryDumps(){return this.memoryDumps_;},set memoryDumps(memoryDumps){this.memoryDumps_=memoryDumps;this.updateContents_();},updateContents_:function(){this.clearTracks_();if(!this.memoryDumps_||!this.memoryDumps_.length)
-return;this.appendDumpDotsTrack_();this.appendUsedMemoryTrack_();this.appendAllocatedMemoryTrack_();},appendDumpDotsTrack_:function(){var items=tr.ui.tracks.buildMemoryLetterDots(this.memoryDumps_);if(!items)
-return;var track=new tr.ui.tracks.LetterDotTrack(this.viewport);track.heading='Memory Dumps';track.items=items;this.appendChild(track);},appendUsedMemoryTrack_:function(){var series=tr.ui.tracks.buildGlobalUsedMemoryChartSeries(this.memoryDumps_);if(!series)
-return;var track=new tr.ui.tracks.ChartTrack(this.viewport);track.heading='Memory per process';track.height=USED_MEMORY_TRACK_HEIGHT+'px';track.series=series;track.autoSetAllAxes({expandMax:true});this.appendChild(track);},appendAllocatedMemoryTrack_:function(){var series=tr.ui.tracks.buildGlobalAllocatedMemoryChartSeries(this.memoryDumps_);if(!series)
-return;var track=new tr.ui.tracks.ChartTrack(this.viewport);track.heading='Memory per component';track.height=ALLOCATED_MEMORY_TRACK_HEIGHT+'px';track.series=series;track.autoSetAllAxes({expandMax:true});this.appendChild(track);}};return{GlobalMemoryDumpTrack:GlobalMemoryDumpTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){function Highlighter(viewport){if(viewport===undefined){throw new Error('viewport must be provided');}
-this.viewport_=viewport;};Highlighter.prototype={__proto__:Object.prototype,processModel:function(model){throw new Error('processModel implementation missing');},drawHighlight:function(ctx,dt,viewLWorld,viewRWorld,viewHeight){throw new Error('drawHighlight implementation missing');}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Highlighter;tr.b.decorateExtensionRegistry(Highlighter,options);return{Highlighter:Highlighter};});'use strict';tr.exportTo('tr.model',function(){var Settings=tr.b.Settings;function ModelSettings(model){this.model=model;this.objectsByKey_=[];this.nonuniqueKeys_=[];this.buildObjectsByKeyMap_();this.removeNonuniqueKeysFromSettings_();this.ephemeralSettingsByGUID_={};}
-ModelSettings.prototype={buildObjectsByKeyMap_:function(){var objects=[];this.model.iterateAllPersistableObjects(function(o){objects.push(o);});var objectsByKey={};var NONUNIQUE_KEY='nonuniqueKey';for(var i=0;i<objects.length;i++){var object=objects[i];var objectKey=object.getSettingsKey();if(!objectKey)
-continue;if(objectsByKey[objectKey]===undefined){objectsByKey[objectKey]=object;continue;}
+function buildGlobalUsedMemoryChartSeries(globalMemoryDumps){return buildMemoryChartSeries(globalMemoryDumps,extractGlobalMemoryDumpUsedSizes);}
+function buildProcessAllocatedMemoryChartSeries(processMemoryDumps){return buildMemoryChartSeries(processMemoryDumps,extractProcessMemoryDumpAllocatorSizes);}
+function buildGlobalAllocatedMemoryChartSeries(globalMemoryDumps){return buildMemoryChartSeries(globalMemoryDumps,extractGlobalMemoryDumpAllocatorSizes);}
+function buildSystemMemoryChartSeries(model){if(model.kernel.counters===undefined)return;const memoryCounter=model.kernel.counters['global.SystemMemory'];if(memoryCounter===undefined)return;const tracks=[];for(const name of SYSTEM_MEMORY_SERIES_NAMES){const series=memoryCounter.series.find(series=>series.name===name);if(series===undefined||series.samples.length===0)return;const chartPoints=[];const valueRange=new tr.b.math.Range();for(const sample of series.samples){chartPoints.push(new tr.ui.tracks.ChartPoint(sample,sample.timestamp,sample.value,0));valueRange.addValue(sample.value);}
+const baseLine=Math.max(0,valueRange.min-valueRange.range);const axisY=new tr.ui.tracks.ChartSeriesYAxis(baseLine,valueRange.max);const chartSeries=[new tr.ui.tracks.ChartSeries(chartPoints,axisY,SYSTEM_MEMORY_CHART_RENDERING_CONFIG)];tracks.push({name:'System Memory '+name,series:chartSeries});}
+return tracks;}
+return{buildMemoryLetterDots,buildGlobalUsedMemoryChartSeries,buildProcessAllocatedMemoryChartSeries,buildGlobalAllocatedMemoryChartSeries,buildSystemMemoryChartSeries,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const USED_MEMORY_TRACK_HEIGHT=50;const ALLOCATED_MEMORY_TRACK_HEIGHT=50;const GlobalMemoryDumpTrack=tr.ui.b.define('global-memory-dump-track',tr.ui.tracks.ContainerTrack);GlobalMemoryDumpTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.memoryDumps_=undefined;},get memoryDumps(){return this.memoryDumps_;},set memoryDumps(memoryDumps){this.memoryDumps_=memoryDumps;this.updateContents_();},updateContents_(){this.clearTracks_();if(!this.memoryDumps_||!this.memoryDumps_.length)return;this.appendDumpDotsTrack_();this.appendUsedMemoryTrack_();this.appendAllocatedMemoryTrack_();},appendDumpDotsTrack_(){const items=tr.ui.tracks.buildMemoryLetterDots(this.memoryDumps_);if(!items)return;const track=new tr.ui.tracks.LetterDotTrack(this.viewport);track.heading='Memory Dumps';track.items=items;Polymer.dom(this).appendChild(track);},appendUsedMemoryTrack_(){const tracks=[];const perProcessSeries=tr.ui.tracks.buildGlobalUsedMemoryChartSeries(this.memoryDumps_);if(perProcessSeries!==undefined){tracks.push({name:'Memory per process',series:perProcessSeries});}else{tracks.push.apply(tracks,tr.ui.tracks.buildSystemMemoryChartSeries(this.memoryDumps_[0].model));}
+for(const{name,series}of tracks){const track=new tr.ui.tracks.ChartTrack(this.viewport);track.heading=name;track.height=USED_MEMORY_TRACK_HEIGHT+'px';track.series=series;track.autoSetAllAxes({expandMax:true});Polymer.dom(this).appendChild(track);}},appendAllocatedMemoryTrack_(){const series=tr.ui.tracks.buildGlobalAllocatedMemoryChartSeries(this.memoryDumps_);if(!series)return;const track=new tr.ui.tracks.ChartTrack(this.viewport);track.heading='Memory per component';track.height=ALLOCATED_MEMORY_TRACK_HEIGHT+'px';track.series=series;track.autoSetAllAxes({expandMax:true});Polymer.dom(this).appendChild(track);}};return{GlobalMemoryDumpTrack,};});'use strict';tr.exportTo('tr.ui.b',function(){function FastRectRenderer(ctx,xMin,xMax,minRectSize,maxMergeDist,palette){this.ctx_=ctx;this.xMin_=xMin;this.xMax_=xMax;this.minRectSize_=minRectSize;this.maxMergeDist_=maxMergeDist;this.palette_=palette;}
+FastRectRenderer.prototype={y_:0,h_:0,merging_:false,mergeStartX_:0,mergeCurRight_:0,mergedColorId_:0,mergedAlpha_:0,setYandH(y,h){if(this.y_===y&&this.h_===h){return;}
+this.flush();this.y_=y;this.h_=h;},fillRect(x,w,colorId,alpha){const r=x+w;if(w<this.minRectSize_){if(r-this.mergeStartX_>this.maxMergeDist_){this.flush();}
+if(!this.merging_){this.merging_=true;this.mergeStartX_=x;this.mergeCurRight_=r;this.mergedColorId_=colorId;this.mergedAlpha_=alpha;}else{this.mergeCurRight_=r;if(this.mergedAlpha_<alpha||(this.mergedAlpha_===alpha&&this.mergedColorId_<colorId)){this.mergedAlpha_=alpha;this.mergedColorId_=colorId;}}}else{if(this.merging_){this.flush();}
+this.ctx_.fillStyle=this.palette_[colorId];this.ctx_.globalAlpha=alpha;const xLeft=Math.max(x,this.xMin_);const xRight=Math.min(r,this.xMax_);if(xLeft<xRight){this.ctx_.fillRect(xLeft,this.y_,xRight-xLeft,this.h_);}}},flush(){if(this.merging_){this.ctx_.fillStyle=this.palette_[this.mergedColorId_];this.ctx_.globalAlpha=this.mergedAlpha_;const xLeft=Math.max(this.mergeStartX_,this.xMin_);const xRight=Math.min(this.mergeCurRight_,this.xMax_);if(xLeft<xRight){this.ctx_.fillRect(xLeft,this.y_,xRight-xLeft,this.h_);}
+this.merging_=false;}}};return{FastRectRenderer,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const RectTrack=tr.ui.b.define('rect-track',tr.ui.tracks.Track);RectTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('rect-track');this.asyncStyle_=false;this.rects_=null;this.heading_=document.createElement('tr-ui-b-heading');Polymer.dom(this).appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},set selectionGenerator(generator){this.heading_.selectionGenerator=generator;},set expanded(expanded){this.heading_.expanded=!!expanded;},set arrowVisible(arrowVisible){this.heading_.arrowVisible=!!arrowVisible;},get expanded(){return this.heading_.expanded;},get asyncStyle(){return this.asyncStyle_;},set asyncStyle(v){this.asyncStyle_=!!v;},get rects(){return this.rects_;},set rects(rects){this.rects_=rects||[];this.invalidateDrawingContainer();},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;this.invalidateDrawingContainer();},get hasVisibleContent(){return this.rects_.length>0;},draw(type,viewLWorld,viewRWorld,viewHeight){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawRects_(viewLWorld,viewRWorld);break;}},drawRects_(viewLWorld,viewRWorld){const ctx=this.context();ctx.save();const bounds=this.getBoundingClientRect();tr.ui.b.drawSlices(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,bounds.height,this.rects_,this.asyncStyle_);ctx.restore();if(bounds.height<=6)return;let fontSize;let yOffset;if(bounds.height<15){fontSize=6;yOffset=1.0;}else{fontSize=10;yOffset=2.5;}
+tr.ui.b.drawLabels(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,this.rects_,this.asyncStyle_,fontSize,yOffset);},addEventsToTrackMap(eventToTrackMap){if(this.rects_===undefined||this.rects_===null){return;}
+this.rects_.forEach(function(rect){rect.addToTrackMap(eventToTrackMap,this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection){function onRect(rect){rect.addToSelection(selection);}
+onRect=onRect.bind(this);const instantEventWidth=2*viewPixWidthWorld;tr.b.iterateOverIntersectingIntervals(this.rects_,function(x){return x.start;},function(x){return x.duration===0?x.duration+instantEventWidth:x.duration;},loWX,hiWX,onRect);},addEventNearToProvidedEventToSelection(event,offset,selection){const index=this.rects_.findIndex(rect=>rect.modelItem===event);if(index===-1)return false;const newIndex=index+offset;if(newIndex<0||newIndex>=this.rects_.length)return false;this.rects_[newIndex].addToSelection(selection);return true;},addAllEventsMatchingFilterToSelection(filter,selection){for(let i=0;i<this.rects_.length;++i){const modelItem=this.rects_[i].modelItem;if(!modelItem)continue;if(filter.matchSlice(modelItem)){selection.push(modelItem);}}},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){const rect=tr.b.findClosestIntervalInSortedIntervals(this.rects_,function(x){return x.start;},function(x){return x.end;},worldX,worldMaxDist);if(!rect)return;rect.addToSelection(selection);}};function Rect(modelItem,title,colorId,start,duration){tr.model.ProxySelectableItem.call(this,modelItem);this.title=title;this.colorId=colorId;this.start=start;this.duration=duration;this.end=start+duration;}
+Rect.prototype={__proto__:tr.model.ProxySelectableItem.prototype};return{RectTrack,Rect,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const SliceTrack=tr.ui.b.define('slice-track',tr.ui.tracks.RectTrack);SliceTrack.prototype={__proto__:tr.ui.tracks.RectTrack.prototype,decorate(viewport){tr.ui.tracks.RectTrack.prototype.decorate.call(this,viewport);},get slices(){return this.rects;},set slices(slices){this.rects=slices;}};return{SliceTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const CpuTrack=tr.ui.b.define('cpu-track',tr.ui.tracks.ContainerTrack);CpuTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('cpu-track');this.detailedMode_=true;},get cpu(){return this.cpu_;},set cpu(cpu){this.cpu_=cpu;this.updateContents_();},get detailedMode(){return this.detailedMode_;},set detailedMode(detailedMode){this.detailedMode_=detailedMode;this.updateContents_();},get tooltip(){return this.tooltip_;},set tooltip(value){this.tooltip_=value;this.updateContents_();},get hasVisibleContent(){if(this.cpu_===undefined)return false;const cpu=this.cpu_;if(cpu.slices.length)return true;if(cpu.samples&&cpu.samples.length)return true;if(Object.keys(cpu.counters).length>0)return true;return false;},updateContents_(){this.detach();if(!this.cpu_)return;const slices=this.cpu_.slices;if(slices.length){const track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;track.heading=this.cpu_.userFriendlyName+':';Polymer.dom(this).appendChild(track);}
+if(this.detailedMode_){this.appendSamplesTracks_();for(const counterName in this.cpu_.counters){const counter=this.cpu_.counters[counterName];const track=new tr.ui.tracks.CounterTrack(this.viewport);track.heading=this.cpu_.userFriendlyName+' '+
+counter.name+':';track.counter=counter;Polymer.dom(this).appendChild(track);}}},appendSamplesTracks_(){const samples=this.cpu_.samples;if(samples===undefined||samples.length===0){return;}
+const samplesByTitle={};samples.forEach(function(sample){if(samplesByTitle[sample.title]===undefined){samplesByTitle[sample.title]=[];}
+samplesByTitle[sample.title].push(sample);});const sampleTitles=Object.keys(samplesByTitle);sampleTitles.sort();sampleTitles.forEach(function(sampleTitle){const samples=samplesByTitle[sampleTitle];const samplesTrack=new tr.ui.tracks.SliceTrack(this.viewport);samplesTrack.group=this.cpu_;samplesTrack.slices=samples;samplesTrack.heading=this.cpu_.userFriendlyName+': '+
+sampleTitle;samplesTrack.tooltip=this.cpu_.userFriendlyDetails;samplesTrack.selectionGenerator=function(){const selection=new tr.model.EventSet();for(let i=0;i<samplesTrack.slices.length;i++){selection.push(samplesTrack.slices[i]);}
+return selection;};Polymer.dom(this).appendChild(samplesTrack);},this);}};return{CpuTrack,};});'use strict';tr.exportTo('tr.model',function(){const Settings=tr.b.Settings;function ModelSettings(model){this.model=model;this.objectsByKey_=[];this.nonuniqueKeys_=[];this.buildObjectsByKeyMap_();this.removeNonuniqueKeysFromSettings_();this.ephemeralSettingsByGUID_={};}
+ModelSettings.prototype={buildObjectsByKeyMap_(){const objects=[];this.model.iterateAllPersistableObjects(function(o){objects.push(o);});const objectsByKey={};const NONUNIQUE_KEY='nonuniqueKey';for(let i=0;i<objects.length;i++){const object=objects[i];const objectKey=object.getSettingsKey();if(!objectKey)continue;if(objectsByKey[objectKey]===undefined){objectsByKey[objectKey]=object;continue;}
 objectsByKey[objectKey]=NONUNIQUE_KEY;}
-var nonuniqueKeys={};tr.b.dictionaryKeys(objectsByKey).forEach(function(objectKey){if(objectsByKey[objectKey]!==NONUNIQUE_KEY)
-return;delete objectsByKey[objectKey];nonuniqueKeys[objectKey]=true;});this.nonuniqueKeys=nonuniqueKeys;this.objectsByKey_=objectsByKey;},removeNonuniqueKeysFromSettings_:function(){var settings=Settings.get('trace_model_settings',{});var settingsChanged=false;tr.b.dictionaryKeys(settings).forEach(function(objectKey){if(!this.nonuniqueKeys[objectKey])
-return;settingsChanged=true;delete settings[objectKey];},this);if(settingsChanged)
-Settings.set('trace_model_settings',settings);},hasUniqueSettingKey:function(object){var objectKey=object.getSettingsKey();if(!objectKey)
-return false;return this.objectsByKey_[objectKey]!==undefined;},getSettingFor:function(object,objectLevelKey,defaultValue){var objectKey=object.getSettingsKey();if(!objectKey||!this.objectsByKey_[objectKey]){var settings=this.getEphemeralSettingsFor_(object);var ephemeralValue=settings[objectLevelKey];if(ephemeralValue!==undefined)
-return ephemeralValue;return defaultValue;}
-var settings=Settings.get('trace_model_settings',{});if(!settings[objectKey])
-settings[objectKey]={};var value=settings[objectKey][objectLevelKey];if(value!==undefined)
-return value;return defaultValue;},setSettingFor:function(object,objectLevelKey,value){var objectKey=object.getSettingsKey();if(!objectKey||!this.objectsByKey_[objectKey]){this.getEphemeralSettingsFor_(object)[objectLevelKey]=value;return;}
-var settings=Settings.get('trace_model_settings',{});if(!settings[objectKey])
-settings[objectKey]={};if(settings[objectKey][objectLevelKey]===value)
-return;settings[objectKey][objectLevelKey]=value;Settings.set('trace_model_settings',settings);},getEphemeralSettingsFor_:function(object){if(object.guid===undefined)
-throw new Error('Only objects with GUIDs can be persisted');if(this.ephemeralSettingsByGUID_[object.guid]===undefined)
-this.ephemeralSettingsByGUID_[object.guid]={};return this.ephemeralSettingsByGUID_[object.guid];}};return{ModelSettings:ModelSettings};});'use strict';tr.exportTo('tr.ui.tracks',function(){var CounterTrack=tr.ui.b.define('counter-track',tr.ui.tracks.ChartTrack);CounterTrack.prototype={__proto__:tr.ui.tracks.ChartTrack.prototype,decorate:function(viewport){tr.ui.tracks.ChartTrack.prototype.decorate.call(this,viewport);this.classList.add('counter-track');},get counter(){return this.chart;},set counter(counter){this.heading=counter.name+': ';this.series=CounterTrack.buildChartSeriesFromCounter(counter);this.autoSetAllAxes({expandMax:true});},getModelEventFromItem:function(chartValue){return chartValue;}};CounterTrack.buildChartSeriesFromCounter=function(counter){var numSeries=counter.series.length;var totals=counter.totals;var chartAxis=new tr.ui.tracks.ChartAxis(0,undefined);var chartSeries=counter.series.map(function(series,seriesIndex){var chartPoints=series.samples.map(function(sample,sampleIndex){var total=totals[sampleIndex*numSeries+seriesIndex];return new tr.ui.tracks.ChartPoint(sample,sample.timestamp,total);});var renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:series.color};return new tr.ui.tracks.ChartSeries(chartPoints,chartAxis,renderingConfig);});chartSeries.reverse();return chartSeries;};return{CounterTrack:CounterTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var startCompare=function(x,y){return x.start-y.start;}
-var FrameTrack=tr.ui.b.define('frame-track',tr.ui.tracks.LetterDotTrack);FrameTrack.prototype={__proto__:tr.ui.tracks.LetterDotTrack.prototype,decorate:function(viewport){tr.ui.tracks.LetterDotTrack.prototype.decorate.call(this,viewport);this.heading='Frames';this.frames_=undefined;this.items=undefined;},get frames(){return this.frames_;},set frames(frames){this.frames_=frames;if(frames===undefined)
-return;this.frames_=this.frames_.slice();this.frames_.sort(startCompare);this.items=this.frames_.map(function(frame){return new FrameDot(frame);});}};function FrameDot(frame){tr.ui.tracks.LetterDot.call(this,frame,'F',frame.colorId,frame.start);}
-FrameDot.prototype={__proto__:tr.ui.tracks.LetterDot.prototype};return{FrameTrack:FrameTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var MultiRowTrack=tr.ui.b.define('multi-row-track',tr.ui.tracks.ContainerTrack);MultiRowTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.tooltip_='';this.heading_='';this.groupingSource_=undefined;this.itemsToGroup_=undefined;this.defaultToCollapsedWhenSubRowCountMoreThan=1;this.itemsGroupedOnLastUpdateContents_=undefined;this.currentSubRows_=[];this.expanded_=true;},get itemsToGroup(){return this.itemsToGroup_;},setItemsToGroup:function(itemsToGroup,opt_groupingSource){this.itemsToGroup_=itemsToGroup;this.groupingSource_=opt_groupingSource;this.updateContents_();this.updateExpandedStateFromGroupingSource_();},get heading(){return this.heading_;},set heading(h){this.heading_=h;this.updateContents_();},get tooltip(){return this.tooltip_;},set tooltip(t){this.tooltip_=t;this.updateContents_();},get subRows(){return this.currentSubRows_;},get hasVisibleContent(){return this.children.length>0;},get expanded(){return this.expanded_;},set expanded(expanded){if(this.expanded_==expanded)
-return;this.expanded_=expanded;this.expandedStateChanged_();},onHeadingClicked_:function(e){if(this.subRows.length<=1)
-return;this.expanded=!this.expanded;if(this.groupingSource_){var modelSettings=new tr.model.ModelSettings(this.groupingSource_.model);modelSettings.setSettingFor(this.groupingSource_,'expanded',this.expanded);}
-e.stopPropagation();},updateExpandedStateFromGroupingSource_:function(){if(this.groupingSource_){var numSubRows=this.subRows.length;var modelSettings=new tr.model.ModelSettings(this.groupingSource_.model);if(numSubRows>1){var defaultExpanded;if(numSubRows>this.defaultToCollapsedWhenSubRowCountMoreThan){defaultExpanded=false;}else{defaultExpanded=true;}
-this.expanded=modelSettings.getSettingFor(this.groupingSource_,'expanded',defaultExpanded);}else{this.expanded=undefined;}}},expandedStateChanged_:function(){var minH=Math.max(2,Math.ceil(18/this.children.length));var h=(this.expanded_?18:minH)+'px';for(var i=0;i<this.children.length;i++){this.children[i].height=h;if(i===0)
-this.children[i].arrowVisible=true;this.children[i].expanded=this.expanded;}
-if(this.children.length===1){this.children[0].expanded=true;this.children[0].arrowVisible=false;}},updateContents_:function(){tr.ui.tracks.ContainerTrack.prototype.updateContents_.call(this);if(!this.itemsToGroup_){this.updateHeadingAndTooltip_();this.currentSubRows_=[];return;}
-if(this.areArrayContentsSame_(this.itemsGroupedOnLastUpdateContents_,this.itemsToGroup_)){this.updateHeadingAndTooltip_();return;}
-this.itemsGroupedOnLastUpdateContents_=this.itemsToGroup_;this.detach();if(!this.itemsToGroup_.length){this.currentSubRows_=[];return;}
-var subRows=this.buildSubRows_(this.itemsToGroup_);this.currentSubRows_=subRows;for(var srI=0;srI<subRows.length;srI++){var subRow=subRows[srI];if(!subRow.length)
-continue;var track=this.addSubTrack_(subRow);track.addEventListener('heading-clicked',this.onHeadingClicked_.bind(this));}
-this.updateHeadingAndTooltip_();this.expandedStateChanged_();},updateHeadingAndTooltip_:function(){if(!this.firstChild)
-return;this.firstChild.heading=this.heading_;this.firstChild.tooltip=this.tooltip_;},buildSubRows_:function(itemsToGroup){throw new Error('Not implemented');},addSubTrack_:function(subRowItems){throw new Error('Not implemented');},areArrayContentsSame_:function(a,b){if(!a||!b)
-return false;if(!a.length||!b.length)
-return false;if(a.length!=b.length)
-return false;for(var i=0;i<a.length;++i){if(a[i]!=b[i])
-return false;}
-return true;}};return{MultiRowTrack:MultiRowTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ObjectInstanceGroupTrack=tr.ui.b.define('object-instance-group-track',tr.ui.tracks.MultiRowTrack);ObjectInstanceGroupTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate:function(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);this.classList.add('object-instance-group-track');this.objectInstances_=undefined;},get objectInstances(){return this.itemsToGroup;},set objectInstances(objectInstances){this.setItemsToGroup(objectInstances);},addSubTrack_:function(objectInstances){var hasMultipleRows=this.subRows.length>1;var track=new tr.ui.tracks.ObjectInstanceTrack(this.viewport);track.objectInstances=objectInstances;this.appendChild(track);return track;},buildSubRows_:function(objectInstances){objectInstances.sort(function(x,y){return x.creationTs-y.creationTs;});var subRows=[];for(var i=0;i<objectInstances.length;i++){var objectInstance=objectInstances[i];var found=false;for(var j=0;j<subRows.length;j++){var subRow=subRows[j];var lastItemInSubRow=subRow[subRow.length-1];if(objectInstance.creationTs>=lastItemInSubRow.deletionTs){found=true;subRow.push(objectInstance);break;}}
-if(!found){var subRow=[objectInstance];subRows.push(subRow);}}
-return subRows;},updateHeadingAndTooltip_:function(){}};return{ObjectInstanceGroupTrack:ObjectInstanceGroupTrack};});'use strict';tr.exportTo('tr.ui.b',function(){function FastRectRenderer(ctx,minRectSize,maxMergeDist,pallette){this.ctx_=ctx;this.minRectSize_=minRectSize;this.maxMergeDist_=maxMergeDist;this.pallette_=pallette;}
-FastRectRenderer.prototype={y_:0,h_:0,merging_:false,mergeStartX_:0,mergeCurRight_:0,mergedColorId_:0,mergedAlpha_:0,setYandH:function(y,h){if(this.y_===y&&this.h_===h)
-return;this.flush();this.y_=y;this.h_=h;},fillRect:function(x,w,colorId,alpha){var r=x+w;if(w<this.minRectSize_){if(r-this.mergeStartX_>this.maxMergeDist_)
-this.flush();if(!this.merging_){this.merging_=true;this.mergeStartX_=x;this.mergeCurRight_=r;this.mergedColorId_=colorId;this.mergedAlpha_=alpha;}else{this.mergeCurRight_=r;if(this.mergedAlpha_<alpha||(this.mergedAlpha_===alpha&&this.mergedColorId_<colorId)){this.mergedAlpha_=alpha;this.mergedColorId_=colorId;}}}else{if(this.merging_)
-this.flush();this.ctx_.fillStyle=this.pallette_[colorId];this.ctx_.globalAlpha=alpha;this.ctx_.fillRect(x,this.y_,w,this.h_);}},flush:function(){if(this.merging_){this.ctx_.fillStyle=this.pallette_[this.mergedColorId_];this.ctx_.globalAlpha=this.mergedAlpha_;this.ctx_.fillRect(this.mergeStartX_,this.y_,this.mergeCurRight_-this.mergeStartX_,this.h_);this.merging_=false;}}};return{FastRectRenderer:FastRectRenderer};});'use strict';tr.exportTo('tr.ui.tracks',function(){var RectTrack=tr.ui.b.define('rect-track',tr.ui.tracks.Track);RectTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('rect-track');this.asyncStyle_=false;this.rects_=null;this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},set selectionGenerator(generator){this.heading_.selectionGenerator=generator;},set expanded(expanded){this.heading_.expanded=!!expanded;},set arrowVisible(arrowVisible){this.heading_.arrowVisible=!!arrowVisible;},get expanded(){return this.heading_.expanded;},get asyncStyle(){return this.asyncStyle_;},set asyncStyle(v){this.asyncStyle_=!!v;},get rects(){return this.rects_;},set rects(rects){this.rects_=rects||[];this.invalidateDrawingContainer();},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;this.invalidateDrawingContainer();},get hasVisibleContent(){return this.rects_.length>0;},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawRects_(viewLWorld,viewRWorld);break;}},drawRects_:function(viewLWorld,viewRWorld){var ctx=this.context();ctx.save();var bounds=this.getBoundingClientRect();tr.ui.b.drawSlices(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,bounds.height,this.rects_,this.asyncStyle_);ctx.restore();if(bounds.height<=6)
-return;var fontSize,yOffset;if(bounds.height<15){fontSize=6;yOffset=1.0;}else{fontSize=10;yOffset=2.5;}
-tr.ui.b.drawLabels(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,this.rects_,this.asyncStyle_,fontSize,yOffset);},addEventsToTrackMap:function(eventToTrackMap){if(this.rects_===undefined||this.rects_===null)
-return;this.rects_.forEach(function(rect){rect.addToTrackMap(eventToTrackMap,this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){function onRect(rect){rect.addToSelection(selection);}
-onRect=onRect.bind(this);var instantEventWidth=2*viewPixWidthWorld;tr.b.iterateOverIntersectingIntervals(this.rects_,function(x){return x.start;},function(x){return x.duration==0?x.duration+instantEventWidth:x.duration;},loWX,hiWX,onRect);},addEventNearToProvidedEventToSelection:function(event,offset,selection){var index=tr.b.findFirstIndexInArray(this.rects_,function(rect){return rect.modelItem===event;});if(index===-1)
-return false;var newIndex=index+offset;if(newIndex<0||newIndex>=this.rects_.length)
-return false;this.rects_[newIndex].addToSelection(selection);return true;},addAllEventsMatchingFilterToSelection:function(filter,selection){for(var i=0;i<this.rects_.length;++i){var modelItem=this.rects_[i].modelItem;if(!modelItem)
-continue;if(filter.matchSlice(modelItem))
-selection.push(modelItem);}},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){var rect=tr.b.findClosestIntervalInSortedIntervals(this.rects_,function(x){return x.start;},function(x){return x.end;},worldX,worldMaxDist);if(!rect)
-return;rect.addToSelection(selection);}};function Rect(modelItem,title,colorId,start,duration){tr.model.ProxySelectableItem.call(this,modelItem);this.title=title;this.colorId=colorId;this.start=start;this.duration=duration;this.end=start+duration;};Rect.prototype={__proto__:tr.model.ProxySelectableItem.prototype};return{RectTrack:RectTrack,Rect:Rect};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ColorScheme=tr.b.ColorScheme;var ProcessSummaryTrack=tr.ui.b.define('process-summary-track',tr.ui.tracks.RectTrack);ProcessSummaryTrack.buildRectsFromProcess=function(process){if(!process)
-return[];var ops=[];var pushOp=function(isStart,time,slice){ops.push({isStart:isStart,time:time,slice:slice});};for(var tid in process.threads){var sliceGroup=process.threads[tid].sliceGroup;sliceGroup.topLevelSlices.forEach(function(slice){pushOp(true,slice.start,undefined);pushOp(false,slice.end,undefined);});sliceGroup.slices.forEach(function(slice){if(slice.important){pushOp(true,slice.start,slice);pushOp(false,slice.end,slice);}});}
-ops.sort(function(a,b){return a.time-b.time;});var rects=[];var genericColorId=ColorScheme.getColorIdForReservedName('generic_work');var pushRect=function(start,end,slice){rects.push(new tr.ui.tracks.Rect(slice,slice?slice.title:'',slice?slice.colorId:genericColorId,start,end-start));}
-var depth=0;var currentSlice=undefined;var lastStart=undefined;ops.forEach(function(op){depth+=op.isStart?1:-1;if(currentSlice){if(!op.isStart&&op.slice==currentSlice){pushRect(lastStart,op.time,currentSlice);lastStart=depth>=1?op.time:undefined;currentSlice=undefined;}}else{if(op.isStart){if(depth==1){lastStart=op.time;currentSlice=op.slice;}else if(op.slice){if(op.time!=lastStart){pushRect(lastStart,op.time,undefined);lastStart=op.time;}
-currentSlice=op.slice;}}else{if(depth==0){pushRect(lastStart,op.time,undefined);lastStart=undefined;}}}});return rects;};ProcessSummaryTrack.prototype={__proto__:tr.ui.tracks.RectTrack.prototype,decorate:function(viewport){tr.ui.tracks.RectTrack.prototype.decorate.call(this,viewport);},get process(){return this.process_;},set process(process){this.process_=process;this.rects=ProcessSummaryTrack.buildRectsFromProcess(process);}};return{ProcessSummaryTrack:ProcessSummaryTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SliceTrack=tr.ui.b.define('slice-track',tr.ui.tracks.RectTrack);SliceTrack.prototype={__proto__:tr.ui.tracks.RectTrack.prototype,decorate:function(viewport){tr.ui.tracks.RectTrack.prototype.decorate.call(this,viewport);},get slices(){return this.rects;},set slices(slices){this.rects=slices;}};return{SliceTrack:SliceTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var AsyncSliceGroupTrack=tr.ui.b.define('async-slice-group-track',tr.ui.tracks.MultiRowTrack);AsyncSliceGroupTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate:function(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);this.classList.add('async-slice-group-track');this.group_=undefined;},addSubTrack_:function(slices){var track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;this.appendChild(track);track.asyncStyle=true;return track;},get group(){return this.group_;},set group(group){this.group_=group;this.setItemsToGroup(this.group_.slices,this.group_);},get eventContainer(){return this.group;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.MultiRowTrack.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.group,this);},buildSubRows_:function(slices,opt_skipSort){if(!opt_skipSort){slices.sort(function(x,y){return x.start-y.start;});}
-var findLevel=function(sliceToPut,rows,n){if(n>=rows.length)
-return true;var subRow=rows[n];var lastSliceInSubRow=subRow[subRow.length-1];if(sliceToPut.start>=lastSliceInSubRow.end){if(sliceToPut.subSlices===undefined||sliceToPut.subSlices.length===0){return true;}
-for(var i=0;i<sliceToPut.subSlices.length;i++){if(!findLevel(sliceToPut.subSlices[i],rows,n+1))
-return false;}
-return true;}
-return false;};var subRows=[];for(var i=0;i<slices.length;i++){var slice=slices[i];var found=false;var index=subRows.length;for(var j=0;j<subRows.length;j++){if(findLevel(slice,subRows,j)){found=true;index=j;break;}}
-if(!found)
-subRows.push([]);subRows[index].push(slice);var fitSubSlicesRecursively=function(subSlices,level,rows){if(subSlices===undefined||subSlices.length===0)
-return;if(level===rows.length)
-rows.push([]);for(var h=0;h<subSlices.length;h++){rows[level].push(subSlices[h]);fitSubSlicesRecursively(subSlices[h].subSlices,level+1,rows);}};fitSubSlicesRecursively(slice.subSlices,index+1,subRows);}
-return subRows;}};return{AsyncSliceGroupTrack:AsyncSliceGroupTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SampleTrack=tr.ui.b.define('sample-track',tr.ui.tracks.RectTrack);SampleTrack.prototype={__proto__:tr.ui.tracks.RectTrack.prototype,decorate:function(viewport){tr.ui.tracks.RectTrack.prototype.decorate.call(this,viewport);},get samples(){return this.rects;},set samples(samples){this.rects=samples;}};return{SampleTrack:SampleTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SliceGroupTrack=tr.ui.b.define('slice-group-track',tr.ui.tracks.MultiRowTrack);SliceGroupTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate:function(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);this.classList.add('slice-group-track');this.group_=undefined;this.defaultToCollapsedWhenSubRowCountMoreThan=100;},addSubTrack_:function(slices){var track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;this.appendChild(track);return track;},get group(){return this.group_;},set group(group){this.group_=group;this.setItemsToGroup(this.group_.slices,this.group_);},get eventContainer(){return this.group;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.MultiRowTrack.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.group,this);},buildSubRows_:function(slices){var precisionUnit=this.group.model.intrinsicTimeUnit;if(!slices.length)
-return[];var ops=[];for(var i=0;i<slices.length;i++){if(slices[i].subSlices)
-slices[i].subSlices.splice(0,slices[i].subSlices.length);ops.push(i);}
-ops.sort(function(ix,iy){var x=slices[ix];var y=slices[iy];if(x.start!=y.start)
-return x.start-y.start;return ix-iy;});var subRows=[[]];this.badSlices_=[];for(var i=0;i<ops.length;i++){var op=ops[i];var slice=slices[op];var inserted=false;for(var j=subRows.length-1;j>=0;j--){if(subRows[j].length==0)
-continue;var insertedSlice=subRows[j][subRows[j].length-1];if(slice.start<insertedSlice.start){this.badSlices_.push(slice);inserted=true;}
-if(insertedSlice.bounds(slice,precisionUnit)){while(subRows.length<=j+1)
-subRows.push([]);subRows[j+1].push(slice);if(insertedSlice.subSlices)
-insertedSlice.subSlices.push(slice);inserted=true;break;}}
-if(inserted)
-continue;subRows[0].push(slice);}
-return subRows;}};return{SliceGroupTrack:SliceGroupTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ThreadTrack=tr.ui.b.define('thread-track',tr.ui.tracks.ContainerTrack);ThreadTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.classList.add('thread-track');},get thread(){return this.thread_;},set thread(thread){this.thread_=thread;this.updateContents_();},get hasVisibleContent(){return this.tracks_.length>0;},get eventContainer(){return this.thread;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.ContainerTrack.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.thread,this);},updateContents_:function(){this.detach();if(!this.thread_)
-return;this.heading=this.thread_.userFriendlyName+': ';this.tooltip=this.thread_.userFriendlyDetails;if(this.thread_.asyncSliceGroup.length)
-this.appendAsyncSliceTracks_();this.appendThreadSamplesTracks_();if(this.thread_.timeSlices){var timeSlicesTrack=new tr.ui.tracks.SliceTrack(this.viewport);timeSlicesTrack.heading='';timeSlicesTrack.height=tr.ui.b.THIN_SLICE_HEIGHT+'px';timeSlicesTrack.slices=this.thread_.timeSlices;if(timeSlicesTrack.hasVisibleContent)
-this.appendChild(timeSlicesTrack);}
-if(this.thread_.sliceGroup.length){var track=new tr.ui.tracks.SliceGroupTrack(this.viewport);track.heading=this.thread_.userFriendlyName;track.tooltip=this.thread_.userFriendlyDetails;track.group=this.thread_.sliceGroup;if(track.hasVisibleContent)
-this.appendChild(track);}},appendAsyncSliceTracks_:function(){var subGroups=this.thread_.asyncSliceGroup.viewSubGroups;subGroups.forEach(function(subGroup){var asyncTrack=new tr.ui.tracks.AsyncSliceGroupTrack(this.viewport);var title=subGroup.slices[0].viewSubGroupTitle;asyncTrack.group=subGroup;asyncTrack.heading=title;if(asyncTrack.hasVisibleContent)
-this.appendChild(asyncTrack);},this);},appendThreadSamplesTracks_:function(){var threadSamples=this.thread_.samples;if(threadSamples===undefined||threadSamples.length===0)
-return;var samplesByTitle={};threadSamples.forEach(function(sample){if(samplesByTitle[sample.title]===undefined)
-samplesByTitle[sample.title]=[];samplesByTitle[sample.title].push(sample);});var sampleTitles=tr.b.dictionaryKeys(samplesByTitle);sampleTitles.sort();sampleTitles.forEach(function(sampleTitle){var samples=samplesByTitle[sampleTitle];var samplesTrack=new tr.ui.tracks.SampleTrack(this.viewport);samplesTrack.group=this.thread_;samplesTrack.samples=samples;samplesTrack.heading=this.thread_.userFriendlyName+': '+
-sampleTitle;samplesTrack.tooltip=this.thread_.userFriendlyDetails;samplesTrack.selectionGenerator=function(){var selection=new tr.model.EventSet();for(var i=0;i<samplesTrack.samples.length;i++){selection.push(samplesTrack.samples[i]);}
-return selection;};this.appendChild(samplesTrack);},this);},collapsedDidChange:function(collapsed){if(collapsed){var h=parseInt(this.tracks[0].height);for(var i=0;i<this.tracks.length;++i){if(h>2){this.tracks[i].height=Math.floor(h)+'px';}else{this.tracks[i].style.display='none';}
-h=h*0.5;}}else{for(var i=0;i<this.tracks.length;++i){this.tracks[i].height=this.tracks[0].height;this.tracks[i].style.display='';}}}};return{ThreadTrack:ThreadTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ObjectSnapshotView=tr.ui.analysis.ObjectSnapshotView;var ObjectInstanceView=tr.ui.analysis.ObjectInstanceView;var SpacingTrack=tr.ui.tracks.SpacingTrack;var ProcessTrackBase=tr.ui.b.define('process-track-base',tr.ui.tracks.ContainerTrack);ProcessTrackBase.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.processBase_=undefined;this.classList.add('process-track-base');this.classList.add('expanded');this.processNameEl_=tr.ui.b.createSpan();this.processNameEl_.classList.add('process-track-name');this.headerEl_=tr.ui.b.createDiv({className:'process-track-header'});this.headerEl_.appendChild(this.processNameEl_);this.headerEl_.addEventListener('click',this.onHeaderClick_.bind(this));this.appendChild(this.headerEl_);},get processBase(){return this.processBase_;},set processBase(processBase){this.processBase_=processBase;if(this.processBase_){var modelSettings=new tr.model.ModelSettings(this.processBase_.model);var defaultValue=this.processBase_.important;this.expanded=modelSettings.getSettingFor(this.processBase_,'expanded',defaultValue);}
-this.updateContents_();},get expanded(){return this.classList.contains('expanded');},set expanded(expanded){expanded=!!expanded;if(this.expanded===expanded)
-return;this.classList.toggle('expanded');this.viewport_.dispatchChangeEvent();if(!this.processBase_)
-return;var modelSettings=new tr.model.ModelSettings(this.processBase_.model);modelSettings.setSettingFor(this.processBase_,'expanded',expanded);this.updateContents_();this.viewport.rebuildEventToTrackMap();this.viewport.rebuildContainerToTrackMap();},get hasVisibleContent(){if(this.expanded)
-return this.children.length>1;return true;},onHeaderClick_:function(e){e.stopPropagation();e.preventDefault();this.expanded=!this.expanded;},updateContents_:function(){this.clearTracks_();if(!this.processBase_)
-return;this.processNameEl_.textContent=this.processBase_.userFriendlyName;this.headerEl_.title=this.processBase_.userFriendlyDetails;this.willAppendTracks_();if(this.expanded){this.appendMemoryDumpTrack_();this.appendObjectInstanceTracks_();this.appendCounterTracks_();this.appendFrameTrack_();this.appendThreadTracks_();}else{this.appendSummaryTrack_();}
-this.didAppendTracks_();},addEventsToTrackMap:function(eventToTrackMap){this.tracks_.forEach(function(track){track.addEventsToTrackMap(eventToTrackMap);});},willAppendTracks_:function(){},didAppendTracks_:function(){},appendMemoryDumpTrack_:function(){},appendSummaryTrack_:function(){var track=new tr.ui.tracks.ProcessSummaryTrack(this.viewport);track.process=this.process;if(!track.hasVisibleContent)
-return;this.appendChild(track);},appendFrameTrack_:function(){var frames=this.process?this.process.frames:undefined;if(!frames||!frames.length)
-return;var track=new tr.ui.tracks.FrameTrack(this.viewport);track.frames=frames;this.appendChild(track);},appendObjectInstanceTracks_:function(){var instancesByTypeName=this.processBase_.objects.getAllInstancesByTypeName();var instanceTypeNames=tr.b.dictionaryKeys(instancesByTypeName);instanceTypeNames.sort();var didAppendAtLeastOneTrack=false;instanceTypeNames.forEach(function(typeName){var allInstances=instancesByTypeName[typeName];var instanceViewInfo=ObjectInstanceView.getTypeInfo(undefined,typeName);var snapshotViewInfo=ObjectSnapshotView.getTypeInfo(undefined,typeName);if(instanceViewInfo&&!instanceViewInfo.metadata.showInTrackView)
-instanceViewInfo=undefined;if(snapshotViewInfo&&!snapshotViewInfo.metadata.showInTrackView)
-snapshotViewInfo=undefined;var hasViewInfo=instanceViewInfo||snapshotViewInfo;var visibleInstances=[];for(var i=0;i<allInstances.length;i++){var instance=allInstances[i];if(instance.snapshots.length===0)
-continue;if(instance.hasImplicitSnapshots&&!hasViewInfo)
-continue;visibleInstances.push(instance);}
-if(visibleInstances.length===0)
-return;var trackConstructor=tr.ui.tracks.ObjectInstanceTrack.getConstructor(undefined,typeName);if(!trackConstructor){var snapshotViewInfo=ObjectSnapshotView.getTypeInfo(undefined,typeName);if(snapshotViewInfo&&snapshotViewInfo.metadata.showInstances){trackConstructor=tr.ui.tracks.ObjectInstanceGroupTrack;}else{trackConstructor=tr.ui.tracks.ObjectInstanceTrack;}}
-var track=new trackConstructor(this.viewport);track.objectInstances=visibleInstances;this.appendChild(track);didAppendAtLeastOneTrack=true;},this);if(didAppendAtLeastOneTrack)
-this.appendChild(new SpacingTrack(this.viewport));},appendCounterTracks_:function(){var counters=tr.b.dictionaryValues(this.processBase.counters);counters.sort(tr.model.Counter.compare);counters.forEach(function(counter){var track=new tr.ui.tracks.CounterTrack(this.viewport);track.counter=counter;this.appendChild(track);this.appendChild(new SpacingTrack(this.viewport));}.bind(this));},appendThreadTracks_:function(){var threads=tr.b.dictionaryValues(this.processBase.threads);threads.sort(tr.model.Thread.compare);threads.forEach(function(thread){var track=new tr.ui.tracks.ThreadTrack(this.viewport);track.thread=thread;if(!track.hasVisibleContent)
-return;this.appendChild(track);this.appendChild(new SpacingTrack(this.viewport));}.bind(this));}};return{ProcessTrackBase:ProcessTrackBase};});'use strict';tr.exportTo('tr.ui.tracks',function(){var CpuTrack=tr.ui.b.define('cpu-track',tr.ui.tracks.ContainerTrack);CpuTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.classList.add('cpu-track');this.detailedMode_=true;},get cpu(){return this.cpu_;},set cpu(cpu){this.cpu_=cpu;this.updateContents_();},get detailedMode(){return this.detailedMode_;},set detailedMode(detailedMode){this.detailedMode_=detailedMode;this.updateContents_();},get tooltip(){return this.tooltip_;},set tooltip(value){this.tooltip_=value;this.updateContents_();},get hasVisibleContent(){if(this.cpu_===undefined)
-return false;var cpu=this.cpu_;if(cpu.slices.length)
-return true;if(cpu.samples&&cpu.samples.length)
-return true;if(tr.b.dictionaryLength(cpu.counters)>0)
-return true;return false;},updateContents_:function(){this.detach();if(!this.cpu_)
-return;var slices=this.cpu_.slices;if(slices.length){var track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;track.heading=this.cpu_.userFriendlyName+':';this.appendChild(track);}
-if(this.detailedMode_){this.appendSamplesTracks_();for(var counterName in this.cpu_.counters){var counter=this.cpu_.counters[counterName];track=new tr.ui.tracks.CounterTrack(this.viewport);track.heading=this.cpu_.userFriendlyName+' '+
-counter.name+':';track.counter=counter;this.appendChild(track);}}},appendSamplesTracks_:function(){var samples=this.cpu_.samples;if(samples===undefined||samples.length===0)
-return;var samplesByTitle={};samples.forEach(function(sample){if(samplesByTitle[sample.title]===undefined)
-samplesByTitle[sample.title]=[];samplesByTitle[sample.title].push(sample);});var sampleTitles=tr.b.dictionaryKeys(samplesByTitle);sampleTitles.sort();sampleTitles.forEach(function(sampleTitle){var samples=samplesByTitle[sampleTitle];var samplesTrack=new tr.ui.tracks.SliceTrack(this.viewport);samplesTrack.group=this.cpu_;samplesTrack.slices=samples;samplesTrack.heading=this.cpu_.userFriendlyName+': '+
-sampleTitle;samplesTrack.tooltip=this.cpu_.userFriendlyDetails;samplesTrack.selectionGenerator=function(){var selection=new tr.model.EventSet();for(var i=0;i<samplesTrack.slices.length;i++){selection.push(samplesTrack.slices[i]);}
-return selection;};this.appendChild(samplesTrack);},this);}};return{CpuTrack:CpuTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var Cpu=tr.model.Cpu;var CpuTrack=tr.ui.tracks.cpu_track;var ProcessTrackBase=tr.ui.tracks.ProcessTrackBase;var SpacingTrack=tr.ui.tracks.SpacingTrack;var KernelTrack=tr.ui.b.define('kernel-track',ProcessTrackBase);KernelTrack.prototype={__proto__:ProcessTrackBase.prototype,decorate:function(viewport){ProcessTrackBase.prototype.decorate.call(this,viewport);},set kernel(kernel){this.processBase=kernel;},get kernel(){return this.processBase;},get eventContainer(){return this.kernel;},get hasVisibleContent(){return this.children.length>1;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.ProcessTrackBase.prototype.addContainersToTrackMap.call(this,containerToTrackMap);containerToTrackMap.addContainer(this.kernel,this);},willAppendTracks_:function(){var cpus=tr.b.dictionaryValues(this.kernel.cpus);cpus.sort(tr.model.Cpu.compare);var didAppendAtLeastOneTrack=false;for(var i=0;i<cpus.length;++i){var cpu=cpus[i];var track=new tr.ui.tracks.CpuTrack(this.viewport);track.detailedMode=this.expanded;track.cpu=cpu;if(!track.hasVisibleContent)
-continue;this.appendChild(track);didAppendAtLeastOneTrack=true;}
-if(didAppendAtLeastOneTrack)
-this.appendChild(new SpacingTrack(this.viewport));}};return{KernelTrack:KernelTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var InteractionTrack=tr.ui.b.define('interaction-track',tr.ui.tracks.MultiRowTrack);InteractionTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate:function(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);this.heading='Interactions';this.subRows_=[];},set model(model){this.setItemsToGroup(model.userModel.expectations,{guid:tr.b.GUID.allocate(),model:model,getSettingsKey:function(){return undefined;}});},buildSubRows_:function(slices){if(this.subRows_.length)
-return this.subRows_;this.subRows_.push.apply(this.subRows_,tr.ui.tracks.AsyncSliceGroupTrack.prototype.buildSubRows_.call({},slices,true));return this.subRows_;},addSubTrack_:function(slices){var track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;this.appendChild(track);return track;}};return{InteractionTrack:InteractionTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ALLOCATED_MEMORY_TRACK_HEIGHT=50;var ProcessMemoryDumpTrack=tr.ui.b.define('process-memory-dump-track',tr.ui.tracks.ContainerTrack);ProcessMemoryDumpTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.memoryDumps_=undefined;},get memoryDumps(){return this.memoryDumps_;},set memoryDumps(memoryDumps){this.memoryDumps_=memoryDumps;this.updateContents_();},updateContents_:function(){this.clearTracks_();if(!this.memoryDumps_||!this.memoryDumps_.length)
-return;this.appendAllocatedMemoryTrack_();},appendAllocatedMemoryTrack_:function(){var series=tr.ui.tracks.buildProcessAllocatedMemoryChartSeries(this.memoryDumps_);if(!series)
-return;var track=new tr.ui.tracks.ChartTrack(this.viewport);track.heading='Memory per component';track.height=ALLOCATED_MEMORY_TRACK_HEIGHT+'px';track.series=series;track.autoSetAllAxes({expandMax:true});this.appendChild(track);}};return{ProcessMemoryDumpTrack:ProcessMemoryDumpTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ProcessTrackBase=tr.ui.tracks.ProcessTrackBase;var ProcessTrack=tr.ui.b.define('process-track',ProcessTrackBase);ProcessTrack.prototype={__proto__:ProcessTrackBase.prototype,decorate:function(viewport){tr.ui.tracks.ProcessTrackBase.prototype.decorate.call(this,viewport);},drawTrack:function(type){switch(type){case tr.ui.tracks.DrawType.INSTANT_EVENT:if(!this.processBase.instantEvents||this.processBase.instantEvents.length===0)
-break;var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var canvasBounds=ctx.canvas.getBoundingClientRect();ctx.save();ctx.translate(0,pixelRatio*(bounds.top-canvasBounds.top));var dt=this.viewport.currentDisplayTransform;var viewLWorld=dt.xViewToWorld(0);var viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);tr.ui.b.drawInstantSlicesAsLines(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,bounds.height,this.processBase.instantEvents,2);ctx.restore();break;case tr.ui.tracks.DrawType.BACKGROUND:this.drawBackground_();return;}
-tr.ui.tracks.ContainerTrack.prototype.drawTrack.call(this,type);},drawBackground_:function(){var ctx=this.context();var canvasBounds=ctx.canvas.getBoundingClientRect();var pixelRatio=window.devicePixelRatio||1;var draw=false;ctx.fillStyle='#eee';for(var i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track)||(this.children[i]instanceof tr.ui.tracks.SpacingTrack))
-continue;draw=!draw;if(!draw)
-continue;var bounds=this.children[i].getBoundingClientRect();ctx.fillRect(0,pixelRatio*(bounds.top-canvasBounds.top),ctx.canvas.width,pixelRatio*bounds.height);}},set process(process){this.processBase=process;},get process(){return this.processBase;},get eventContainer(){return this.process;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.ProcessTrackBase.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.process,this);},appendMemoryDumpTrack_:function(){var processMemoryDumps=this.process.memoryDumps;if(processMemoryDumps.length){var pmdt=new tr.ui.tracks.ProcessMemoryDumpTrack(this.viewport_);pmdt.memoryDumps=processMemoryDumps;this.appendChild(pmdt);}},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){function onPickHit(instantEvent){selection.push(instantEvent);}
-var instantEventWidth=2*viewPixWidthWorld;tr.b.iterateOverIntersectingIntervals(this.processBase.instantEvents,function(x){return x.start;},function(x){return x.duration+instantEventWidth;},loWX,hiWX,onPickHit.bind(this));tr.ui.tracks.ContainerTrack.prototype.addIntersectingEventsInRangeToSelectionInWorldSpace.apply(this,arguments);},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){this.addClosestInstantEventToSelection(this.processBase.instantEvents,worldX,worldMaxDist,selection);tr.ui.tracks.ContainerTrack.prototype.addClosestEventToSelection.apply(this,arguments);}};return{ProcessTrack:ProcessTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SelectionState=tr.model.SelectionState;var EventPresenter=tr.ui.b.EventPresenter;var ModelTrack=tr.ui.b.define('model-track',tr.ui.tracks.ContainerTrack);ModelTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.classList.add('model-track');var typeInfos=tr.ui.tracks.Highlighter.getAllRegisteredTypeInfos();this.highlighters_=typeInfos.map(function(typeInfo){return new typeInfo.constructor(viewport);});this.upperMode_=false;this.annotationViews_=[];},get upperMode(){return this.upperMode_;},set upperMode(upperMode){this.upperMode_=upperMode;this.updateContents_();},detach:function(){tr.ui.tracks.ContainerTrack.prototype.detach.call(this);},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();this.model_.addEventListener('annotationChange',this.updateAnnotations_.bind(this));},get hasVisibleContent(){return this.children.length>0;},updateContents_:function(){this.textContent='';if(!this.model_)
-return;if(this.upperMode_)
-this.updateContentsForUpperMode_();else
-this.updateContentsForLowerMode_();},updateContentsForUpperMode_:function(){},updateContentsForLowerMode_:function(){if(this.model_.userModel.expectations.length){var mrt=new tr.ui.tracks.InteractionTrack(this.viewport_);mrt.model=this.model_;this.appendChild(mrt);}
-if(this.model_.alerts.length){var at=new tr.ui.tracks.AlertTrack(this.viewport_);at.alerts=this.model_.alerts;this.appendChild(at);}
-if(this.model_.globalMemoryDumps.length){var gmdt=new tr.ui.tracks.GlobalMemoryDumpTrack(this.viewport_);gmdt.memoryDumps=this.model_.globalMemoryDumps;this.appendChild(gmdt);}
-this.appendDeviceTrack_();this.appendKernelTrack_();var processes=this.model_.getAllProcesses();processes.sort(tr.model.Process.compare);for(var i=0;i<processes.length;++i){var process=processes[i];var track=new tr.ui.tracks.ProcessTrack(this.viewport);track.process=process;if(!track.hasVisibleContent)
-continue;this.appendChild(track);}
-this.viewport_.rebuildEventToTrackMap();this.viewport_.rebuildContainerToTrackMap();for(var i=0;i<this.highlighters_.length;i++){this.highlighters_[i].processModel(this.model_);}
-this.updateAnnotations_();},updateAnnotations_:function(){this.annotationViews_=[];var annotations=this.model_.getAllAnnotations();for(var i=0;i<annotations.length;i++){this.annotationViews_.push(annotations[i].getOrCreateView(this.viewport_));}
-this.invalidateDrawingContainer();},addEventsToTrackMap:function(eventToTrackMap){if(!this.model_)
-return;var tracks=this.children;for(var i=0;i<tracks.length;++i)
-tracks[i].addEventsToTrackMap(eventToTrackMap);if(this.instantEvents===undefined)
-return;var vp=this.viewport_;this.instantEvents.forEach(function(ev){eventToTrackMap.addEvent(ev,this);}.bind(this));},appendDeviceTrack_:function(){var device=this.model.device;var track=new tr.ui.tracks.DeviceTrack(this.viewport);track.device=this.model.device;if(!track.hasVisibleContent)
-return;this.appendChild(track);},appendKernelTrack_:function(){var kernel=this.model.kernel;var track=new tr.ui.tracks.KernelTrack(this.viewport);track.kernel=this.model.kernel;if(!track.hasVisibleContent)
-return;this.appendChild(track);},drawTrack:function(type){var ctx=this.context();if(!this.model_)
-return;var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var canvasBounds=ctx.canvas.getBoundingClientRect();ctx.save();ctx.translate(0,pixelRatio*(bounds.top-canvasBounds.top));var dt=this.viewport.currentDisplayTransform;var viewLWorld=dt.xViewToWorld(0);var viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);switch(type){case tr.ui.tracks.DrawType.GRID:this.viewport.drawMajorMarkLines(ctx);ctx.restore();return;case tr.ui.tracks.DrawType.FLOW_ARROWS:if(this.model_.flowIntervalTree.size===0){ctx.restore();return;}
-this.drawFlowArrows_(viewLWorld,viewRWorld);ctx.restore();return;case tr.ui.tracks.DrawType.INSTANT_EVENT:if(!this.model_.instantEvents||this.model_.instantEvents.length===0)
-break;tr.ui.b.drawInstantSlicesAsLines(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,bounds.height,this.model_.instantEvents,4);break;case tr.ui.tracks.DrawType.MARKERS:if(!this.viewport.interestRange.isEmpty){this.viewport.interestRange.draw(ctx,viewLWorld,viewRWorld);this.viewport.interestRange.drawIndicators(ctx,viewLWorld,viewRWorld);}
-ctx.restore();return;case tr.ui.tracks.DrawType.HIGHLIGHTS:for(var i=0;i<this.highlighters_.length;i++){this.highlighters_[i].drawHighlight(ctx,dt,viewLWorld,viewRWorld,bounds.height);}
-ctx.restore();return;case tr.ui.tracks.DrawType.ANNOTATIONS:for(var i=0;i<this.annotationViews_.length;i++){this.annotationViews_[i].draw(ctx);}
+const nonuniqueKeys={};Object.keys(objectsByKey).forEach(function(objectKey){if(objectsByKey[objectKey]!==NONUNIQUE_KEY){return;}
+delete objectsByKey[objectKey];nonuniqueKeys[objectKey]=true;});this.nonuniqueKeys=nonuniqueKeys;this.objectsByKey_=objectsByKey;},removeNonuniqueKeysFromSettings_(){const settings=Settings.get('trace_model_settings',{});let settingsChanged=false;Object.keys(settings).forEach(function(objectKey){if(!this.nonuniqueKeys[objectKey]){return;}
+settingsChanged=true;delete settings[objectKey];},this);if(settingsChanged){Settings.set('trace_model_settings',settings);}},hasUniqueSettingKey(object){const objectKey=object.getSettingsKey();if(!objectKey)return false;return this.objectsByKey_[objectKey]!==undefined;},getSettingFor(object,objectLevelKey,defaultValue){const objectKey=object.getSettingsKey();if(!objectKey||!this.objectsByKey_[objectKey]){const settings=this.getEphemeralSettingsFor_(object);const ephemeralValue=settings[objectLevelKey];if(ephemeralValue!==undefined){return ephemeralValue;}
+return defaultValue;}
+const settings=Settings.get('trace_model_settings',{});if(!settings[objectKey]){settings[objectKey]={};}
+const value=settings[objectKey][objectLevelKey];if(value!==undefined){return value;}
+return defaultValue;},setSettingFor(object,objectLevelKey,value){const objectKey=object.getSettingsKey();if(!objectKey||!this.objectsByKey_[objectKey]){this.getEphemeralSettingsFor_(object)[objectLevelKey]=value;return;}
+const settings=Settings.get('trace_model_settings',{});if(!settings[objectKey]){settings[objectKey]={};}
+if(settings[objectKey][objectLevelKey]===value){return;}
+settings[objectKey][objectLevelKey]=value;Settings.set('trace_model_settings',settings);},getEphemeralSettingsFor_(object){if(object.guid===undefined){throw new Error('Only objects with GUIDs can be persisted');}
+if(this.ephemeralSettingsByGUID_[object.guid]===undefined){this.ephemeralSettingsByGUID_[object.guid]={};}
+return this.ephemeralSettingsByGUID_[object.guid];}};return{ModelSettings,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const CounterTrack=tr.ui.b.define('counter-track',tr.ui.tracks.ChartTrack);CounterTrack.prototype={__proto__:tr.ui.tracks.ChartTrack.prototype,decorate(viewport){tr.ui.tracks.ChartTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('counter-track');},get counter(){return this.chart;},set counter(counter){this.heading=counter.name+': ';this.series=CounterTrack.buildChartSeriesFromCounter(counter);this.autoSetAllAxes({expandMax:true});},getModelEventFromItem(chartValue){return chartValue;}};CounterTrack.buildChartSeriesFromCounter=function(counter){const numSeries=counter.series.length;const totals=counter.totals;const seriesYAxis=new tr.ui.tracks.ChartSeriesYAxis(0,undefined);const chartSeries=counter.series.map(function(series,seriesIndex){const chartPoints=series.samples.map(function(sample,sampleIndex){const total=totals[sampleIndex*numSeries+seriesIndex];return new tr.ui.tracks.ChartPoint(sample,sample.timestamp,total);});const renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:series.color};return new tr.ui.tracks.ChartSeries(chartPoints,seriesYAxis,renderingConfig);});chartSeries.reverse();return chartSeries;};return{CounterTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const startCompare=function(x,y){return x.start-y.start;};const FrameTrack=tr.ui.b.define('frame-track',tr.ui.tracks.LetterDotTrack);FrameTrack.prototype={__proto__:tr.ui.tracks.LetterDotTrack.prototype,decorate(viewport){tr.ui.tracks.LetterDotTrack.prototype.decorate.call(this,viewport);this.heading='Frames';this.frames_=undefined;this.items=undefined;},get frames(){return this.frames_;},set frames(frames){this.frames_=frames;if(frames===undefined)return;this.frames_=this.frames_.slice();this.frames_.sort(startCompare);this.items=this.frames_.map(function(frame){return new FrameDot(frame);});}};function FrameDot(frame){tr.ui.tracks.LetterDot.call(this,frame,'F',frame.colorId,frame.start);}
+FrameDot.prototype={__proto__:tr.ui.tracks.LetterDot.prototype};return{FrameTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const MultiRowTrack=tr.ui.b.define('multi-row-track',tr.ui.tracks.ContainerTrack);MultiRowTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.tooltip_='';this.heading_='';this.groupingSource_=undefined;this.itemsToGroup_=undefined;this.defaultToCollapsedWhenSubRowCountMoreThan=1;this.currentSubRowsWithHeadings_=undefined;this.expanded_=true;},get itemsToGroup(){return this.itemsToGroup_;},setItemsToGroup(itemsToGroup,opt_groupingSource){this.itemsToGroup_=itemsToGroup;this.groupingSource_=opt_groupingSource;this.currentSubRowsWithHeadings_=undefined;this.updateContents_();this.updateExpandedStateFromGroupingSource_();},setPrebuiltSubRows(groupingSource,subRowsWithHeadings){this.itemsToGroup_=undefined;this.groupingSource_=groupingSource;this.currentSubRowsWithHeadings_=subRowsWithHeadings;this.updateContents_();this.updateExpandedStateFromGroupingSource_();},get heading(){return this.heading_;},set heading(h){this.heading_=h;this.updateHeadingAndTooltip_();},get tooltip(){return this.tooltip_;},set tooltip(t){this.tooltip_=t;this.updateHeadingAndTooltip_();},get subRows(){return this.currentSubRowsWithHeadings_.map(elem=>elem.row);},get hasVisibleContent(){return this.children.length>0;},get expanded(){return this.expanded_;},set expanded(expanded){if(this.expanded_===expanded)return;this.expanded_=expanded;this.expandedStateChanged_();},onHeadingClicked_(e){if(this.subRows.length<=1)return;this.expanded=!this.expanded;if(this.groupingSource_){const modelSettings=new tr.model.ModelSettings(this.groupingSource_.model);modelSettings.setSettingFor(this.groupingSource_,'expanded',this.expanded);}
+e.stopPropagation();},updateExpandedStateFromGroupingSource_(){if(this.groupingSource_){const numSubRows=this.subRows.length;const modelSettings=new tr.model.ModelSettings(this.groupingSource_.model);if(numSubRows>1){let defaultExpanded;if(numSubRows>this.defaultToCollapsedWhenSubRowCountMoreThan){defaultExpanded=false;}else{defaultExpanded=true;}
+this.expanded=modelSettings.getSettingFor(this.groupingSource_,'expanded',defaultExpanded);}else{this.expanded=undefined;}}},expandedStateChanged_(){const minH=Math.max(2,Math.ceil(18/this.children.length));const h=(this.expanded_?18:minH)+'px';for(let i=0;i<this.children.length;i++){this.children[i].height=h;if(i===0){this.children[i].arrowVisible=true;}
+this.children[i].expanded=this.expanded;}
+if(this.children.length===1){this.children[0].expanded=true;this.children[0].arrowVisible=false;}},updateContents_(){tr.ui.tracks.ContainerTrack.prototype.updateContents_.call(this);this.detach();if(this.currentSubRowsWithHeadings_===undefined){if(this.itemsToGroup_===undefined){return;}
+const subRows=this.buildSubRows_(this.itemsToGroup_);this.currentSubRowsWithHeadings_=subRows.map(row=>{return{row,heading:undefined};});}
+if(this.currentSubRowsWithHeadings_===undefined||this.currentSubRowsWithHeadings_.length===0){return;}
+const addSubTrackEx=(items,opt_heading)=>{const track=this.addSubTrack_(items);if(opt_heading!==undefined){track.heading=opt_heading;}
+track.addEventListener('heading-clicked',this.onHeadingClicked_.bind(this));};if(this.currentSubRowsWithHeadings_[0].heading!==undefined&&this.currentSubRowsWithHeadings_[0].heading!==this.heading_){addSubTrackEx([]);}
+for(const subRowWithHeading of this.currentSubRowsWithHeadings_){const subRow=subRowWithHeading.row;if(subRow.length===0){continue;}
+addSubTrackEx(subRow,subRowWithHeading.heading);}
+this.updateHeadingAndTooltip_();this.expandedStateChanged_();},updateHeadingAndTooltip_(){if(!Polymer.dom(this).firstChild)return;Polymer.dom(this).firstChild.heading=this.heading_;Polymer.dom(this).firstChild.tooltip=this.tooltip_;},buildSubRows_(itemsToGroup){throw new Error('Not implemented');},addSubTrack_(subRowItems){throw new Error('Not implemented');},areArrayContentsSame_(a,b){if(!a||!b)return false;if(!a.length||!b.length)return false;if(a.length!==b.length)return false;for(let i=0;i<a.length;++i){if(a[i]!==b[i])return false;}
+return true;}};return{MultiRowTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ObjectInstanceGroupTrack=tr.ui.b.define('object-instance-group-track',tr.ui.tracks.MultiRowTrack);ObjectInstanceGroupTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('object-instance-group-track');this.objectInstances_=undefined;},get objectInstances(){return this.itemsToGroup;},set objectInstances(objectInstances){this.setItemsToGroup(objectInstances);},addSubTrack_(objectInstances){const hasMultipleRows=this.subRows.length>1;const track=new tr.ui.tracks.ObjectInstanceTrack(this.viewport);track.objectInstances=objectInstances;Polymer.dom(this).appendChild(track);return track;},buildSubRows_(objectInstances){objectInstances.sort(function(x,y){return x.creationTs-y.creationTs;});const subRows=[];for(let i=0;i<objectInstances.length;i++){const objectInstance=objectInstances[i];let found=false;for(let j=0;j<subRows.length;j++){const subRow=subRows[j];const lastItemInSubRow=subRow[subRow.length-1];if(objectInstance.creationTs>=lastItemInSubRow.deletionTs){found=true;subRow.push(objectInstance);break;}}
+if(!found){subRows.push([objectInstance]);}}
+return subRows;},updateHeadingAndTooltip_(){}};return{ObjectInstanceGroupTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const AsyncSliceGroupTrack=tr.ui.b.define('async-slice-group-track',tr.ui.tracks.MultiRowTrack);AsyncSliceGroupTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('async-slice-group-track');this.group_=undefined;},addSubTrack_(slices){const track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;Polymer.dom(this).appendChild(track);track.asyncStyle=true;return track;},get group(){return this.group_;},set group(group){this.group_=group;this.buildAndSetSubRows_();},get eventContainer(){return this.group;},addContainersToTrackMap(containerToTrackMap){tr.ui.tracks.MultiRowTrack.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.group,this);},buildAndSetSubRows_(){if(this.group_.viewSubGroups.length<=1){const rows=groupAsyncSlicesIntoSubRows(this.group_.slices);const rowsWithHeadings=rows.map(row=>{return{row,heading:undefined};});this.setPrebuiltSubRows(this.group_,rowsWithHeadings);return;}
+const rowsWithHeadings=[];for(const subGroup of this.group_.viewSubGroups){const subGroupRows=groupAsyncSlicesIntoSubRows(subGroup.slices);if(subGroupRows.length===0){continue;}
+for(let i=0;i<subGroupRows.length;i++){rowsWithHeadings.push({row:subGroupRows[i],heading:(i===0?subGroup.title:'')});}}
+this.setPrebuiltSubRows(this.group_,rowsWithHeadings);}};function stripSlice_(slice){if(slice.subSlices!==undefined&&slice.subSlices.length===1){const subSlice=slice.subSlices[0];if(tr.b.math.approximately(subSlice.start,slice.start,1)&&tr.b.math.approximately(subSlice.duration,slice.duration,1)){return subSlice;}}
+return slice;}
+function makeLevelSubRows_(slices){const rows=[];const putSlice=(slice,level)=>{while(rows.length<=level){rows.push([]);}
+rows[level].push(slice);};const putSliceRecursively=(slice,level)=>{putSlice(slice,level);if(slice.subSlices!==undefined){for(const subSlice of slice.subSlices){putSliceRecursively(subSlice,level+1);}}};for(const slice of slices){putSliceRecursively(stripSlice_(slice),0);}
+return rows;}
+function groupAsyncSlicesIntoSubRows(slices,opt_skipSort){if(!opt_skipSort){slices.sort((x,y)=>x.start-y.start);}
+const rows=[];let slicesLeft=slices;while(slicesLeft.length!==0){const fit=[];const unfit=[];let levelEndTime=-1;for(const slice of slicesLeft){if(slice.start>=levelEndTime){levelEndTime=slice.end;fit.push(slice);}else{unfit.push(slice);}}
+rows.push(...makeLevelSubRows_(fit));slicesLeft=unfit;}
+return rows;}
+return{AsyncSliceGroupTrack,groupAsyncSlicesIntoSubRows,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const SampleTrack=tr.ui.b.define('sample-track',tr.ui.tracks.RectTrack);SampleTrack.prototype={__proto__:tr.ui.tracks.RectTrack.prototype,decorate(viewport){tr.ui.tracks.RectTrack.prototype.decorate.call(this,viewport);},get samples(){return this.rects;},set samples(samples){this.rects=samples;}};return{SampleTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const SliceGroupTrack=tr.ui.b.define('slice-group-track',tr.ui.tracks.MultiRowTrack);SliceGroupTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('slice-group-track');this.group_=undefined;this.defaultToCollapsedWhenSubRowCountMoreThan=100;},addSubTrack_(slices){const track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;Polymer.dom(this).appendChild(track);return track;},get group(){return this.group_;},set group(group){this.group_=group;this.setItemsToGroup(this.group_.slices,this.group_);},get eventContainer(){return this.group;},addContainersToTrackMap(containerToTrackMap){tr.ui.tracks.MultiRowTrack.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.group,this);},buildSubRows_(slices){const precisionUnit=this.group.model.intrinsicTimeUnit;if(!slices.length)return[];const ops=[];for(let i=0;i<slices.length;i++){if(slices[i].subSlices){slices[i].subSlices.splice(0,slices[i].subSlices.length);}
+ops.push(i);}
+ops.sort(function(ix,iy){const x=slices[ix];const y=slices[iy];if(x.start!==y.start)return x.start-y.start;return ix-iy;});const subRows=[[]];this.badSlices_=[];for(let i=0;i<ops.length;i++){const op=ops[i];const slice=slices[op];let inserted=false;for(let j=subRows.length-1;j>=0;j--){if(subRows[j].length===0)continue;const insertedSlice=subRows[j][subRows[j].length-1];if(slice.start<insertedSlice.start){this.badSlices_.push(slice);inserted=true;}
+if(insertedSlice.bounds(slice,precisionUnit)){while(subRows.length<=j+1){subRows.push([]);}
+subRows[j+1].push(slice);if(insertedSlice.subSlices){insertedSlice.subSlices.push(slice);}
+inserted=true;break;}}
+if(inserted)continue;subRows[0].push(slice);}
+return subRows;}};return{SliceGroupTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ThreadTrack=tr.ui.b.define('thread-track',tr.ui.tracks.ContainerTrack);ThreadTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('thread-track');this.heading_=document.createElement('tr-ui-b-heading');},get thread(){return this.thread_;},set thread(thread){this.thread_=thread;this.updateContents_();},get hasVisibleContent(){return this.tracks_.length>0;},get hasSlices(){return this.thread_.asyncSliceGroup.length>0||this.thread_.sliceGroup.length>0;},get hasTimeSlices(){return this.thread_.timeSlices;},get eventContainer(){return this.thread;},addContainersToTrackMap(containerToTrackMap){tr.ui.tracks.ContainerTrack.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.thread,this);},updateContents_(){this.detach();if(!this.thread_)return;this.heading_.heading=this.thread_.userFriendlyName;this.heading_.tooltip=this.thread_.userFriendlyDetails;if(this.thread_.asyncSliceGroup.length){this.appendAsyncSliceTracks_();}
+this.appendThreadSamplesTracks_();let needsHeading=false;if(this.thread_.timeSlices){const timeSlicesTrack=new tr.ui.tracks.SliceTrack(this.viewport);timeSlicesTrack.heading='';timeSlicesTrack.height=tr.ui.b.THIN_SLICE_HEIGHT+'px';timeSlicesTrack.slices=this.thread_.timeSlices;if(timeSlicesTrack.hasVisibleContent){needsHeading=true;Polymer.dom(this).appendChild(timeSlicesTrack);}}
+if(this.thread_.sliceGroup.length){const track=new tr.ui.tracks.SliceGroupTrack(this.viewport);track.heading=this.thread_.userFriendlyName;track.tooltip=this.thread_.userFriendlyDetails;track.group=this.thread_.sliceGroup;if(track.hasVisibleContent){needsHeading=false;Polymer.dom(this).appendChild(track);}}
+if(needsHeading){Polymer.dom(this).appendChild(this.heading_);}},appendAsyncSliceTracks_(){const subGroups=this.thread_.asyncSliceGroup.viewSubGroups;subGroups.forEach(function(subGroup){const asyncTrack=new tr.ui.tracks.AsyncSliceGroupTrack(this.viewport);asyncTrack.group=subGroup;asyncTrack.heading=subGroup.title;if(asyncTrack.hasVisibleContent){Polymer.dom(this).appendChild(asyncTrack);}},this);},appendThreadSamplesTracks_(){const threadSamples=this.thread_.samples;if(threadSamples===undefined||threadSamples.length===0){return;}
+const samplesByTitle={};threadSamples.forEach(function(sample){if(samplesByTitle[sample.title]===undefined){samplesByTitle[sample.title]=[];}
+samplesByTitle[sample.title].push(sample);});const sampleTitles=Object.keys(samplesByTitle);sampleTitles.sort();sampleTitles.forEach(function(sampleTitle){const samples=samplesByTitle[sampleTitle];const samplesTrack=new tr.ui.tracks.SampleTrack(this.viewport);samplesTrack.group=this.thread_;samplesTrack.samples=samples;samplesTrack.heading=this.thread_.userFriendlyName+': '+
+sampleTitle;samplesTrack.tooltip=this.thread_.userFriendlyDetails;samplesTrack.selectionGenerator=function(){const selection=new tr.model.EventSet();for(let i=0;i<samplesTrack.samples.length;i++){selection.push(samplesTrack.samples[i]);}
+return selection;};Polymer.dom(this).appendChild(samplesTrack);},this);},collapsedDidChange(collapsed){if(collapsed){let h=parseInt(this.tracks[0].height);for(let i=0;i<this.tracks.length;++i){if(h>2){this.tracks[i].height=Math.floor(h)+'px';}else{this.tracks[i].style.display='none';}
+h=h*0.5;}}else{for(let i=0;i<this.tracks.length;++i){this.tracks[i].height=this.tracks[0].height;this.tracks[i].style.display='';}}}};return{ThreadTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const OtherThreadsTrack=tr.ui.b.define('other-threads-track',tr.ui.tracks.OtherThreadsTrack);const SpacingTrack=tr.ui.tracks.SpacingTrack;OtherThreadsTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.header_=document.createElement('tr-ui-b-heading');this.header_.addEventListener('click',this.onHeaderClick_.bind(this));this.header_.heading='Other Threads';this.header_.tooltip='Threads with only scheduling information';this.header_.arrowVisible=true;this.threads_=[];this.expanded=false;this.collapsible_=true;},set threads(threads){this.threads_=threads;this.updateContents_();},set collapsible(collapsible){this.collapsible_=collapsible;this.updateContents_();},onHeaderClick_(e){e.stopPropagation();e.preventDefault();this.expanded=!this.expanded;},get expanded(){return this.header_.expanded;},set expanded(expanded){expanded=!!expanded;if(this.expanded===expanded)return;this.header_.expanded=expanded;this.viewport_.dispatchChangeEvent();this.updateContents_();},updateContents_(){this.detach();if(this.collapsible_){Polymer.dom(this).appendChild(this.header_);}
+if(this.expanded||!this.collapsible_){for(const thread of this.threads_){const track=new tr.ui.tracks.ThreadTrack(this.viewport);track.thread=thread;if(!track.hasVisibleContent)return;Polymer.dom(this).appendChild(track);Polymer.dom(this).appendChild(new SpacingTrack(this.viewport));}}}};return{OtherThreadsTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ColorScheme=tr.b.ColorScheme;const ProcessSummaryTrack=tr.ui.b.define('process-summary-track',tr.ui.tracks.RectTrack);ProcessSummaryTrack.buildRectsFromProcess=function(process){if(!process)return[];const ops=[];const pushOp=function(isStart,time,slice){ops.push({isStart,time,slice});};for(const tid in process.threads){const sliceGroup=process.threads[tid].sliceGroup;sliceGroup.topLevelSlices.forEach(function(slice){pushOp(true,slice.start,undefined);pushOp(false,slice.end,undefined);});sliceGroup.slices.forEach(function(slice){if(slice.important){pushOp(true,slice.start,slice);pushOp(false,slice.end,slice);}});}
+ops.sort(function(a,b){return a.time-b.time;});const rects=[];const genericColorId=ColorScheme.getColorIdForReservedName('generic_work');const pushRect=function(start,end,slice){rects.push(new tr.ui.tracks.Rect(slice,slice?slice.title:'',slice?slice.colorId:genericColorId,start,end-start));};let depth=0;let currentSlice=undefined;let lastStart=undefined;ops.forEach(function(op){depth+=op.isStart?1:-1;if(currentSlice){if(!op.isStart&&op.slice===currentSlice){pushRect(lastStart,op.time,currentSlice);lastStart=depth>=1?op.time:undefined;currentSlice=undefined;}}else{if(op.isStart){if(depth===1){lastStart=op.time;currentSlice=op.slice;}else if(op.slice){if(op.time!==lastStart){pushRect(lastStart,op.time,undefined);lastStart=op.time;}
+currentSlice=op.slice;}}else{if(depth===0){pushRect(lastStart,op.time,undefined);lastStart=undefined;}}}});return rects;};ProcessSummaryTrack.prototype={__proto__:tr.ui.tracks.RectTrack.prototype,decorate(viewport){tr.ui.tracks.RectTrack.prototype.decorate.call(this,viewport);},get process(){return this.process_;},set process(process){this.process_=process;this.rects=ProcessSummaryTrack.buildRectsFromProcess(process);}};return{ProcessSummaryTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ObjectSnapshotView=tr.ui.analysis.ObjectSnapshotView;const ObjectInstanceView=tr.ui.analysis.ObjectInstanceView;const SpacingTrack=tr.ui.tracks.SpacingTrack;const ProcessTrackBase=tr.ui.b.define('process-track-base',tr.ui.tracks.ContainerTrack);ProcessTrackBase.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.processBase_=undefined;Polymer.dom(this).classList.add('process-track-base');Polymer.dom(this).classList.add('expanded');this.processNameEl_=tr.ui.b.createSpan();Polymer.dom(this.processNameEl_).classList.add('process-track-name');this.closeEl_=tr.ui.b.createSpan();Polymer.dom(this.closeEl_).classList.add('process-track-close');this.closeEl_.textContent='X';this.headerEl_=tr.ui.b.createDiv({className:'process-track-header'});Polymer.dom(this.headerEl_).appendChild(this.processNameEl_);Polymer.dom(this.headerEl_).appendChild(this.closeEl_);this.headerEl_.addEventListener('click',this.onHeaderClick_.bind(this));Polymer.dom(this).appendChild(this.headerEl_);},get processBase(){return this.processBase_;},set processBase(processBase){this.processBase_=processBase;if(this.processBase_){const modelSettings=new tr.model.ModelSettings(this.processBase_.model);const defaultValue=this.processBase_.important;this.expanded=modelSettings.getSettingFor(this.processBase_,'expanded',defaultValue);}
+this.updateContents_();},get expanded(){return Polymer.dom(this).classList.contains('expanded');},set expanded(expanded){expanded=!!expanded;if(this.expanded===expanded)return;Polymer.dom(this).classList.toggle('expanded');this.viewport_.dispatchChangeEvent();if(!this.processBase_)return;const modelSettings=new tr.model.ModelSettings(this.processBase_.model);modelSettings.setSettingFor(this.processBase_,'expanded',expanded);this.updateContents_();this.viewport.rebuildEventToTrackMap();this.viewport.rebuildContainerToTrackMap();},set visible(visible){if(visible===this.visible)return;this.hidden=!visible;tr.b.dispatchSimpleEvent(this,'visibility');this.viewport_.dispatchChangeEvent();if(!this.processBase_)return;this.updateContents_();this.viewport.rebuildEventToTrackMap();this.viewport.rebuildContainerToTrackMap();},get visible(){return!this.hidden;},get hasVisibleContent(){if(this.expanded){return this.children.length>1;}
+return true;},onHeaderClick_(e){e.stopPropagation();e.preventDefault();if(e.target===this.closeEl_){this.visible=false;}else{this.expanded=!this.expanded;}},updateContents_(){this.clearTracks_();if(!this.processBase_)return;Polymer.dom(this.processNameEl_).textContent=this.processBase_.userFriendlyName;this.headerEl_.title=this.processBase_.userFriendlyDetails;this.willAppendTracks_();if(this.expanded){this.appendMemoryDumpTrack_();this.appendObjectInstanceTracks_();this.appendCounterTracks_();this.appendFrameTrack_();this.appendThreadTracks_();}else{this.appendSummaryTrack_();}
+this.didAppendTracks_();},willAppendTracks_(){},didAppendTracks_(){},appendMemoryDumpTrack_(){},appendSummaryTrack_(){const track=new tr.ui.tracks.ProcessSummaryTrack(this.viewport);track.process=this.process;if(!track.hasVisibleContent)return;Polymer.dom(this).appendChild(track);},appendFrameTrack_(){const frames=this.process?this.process.frames:undefined;if(!frames||!frames.length)return;const track=new tr.ui.tracks.FrameTrack(this.viewport);track.frames=frames;Polymer.dom(this).appendChild(track);},appendObjectInstanceTracks_(){const instancesByTypeName=this.processBase_.objects.getAllInstancesByTypeName();const instanceTypeNames=Object.keys(instancesByTypeName);instanceTypeNames.sort();let didAppendAtLeastOneTrack=false;instanceTypeNames.forEach(function(typeName){const allInstances=instancesByTypeName[typeName];let instanceViewInfo=ObjectInstanceView.getTypeInfo(undefined,typeName);let snapshotViewInfo=ObjectSnapshotView.getTypeInfo(undefined,typeName);if(instanceViewInfo&&!instanceViewInfo.metadata.showInTrackView){instanceViewInfo=undefined;}
+if(snapshotViewInfo&&!snapshotViewInfo.metadata.showInTrackView){snapshotViewInfo=undefined;}
+const hasViewInfo=instanceViewInfo||snapshotViewInfo;const visibleInstances=[];for(let i=0;i<allInstances.length;i++){const instance=allInstances[i];if(instance.snapshots.length===0)continue;if(instance.hasImplicitSnapshots&&!hasViewInfo)continue;visibleInstances.push(instance);}
+if(visibleInstances.length===0)return;let trackConstructor=tr.ui.tracks.ObjectInstanceTrack.getConstructor(undefined,typeName);if(!trackConstructor){snapshotViewInfo=ObjectSnapshotView.getTypeInfo(undefined,typeName);if(snapshotViewInfo&&snapshotViewInfo.metadata.showInstances){trackConstructor=tr.ui.tracks.ObjectInstanceGroupTrack;}else{trackConstructor=tr.ui.tracks.ObjectInstanceTrack;}}
+const track=new trackConstructor(this.viewport);track.objectInstances=visibleInstances;Polymer.dom(this).appendChild(track);didAppendAtLeastOneTrack=true;},this);if(didAppendAtLeastOneTrack){Polymer.dom(this).appendChild(new SpacingTrack(this.viewport));}},appendCounterTracks_(){const counters=Object.values(this.processBase.counters);counters.sort(tr.model.Counter.compare);counters.forEach(function(counter){const track=new tr.ui.tracks.CounterTrack(this.viewport);track.counter=counter;Polymer.dom(this).appendChild(track);Polymer.dom(this).appendChild(new SpacingTrack(this.viewport));}.bind(this));},appendThreadTracks_(){const threads=Object.values(this.processBase.threads);threads.sort(tr.model.Thread.compare);const otherThreads=[];let hasVisibleThreads=false;threads.forEach(function(thread){const track=new tr.ui.tracks.ThreadTrack(this.viewport);track.thread=thread;if(!track.hasVisibleContent)return;if(track.hasSlices){hasVisibleThreads=true;Polymer.dom(this).appendChild(track);Polymer.dom(this).appendChild(new SpacingTrack(this.viewport));}else if(track.hasTimeSlices){otherThreads.push(thread);}}.bind(this));if(otherThreads.length>0){const track=new tr.ui.tracks.OtherThreadsTrack(this.viewport);track.threads=otherThreads;track.collapsible=otherThreads.length>1&&hasVisibleThreads;Polymer.dom(this).appendChild(track);}}};return{ProcessTrackBase,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const Cpu=tr.model.Cpu;const CpuTrack=tr.ui.tracks.cpu_track;const ProcessTrackBase=tr.ui.tracks.ProcessTrackBase;const SpacingTrack=tr.ui.tracks.SpacingTrack;const KernelTrack=tr.ui.b.define('kernel-track',ProcessTrackBase);KernelTrack.prototype={__proto__:ProcessTrackBase.prototype,decorate(viewport){ProcessTrackBase.prototype.decorate.call(this,viewport);},set kernel(kernel){this.processBase=kernel;},get kernel(){return this.processBase;},get eventContainer(){return this.kernel;},get hasVisibleContent(){return this.children.length>1;},addContainersToTrackMap(containerToTrackMap){tr.ui.tracks.ProcessTrackBase.prototype.addContainersToTrackMap.call(this,containerToTrackMap);containerToTrackMap.addContainer(this.kernel,this);},willAppendTracks_(){const cpus=Object.values(this.kernel.cpus);cpus.sort(tr.model.Cpu.compare);let didAppendAtLeastOneTrack=false;for(let i=0;i<cpus.length;++i){const cpu=cpus[i];const track=new tr.ui.tracks.CpuTrack(this.viewport);track.detailedMode=this.expanded;track.cpu=cpu;if(!track.hasVisibleContent)continue;Polymer.dom(this).appendChild(track);didAppendAtLeastOneTrack=true;}
+if(didAppendAtLeastOneTrack){Polymer.dom(this).appendChild(new SpacingTrack(this.viewport));}}};return{KernelTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const InteractionTrack=tr.ui.b.define('interaction-track',tr.ui.tracks.MultiRowTrack);InteractionTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);this.heading='Interactions';this.subRows_=[];},set model(model){this.setItemsToGroup(model.userModel.expectations,{guid:tr.b.GUID.allocateSimple(),model,getSettingsKey(){return undefined;}});},buildSubRows_(slices){if(this.subRows_.length){return this.subRows_;}
+this.subRows_.push(...tr.ui.tracks.groupAsyncSlicesIntoSubRows(slices,true));return this.subRows_;},addSubTrack_(slices){const track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;Polymer.dom(this).appendChild(track);return track;}};return{InteractionTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ColorScheme=tr.b.ColorScheme;const LetterDotTrack=tr.ui.tracks.LetterDotTrack;const MemoryTrack=tr.ui.b.define('memory-track',LetterDotTrack);MemoryTrack.prototype={__proto__:LetterDotTrack.prototype,decorate(viewport){LetterDotTrack.prototype.decorate.call(this,viewport);this.classList.add('memory-track');this.heading='Memory Events';this.lowMemoryEvents_=undefined;},initialize(model){if(model!==undefined){this.lowMemoryEvents_=model.device.lowMemoryEvents;}else{this.lowMemoryEvents_=undefined;}
+if(this.hasVisibleContent){this.items=this.buildMemoryLetterDots_(this.lowMemoryEvents_);}},get hasVisibleContent(){return!!this.lowMemoryEvents_&&this.lowMemoryEvents_.length!==0;},buildMemoryLetterDots_(memoryEvents){return memoryEvents.map(memoryEvent=>new tr.ui.tracks.LetterDot(memoryEvent,'K',ColorScheme.getColorIdForReservedName('background_memory_dump'),memoryEvent.start));},};return{MemoryTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ALLOCATED_MEMORY_TRACK_HEIGHT=50;const ProcessMemoryDumpTrack=tr.ui.b.define('process-memory-dump-track',tr.ui.tracks.ContainerTrack);ProcessMemoryDumpTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.memoryDumps_=undefined;},get memoryDumps(){return this.memoryDumps_;},set memoryDumps(memoryDumps){this.memoryDumps_=memoryDumps;this.updateContents_();},updateContents_(){this.clearTracks_();if(!this.memoryDumps_||!this.memoryDumps_.length)return;this.appendAllocatedMemoryTrack_();},appendAllocatedMemoryTrack_(){const series=tr.ui.tracks.buildProcessAllocatedMemoryChartSeries(this.memoryDumps_);if(!series)return;const track=new tr.ui.tracks.ChartTrack(this.viewport);track.heading='Memory per component';track.height=ALLOCATED_MEMORY_TRACK_HEIGHT+'px';track.series=series;track.autoSetAllAxes({expandMax:true});Polymer.dom(this).appendChild(track);}};return{ProcessMemoryDumpTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ProcessTrackBase=tr.ui.tracks.ProcessTrackBase;const ProcessTrack=tr.ui.b.define('process-track',ProcessTrackBase);ProcessTrack.prototype={__proto__:ProcessTrackBase.prototype,decorate(viewport){tr.ui.tracks.ProcessTrackBase.prototype.decorate.call(this,viewport);},drawTrack(type){switch(type){case tr.ui.tracks.DrawType.INSTANT_EVENT:{if(!this.processBase.instantEvents||this.processBase.instantEvents.length===0){break;}
+const ctx=this.context();const pixelRatio=window.devicePixelRatio||1;const bounds=this.getBoundingClientRect();const canvasBounds=ctx.canvas.getBoundingClientRect();ctx.save();ctx.translate(0,pixelRatio*(bounds.top-canvasBounds.top));const dt=this.viewport.currentDisplayTransform;const viewLWorld=dt.xViewToWorld(0);const viewRWorld=dt.xViewToWorld(canvasBounds.width*pixelRatio);tr.ui.b.drawInstantSlicesAsLines(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,bounds.height,this.processBase.instantEvents,2);ctx.restore();break;}
+case tr.ui.tracks.DrawType.BACKGROUND:this.drawBackground_();return;}
+tr.ui.tracks.ContainerTrack.prototype.drawTrack.call(this,type);},drawBackground_(){const ctx=this.context();const canvasBounds=ctx.canvas.getBoundingClientRect();const pixelRatio=window.devicePixelRatio||1;let draw=false;ctx.fillStyle='#eee';for(let i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track)||(this.children[i]instanceof tr.ui.tracks.SpacingTrack)){continue;}
+draw=!draw;if(!draw)continue;const bounds=this.children[i].getBoundingClientRect();ctx.fillRect(0,pixelRatio*(bounds.top-canvasBounds.top),ctx.canvas.width,pixelRatio*bounds.height);}},set process(process){this.processBase=process;},get process(){return this.processBase;},get eventContainer(){return this.process;},addContainersToTrackMap(containerToTrackMap){tr.ui.tracks.ProcessTrackBase.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.process,this);},appendMemoryDumpTrack_(){const processMemoryDumps=this.process.memoryDumps;if(processMemoryDumps.length){const pmdt=new tr.ui.tracks.ProcessMemoryDumpTrack(this.viewport_);pmdt.memoryDumps=processMemoryDumps;Polymer.dom(this).appendChild(pmdt);}},addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection){function onPickHit(instantEvent){selection.push(instantEvent);}
+const instantEventWidth=2*viewPixWidthWorld;tr.b.iterateOverIntersectingIntervals(this.processBase.instantEvents,function(x){return x.start;},function(x){return x.duration+instantEventWidth;},loWX,hiWX,onPickHit.bind(this));tr.ui.tracks.ContainerTrack.prototype.addIntersectingEventsInRangeToSelectionInWorldSpace.apply(this,arguments);},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){this.addClosestInstantEventToSelection(this.processBase.instantEvents,worldX,worldMaxDist,selection);tr.ui.tracks.ContainerTrack.prototype.addClosestEventToSelection.apply(this,arguments);}};return{ProcessTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const SelectionState=tr.model.SelectionState;const ColorScheme=tr.b.ColorScheme;const EventPresenter=tr.ui.b.EventPresenter;const ModelTrack=tr.ui.b.define('model-track',tr.ui.tracks.ContainerTrack);ModelTrack.VSYNC_HIGHLIGHT_ALPHA=0.1;ModelTrack.VSYNC_DENSITY_TRANSPARENT=0.20;ModelTrack.VSYNC_DENSITY_OPAQUE=0.10;ModelTrack.VSYNC_DENSITY_RANGE=ModelTrack.VSYNC_DENSITY_TRANSPARENT-ModelTrack.VSYNC_DENSITY_OPAQUE;ModelTrack.generateStripes_=function(times,minTime,maxTime){if(times.length===0)return[];const lowIndex=tr.b.findLowIndexInSortedArray(times,(x=>x),minTime);let highIndex=lowIndex-1;while(times[highIndex+1]<=maxTime){highIndex++;}
+const stripes=[];for(let i=lowIndex-(lowIndex%2);i<=highIndex;i+=2){const left=i<lowIndex?minTime:times[i];const right=i+1>highIndex?maxTime:times[i+1];stripes.push(tr.b.math.Range.fromExplicitRange(left,right));}
+return stripes;};ModelTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('model-track');this.upperMode_=false;this.annotationViews_=[];this.vSyncTimes_=[];},get processViews(){return Polymer.dom(this).querySelectorAll('.process-track-base');},get upperMode(){return this.upperMode_;},set upperMode(upperMode){this.upperMode_=upperMode;this.updateContents_();},detach(){tr.ui.tracks.ContainerTrack.prototype.detach.call(this);},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();this.model_.addEventListener('annotationChange',this.updateAnnotations_.bind(this));},get hasVisibleContent(){return this.children.length>0;},updateContents_(){Polymer.dom(this).textContent='';if(!this.model_)return;if(this.upperMode_){this.updateContentsForUpperMode_();}else{this.updateContentsForLowerMode_();}},updateContentsForUpperMode_(){},updateContentsForLowerMode_(){if(this.model_.userModel.expectations.length>1){const mrt=new tr.ui.tracks.InteractionTrack(this.viewport_);mrt.model=this.model_;Polymer.dom(this).appendChild(mrt);}
+if(this.model_.alerts.length){const at=new tr.ui.tracks.AlertTrack(this.viewport_);at.alerts=this.model_.alerts;Polymer.dom(this).appendChild(at);}
+if(this.model_.globalMemoryDumps.length){const gmdt=new tr.ui.tracks.GlobalMemoryDumpTrack(this.viewport_);gmdt.memoryDumps=this.model_.globalMemoryDumps;Polymer.dom(this).appendChild(gmdt);}
+this.appendDeviceTrack_();this.appendCpuUsageTrack_();this.appendMemoryTrack_();this.appendKernelTrack_();const processes=this.model_.getAllProcesses();processes.sort(tr.model.Process.compare);for(let i=0;i<processes.length;++i){const process=processes[i];const track=new tr.ui.tracks.ProcessTrack(this.viewport);track.process=process;if(!track.hasVisibleContent)continue;Polymer.dom(this).appendChild(track);}
+this.viewport_.rebuildEventToTrackMap();this.viewport_.rebuildContainerToTrackMap();this.vSyncTimes_=this.model_.device.vSyncTimestamps;this.updateAnnotations_();},getContentBounds(){return this.model.bounds;},addAnnotation(annotation){this.model.addAnnotation(annotation);},removeAnnotation(annotation){this.model.removeAnnotation(annotation);},updateAnnotations_(){this.annotationViews_=[];const annotations=this.model_.getAllAnnotations();for(let i=0;i<annotations.length;i++){this.annotationViews_.push(annotations[i].getOrCreateView(this.viewport_));}
+this.invalidateDrawingContainer();},addEventsToTrackMap(eventToTrackMap){if(!this.model_)return;const tracks=this.children;for(let i=0;i<tracks.length;++i){tracks[i].addEventsToTrackMap(eventToTrackMap);}
+if(this.instantEvents===undefined)return;const vp=this.viewport_;this.instantEvents.forEach(function(ev){eventToTrackMap.addEvent(ev,this);}.bind(this));},appendDeviceTrack_(){const device=this.model.device;const track=new tr.ui.tracks.DeviceTrack(this.viewport);track.device=this.model.device;if(!track.hasVisibleContent)return;Polymer.dom(this).appendChild(track);},appendKernelTrack_(){const kernel=this.model.kernel;const track=new tr.ui.tracks.KernelTrack(this.viewport);track.kernel=this.model.kernel;if(!track.hasVisibleContent)return;Polymer.dom(this).appendChild(track);},appendCpuUsageTrack_(){const track=new tr.ui.tracks.CpuUsageTrack(this.viewport);track.initialize(this.model);if(!track.hasVisibleContent)return;this.appendChild(track);},appendMemoryTrack_(){const track=new tr.ui.tracks.MemoryTrack(this.viewport);track.initialize(this.model);if(!track.hasVisibleContent)return;Polymer.dom(this).appendChild(track);},drawTrack(type){const ctx=this.context();if(!this.model_)return;const pixelRatio=window.devicePixelRatio||1;const bounds=this.getBoundingClientRect();const canvasBounds=ctx.canvas.getBoundingClientRect();ctx.save();ctx.translate(0,pixelRatio*(bounds.top-canvasBounds.top));const dt=this.viewport.currentDisplayTransform;const viewLWorld=dt.xViewToWorld(0);const viewRWorld=dt.xViewToWorld(canvasBounds.width*pixelRatio);const viewHeight=bounds.height*pixelRatio;switch(type){case tr.ui.tracks.DrawType.GRID:this.viewport.drawMajorMarkLines(ctx,viewHeight);ctx.restore();return;case tr.ui.tracks.DrawType.FLOW_ARROWS:if(this.model_.flowIntervalTree.size===0){ctx.restore();return;}
+this.drawFlowArrows_(viewLWorld,viewRWorld);ctx.restore();return;case tr.ui.tracks.DrawType.INSTANT_EVENT:if(!this.model_.instantEvents||this.model_.instantEvents.length===0){break;}
+tr.ui.b.drawInstantSlicesAsLines(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,bounds.height,this.model_.instantEvents,4);break;case tr.ui.tracks.DrawType.MARKERS:if(!this.viewport.interestRange.isEmpty){this.viewport.interestRange.draw(ctx,viewLWorld,viewRWorld,viewHeight);this.viewport.interestRange.drawIndicators(ctx,viewLWorld,viewRWorld);}
+ctx.restore();return;case tr.ui.tracks.DrawType.HIGHLIGHTS:this.drawVSyncHighlight(ctx,dt,viewLWorld,viewRWorld,viewHeight);ctx.restore();return;case tr.ui.tracks.DrawType.ANNOTATIONS:for(let i=0;i<this.annotationViews_.length;i++){this.annotationViews_[i].draw(ctx);}
 ctx.restore();return;}
-ctx.restore();tr.ui.tracks.ContainerTrack.prototype.drawTrack.call(this,type);},drawFlowArrows_:function(viewLWorld,viewRWorld){var ctx=this.context();var dt=this.viewport.currentDisplayTransform;dt.applyTransformToCanvas(ctx);var pixWidth=dt.xViewVectorToWorld(1);ctx.strokeStyle='rgba(0, 0, 0, 0.4)';ctx.fillStyle='rgba(0, 0, 0, 0.4)';ctx.lineWidth=pixWidth>1.0?1:pixWidth;var events=this.model_.flowIntervalTree.findIntersection(viewLWorld,viewRWorld);var onlyHighlighted=!this.viewport.showFlowEvents;var canvasBounds=ctx.canvas.getBoundingClientRect();for(var i=0;i<events.length;++i){if(onlyHighlighted&&events[i].selectionState!==SelectionState.SELECTED&&events[i].selectionState!==SelectionState.HIGHLIGHTED)
-continue;this.drawFlowArrow_(ctx,events[i],canvasBounds,pixWidth);}},drawFlowArrow_:function(ctx,flowEvent,canvasBounds,pixWidth){var pixelRatio=window.devicePixelRatio||1;var startTrack=this.viewport.trackForEvent(flowEvent.startSlice);var endTrack=this.viewport.trackForEvent(flowEvent.endSlice);if(startTrack===undefined||endTrack===undefined)
-return;var startBounds=startTrack.getBoundingClientRect();var endBounds=endTrack.getBoundingClientRect();if(flowEvent.selectionState==SelectionState.SELECTED){ctx.shadowBlur=1;ctx.shadowColor='red';ctx.shadowOffsety=2;ctx.strokeStyle='red';}else if(flowEvent.selectionState==SelectionState.HIGHLIGHTED){ctx.shadowBlur=1;ctx.shadowColor='red';ctx.shadowOffsety=2;ctx.strokeStyle='red';}else if(flowEvent.selectionState==SelectionState.DIMMED){ctx.shadowBlur=0;ctx.shadowOffsetX=0;ctx.strokeStyle='rgba(0, 0, 0, 0.2)';}else{var hasBoost=false;var startSlice=flowEvent.startSlice;hasBoost|=startSlice.selectionState===SelectionState.SELECTED;hasBoost|=startSlice.selectionState===SelectionState.HIGHLIGHTED;var endSlice=flowEvent.endSlice;hasBoost|=endSlice.selectionState===SelectionState.SELECTED;hasBoost|=endSlice.selectionState===SelectionState.HIGHLIGHTED;if(hasBoost){ctx.shadowBlur=1;ctx.shadowColor='rgba(255, 0, 0, 0.4)';ctx.shadowOffsety=2;ctx.strokeStyle='rgba(255, 0, 0, 0.4)';}else{ctx.shadowBlur=0;ctx.shadowOffsetX=0;ctx.strokeStyle='rgba(0, 0, 0, 0.4)';}}
-var startSize=startBounds.left+startBounds.top+
-startBounds.bottom+startBounds.right;var endSize=endBounds.left+endBounds.top+
-endBounds.bottom+endBounds.right;if(startSize===0&&endSize===0)
-return;var startY=this.calculateTrackY_(startTrack,canvasBounds);var endY=this.calculateTrackY_(endTrack,canvasBounds);var pixelStartY=pixelRatio*startY;var pixelEndY=pixelRatio*endY;var half=(flowEvent.end-flowEvent.start)/2;ctx.beginPath();ctx.moveTo(flowEvent.start,pixelStartY);ctx.bezierCurveTo(flowEvent.start+half,pixelStartY,flowEvent.start+half,pixelEndY,flowEvent.end,pixelEndY);ctx.stroke();var arrowWidth=5*pixWidth*pixelRatio;var distance=flowEvent.end-flowEvent.start;if(distance<=(2*arrowWidth))
-return;var tipX=flowEvent.end;var tipY=pixelEndY;var arrowHeight=(endBounds.height/4)*pixelRatio;tr.ui.b.drawTriangle(ctx,tipX,tipY,tipX-arrowWidth,tipY-arrowHeight,tipX-arrowWidth,tipY+arrowHeight);ctx.fill();},calculateTrackY_:function(track,canvasBounds){var bounds=track.getBoundingClientRect();var size=bounds.left+bounds.top+bounds.bottom+bounds.right;if(size===0)
-return this.calculateTrackY_(track.parentNode,canvasBounds);return bounds.top-canvasBounds.top+(bounds.height/2);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){function onPickHit(instantEvent){selection.push(instantEvent);}
-var instantEventWidth=3*viewPixWidthWorld;tr.b.iterateOverIntersectingIntervals(this.model_.instantEvents,function(x){return x.start;},function(x){return x.duration+instantEventWidth;},loWX,hiWX,onPickHit.bind(this));tr.ui.tracks.ContainerTrack.prototype.addIntersectingEventsInRangeToSelectionInWorldSpace.apply(this,arguments);},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){this.addClosestInstantEventToSelection(this.model_.instantEvents,worldX,worldMaxDist,selection);tr.ui.tracks.ContainerTrack.prototype.addClosestEventToSelection.apply(this,arguments);}};return{ModelTrack:ModelTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var RulerTrack=tr.ui.b.define('ruler-track',tr.ui.tracks.Track);var logOf10=Math.log(10);function log10(x){return Math.log(x)/logOf10;}
-RulerTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('ruler-track');this.strings_secs_=[];this.strings_msecs_=[];this.strings_usecs_=[];this.strings_nsecs_=[];this.viewportChange_=this.viewportChange_.bind(this);viewport.addEventListener('change',this.viewportChange_);var heading=document.createElement('tr-ui-heading');heading.arrowVisible=false;this.appendChild(heading);},detach:function(){tr.ui.tracks.Track.prototype.detach.call(this);this.viewport.removeEventListener('change',this.viewportChange_);},viewportChange_:function(){if(this.viewport.interestRange.isEmpty)
-this.classList.remove('tall-mode');else
-this.classList.add('tall-mode');},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GRID:this.drawGrid_(viewLWorld,viewRWorld);break;case tr.ui.tracks.DrawType.MARKERS:if(!this.viewport.interestRange.isEmpty)
-this.viewport.interestRange.draw(this.context(),viewLWorld,viewRWorld);break;}},drawGrid_:function(viewLWorld,viewRWorld){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var canvasBounds=ctx.canvas.getBoundingClientRect();var trackBounds=this.getBoundingClientRect();var width=canvasBounds.width*pixelRatio;var height=trackBounds.height*pixelRatio;var hasInterestRange=!this.viewport.interestRange.isEmpty;var rulerHeight=hasInterestRange?(height*2)/5:height;var vp=this.viewport;var dt=vp.currentDisplayTransform;var idealMajorMarkDistancePix=150*pixelRatio;var idealMajorMarkDistanceWorld=dt.xViewVectorToWorld(idealMajorMarkDistancePix);var majorMarkDistanceWorld;var conservativeGuess=Math.pow(10,Math.ceil(log10(idealMajorMarkDistanceWorld)));var divisors=[10,5,2,1];for(var i=0;i<divisors.length;++i){var tightenedGuess=conservativeGuess/divisors[i];if(dt.xWorldVectorToView(tightenedGuess)<idealMajorMarkDistancePix)
-continue;majorMarkDistanceWorld=conservativeGuess/divisors[i-1];break;}
-var unit;var unitDivisor;var tickLabels=undefined;if(majorMarkDistanceWorld<0.0001){unit='ns';unitDivisor=0.000001;tickLabels=this.strings_nsecs_;}else if(majorMarkDistanceWorld<0.1){unit='us';unitDivisor=0.001;tickLabels=this.strings_usecs_;}else if(majorMarkDistanceWorld<100){unit='ms';unitDivisor=1;tickLabels=this.strings_msecs_;}else{unit='s';unitDivisor=1000;tickLabels=this.strings_secs_;}
-var numTicksPerMajor=5;var minorMarkDistanceWorld=majorMarkDistanceWorld/numTicksPerMajor;var minorMarkDistancePx=dt.xWorldVectorToView(minorMarkDistanceWorld);var firstMajorMark=Math.floor(viewLWorld/majorMarkDistanceWorld)*majorMarkDistanceWorld;var minorTickH=Math.floor(rulerHeight*0.25);ctx.save();var pixelRatio=window.devicePixelRatio||1;ctx.lineWidth=Math.round(pixelRatio);var crispLineCorrection=(ctx.lineWidth%2)/2;ctx.translate(crispLineCorrection,-crispLineCorrection);ctx.fillStyle='rgb(0, 0, 0)';ctx.strokeStyle='rgb(0, 0, 0)';ctx.textAlign='left';ctx.textBaseline='top';ctx.font=(9*pixelRatio)+'px sans-serif';vp.majorMarkPositions=[];ctx.beginPath();for(var curX=firstMajorMark;curX<viewRWorld;curX+=majorMarkDistanceWorld){var curXView=Math.floor(dt.xWorldToView(curX));var unitValue=curX/unitDivisor;var roundedUnitValue=Math.round(unitValue*100000)/100000;if(!tickLabels[roundedUnitValue])
-tickLabels[roundedUnitValue]=roundedUnitValue+' '+unit;ctx.fillText(tickLabels[roundedUnitValue],curXView+(2*pixelRatio),0);vp.majorMarkPositions.push(curXView);tr.ui.b.drawLine(ctx,curXView,0,curXView,rulerHeight);for(var i=1;i<numTicksPerMajor;++i){var xView=Math.floor(curXView+minorMarkDistancePx*i);tr.ui.b.drawLine(ctx,xView,rulerHeight-minorTickH,xView,rulerHeight);}}
-ctx.strokeStyle='rgb(0, 0, 0)';tr.ui.b.drawLine(ctx,0,height,width,height);ctx.stroke();if(!hasInterestRange)
-return;tr.ui.b.drawLine(ctx,0,rulerHeight,width,rulerHeight);ctx.stroke();var displayDistance;var displayTextColor='rgb(0,0,0)';var arrowSpacing=10*pixelRatio;var arrowColor='rgb(128,121,121)';var arrowPosY=rulerHeight*1.75;var arrowWidthView=3*pixelRatio;var arrowLengthView=10*pixelRatio;var spaceForArrowsView=2*(arrowWidthView+arrowSpacing);ctx.textBaseline='middle';ctx.font=(14*pixelRatio)+'px sans-serif';var textPosY=arrowPosY;var interestRange=vp.interestRange;if(interestRange.range===0){var markerWorld=interestRange.min;var markerView=dt.xWorldToView(markerWorld);var displayValue=markerWorld/unitDivisor;displayValue=Math.abs((Math.round(displayValue*1000)/1000));var textToDraw=displayValue+' '+unit;var textLeftView=markerView+4*pixelRatio;var textWidthView=ctx.measureText(textToDraw).width;if(textLeftView+textWidthView>width)
-textLeftView=markerView-4*pixelRatio-textWidthView;ctx.fillStyle=displayTextColor;ctx.fillText(textToDraw,textLeftView,textPosY);return;}
-var leftMarker=interestRange.min;var rightMarker=interestRange.max;var leftMarkerView=dt.xWorldToView(leftMarker);var rightMarkerView=dt.xWorldToView(rightMarker);var distanceBetweenMarkers=interestRange.range;var distanceBetweenMarkersView=dt.xWorldVectorToView(distanceBetweenMarkers);var positionInMiddleOfMarkersView=leftMarkerView+(distanceBetweenMarkersView/2);if(distanceBetweenMarkers<0.0001){unit='ns';unitDivisor=0.000001;}else if(distanceBetweenMarkers<0.1){unit='us';unitDivisor=0.001;}else if(distanceBetweenMarkers<100){unit='ms';unitDivisor=1;}else{unit='s';unitDivisor=1000;}
-displayDistance=distanceBetweenMarkers/unitDivisor;var roundedDisplayDistance=Math.abs((Math.round(displayDistance*1000)/1000));var textToDraw=roundedDisplayDistance+' '+unit;var textWidthView=ctx.measureText(textToDraw).width;var spaceForArrowsAndTextView=textWidthView+spaceForArrowsView+arrowSpacing;var textLeftView=positionInMiddleOfMarkersView-textWidthView/2;var textRightView=textLeftView+textWidthView;if(spaceForArrowsAndTextView>distanceBetweenMarkersView){textLeftView=rightMarkerView+2*arrowSpacing;if(textLeftView+textWidthView>width)
-textLeftView=leftMarkerView-2*arrowSpacing-textWidthView;ctx.fillStyle=displayTextColor;ctx.fillText(textToDraw,textLeftView,textPosY);ctx.strokeStyle=arrowColor;ctx.beginPath();tr.ui.b.drawLine(ctx,leftMarkerView,arrowPosY,rightMarkerView,arrowPosY);ctx.stroke();ctx.fillStyle=arrowColor;tr.ui.b.drawArrow(ctx,leftMarkerView-1.5*arrowSpacing,arrowPosY,leftMarkerView,arrowPosY,arrowLengthView,arrowWidthView);tr.ui.b.drawArrow(ctx,rightMarkerView+1.5*arrowSpacing,arrowPosY,rightMarkerView,arrowPosY,arrowLengthView,arrowWidthView);}else if(spaceForArrowsView<=distanceBetweenMarkersView){var leftArrowStart;var rightArrowStart;if(spaceForArrowsAndTextView<=distanceBetweenMarkersView){ctx.fillStyle=displayTextColor;ctx.fillText(textToDraw,textLeftView,textPosY);leftArrowStart=textLeftView-arrowSpacing;rightArrowStart=textRightView+arrowSpacing;}else{leftArrowStart=positionInMiddleOfMarkersView;rightArrowStart=positionInMiddleOfMarkersView;}
+ctx.restore();tr.ui.tracks.ContainerTrack.prototype.drawTrack.call(this,type);},drawFlowArrows_(viewLWorld,viewRWorld){const ctx=this.context();ctx.strokeStyle='rgba(0, 0, 0, 0.4)';ctx.fillStyle='rgba(0, 0, 0, 0.4)';ctx.lineWidth=1;const events=this.model_.flowIntervalTree.findIntersection(viewLWorld,viewRWorld);const onlyHighlighted=!this.viewport.showFlowEvents;const canvasBounds=ctx.canvas.getBoundingClientRect();for(let i=0;i<events.length;++i){if(onlyHighlighted&&events[i].selectionState!==SelectionState.SELECTED&&events[i].selectionState!==SelectionState.HIGHLIGHTED){continue;}
+this.drawFlowArrow_(ctx,events[i],canvasBounds);}},drawFlowArrow_(ctx,flowEvent,canvasBounds){const dt=this.viewport.currentDisplayTransform;const pixelRatio=window.devicePixelRatio||1;const startTrack=this.viewport.trackForEvent(flowEvent.startSlice);const endTrack=this.viewport.trackForEvent(flowEvent.endSlice);if(startTrack===undefined||endTrack===undefined)return;const startBounds=startTrack.getBoundingClientRect();const endBounds=endTrack.getBoundingClientRect();if(flowEvent.selectionState===SelectionState.SELECTED){ctx.shadowBlur=1;ctx.shadowColor='red';ctx.shadowOffsety=2;ctx.strokeStyle=tr.b.ColorScheme.colorsAsStrings[tr.b.ColorScheme.getVariantColorId(flowEvent.colorId,tr.b.ColorScheme.properties.brightenedOffsets[0])];}else if(flowEvent.selectionState===SelectionState.HIGHLIGHTED){ctx.shadowBlur=1;ctx.shadowColor='red';ctx.shadowOffsety=2;ctx.strokeStyle=tr.b.ColorScheme.colorsAsStrings[tr.b.ColorScheme.getVariantColorId(flowEvent.colorId,tr.b.ColorScheme.properties.brightenedOffsets[0])];}else if(flowEvent.selectionState===SelectionState.DIMMED){ctx.shadowBlur=0;ctx.shadowOffsetX=0;ctx.strokeStyle=tr.b.ColorScheme.colorsAsStrings[flowEvent.colorId];}else{let hasBoost=false;const startSlice=flowEvent.startSlice;hasBoost|=startSlice.selectionState===SelectionState.SELECTED;hasBoost|=startSlice.selectionState===SelectionState.HIGHLIGHTED;const endSlice=flowEvent.endSlice;hasBoost|=endSlice.selectionState===SelectionState.SELECTED;hasBoost|=endSlice.selectionState===SelectionState.HIGHLIGHTED;if(hasBoost){ctx.shadowBlur=1;ctx.shadowColor='rgba(255, 0, 0, 0.4)';ctx.shadowOffsety=2;ctx.strokeStyle=tr.b.ColorScheme.colorsAsStrings[tr.b.ColorScheme.getVariantColorId(flowEvent.colorId,tr.b.ColorScheme.properties.brightenedOffsets[0])];}else{ctx.shadowBlur=0;ctx.shadowOffsetX=0;ctx.strokeStyle=tr.b.ColorScheme.colorsAsStrings[flowEvent.colorId];}}
+const startSize=startBounds.left+startBounds.top+
+startBounds.bottom+startBounds.right;const endSize=endBounds.left+endBounds.top+
+endBounds.bottom+endBounds.right;if(startSize===0&&endSize===0)return;const startY=this.calculateTrackY_(startTrack,canvasBounds);const endY=this.calculateTrackY_(endTrack,canvasBounds);const worldOffset=this.getBoundingClientRect().top-canvasBounds.top;const pixelStartY=pixelRatio*(startY-worldOffset);const pixelEndY=pixelRatio*(endY-worldOffset);const startXView=dt.xWorldToView(flowEvent.start);const endXView=dt.xWorldToView(flowEvent.end);const midXView=(startXView+endXView)/2;ctx.beginPath();ctx.moveTo(startXView,pixelStartY);ctx.bezierCurveTo(midXView,pixelStartY,midXView,pixelEndY,endXView,pixelEndY);ctx.stroke();const arrowWidth=5*pixelRatio;const distance=endXView-startXView;if(distance<=(2*arrowWidth))return;const tipX=endXView;const tipY=pixelEndY;const arrowHeight=(endBounds.height/4)*pixelRatio;tr.ui.b.drawTriangle(ctx,tipX,tipY,tipX-arrowWidth,tipY-arrowHeight,tipX-arrowWidth,tipY+arrowHeight);ctx.fill();},drawVSyncHighlight(ctx,dt,viewLWorld,viewRWorld,viewHeight){if(!this.viewport_.highlightVSync){return;}
+const stripes=ModelTrack.generateStripes_(this.vSyncTimes_,viewLWorld,viewRWorld);if(stripes.length===0){return;}
+const vSyncHighlightColor=new tr.b.Color(ColorScheme.getColorForReservedNameAsString('vsync_highlight_color'));const stripeRange=stripes[stripes.length-1].max-stripes[0].min;const stripeDensity=stripeRange?stripes.length/(dt.scaleX*stripeRange):0;const clampedStripeDensity=tr.b.math.clamp(stripeDensity,ModelTrack.VSYNC_DENSITY_OPAQUE,ModelTrack.VSYNC_DENSITY_TRANSPARENT);const opacity=(ModelTrack.VSYNC_DENSITY_TRANSPARENT-clampedStripeDensity)/ModelTrack.VSYNC_DENSITY_RANGE;if(opacity===0){return;}
+ctx.fillStyle=vSyncHighlightColor.toStringWithAlphaOverride(ModelTrack.VSYNC_HIGHLIGHT_ALPHA*opacity);for(let i=0;i<stripes.length;i++){const xLeftView=dt.xWorldToView(stripes[i].min);const xRightView=dt.xWorldToView(stripes[i].max);ctx.fillRect(xLeftView,0,xRightView-xLeftView,viewHeight);}},calculateTrackY_(track,canvasBounds){const bounds=track.getBoundingClientRect();const size=bounds.left+bounds.top+bounds.bottom+bounds.right;if(size===0){return this.calculateTrackY_(Polymer.dom(track).parentNode,canvasBounds);}
+return bounds.top-canvasBounds.top+(bounds.height/2);},addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection){function onPickHit(instantEvent){selection.push(instantEvent);}
+const instantEventWidth=3*viewPixWidthWorld;tr.b.iterateOverIntersectingIntervals(this.model_.instantEvents,function(x){return x.start;},function(x){return x.duration+instantEventWidth;},loWX,hiWX,onPickHit.bind(this));tr.ui.tracks.ContainerTrack.prototype.addIntersectingEventsInRangeToSelectionInWorldSpace.apply(this,arguments);},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){this.addClosestInstantEventToSelection(this.model_.instantEvents,worldX,worldMaxDist,selection);tr.ui.tracks.ContainerTrack.prototype.addClosestEventToSelection.apply(this,arguments);}};return{ModelTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const XAxisTrack=tr.ui.b.define('x-axis-track',tr.ui.tracks.Track);XAxisTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('x-axis-track');this.strings_secs_=[];this.strings_msecs_=[];this.strings_usecs_=[];this.strings_nsecs_=[];this.viewportChange_=this.viewportChange_.bind(this);viewport.addEventListener('change',this.viewportChange_);const heading=document.createElement('tr-ui-b-heading');heading.arrowVisible=false;Polymer.dom(this).appendChild(heading);},detach(){tr.ui.tracks.Track.prototype.detach.call(this);this.viewport.removeEventListener('change',this.viewportChange_);},viewportChange_(){if(this.viewport.interestRange.isEmpty){Polymer.dom(this).classList.remove('tall-mode');}else{Polymer.dom(this).classList.add('tall-mode');}},draw(type,viewLWorld,viewRWorld,viewHeight){switch(type){case tr.ui.tracks.DrawType.GRID:this.drawGrid_(viewLWorld,viewRWorld);break;case tr.ui.tracks.DrawType.MARKERS:this.drawMarkers_(viewLWorld,viewRWorld);break;}},drawGrid_(viewLWorld,viewRWorld){const ctx=this.context();const pixelRatio=window.devicePixelRatio||1;const canvasBounds=ctx.canvas.getBoundingClientRect();const trackBounds=this.getBoundingClientRect();const width=canvasBounds.width*pixelRatio;const height=trackBounds.height*pixelRatio;const hasInterestRange=!this.viewport.interestRange.isEmpty;const xAxisHeightPx=hasInterestRange?(height*2)/5:height;const vp=this.viewport;const dt=vp.currentDisplayTransform;vp.updateMajorMarkData(viewLWorld,viewRWorld);const majorMarkDistanceWorld=vp.majorMarkWorldPositions.length>1?vp.majorMarkWorldPositions[1]-vp.majorMarkWorldPositions[0]:0;const numTicksPerMajor=5;const minorMarkDistanceWorld=majorMarkDistanceWorld/numTicksPerMajor;const minorMarkDistancePx=dt.xWorldVectorToView(minorMarkDistanceWorld);const minorTickHeight=Math.floor(xAxisHeightPx*0.25);ctx.save();ctx.lineWidth=Math.round(pixelRatio);const crispLineCorrection=(ctx.lineWidth%2)/2;ctx.translate(crispLineCorrection,-crispLineCorrection);ctx.fillStyle='rgb(0, 0, 0)';ctx.strokeStyle='rgb(0, 0, 0)';ctx.textAlign='left';ctx.textBaseline='top';ctx.font=(9*pixelRatio)+'px sans-serif';const tickLabels=[];ctx.beginPath();for(let i=0;i<vp.majorMarkWorldPositions.length;i++){const curXWorld=vp.majorMarkWorldPositions[i];const curXView=dt.xWorldToView(curXWorld);const displayText=vp.majorMarkUnit.format(curXWorld,{deltaValue:majorMarkDistanceWorld});ctx.fillText(displayText,curXView+(2*pixelRatio),0);tr.ui.b.drawLine(ctx,curXView,0,curXView,xAxisHeightPx);if(minorMarkDistancePx){for(let j=1;j<numTicksPerMajor;++j){const xView=Math.floor(curXView+minorMarkDistancePx*j);tr.ui.b.drawLine(ctx,xView,xAxisHeightPx-minorTickHeight,xView,xAxisHeightPx);}}}
+ctx.strokeStyle='rgb(0, 0, 0)';tr.ui.b.drawLine(ctx,0,height,width,height);ctx.stroke();if(!hasInterestRange)return;tr.ui.b.drawLine(ctx,0,xAxisHeightPx,width,xAxisHeightPx);ctx.stroke();let displayDistance;const displayTextColor='rgb(0,0,0)';const arrowSpacing=10*pixelRatio;const arrowColor='rgb(128,121,121)';const arrowPosY=xAxisHeightPx*1.75;const arrowWidthView=3*pixelRatio;const arrowLengthView=10*pixelRatio;const spaceForArrowsView=2*(arrowWidthView+arrowSpacing);ctx.textBaseline='middle';ctx.font=(14*pixelRatio)+'px sans-serif';const textPosY=arrowPosY;const interestRange=vp.interestRange;if(interestRange.range===0){const markerWorld=interestRange.min;const markerView=dt.xWorldToView(markerWorld);const textToDraw=vp.majorMarkUnit.format(markerWorld);let textLeftView=markerView+4*pixelRatio;const textWidthView=ctx.measureText(textToDraw).width;if(textLeftView+textWidthView>width){textLeftView=markerView-4*pixelRatio-textWidthView;}
+ctx.fillStyle=displayTextColor;ctx.fillText(textToDraw,textLeftView,textPosY);return;}
+const leftMarker=interestRange.min;const rightMarker=interestRange.max;const leftMarkerView=dt.xWorldToView(leftMarker);const rightMarkerView=dt.xWorldToView(rightMarker);const distanceBetweenMarkers=interestRange.range;const distanceBetweenMarkersView=dt.xWorldVectorToView(distanceBetweenMarkers);const positionInMiddleOfMarkersView=leftMarkerView+(distanceBetweenMarkersView/2);const textToDraw=vp.majorMarkUnit.format(distanceBetweenMarkers);const textWidthView=ctx.measureText(textToDraw).width;const spaceForArrowsAndTextView=textWidthView+spaceForArrowsView+arrowSpacing;let textLeftView=positionInMiddleOfMarkersView-textWidthView/2;const textRightView=textLeftView+textWidthView;if(spaceForArrowsAndTextView>distanceBetweenMarkersView){textLeftView=rightMarkerView+2*arrowSpacing;if(textLeftView+textWidthView>width){textLeftView=leftMarkerView-2*arrowSpacing-textWidthView;}
+ctx.fillStyle=displayTextColor;ctx.fillText(textToDraw,textLeftView,textPosY);ctx.strokeStyle=arrowColor;ctx.beginPath();tr.ui.b.drawLine(ctx,leftMarkerView,arrowPosY,rightMarkerView,arrowPosY);ctx.stroke();ctx.fillStyle=arrowColor;tr.ui.b.drawArrow(ctx,leftMarkerView-1.5*arrowSpacing,arrowPosY,leftMarkerView,arrowPosY,arrowLengthView,arrowWidthView);tr.ui.b.drawArrow(ctx,rightMarkerView+1.5*arrowSpacing,arrowPosY,rightMarkerView,arrowPosY,arrowLengthView,arrowWidthView);}else if(spaceForArrowsView<=distanceBetweenMarkersView){let leftArrowStart;let rightArrowStart;if(spaceForArrowsAndTextView<=distanceBetweenMarkersView){ctx.fillStyle=displayTextColor;ctx.fillText(textToDraw,textLeftView,textPosY);leftArrowStart=textLeftView-arrowSpacing;rightArrowStart=textRightView+arrowSpacing;}else{leftArrowStart=positionInMiddleOfMarkersView;rightArrowStart=positionInMiddleOfMarkersView;}
 ctx.strokeStyle=arrowColor;ctx.fillStyle=arrowColor;tr.ui.b.drawArrow(ctx,leftArrowStart,arrowPosY,leftMarkerView,arrowPosY,arrowLengthView,arrowWidthView);tr.ui.b.drawArrow(ctx,rightArrowStart,arrowPosY,rightMarkerView,arrowPosY,arrowLengthView,arrowWidthView);}
-ctx.restore();},addIntersectingEventsInRangeToSelection:function(loVX,hiVX,loY,hiY,selection){},addAllEventsMatchingFilterToSelection:function(filter,selection){}};return{RulerTrack:RulerTrack};});'use strict';Polymer('tr-ui-timeline-track-view',{ready:function(){this.displayTransform_=new tr.ui.TimelineDisplayTransform();this.model_=undefined;this.timelineView_=undefined;this.viewport_=new tr.ui.TimelineViewport(this);this.viewportDisplayTransformAtMouseDown_=undefined;this.brushingStateController_=undefined;this.rulerTrackContainer_=new tr.ui.tracks.DrawingContainer(this.viewport_);this.appendChild(this.rulerTrackContainer_);this.rulerTrackContainer_.invalidate();this.rulerTrack_=new tr.ui.tracks.RulerTrack(this.viewport_);this.rulerTrackContainer_.appendChild(this.rulerTrack_);this.upperModelTrack_=new tr.ui.tracks.ModelTrack(this.viewport_);this.upperModelTrack_.upperMode=true;this.rulerTrackContainer_.appendChild(this.upperModelTrack_);this.modelTrackContainer_=new tr.ui.tracks.DrawingContainer(this.viewport_);this.appendChild(this.modelTrackContainer_);this.modelTrackContainer_.style.display='block';this.modelTrackContainer_.invalidate();this.viewport_.modelTrackContainer=this.modelTrackContainer_;this.modelTrack_=new tr.ui.tracks.ModelTrack(this.viewport_);this.modelTrackContainer_.appendChild(this.modelTrack_);this.timingTool_=new tr.ui.b.TimingTool(this.viewport_,this);this.initMouseModeSelector();this.hideDragBox_();this.initHintText_();this.onSelectionChanged_=this.onSelectionChanged_.bind(this);this.onDblClick_=this.onDblClick_.bind(this);this.addEventListener('dblclick',this.onDblClick_);this.onMouseWheel_=this.onMouseWheel_.bind(this);this.addEventListener('mousewheel',this.onMouseWheel_);this.onMouseDown_=this.onMouseDown_.bind(this);this.addEventListener('mousedown',this.onMouseDown_);this.onMouseMove_=this.onMouseMove_.bind(this);this.addEventListener('mousemove',this.onMouseMove_);this.onTouchStart_=this.onTouchStart_.bind(this);this.addEventListener('touchstart',this.onTouchStart_);this.onTouchMove_=this.onTouchMove_.bind(this);this.addEventListener('touchmove',this.onTouchMove_);this.onTouchEnd_=this.onTouchEnd_.bind(this);this.addEventListener('touchend',this.onTouchEnd_);this.addHotKeys_();this.mouseViewPosAtMouseDown_={x:0,y:0};this.lastMouseViewPos_={x:0,y:0};this.lastTouchViewPositions_=[];this.alert_=undefined;this.isPanningAndScanning_=false;this.isZooming_=false;},initMouseModeSelector:function(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this;this.appendChild(this.mouseModeSelector_);this.mouseModeSelector_.addEventListener('beginpan',this.onBeginPanScan_.bind(this));this.mouseModeSelector_.addEventListener('updatepan',this.onUpdatePanScan_.bind(this));this.mouseModeSelector_.addEventListener('endpan',this.onEndPanScan_.bind(this));this.mouseModeSelector_.addEventListener('beginselection',this.onBeginSelection_.bind(this));this.mouseModeSelector_.addEventListener('updateselection',this.onUpdateSelection_.bind(this));this.mouseModeSelector_.addEventListener('endselection',this.onEndSelection_.bind(this));this.mouseModeSelector_.addEventListener('beginzoom',this.onBeginZoom_.bind(this));this.mouseModeSelector_.addEventListener('updatezoom',this.onUpdateZoom_.bind(this));this.mouseModeSelector_.addEventListener('endzoom',this.onEndZoom_.bind(this));this.mouseModeSelector_.addEventListener('entertiming',this.timingTool_.onEnterTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('begintiming',this.timingTool_.onBeginTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('updatetiming',this.timingTool_.onUpdateTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('endtiming',this.timingTool_.onEndTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('exittiming',this.timingTool_.onExitTiming.bind(this.timingTool_));var m=tr.ui.b.MOUSE_SELECTOR_MODE;this.mouseModeSelector_.supportedModeMask=m.SELECTION|m.PANSCAN|m.ZOOM|m.TIMING;this.mouseModeSelector_.settingsKey='timelineTrackView.mouseModeSelector';this.mouseModeSelector_.setKeyCodeForMode(m.PANSCAN,'2'.charCodeAt(0));this.mouseModeSelector_.setKeyCodeForMode(m.SELECTION,'1'.charCodeAt(0));this.mouseModeSelector_.setKeyCodeForMode(m.ZOOM,'3'.charCodeAt(0));this.mouseModeSelector_.setKeyCodeForMode(m.TIMING,'4'.charCodeAt(0));this.mouseModeSelector_.setModifierForAlternateMode(m.SELECTION,tr.ui.b.MODIFIER.SHIFT);this.mouseModeSelector_.setModifierForAlternateMode(m.PANSCAN,tr.ui.b.MODIFIER.SPACE);},get brushingStateController(){return this.brushingStateController_;},set brushingStateController(brushingStateController){if(this.brushingStateController_){this.brushingStateController_.removeEventListener('change',this.onSelectionChanged_);}
-this.brushingStateController_=brushingStateController;if(this.brushingStateController_){this.brushingStateController_.addEventListener('change',this.onSelectionChanged_);}},set timelineView(view){this.timelineView_=view;},onSelectionChanged_:function(){this.showHintText_('Press \'m\' to mark current selection');this.viewport_.dispatchChangeEvent();},set selection(selection){throw new Error('DO NOT CALL THIS');},set highlight(highlight){throw new Error('DO NOT CALL THIS');},detach:function(){this.modelTrack_.detach();this.upperModelTrack_.detach();this.viewport_.detach();},get viewport(){return this.viewport_;},get model(){return this.model_;},set model(model){if(!model)
-throw new Error('Model cannot be undefined');var modelInstanceChanged=this.model_!==model;this.model_=model;this.modelTrack_.model=model;this.upperModelTrack_.model=model;if(modelInstanceChanged)
-this.viewport_.setWhenPossible(this.setInitialViewport_.bind(this));},get hasVisibleContent(){return this.modelTrack_.hasVisibleContent||this.upperModelTrack_.hasVisibleContent;},setInitialViewport_:function(){this.modelTrackContainer_.updateCanvasSizeIfNeeded_();var w=this.modelTrackContainer_.canvas.width;var min;var range;if(this.model_.bounds.isEmpty){min=0;range=1000;}else if(this.model_.bounds.range===0){min=this.model_.bounds.min;range=1000;}else{min=this.model_.bounds.min;range=this.model_.bounds.range;}
-var boost=range*0.15;this.displayTransform_.set(this.viewport_.currentDisplayTransform);this.displayTransform_.xSetWorldBounds(min-boost,min+range+boost,w);this.viewport_.setDisplayTransformImmediately(this.displayTransform_);},addAllEventsMatchingFilterToSelectionAsTask:function(filter,selection){var modelTrack=this.modelTrack_;var firstT=modelTrack.addAllEventsMatchingFilterToSelectionAsTask(filter,selection);var lastT=firstT.after(function(){this.upperModelTrack_.addAllEventsMatchingFilterToSelection(filter,selection);},this);return firstT;},onMouseMove_:function(e){if(this.isZooming_)
-return;this.storeLastMousePos_(e);},onTouchStart_:function(e){this.storeLastTouchPositions_(e);this.focusElements_();},onTouchMove_:function(e){e.preventDefault();this.onUpdateTransformForTouch_(e);},onTouchEnd_:function(e){this.storeLastTouchPositions_(e);this.focusElements_();},addHotKeys_:function(){this.addKeyDownHotKeys_();this.addKeyPressHotKeys_();},addKeyPressHotKeys_:function(){var addBinding=function(dict){dict.eventType='keypress';dict.useCapture=false;dict.thisArg=this;var binding=new tr.ui.b.HotKey(dict);this.$.hotkey_controller.addHotKey(binding);}.bind(this);addBinding({keyCodes:['w'.charCodeAt(0),','.charCodeAt(0)],callback:function(e){this.zoomBy_(1.5,true);e.stopPropagation();}});addBinding({keyCodes:['s'.charCodeAt(0),'o'.charCodeAt(0)],callback:function(e){this.zoomBy_(1/1.5,true);e.stopPropagation();}});addBinding({keyCode:'g'.charCodeAt(0),callback:function(e){this.onGridToggle_(true);e.stopPropagation();}});addBinding({keyCode:'G'.charCodeAt(0),callback:function(e){this.onGridToggle_(false);e.stopPropagation();}});addBinding({keyCodes:['W'.charCodeAt(0),'<'.charCodeAt(0)],callback:function(e){this.zoomBy_(10,true);e.stopPropagation();}});addBinding({keyCodes:['S'.charCodeAt(0),'O'.charCodeAt(0)],callback:function(e){this.zoomBy_(1/10,true);e.stopPropagation();}});addBinding({keyCode:'a'.charCodeAt(0),callback:function(e){this.queueSmoothPan_(this.viewWidth_*0.3,0);e.stopPropagation();}});addBinding({keyCodes:['d'.charCodeAt(0),'e'.charCodeAt(0)],callback:function(e){this.queueSmoothPan_(this.viewWidth_*-0.3,0);e.stopPropagation();}});addBinding({keyCode:'A'.charCodeAt(0),callback:function(e){this.queueSmoothPan_(viewWidth*0.5,0);e.stopPropagation();}});addBinding({keyCode:'D'.charCodeAt(0),callback:function(e){this.queueSmoothPan_(viewWidth*-0.5,0);e.stopPropagation();}});addBinding({keyCode:'0'.charCodeAt(0),callback:function(e){this.setInitialViewport_();e.stopPropagation();}});addBinding({keyCode:'f'.charCodeAt(0),callback:function(e){this.zoomToSelection();e.stopPropagation();}});addBinding({keyCode:'m'.charCodeAt(0),callback:function(e){this.setCurrentSelectionAsInterestRange_();e.stopPropagation();}});addBinding({keyCode:'h'.charCodeAt(0),callback:function(e){this.toggleHighDetails_();e.stopPropagation();}});},get viewWidth_(){return this.modelTrackContainer_.canvas.clientWidth;},addKeyDownHotKeys_:function(){var addBinding=function(dict){dict.eventType='keydown';dict.useCapture=false;dict.thisArg=this;var binding=new tr.ui.b.HotKey(dict);this.$.hotkey_controller.addHotKey(binding);}.bind(this);addBinding({keyCode:37,callback:function(e){var curSel=this.brushingStateController_.selection;var sel=this.viewport.getShiftedSelection(curSel,-1);if(sel){this.brushingStateController.changeSelectionFromTimeline(sel);this.panToSelection();}else{this.queueSmoothPan_(this.viewWidth_*0.3,0);}
-e.preventDefault();e.stopPropagation();}});addBinding({keyCode:39,callback:function(e){var curSel=this.brushingStateController_.selection;var sel=this.viewport.getShiftedSelection(curSel,1);if(sel){this.brushingStateController.changeSelectionFromTimeline(sel);this.panToSelection();}else{this.queueSmoothPan_(-this.viewWidth_*0.3,0);}
-e.preventDefault();e.stopPropagation();}});},onDblClick_:function(e){if(this.mouseModeSelector_.mode!==tr.ui.b.MOUSE_SELECTOR_MODE.SELECTION)
-return;var curSelection=this.brushingStateController_.selection;if(!curSelection.length||!curSelection[0].title)
-return;var selection=new tr.model.EventSet();var filter=new tr.c.ExactTitleFilter(curSelection[0].title);this.modelTrack_.addAllEventsMatchingFilterToSelection(filter,selection);this.brushingStateController.changeSelectionFromTimeline(selection);},onMouseWheel_:function(e){if(!e.altKey)
-return;var delta=e.wheelDelta/120;var zoomScale=Math.pow(1.5,delta);this.zoomBy_(zoomScale);e.preventDefault();},onMouseDown_:function(e){if(this.mouseModeSelector_.mode!==tr.ui.b.MOUSE_SELECTOR_MODE.SELECTION)
-return;if(e.target!==this.rulerTrack_)
-return;this.dragBeginEvent_=undefined;if(this.xNavStringMarker_){this.model.removeAnnotation(this.xNavStringMarker_);this.xNavStringMarker_=undefined;}
-var dt=this.viewport_.currentDisplayTransform;tr.ui.b.trackMouseMovesUntilMouseUp(function(e){if(e.target===this.rulerTrack_)
-return;var relativePosition=this.extractRelativeMousePosition_(e);var loc=tr.model.Location.fromViewCoordinates(this.viewport_,relativePosition.x,relativePosition.y);if(!loc)
-return;if(this.guideLineAnnotation_===undefined){this.guideLineAnnotation_=new tr.model.XMarkerAnnotation(loc.xWorld);this.model.addAnnotation(this.guideLineAnnotation_);}else{this.guideLineAnnotation_.timestamp=loc.xWorld;this.modelTrackContainer_.invalidate();}
-var state=new tr.ui.b.UIState(loc,this.viewport_.currentDisplayTransform.scaleX);this.timelineView_.setFindCtlText(state.toUserFriendlyString(this.viewport_));}.bind(this),undefined,function onKeyUpDuringDrag(){if(this.dragBeginEvent_){this.setDragBoxPosition_(this.dragBoxXStart_,this.dragBoxYStart_,this.dragBoxXEnd_,this.dragBoxYEnd_);}}.bind(this));},queueSmoothPan_:function(viewDeltaX,deltaY){var deltaX=this.viewport_.currentDisplayTransform.xViewVectorToWorld(viewDeltaX);var animation=new tr.ui.TimelineDisplayTransformPanAnimation(deltaX,deltaY);this.viewport_.queueDisplayTransformAnimation(animation);},zoomBy_:function(scale,smooth){if(scale<=0){return;}
-smooth=!!smooth;var vp=this.viewport_;var pixelRatio=window.devicePixelRatio||1;var goalFocalPointXView=this.lastMouseViewPos_.x*pixelRatio;var goalFocalPointXWorld=vp.currentDisplayTransform.xViewToWorld(goalFocalPointXView);if(smooth){var animation=new tr.ui.TimelineDisplayTransformZoomToAnimation(goalFocalPointXWorld,goalFocalPointXView,vp.currentDisplayTransform.panY,scale);vp.queueDisplayTransformAnimation(animation);}else{this.displayTransform_.set(vp.currentDisplayTransform);this.displayTransform_.scaleX*=scale;this.displayTransform_.xPanWorldPosToViewPos(goalFocalPointXWorld,goalFocalPointXView,this.viewWidth_);vp.setDisplayTransformImmediately(this.displayTransform_);}},zoomToSelection:function(){if(!this.brushingStateController.selectionOfInterest.length)
-return;var bounds=this.brushingStateController.selectionOfInterest.bounds;if(!bounds.range)
-return;var worldCenter=bounds.center;var viewCenter=this.modelTrackContainer_.canvas.width/2;var adjustedWorldRange=bounds.range*1.25;var newScale=this.modelTrackContainer_.canvas.width/adjustedWorldRange;var zoomInRatio=newScale/this.viewport_.currentDisplayTransform.scaleX;var animation=new tr.ui.TimelineDisplayTransformZoomToAnimation(worldCenter,viewCenter,this.viewport_.currentDisplayTransform.panY,zoomInRatio);this.viewport_.queueDisplayTransformAnimation(animation);},panToSelection:function(){if(!this.brushingStateController.selectionOfInterest.length)
-return;var bounds=this.brushingStateController.selectionOfInterest.bounds;var worldCenter=bounds.center;var viewWidth=this.viewWidth_;var dt=this.viewport_.currentDisplayTransform;if(false&&!bounds.range){if(dt.xWorldToView(bounds.center)<0||dt.xWorldToView(bounds.center)>viewWidth){this.displayTransform_.set(dt);this.displayTransform_.xPanWorldPosToViewPos(worldCenter,'center',viewWidth);var deltaX=this.displayTransform_.panX-dt.panX;var animation=new tr.ui.TimelineDisplayTransformPanAnimation(deltaX,0);this.viewport_.queueDisplayTransformAnimation(animation);}
+ctx.restore();},drawMarkers_(viewLWorld,viewRWorld){const pixelRatio=window.devicePixelRatio||1;const trackBounds=this.getBoundingClientRect();const viewHeight=trackBounds.height*pixelRatio;if(!this.viewport.interestRange.isEmpty){this.viewport.interestRange.draw(this.context(),viewLWorld,viewRWorld,viewHeight);}},addIntersectingEventsInRangeToSelection(loVX,hiVX,loY,hiY,selection){},addAllEventsMatchingFilterToSelection(filter,selection){}};return{XAxisTrack,};});'use strict';Polymer({is:'tr-ui-timeline-track-view',ready(){this.displayTransform_=new tr.ui.TimelineDisplayTransform();this.model_=undefined;this.timelineView_=undefined;this.pollIfViewportAttachedInterval_=undefined;this.viewport_=new tr.ui.TimelineViewport(this);this.viewportDisplayTransformAtMouseDown_=undefined;this.brushingStateController_=undefined;this.rulerTrackContainer_=new tr.ui.tracks.DrawingContainer(this.viewport_);Polymer.dom(this).appendChild(this.rulerTrackContainer_);this.rulerTrackContainer_.invalidate();this.rulerTrackContainer_.style.overflowY='hidden';this.rulerTrackContainer_.style.flexShrink='0';this.rulerTrack_=new tr.ui.tracks.XAxisTrack(this.viewport_);Polymer.dom(this.rulerTrackContainer_).appendChild(this.rulerTrack_);this.upperModelTrack_=new tr.ui.tracks.ModelTrack(this.viewport_);this.upperModelTrack_.upperMode=true;Polymer.dom(this.rulerTrackContainer_).appendChild(this.upperModelTrack_);this.modelTrackContainer_=new tr.ui.tracks.DrawingContainer(this.viewport_);Polymer.dom(this).appendChild(this.modelTrackContainer_);this.modelTrackContainer_.style.display='block';this.modelTrackContainer_.style.flexGrow='1';this.modelTrackContainer_.invalidate();this.viewport_.modelTrackContainer=this.modelTrackContainer_;this.modelTrack_=new tr.ui.tracks.ModelTrack(this.viewport_);Polymer.dom(this.modelTrackContainer_).appendChild(this.modelTrack_);this.timingTool_=new tr.ui.b.TimingTool(this.viewport_,this);this.initMouseModeSelector();this.hideDragBox_();this.initHintText_();this.onSelectionChanged_=this.onSelectionChanged_.bind(this);this.onDblClick_=this.onDblClick_.bind(this);this.addEventListener('dblclick',this.onDblClick_);this.onMouseWheel_=this.onMouseWheel_.bind(this);this.addEventListener('mousewheel',this.onMouseWheel_);this.onMouseDown_=this.onMouseDown_.bind(this);this.addEventListener('mousedown',this.onMouseDown_);this.onMouseMove_=this.onMouseMove_.bind(this);this.addEventListener('mousemove',this.onMouseMove_);this.onTouchStart_=this.onTouchStart_.bind(this);this.addEventListener('touchstart',this.onTouchStart_);this.onTouchMove_=this.onTouchMove_.bind(this);this.addEventListener('touchmove',this.onTouchMove_);this.onTouchEnd_=this.onTouchEnd_.bind(this);this.addEventListener('touchend',this.onTouchEnd_);this.addHotKeys_();this.mouseViewPosAtMouseDown_={x:0,y:0};this.lastMouseViewPos_={x:0,y:0};this.lastTouchViewPositions_=[];this.alert_=undefined;this.isPanningAndScanning_=false;this.isZooming_=false;},initMouseModeSelector(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this;Polymer.dom(this).appendChild(this.mouseModeSelector_);this.mouseModeSelector_.addEventListener('beginpan',this.onBeginPanScan_.bind(this));this.mouseModeSelector_.addEventListener('updatepan',this.onUpdatePanScan_.bind(this));this.mouseModeSelector_.addEventListener('endpan',this.onEndPanScan_.bind(this));this.mouseModeSelector_.addEventListener('beginselection',this.onBeginSelection_.bind(this));this.mouseModeSelector_.addEventListener('updateselection',this.onUpdateSelection_.bind(this));this.mouseModeSelector_.addEventListener('endselection',this.onEndSelection_.bind(this));this.mouseModeSelector_.addEventListener('beginzoom',this.onBeginZoom_.bind(this));this.mouseModeSelector_.addEventListener('updatezoom',this.onUpdateZoom_.bind(this));this.mouseModeSelector_.addEventListener('endzoom',this.onEndZoom_.bind(this));this.mouseModeSelector_.addEventListener('entertiming',this.timingTool_.onEnterTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('begintiming',this.timingTool_.onBeginTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('updatetiming',this.timingTool_.onUpdateTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('endtiming',this.timingTool_.onEndTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('exittiming',this.timingTool_.onExitTiming.bind(this.timingTool_));const m=tr.ui.b.MOUSE_SELECTOR_MODE;this.mouseModeSelector_.supportedModeMask=m.SELECTION|m.PANSCAN|m.ZOOM|m.TIMING;this.mouseModeSelector_.settingsKey='timelineTrackView.mouseModeSelector';this.mouseModeSelector_.setKeyCodeForMode(m.PANSCAN,'2'.charCodeAt(0));this.mouseModeSelector_.setKeyCodeForMode(m.SELECTION,'1'.charCodeAt(0));this.mouseModeSelector_.setKeyCodeForMode(m.ZOOM,'3'.charCodeAt(0));this.mouseModeSelector_.setKeyCodeForMode(m.TIMING,'4'.charCodeAt(0));this.mouseModeSelector_.setModifierForAlternateMode(m.SELECTION,tr.ui.b.MODIFIER.SHIFT);this.mouseModeSelector_.setModifierForAlternateMode(m.PANSCAN,tr.ui.b.MODIFIER.SPACE);},get brushingStateController(){return this.brushingStateController_;},set brushingStateController(brushingStateController){if(this.brushingStateController_){this.brushingStateController_.removeEventListener('change',this.onSelectionChanged_);}
+this.brushingStateController_=brushingStateController;if(this.brushingStateController_){this.brushingStateController_.addEventListener('change',this.onSelectionChanged_);}},set timelineView(view){this.timelineView_=view;},get processViews(){return this.modelTrack_.processViews;},onSelectionChanged_(){this.showHintText_('Press \'m\' to mark current selection');this.viewport_.dispatchChangeEvent();},set selection(selection){throw new Error('DO NOT CALL THIS');},set highlight(highlight){throw new Error('DO NOT CALL THIS');},detach(){this.modelTrack_.detach();this.upperModelTrack_.detach();if(this.pollIfViewportAttachedInterval_){window.clearInterval(this.pollIfViewportAttachedInterval_);this.pollIfViewportAttachedInterval_=undefined;}
+this.viewport_.detach();},get viewport(){return this.viewport_;},get model(){return this.model_;},set model(model){if(!model){throw new Error('Model cannot be undefined');}
+const modelInstanceChanged=this.model_!==model;this.model_=model;this.modelTrack_.model=model;this.upperModelTrack_.model=model;if(modelInstanceChanged){this.pollIfViewportAttachedInterval_=window.setInterval(this.pollIfViewportAttached_.bind(this),250);}},get hasVisibleContent(){return this.modelTrack_.hasVisibleContent||this.upperModelTrack_.hasVisibleContent;},pollIfViewportAttached_(){if(!this.viewport_.isAttachedToDocumentOrInTestMode||this.viewport_.clientWidth===0){return;}
+window.addEventListener('resize',this.viewport_.dispatchChangeEvent);window.clearInterval(this.pollIfViewportAttachedInterval_);this.pollIfViewportAttachedInterval_=undefined;this.setInitialViewport_();},setInitialViewport_(){this.modelTrackContainer_.updateCanvasSizeIfNeeded_();const w=this.modelTrackContainer_.canvas.width;let min;let range;if(this.model_.bounds.isEmpty){min=0;range=1000;}else if(this.model_.bounds.range===0){min=this.model_.bounds.min;range=1000;}else{min=this.model_.bounds.min;range=this.model_.bounds.range;}
+const boost=range*0.15;this.displayTransform_.set(this.viewport_.currentDisplayTransform);this.displayTransform_.xSetWorldBounds(min-boost,min+range+boost,w);this.viewport_.setDisplayTransformImmediately(this.displayTransform_);},addAllEventsMatchingFilterToSelectionAsTask(filter,selection){const modelTrack=this.modelTrack_;const firstT=modelTrack.addAllEventsMatchingFilterToSelectionAsTask(filter,selection);const lastT=firstT.after(function(){this.upperModelTrack_.addAllEventsMatchingFilterToSelection(filter,selection);},this);return firstT;},onMouseMove_(e){if(this.isZooming_)return;this.storeLastMousePos_(e);},onTouchStart_(e){this.storeLastTouchPositions_(e);this.focusElements_();},onTouchMove_(e){e.preventDefault();this.onUpdateTransformForTouch_(e);},onTouchEnd_(e){this.storeLastTouchPositions_(e);this.focusElements_();},addHotKeys_(){this.addKeyDownHotKeys_();this.addKeyPressHotKeys_();},addKeyPressHotKey(dict){dict.eventType='keypress';dict.useCapture=false;dict.thisArg=this;const binding=new tr.ui.b.HotKey(dict);this.$.hotkey_controller.addHotKey(binding);},addKeyPressHotKeys_(){this.addKeyPressHotKey({keyCodes:['w'.charCodeAt(0),','.charCodeAt(0)],callback(e){this.zoomBy_(1.5,true);e.stopPropagation();}});this.addKeyPressHotKey({keyCodes:['s'.charCodeAt(0),'o'.charCodeAt(0)],callback(e){this.zoomBy_(1/1.5,true);e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'g'.charCodeAt(0),callback(e){this.onGridToggle_(true);e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'G'.charCodeAt(0),callback(e){this.onGridToggle_(false);e.stopPropagation();}});this.addKeyPressHotKey({keyCodes:['W'.charCodeAt(0),'<'.charCodeAt(0)],callback(e){this.zoomBy_(10,true);e.stopPropagation();}});this.addKeyPressHotKey({keyCodes:['S'.charCodeAt(0),'O'.charCodeAt(0)],callback(e){this.zoomBy_(1/10,true);e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'a'.charCodeAt(0),callback(e){this.queueSmoothPan_(this.viewWidth_*0.3,0);e.stopPropagation();}});this.addKeyPressHotKey({keyCodes:['d'.charCodeAt(0),'e'.charCodeAt(0)],callback(e){this.queueSmoothPan_(this.viewWidth_*-0.3,0);e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'A'.charCodeAt(0),callback(e){this.queueSmoothPan_(viewWidth*0.5,0);e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'D'.charCodeAt(0),callback(e){this.queueSmoothPan_(viewWidth*-0.5,0);e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'0'.charCodeAt(0),callback(e){this.setInitialViewport_();e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'f'.charCodeAt(0),callback(e){this.zoomToSelection();e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'m'.charCodeAt(0),callback(e){this.setCurrentSelectionAsInterestRange_();e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'p'.charCodeAt(0),callback(e){this.selectPowerSamplesInCurrentTimeRange_();e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'h'.charCodeAt(0),callback(e){this.toggleHighDetails_();e.stopPropagation();}});},get viewWidth_(){return this.modelTrackContainer_.canvas.clientWidth;},addKeyDownHotKeys_(){const addBinding=function(dict){dict.eventType='keydown';dict.useCapture=false;dict.thisArg=this;const binding=new tr.ui.b.HotKey(dict);this.$.hotkey_controller.addHotKey(binding);}.bind(this);addBinding({keyCode:37,callback(e){const curSel=this.brushingStateController_.selection;const sel=this.viewport.getShiftedSelection(curSel,-1);if(sel){this.brushingStateController.changeSelectionFromTimeline(sel);this.panToSelection();}else{this.queueSmoothPan_(this.viewWidth_*0.3,0);}
+e.preventDefault();e.stopPropagation();}});addBinding({keyCode:39,callback(e){const curSel=this.brushingStateController_.selection;const sel=this.viewport.getShiftedSelection(curSel,1);if(sel){this.brushingStateController.changeSelectionFromTimeline(sel);this.panToSelection();}else{this.queueSmoothPan_(-this.viewWidth_*0.3,0);}
+e.preventDefault();e.stopPropagation();}});},onDblClick_(e){if(this.mouseModeSelector_.mode!==tr.ui.b.MOUSE_SELECTOR_MODE.SELECTION){return;}
+const curSelection=this.brushingStateController_.selection;if(!curSelection.length||!tr.b.getOnlyElement(curSelection).title){return;}
+const selection=new tr.model.EventSet();const filter=new tr.c.ExactTitleFilter(tr.b.getOnlyElement(curSelection).title);this.modelTrack_.addAllEventsMatchingFilterToSelection(filter,selection);this.brushingStateController.changeSelectionFromTimeline(selection);},onMouseWheel_(e){if(!e.altKey)return;const delta=e.wheelDelta/120;const zoomScale=Math.pow(1.5,delta);this.zoomBy_(zoomScale);e.preventDefault();},onMouseDown_(e){if(this.mouseModeSelector_.mode!==tr.ui.b.MOUSE_SELECTOR_MODE.SELECTION){return;}
+if(e.target!==this.rulerTrack_)return;this.dragBeginEvent_=undefined;if(this.xNavStringMarker_){this.model.removeAnnotation(this.xNavStringMarker_);this.xNavStringMarker_=undefined;}
+const dt=this.viewport_.currentDisplayTransform;tr.ui.b.trackMouseMovesUntilMouseUp(function(e){if(e.target===this.rulerTrack_)return;const relativePosition=this.extractRelativeMousePosition_(e);const loc=tr.model.Location.fromViewCoordinates(this.viewport_,relativePosition.x,relativePosition.y);if(!loc)return;if(this.guideLineAnnotation_===undefined){this.guideLineAnnotation_=new tr.model.XMarkerAnnotation(loc.xWorld);this.model.addAnnotation(this.guideLineAnnotation_);}else{this.guideLineAnnotation_.timestamp=loc.xWorld;this.modelTrackContainer_.invalidate();}
+const state=new tr.ui.b.UIState(loc,this.viewport_.currentDisplayTransform.scaleX);this.timelineView_.setFindCtlText(state.toUserFriendlyString(this.viewport_));}.bind(this),undefined,function onKeyUpDuringDrag(){if(this.dragBeginEvent_){this.setDragBoxPosition_(this.dragBoxXStart_,this.dragBoxYStart_,this.dragBoxXEnd_,this.dragBoxYEnd_);}}.bind(this));},queueSmoothPan_(viewDeltaX,deltaY){const deltaX=this.viewport_.currentDisplayTransform.xViewVectorToWorld(viewDeltaX);const animation=new tr.ui.TimelineDisplayTransformPanAnimation(deltaX,deltaY);this.viewport_.queueDisplayTransformAnimation(animation);},zoomBy_(scale,smooth){if(scale<=0){return;}
+smooth=!!smooth;const vp=this.viewport_;const pixelRatio=window.devicePixelRatio||1;const goalFocalPointXView=this.lastMouseViewPos_.x*pixelRatio;const goalFocalPointXWorld=vp.currentDisplayTransform.xViewToWorld(goalFocalPointXView);if(smooth){const animation=new tr.ui.TimelineDisplayTransformZoomToAnimation(goalFocalPointXWorld,goalFocalPointXView,vp.currentDisplayTransform.panY,scale);vp.queueDisplayTransformAnimation(animation);}else{this.displayTransform_.set(vp.currentDisplayTransform);this.displayTransform_.scaleX*=scale;this.displayTransform_.xPanWorldPosToViewPos(goalFocalPointXWorld,goalFocalPointXView,this.viewWidth_);vp.setDisplayTransformImmediately(this.displayTransform_);}},zoomToSelection(){if(!this.brushingStateController.selectionOfInterest.length)return;const bounds=this.brushingStateController.selectionOfInterest.bounds;if(!bounds.range)return;const worldCenter=bounds.center;const viewCenter=this.modelTrackContainer_.canvas.width/2;const adjustedWorldRange=bounds.range*1.25;const newScale=this.modelTrackContainer_.canvas.width/adjustedWorldRange;const zoomInRatio=newScale/this.viewport_.currentDisplayTransform.scaleX;const animation=new tr.ui.TimelineDisplayTransformZoomToAnimation(worldCenter,viewCenter,this.viewport_.currentDisplayTransform.panY,zoomInRatio);this.viewport_.queueDisplayTransformAnimation(animation);},panToSelection(){if(!this.brushingStateController.selectionOfInterest.length)return;const bounds=this.brushingStateController.selectionOfInterest.bounds;const worldCenter=bounds.center;const viewWidth=this.viewWidth_;const dt=this.viewport_.currentDisplayTransform;if(false&&!bounds.range){if(dt.xWorldToView(bounds.center)<0||dt.xWorldToView(bounds.center)>viewWidth){this.displayTransform_.set(dt);this.displayTransform_.xPanWorldPosToViewPos(worldCenter,'center',viewWidth);const deltaX=this.displayTransform_.panX-dt.panX;const animation=new tr.ui.TimelineDisplayTransformPanAnimation(deltaX,0);this.viewport_.queueDisplayTransformAnimation(animation);}
 return;}
-this.displayTransform_.set(dt);this.displayTransform_.xPanWorldBoundsIntoView(bounds.min,bounds.max,viewWidth);var deltaX=this.displayTransform_.panX-dt.panX;var animation=new tr.ui.TimelineDisplayTransformPanAnimation(deltaX,0);this.viewport_.queueDisplayTransformAnimation(animation);},navToPosition:function(uiState,showNavLine){var location=uiState.location;var scaleX=uiState.scaleX;var track=location.getContainingTrack(this.viewport_);var worldCenter=location.xWorld;var viewCenter=this.modelTrackContainer_.canvas.width/5;var zoomInRatio=scaleX/this.viewport_.currentDisplayTransform.scaleX;track.scrollIntoViewIfNeeded();var animation=new tr.ui.TimelineDisplayTransformZoomToAnimation(worldCenter,viewCenter,this.viewport_.currentDisplayTransform.panY,zoomInRatio);this.viewport_.queueDisplayTransformAnimation(animation);if(!showNavLine)
-return;if(this.xNavStringMarker_)
-this.model.removeAnnotation(this.xNavStringMarker_);this.xNavStringMarker_=new tr.model.XMarkerAnnotation(worldCenter);this.model.addAnnotation(this.xNavStringMarker_);},setCurrentSelectionAsInterestRange_:function(){var selectionBounds=this.brushingStateController_.selection.bounds;if(selectionBounds.empty){this.viewport_.interestRange.reset();return;}
-if(this.viewport_.interestRange.min==selectionBounds.min&&this.viewport_.interestRange.max==selectionBounds.max)
-this.viewport_.interestRange.reset();else
-this.viewport_.interestRange.set(selectionBounds);},toggleHighDetails_:function(){this.viewport_.highDetails=!this.viewport_.highDetails;},hideDragBox_:function(){this.$.drag_box.style.left='-1000px';this.$.drag_box.style.top='-1000px';this.$.drag_box.style.width=0;this.$.drag_box.style.height=0;},setDragBoxPosition_:function(xStart,yStart,xEnd,yEnd){var loY=Math.min(yStart,yEnd);var hiY=Math.max(yStart,yEnd);var loX=Math.min(xStart,xEnd);var hiX=Math.max(xStart,xEnd);var modelTrackRect=this.modelTrack_.getBoundingClientRect();var dragRect={left:loX,top:loY,width:hiX-loX,height:hiY-loY};dragRect.right=dragRect.left+dragRect.width;dragRect.bottom=dragRect.top+dragRect.height;var modelTrackContainerRect=this.modelTrackContainer_.getBoundingClientRect();var clipRect={left:modelTrackContainerRect.left,top:modelTrackContainerRect.top,right:modelTrackContainerRect.right,bottom:modelTrackContainerRect.bottom};var headingWidth=window.getComputedStyle(this.querySelector('tr-ui-heading')).width;var trackTitleWidth=parseInt(headingWidth);clipRect.left=clipRect.left+trackTitleWidth;var intersectRect_=function(r1,r2){if(r2.left>r1.right||r2.right<r1.left||r2.top>r1.bottom||r2.bottom<r1.top)
-return false;var results={};results.left=Math.max(r1.left,r2.left);results.top=Math.max(r1.top,r2.top);results.right=Math.min(r1.right,r2.right);results.bottom=Math.min(r1.bottom,r2.bottom);results.width=results.right-results.left;results.height=results.bottom-results.top;return results;};var finalDragBox=intersectRect_(clipRect,dragRect);this.$.drag_box.style.left=finalDragBox.left+'px';this.$.drag_box.style.width=finalDragBox.width+'px';this.$.drag_box.style.top=finalDragBox.top+'px';this.$.drag_box.style.height=finalDragBox.height+'px';this.$.drag_box.style.whiteSpace='nowrap';var pixelRatio=window.devicePixelRatio||1;var canv=this.modelTrackContainer_.canvas;var dt=this.viewport_.currentDisplayTransform;var loWX=dt.xViewToWorld((loX-canv.offsetLeft)*pixelRatio);var hiWX=dt.xViewToWorld((hiX-canv.offsetLeft)*pixelRatio);this.$.drag_box.textContent=tr.v.Unit.byName.timeDurationInMs.format(hiWX-loWX);var e=new tr.b.Event('selectionChanging');e.loWX=loWX;e.hiWX=hiWX;this.dispatchEvent(e);},onGridToggle_:function(left){var selection=this.brushingStateController_.selection;var tb=left?selection.bounds.min:selection.bounds.max;if(this.viewport_.gridEnabled&&this.viewport_.gridSide===left&&this.viewport_.gridInitialTimebase===tb){this.viewport_.gridside=undefined;this.viewport_.gridEnabled=false;this.viewport_.gridInitialTimebase=undefined;return;}
-var numIntervalsSinceStart=Math.ceil((tb-this.model_.bounds.min)/this.viewport_.gridStep_);this.viewport_.gridEnabled=true;this.viewport_.gridSide=left;this.viewport_.gridInitialTimebase=tb;this.viewport_.gridTimebase=tb-
-(numIntervalsSinceStart+1)*this.viewport_.gridStep_;},storeLastMousePos_:function(e){this.lastMouseViewPos_=this.extractRelativeMousePosition_(e);},storeLastTouchPositions_:function(e){this.lastTouchViewPositions_=this.extractRelativeTouchPositions_(e);},extractRelativeMousePosition_:function(e){var canv=this.modelTrackContainer_.canvas;return{x:e.clientX-canv.offsetLeft,y:e.clientY-canv.offsetTop};},extractRelativeTouchPositions_:function(e){var canv=this.modelTrackContainer_.canvas;var touches=[];for(var i=0;i<e.touches.length;++i){touches.push({x:e.touches[i].clientX-canv.offsetLeft,y:e.touches[i].clientY-canv.offsetTop});}
-return touches;},storeInitialMouseDownPos_:function(e){var position=this.extractRelativeMousePosition_(e);this.mouseViewPosAtMouseDown_.x=position.x;this.mouseViewPosAtMouseDown_.y=position.y;},focusElements_:function(){this.$.hotkey_controller.childRequestsGeneralFocus(this);},storeInitialInteractionPositionsAndFocus_:function(e){this.storeInitialMouseDownPos_(e);this.storeLastMousePos_(e);this.focusElements_();},onBeginPanScan_:function(e){var vp=this.viewport_;this.viewportDisplayTransformAtMouseDown_=vp.currentDisplayTransform.clone();this.isPanningAndScanning_=true;this.storeInitialInteractionPositionsAndFocus_(e);e.preventDefault();},onUpdatePanScan_:function(e){if(!this.isPanningAndScanning_)
-return;var viewWidth=this.viewWidth_;var pixelRatio=window.devicePixelRatio||1;var xDeltaView=pixelRatio*(this.lastMouseViewPos_.x-
-this.mouseViewPosAtMouseDown_.x);var yDelta=this.lastMouseViewPos_.y-
-this.mouseViewPosAtMouseDown_.y;this.displayTransform_.set(this.viewportDisplayTransformAtMouseDown_);this.displayTransform_.incrementPanXInViewUnits(xDeltaView);this.displayTransform_.panY-=yDelta;this.viewport_.setDisplayTransformImmediately(this.displayTransform_);e.preventDefault();e.stopPropagation();this.storeLastMousePos_(e);},onEndPanScan_:function(e){this.isPanningAndScanning_=false;this.storeLastMousePos_(e);if(!e.isClick)
-e.preventDefault();},onBeginSelection_:function(e){var canv=this.modelTrackContainer_.canvas;var rect=this.modelTrack_.getBoundingClientRect();var canvRect=canv.getBoundingClientRect();var inside=rect&&e.clientX>=rect.left&&e.clientX<rect.right&&e.clientY>=rect.top&&e.clientY<rect.bottom&&e.clientX>=canvRect.left&&e.clientX<canvRect.right;if(!inside)
-return;this.dragBeginEvent_=e;this.storeInitialInteractionPositionsAndFocus_(e);e.preventDefault();},onUpdateSelection_:function(e){if(!this.dragBeginEvent_)
-return;this.dragBoxXStart_=this.dragBeginEvent_.clientX;this.dragBoxXEnd_=e.clientX;this.dragBoxYStart_=this.dragBeginEvent_.clientY;this.dragBoxYEnd_=e.clientY;this.setDragBoxPosition_(this.dragBoxXStart_,this.dragBoxYStart_,this.dragBoxXEnd_,this.dragBoxYEnd_);},onEndSelection_:function(e){e.preventDefault();if(!this.dragBeginEvent_)
-return;this.hideDragBox_();var eDown=this.dragBeginEvent_;this.dragBeginEvent_=undefined;var loY=Math.min(eDown.clientY,e.clientY);var hiY=Math.max(eDown.clientY,e.clientY);var loX=Math.min(eDown.clientX,e.clientX);var hiX=Math.max(eDown.clientX,e.clientX);var canv=this.modelTrackContainer_.canvas;var worldOffset=canv.getBoundingClientRect().left;var loVX=loX-worldOffset;var hiVX=hiX-worldOffset;var selection=new tr.model.EventSet();if(eDown.appendSelection){var previousSelection=this.brushingStateController_.selection;if(previousSelection!==undefined)
-selection.addEventSet(previousSelection);}
-this.modelTrack_.addIntersectingEventsInRangeToSelection(loVX,hiVX,loY,hiY,selection);this.brushingStateController_.changeSelectionFromTimeline(selection);},onBeginZoom_:function(e){this.isZooming_=true;this.storeInitialInteractionPositionsAndFocus_(e);e.preventDefault();},onUpdateZoom_:function(e){if(!this.isZooming_)
-return;var newPosition=this.extractRelativeMousePosition_(e);var zoomScaleValue=1+(this.lastMouseViewPos_.y-
-newPosition.y)*0.01;this.zoomBy_(zoomScaleValue,false);this.storeLastMousePos_(e);},onEndZoom_:function(e){this.isZooming_=false;if(!e.isClick)
-e.preventDefault();},computeTouchCenter_:function(positions){var xSum=0;var ySum=0;for(var i=0;i<positions.length;++i){xSum+=positions[i].x;ySum+=positions[i].y;}
-return{x:xSum/positions.length,y:ySum/positions.length};},computeTouchSpan_:function(positions){var xMin=Number.MAX_VALUE;var yMin=Number.MAX_VALUE;var xMax=Number.MIN_VALUE;var yMax=Number.MIN_VALUE;for(var i=0;i<positions.length;++i){xMin=Math.min(xMin,positions[i].x);yMin=Math.min(yMin,positions[i].y);xMax=Math.max(xMax,positions[i].x);yMax=Math.max(yMax,positions[i].y);}
+this.displayTransform_.set(dt);this.displayTransform_.xPanWorldBoundsIntoView(bounds.min,bounds.max,viewWidth);const deltaX=this.displayTransform_.panX-dt.panX;const animation=new tr.ui.TimelineDisplayTransformPanAnimation(deltaX,0);this.viewport_.queueDisplayTransformAnimation(animation);},navToPosition(uiState,showNavLine){const location=uiState.location;const scaleX=uiState.scaleX;const track=location.getContainingTrack(this.viewport_);const worldCenter=location.xWorld;const viewCenter=this.modelTrackContainer_.canvas.width/5;const zoomInRatio=scaleX/this.viewport_.currentDisplayTransform.scaleX;track.scrollIntoViewIfNeeded();const animation=new tr.ui.TimelineDisplayTransformZoomToAnimation(worldCenter,viewCenter,this.viewport_.currentDisplayTransform.panY,zoomInRatio);this.viewport_.queueDisplayTransformAnimation(animation);if(!showNavLine)return;if(this.xNavStringMarker_){this.model.removeAnnotation(this.xNavStringMarker_);}
+this.xNavStringMarker_=new tr.model.XMarkerAnnotation(worldCenter);this.model.addAnnotation(this.xNavStringMarker_);},selectPowerSamplesInCurrentTimeRange_(){const selectionBounds=this.brushingStateController_.selection.bounds;if(this.model.device.powerSeries&&!selectionBounds.empty){const events=this.model.device.powerSeries.getSamplesWithinRange(selectionBounds.min,selectionBounds.max);const selection=new tr.model.EventSet(events);this.brushingStateController_.changeSelectionFromTimeline(selection);}},setCurrentSelectionAsInterestRange_(){const selectionBounds=this.brushingStateController_.selection.bounds;if(selectionBounds.empty){this.viewport_.interestRange.reset();return;}
+if(this.viewport_.interestRange.min===selectionBounds.min&&this.viewport_.interestRange.max===selectionBounds.max){this.viewport_.interestRange.reset();}else{this.viewport_.interestRange.set(selectionBounds);}},toggleHighDetails_(){this.viewport_.highDetails=!this.viewport_.highDetails;},hideDragBox_(){this.$.drag_box.style.left='-1000px';this.$.drag_box.style.top='-1000px';this.$.drag_box.style.width=0;this.$.drag_box.style.height=0;},setDragBoxPosition_(xStart,yStart,xEnd,yEnd){const loY=Math.min(yStart,yEnd);const hiY=Math.max(yStart,yEnd);const loX=Math.min(xStart,xEnd);const hiX=Math.max(xStart,xEnd);const modelTrackRect=this.modelTrack_.getBoundingClientRect();const dragRect={left:loX,top:loY,width:hiX-loX,height:hiY-loY};dragRect.right=dragRect.left+dragRect.width;dragRect.bottom=dragRect.top+dragRect.height;const modelTrackContainerRect=this.modelTrackContainer_.getBoundingClientRect();const clipRect={left:modelTrackContainerRect.left,top:modelTrackContainerRect.top,right:modelTrackContainerRect.right,bottom:modelTrackContainerRect.bottom};const headingWidth=window.getComputedStyle(Polymer.dom(this).querySelector('tr-ui-b-heading')).width;const trackTitleWidth=parseInt(headingWidth);clipRect.left=clipRect.left+trackTitleWidth;const intersectRect_=function(r1,r2){if(r2.left>r1.right||r2.right<r1.left||r2.top>r1.bottom||r2.bottom<r1.top){return false;}
+const results={};results.left=Math.max(r1.left,r2.left);results.top=Math.max(r1.top,r2.top);results.right=Math.min(r1.right,r2.right);results.bottom=Math.min(r1.bottom,r2.bottom);results.width=results.right-results.left;results.height=results.bottom-results.top;return results;};const finalDragBox=intersectRect_(clipRect,dragRect);this.$.drag_box.style.left=finalDragBox.left+'px';this.$.drag_box.style.width=finalDragBox.width+'px';this.$.drag_box.style.top=finalDragBox.top+'px';this.$.drag_box.style.height=finalDragBox.height+'px';this.$.drag_box.style.whiteSpace='nowrap';const pixelRatio=window.devicePixelRatio||1;const canv=this.modelTrackContainer_.canvas;const dt=this.viewport_.currentDisplayTransform;const loWX=dt.xViewToWorld((loX-canv.offsetLeft)*pixelRatio);const hiWX=dt.xViewToWorld((hiX-canv.offsetLeft)*pixelRatio);Polymer.dom(this.$.drag_box).textContent=tr.b.Unit.byName.timeDurationInMs.format(hiWX-loWX);const e=new tr.b.Event('selectionChanging');e.loWX=loWX;e.hiWX=hiWX;this.dispatchEvent(e);},onGridToggle_(left){const selection=this.brushingStateController_.selection;const tb=left?selection.bounds.min:selection.bounds.max;if(this.viewport_.gridEnabled&&this.viewport_.gridSide===left&&this.viewport_.gridInitialTimebase===tb){this.viewport_.gridside=undefined;this.viewport_.gridEnabled=false;this.viewport_.gridInitialTimebase=undefined;return;}
+const numIntervalsSinceStart=Math.ceil((tb-this.model_.bounds.min)/this.viewport_.gridStep_);this.viewport_.gridEnabled=true;this.viewport_.gridSide=left;this.viewport_.gridInitialTimebase=tb;this.viewport_.gridTimebase=tb-
+(numIntervalsSinceStart+1)*this.viewport_.gridStep_;},storeLastMousePos_(e){this.lastMouseViewPos_=this.extractRelativeMousePosition_(e);},storeLastTouchPositions_(e){this.lastTouchViewPositions_=this.extractRelativeTouchPositions_(e);},extractRelativeMousePosition_(e){const canv=this.modelTrackContainer_.canvas;return{x:e.clientX-canv.offsetLeft,y:e.clientY-canv.offsetTop};},extractRelativeTouchPositions_(e){const canv=this.modelTrackContainer_.canvas;const touches=[];for(let i=0;i<e.touches.length;++i){touches.push({x:e.touches[i].clientX-canv.offsetLeft,y:e.touches[i].clientY-canv.offsetTop});}
+return touches;},storeInitialMouseDownPos_(e){const position=this.extractRelativeMousePosition_(e);this.mouseViewPosAtMouseDown_.x=position.x;this.mouseViewPosAtMouseDown_.y=position.y;},focusElements_(){this.$.hotkey_controller.childRequestsGeneralFocus(this);},storeInitialInteractionPositionsAndFocus_(e){this.storeInitialMouseDownPos_(e);this.storeLastMousePos_(e);this.focusElements_();},onBeginPanScan_(e){const vp=this.viewport_;this.viewportDisplayTransformAtMouseDown_=vp.currentDisplayTransform.clone();this.isPanningAndScanning_=true;this.storeInitialInteractionPositionsAndFocus_(e);e.preventDefault();},onUpdatePanScan_(e){if(!this.isPanningAndScanning_)return;const viewWidth=this.viewWidth_;const pixelRatio=window.devicePixelRatio||1;const xDeltaView=pixelRatio*(this.lastMouseViewPos_.x-
+this.mouseViewPosAtMouseDown_.x);const yDelta=this.lastMouseViewPos_.y-
+this.mouseViewPosAtMouseDown_.y;this.displayTransform_.set(this.viewportDisplayTransformAtMouseDown_);this.displayTransform_.incrementPanXInViewUnits(xDeltaView);this.displayTransform_.panY-=yDelta;this.viewport_.setDisplayTransformImmediately(this.displayTransform_);e.preventDefault();e.stopPropagation();this.storeLastMousePos_(e);},onEndPanScan_(e){this.isPanningAndScanning_=false;this.storeLastMousePos_(e);if(!e.isClick){e.preventDefault();}},onBeginSelection_(e){const canv=this.modelTrackContainer_.canvas;const rect=this.modelTrack_.getBoundingClientRect();const canvRect=canv.getBoundingClientRect();const inside=rect&&e.clientX>=rect.left&&e.clientX<rect.right&&e.clientY>=rect.top&&e.clientY<rect.bottom&&e.clientX>=canvRect.left&&e.clientX<canvRect.right;if(!inside)return;this.dragBeginEvent_=e;this.storeInitialInteractionPositionsAndFocus_(e);e.preventDefault();},onUpdateSelection_(e){if(!this.dragBeginEvent_)return;this.dragBoxXStart_=this.dragBeginEvent_.clientX;this.dragBoxXEnd_=e.clientX;this.dragBoxYStart_=this.dragBeginEvent_.clientY;this.dragBoxYEnd_=e.clientY;this.setDragBoxPosition_(this.dragBoxXStart_,this.dragBoxYStart_,this.dragBoxXEnd_,this.dragBoxYEnd_);},onEndSelection_(e){e.preventDefault();if(!this.dragBeginEvent_)return;this.hideDragBox_();const eDown=this.dragBeginEvent_;this.dragBeginEvent_=undefined;const loY=Math.min(eDown.clientY,e.clientY);const hiY=Math.max(eDown.clientY,e.clientY);const loX=Math.min(eDown.clientX,e.clientX);const hiX=Math.max(eDown.clientX,e.clientX);const canv=this.modelTrackContainer_.canvas;const worldOffset=canv.getBoundingClientRect().left;const loVX=loX-worldOffset;const hiVX=hiX-worldOffset;const selection=new tr.model.EventSet();if(eDown.appendSelection){const previousSelection=this.brushingStateController_.selection;if(previousSelection!==undefined){selection.addEventSet(previousSelection);}}
+this.modelTrack_.addIntersectingEventsInRangeToSelection(loVX,hiVX,loY,hiY,selection);this.brushingStateController_.changeSelectionFromTimeline(selection);},onBeginZoom_(e){this.isZooming_=true;this.storeInitialInteractionPositionsAndFocus_(e);e.preventDefault();},onUpdateZoom_(e){if(!this.isZooming_)return;const newPosition=this.extractRelativeMousePosition_(e);const zoomScaleValue=1+(this.lastMouseViewPos_.y-
+newPosition.y)*0.01;this.zoomBy_(zoomScaleValue,false);this.storeLastMousePos_(e);},onEndZoom_(e){this.isZooming_=false;if(!e.isClick){e.preventDefault();}},computeTouchCenter_(positions){let xSum=0;let ySum=0;for(let i=0;i<positions.length;++i){xSum+=positions[i].x;ySum+=positions[i].y;}
+return{x:xSum/positions.length,y:ySum/positions.length};},computeTouchSpan_(positions){let xMin=Number.MAX_VALUE;let yMin=Number.MAX_VALUE;let xMax=Number.MIN_VALUE;let yMax=Number.MIN_VALUE;for(let i=0;i<positions.length;++i){xMin=Math.min(xMin,positions[i].x);yMin=Math.min(yMin,positions[i].y);xMax=Math.max(xMax,positions[i].x);yMax=Math.max(yMax,positions[i].y);}
 return Math.sqrt((xMin-xMax)*(xMin-xMax)+
-(yMin-yMax)*(yMin-yMax));},onUpdateTransformForTouch_:function(e){var newPositions=this.extractRelativeTouchPositions_(e);var currentPositions=this.lastTouchViewPositions_;var newCenter=this.computeTouchCenter_(newPositions);var currentCenter=this.computeTouchCenter_(currentPositions);var newSpan=this.computeTouchSpan_(newPositions);var currentSpan=this.computeTouchSpan_(currentPositions);var vp=this.viewport_;var viewWidth=this.viewWidth_;var pixelRatio=window.devicePixelRatio||1;var xDelta=pixelRatio*(newCenter.x-currentCenter.x);var yDelta=newCenter.y-currentCenter.y;var zoomScaleValue=currentSpan>10?newSpan/currentSpan:1;var viewFocus=pixelRatio*newCenter.x;var worldFocus=vp.currentDisplayTransform.xViewToWorld(viewFocus);this.displayTransform_.set(vp.currentDisplayTransform);this.displayTransform_.scaleX*=zoomScaleValue;this.displayTransform_.xPanWorldPosToViewPos(worldFocus,viewFocus,viewWidth);this.displayTransform_.incrementPanXInViewUnits(xDelta);this.displayTransform_.panY-=yDelta;vp.setDisplayTransformImmediately(this.displayTransform_);this.storeLastTouchPositions_(e);},initHintText_:function(){this.$.hint_text.style.display='none';this.pendingHintTextClearTimeout_=undefined;},showHintText_:function(text){if(this.pendingHintTextClearTimeout_){window.clearTimeout(this.pendingHintTextClearTimeout_);this.pendingHintTextClearTimeout_=undefined;}
-this.pendingHintTextClearTimeout_=setTimeout(this.hideHintText_.bind(this),1000);this.$.hint_text.textContent=text;this.$.hint_text.style.display='';},hideHintText_:function(){this.pendingHintTextClearTimeout_=undefined;this.$.hint_text.style.display='none';}});'use strict';Polymer('tr-ui-find-control',{filterKeyDown:function(e){if(e.keyCode===27){var hkc=tr.b.getHotkeyControllerForElement(this);if(hkc){hkc.childRequestsBlur(this);}else{this.blur();}
-e.preventDefault();e.stopPropagation();return;}else if(e.keyCode===13){if(e.shiftKey)
-this.findPrevious();else
-this.findNext();}},filterBlur:function(e){this.updateHitCountEl();},filterFocus:function(e){this.$.filter.select();},filterMouseUp:function(e){e.preventDefault();},get controller(){return this.controller_;},set controller(c){this.controller_=c;this.updateHitCountEl();},focus:function(){this.$.filter.focus();},get hasFocus(){return this===document.activeElement;},filterTextChanged:function(){this.$.hitCount.textContent='';this.$.spinner.style.visibility='visible';this.controller.startFiltering(this.$.filter.value).then(function(){this.$.spinner.style.visibility='hidden';this.updateHitCountEl();}.bind(this));},findNext:function(){if(this.controller)
-this.controller.findNext();this.updateHitCountEl();},findPrevious:function(){if(this.controller)
-this.controller.findPrevious();this.updateHitCountEl();},updateHitCountEl:function(){if(!this.controller||!this.hasFocus){this.$.hitCount.textContent='';return;}
-var n=this.controller.filterHits.length;var i=n===0?-1:this.controller.currentHitIndex;this.$.hitCount.textContent=(i+1)+' of '+n;},setText:function(string){this.$.filter.value=string;}});'use strict';tr.exportTo('tr.e.tquery',function(){function Context(){this.event=undefined;this.ancestors=[];}
-Context.prototype={push:function(event){var ctx=new Context();ctx.ancestors=this.ancestors.slice();ctx.ancestors.push(event);return ctx;},pop:function(event){var ctx=new Context();ctx.event=this.ancestors[this.ancestors.length-1];ctx.ancestors=this.ancestors.slice(0,this.ancestors.length-1);return ctx;}};return{Context:Context};});'use strict';tr.exportTo('tr.e.tquery',function(){function Filter(){tr.c.ScriptingObject.call(this);}
-Filter.normalizeFilterExpression=function(filterExpression){if(filterExpression instanceof String||typeof(filterExpression)=='string'||filterExpression instanceof RegExp){var filter=new tr.e.tquery.FilterHasTitle(filterExpression);return filter;}
-return filterExpression;};Filter.prototype={__proto__:tr.c.ScriptingObject.prototype,evaluate:function(context){throw new Error('Not implemented');},matchValue_:function(value,expected){if(expected instanceof RegExp)
-return expected.test(value);else if(expected instanceof Function)
-return expected(value);return value===expected;}};return{Filter:Filter};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterAllOf(opt_subExpressions){tr.e.tquery.Filter.call(this);this.subExpressions=opt_subExpressions||[];}
-FilterAllOf.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpressions(exprs){this.subExpressions_=[];for(var i=0;i<exprs.length;i++){this.subExpressions_.push(tr.e.tquery.Filter.normalizeFilterExpression(exprs[i]));}},get subExpressions(){return this.subExpressions_;},evaluate:function(context){if(!this.subExpressions.length)
-return true;for(var i=0;i<this.subExpressions.length;i++){if(!this.subExpressions[i].evaluate(context))
-return false;}
-return true;}};tr.c.ScriptingObjectRegistry.register(function(){var exprs=[];for(var i=0;i<arguments.length;i++){exprs.push(arguments[i]);}
-return new FilterAllOf(exprs);},{name:'allOf'});return{FilterAllOf:FilterAllOf};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterNot(subExpression){tr.e.tquery.Filter.call(this);this.subExpression=subExpression;}
-FilterNot.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpression(expr){this.subExpression_=tr.e.tquery.Filter.normalizeFilterExpression(expr);},get subExpression(){return this.subExpression_;},evaluate:function(context){return!this.subExpression.evaluate(context);}};tr.c.ScriptingObjectRegistry.register(function(){var exprs=Array.prototype.slice.call(arguments);if(exprs.length!==1)
-throw new Error('not() must have exactly one subexpression');return new FilterNot(exprs[0]);},{name:'not'});return{FilterNot:FilterNot};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterAnyOf(opt_subExpressions){tr.e.tquery.Filter.call(this);this.subExpressions=opt_subExpressions||[];};FilterAnyOf.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpressions(exprs){this.subExpressions_=[];for(var i=0;i<exprs.length;i++){this.subExpressions_.push(tr.e.tquery.Filter.normalizeFilterExpression(exprs[i]));}},get subExpressions(){return this.subExpressions_;},evaluate:function(context){if(!this.subExpressions.length)
-return true;for(var i=0;i<this.subExpressions.length;i++){if(this.subExpressions[i].evaluate(context))
-return true;}
-return false;}};tr.c.ScriptingObjectRegistry.register(function(){var exprs=Array.prototype.slice.call(arguments);return new FilterAnyOf(exprs);},{name:'anyOf'});tr.c.ScriptingObjectRegistry.register(function(){var exprs=Array.prototype.slice.call(arguments);return new tr.e.tquery.FilterNot(new FilterAnyOf(exprs));},{name:'noneOf'});return{FilterAnyOf:FilterAnyOf};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterHasAncestor(opt_subExpression){this.subExpression=opt_subExpression;};FilterHasAncestor.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpression(expr){this.subExpression_=tr.e.tquery.Filter.normalizeFilterExpression(expr);},get subExpression(){return this.subExpression_;},evaluate:function(context){if(!this.subExpression)
-return context.ancestors.length>0;while(context.ancestors.length){context=context.pop();if(this.subExpression.evaluate(context))
-return true;}
-return false;}};tr.c.ScriptingObjectRegistry.register(function(subExpression){return new FilterHasAncestor(subExpression);},{name:'hasAncestor'});return{FilterHasAncestor:FilterHasAncestor};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterHasDuration(minValueOrExpected,opt_maxValue){if(minValueOrExpected!==undefined&&opt_maxValue!==undefined){this.minValue=minValueOrExpected;this.maxValue=opt_maxValue;}else{this.expected=minValueOrExpected;}};FilterHasDuration.prototype={__proto__:tr.e.tquery.Filter.prototype,evaluate:function(context){if(context.event.duration===undefined)
-return false;if(this.minValue!==undefined&&this.maxValue!==undefined){return context.event.duration>=this.minValue&&context.event.duration<=this.maxValue;}
-return this.matchValue_(context.event.duration,this.expected);}};tr.c.ScriptingObjectRegistry.register(function(minValueOrExpected,opt_maxValue){return new FilterHasDuration(minValueOrExpected,opt_maxValue);},{name:'hasDuration'});return{FilterHasDuration:FilterHasDuration};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterHasTitle(expected){tr.e.tquery.Filter.call(this);this.expected=expected;}
-FilterHasTitle.prototype={__proto__:tr.e.tquery.Filter.prototype,evaluate:function(context){return this.matchValue_(context.event.title,this.expected);}};tr.c.ScriptingObjectRegistry.register(function(expected){var filter=new tr.e.tquery.FilterHasTitle(expected);return filter;},{name:'hasTitle'});return{FilterHasTitle:FilterHasTitle};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterIsTopLevel(opt_subExpression){this.subExpression=opt_subExpression;}
-FilterIsTopLevel.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpression(expr){this.subExpression_=tr.e.tquery.Filter.normalizeFilterExpression(expr);},get subExpression(){return this.subExpression_;},evaluate:function(context){if(context.ancestors.length>0)
-return false;if(!this.subExpression)
-return true;return this.subExpression.evaluate(context);}};tr.c.ScriptingObjectRegistry.register(function(subExpression){return new FilterIsTopLevel(subExpression);},{name:'isTopLevel'});return{FilterIsTopLevel:FilterIsTopLevel};});'use strict';tr.exportTo('tr.e.tquery',function(){function addEventTreeToSelection(selection,event){selection.push(event);if(!event.subSlices)
-return;event.subSlices.forEach(addEventTreeToSelection.bind(undefined,selection));}
-function TQuery(model){tr.c.ScriptingObject.call(this);this.model_=model;this.parent_=undefined;this.filterExpression_=undefined;this.selection_=undefined;};TQuery.prototype={__proto__:tr.c.ScriptingObject.prototype,onModelChanged:function(model){this.model_=model;this.selection_=undefined;},get brushingStateController(){return this.brushingStateController_;},filter:function(filterExpression){var result=new TQuery(this.model_);result.parent_=this;result.filterExpression_=tr.e.tquery.Filter.normalizeFilterExpression(filterExpression);return result;},createFilterTaskGraph_:function(){var nodes=[];var node=this;while(node!==undefined){nodes.push(node);node=node.parent_;}
-var rootTask=new tr.b.Task();var lastTask=rootTask;for(var i=nodes.length-1;i>=0;i--){var node=nodes[i];if(node.selection_!==undefined)
-continue;node.selection_=new tr.model.EventSet();if(node.parent_===undefined){lastTask=lastTask.after(this.selectEverythingAsTask_(node.selection_));}else{var prevNode=nodes[i+1];lastTask=this.createFilterTaskForNode_(lastTask,node,prevNode);}}
-return{rootTask:rootTask,lastTask:lastTask,lastNode:node};},createFilterTaskForNode_:function(lastTask,node,prevNode){return lastTask.after(function(){node.evaluateFilterExpression_(prevNode.selection_,node.selection_);},this);},evaluateFilterExpression_:function(inputSelection,outputSelection){var seenEvents={};inputSelection.forEach(function(event){var context=new tr.e.tquery.Context();context.event=event;this.evaluateFilterExpressionForEvent_(context,inputSelection,outputSelection,seenEvents);}.bind(this));},evaluateFilterExpressionForEvent_:function(context,inputSelection,outputSelection,seenEvents){var event=context.event;if(inputSelection.contains(event)&&!seenEvents[event.guid]){seenEvents[event.guid]=true;if(!this.filterExpression_||this.filterExpression_.evaluate(context))
-outputSelection.push(event);}
-if(!event.subSlices)
-return;context=context.push(event);for(var i=0;i<event.subSlices.length;i++){context.event=event.subSlices[i];this.evaluateFilterExpressionForEvent_(context,inputSelection,outputSelection,seenEvents);}},selectEverythingAsTask_:function(selection){var filterTask=new tr.b.Task();this.model_.iterateAllEventContainers(function(container){filterTask.subTask(function(){container.iterateAllEventsInThisContainer(function(){return true;},addEventTreeToSelection.bind(undefined,selection));},this);},this);return filterTask;},ready:function(){return new Promise(function(resolve,reject){var graph=this.createFilterTaskGraph_();graph.lastTask=graph.lastTask.after(function(){resolve(this.selection_);},this);tr.b.Task.RunWhenIdle(graph.rootTask);}.bind(this));},get selection(){if(this.selection_===undefined){var graph=this.createFilterTaskGraph_();tr.b.Task.RunSynchronously(graph.rootTask);}
-return this.selection_;}};tr.c.ScriptingObjectRegistry.register(new TQuery(),{name:'$t'});return{TQuery:TQuery};});'use strict';Polymer('tr-ui-scripting-control',{_isEnterKey:function(event){return event.keyCode!==229&&event.keyIdentifier==='Enter';},_setFocused:function(focused){var promptEl=this.$.prompt;if(focused){promptEl.focus();this.$.root.classList.add('focused');if(promptEl.innerText.length>0){var sel=window.getSelection();sel.collapse(promptEl.firstChild,promptEl.innerText.length);}}else{promptEl.blur();this.$.root.classList.remove('focused');var parent=promptEl.parentElement;var nextEl=promptEl.nextSibling;promptEl.remove();parent.insertBefore(promptEl,nextEl);}},onConsoleFocus:function(e){e.stopPropagation();this._setFocused(true);},onConsoleBlur:function(e){e.stopPropagation();this._setFocused(false);},promptKeyDown:function(e){e.stopPropagation();if(!this._isEnterKey(e))
-return;e.preventDefault();var promptEl=this.$.prompt;var command=promptEl.innerText;if(command.length===0)
-return;promptEl.innerText='';this.addLine_(String.fromCharCode(187)+' '+command);try{var result=this.controller_.executeCommand(command);}catch(e){result=e.stack||e.stackTrace;}
+(yMin-yMax)*(yMin-yMax));},onUpdateTransformForTouch_(e){const newPositions=this.extractRelativeTouchPositions_(e);const currentPositions=this.lastTouchViewPositions_;const newCenter=this.computeTouchCenter_(newPositions);const currentCenter=this.computeTouchCenter_(currentPositions);const newSpan=this.computeTouchSpan_(newPositions);const currentSpan=this.computeTouchSpan_(currentPositions);const vp=this.viewport_;const viewWidth=this.viewWidth_;const pixelRatio=window.devicePixelRatio||1;const xDelta=pixelRatio*(newCenter.x-currentCenter.x);const yDelta=newCenter.y-currentCenter.y;const zoomScaleValue=currentSpan>10?newSpan/currentSpan:1;const viewFocus=pixelRatio*newCenter.x;const worldFocus=vp.currentDisplayTransform.xViewToWorld(viewFocus);this.displayTransform_.set(vp.currentDisplayTransform);this.displayTransform_.scaleX*=zoomScaleValue;this.displayTransform_.xPanWorldPosToViewPos(worldFocus,viewFocus,viewWidth);this.displayTransform_.incrementPanXInViewUnits(xDelta);this.displayTransform_.panY-=yDelta;vp.setDisplayTransformImmediately(this.displayTransform_);this.storeLastTouchPositions_(e);},initHintText_(){this.$.hint_text.style.display='none';this.pendingHintTextClearTimeout_=undefined;},showHintText_(text){if(this.pendingHintTextClearTimeout_){window.clearTimeout(this.pendingHintTextClearTimeout_);this.pendingHintTextClearTimeout_=undefined;}
+this.pendingHintTextClearTimeout_=setTimeout(this.hideHintText_.bind(this),1000);Polymer.dom(this.$.hint_text).textContent=text;this.$.hint_text.style.display='';},hideHintText_(){this.pendingHintTextClearTimeout_=undefined;this.$.hint_text.style.display='none';}});'use strict';Polymer({is:'tr-ui-find-control',filterKeyDown(e){if(e.keyCode===27){const hkc=tr.b.getHotkeyControllerForElement(this);if(hkc){hkc.childRequestsBlur(this);}else{this.blur();}
+e.preventDefault();e.stopPropagation();return;}else if(e.keyCode===13){if(e.shiftKey){this.findPrevious();}else{this.findNext();}}},filterBlur(e){this.updateHitCountEl();},filterFocus(e){this.$.filter.select();},filterMouseUp(e){e.preventDefault();},get controller(){return this.controller_;},set controller(c){this.controller_=c;this.updateHitCountEl();},focus(){this.$.filter.focus();},get hasFocus(){return this===document.activeElement;},filterTextChanged(){Polymer.dom(this.$.hitCount).textContent='';this.$.spinner.style.visibility='visible';this.$.spinner.style.animation='spin 1s linear infinite';this.controller.startFiltering(this.$.filter.value).then(function(){this.$.spinner.style.visibility='hidden';this.$.spinner.style.animation='';this.updateHitCountEl();}.bind(this));},findNext(){if(this.controller){this.controller.findNext();}
+this.updateHitCountEl();},findPrevious(){if(this.controller){this.controller.findPrevious();}
+this.updateHitCountEl();},updateHitCountEl(){if(!this.controller||this.$.filter.value.length===0){Polymer.dom(this.$.hitCount).textContent='';return;}
+const n=this.controller.filterHits.length;const i=n===0?-1:this.controller.currentHitIndex;Polymer.dom(this.$.hitCount).textContent=(i+1)+' of '+n;},setText(string){this.$.filter.value=string;}});'use strict';tr.exportTo('tr.e.tquery',function(){function Context(){this.event=undefined;this.ancestors=[];}
+Context.prototype={push(event){const ctx=new Context();ctx.ancestors=this.ancestors.slice();ctx.ancestors.push(event);return ctx;},pop(event){const ctx=new Context();ctx.event=this.ancestors[this.ancestors.length-1];ctx.ancestors=this.ancestors.slice(0,this.ancestors.length-1);return ctx;}};return{Context,};});'use strict';tr.exportTo('tr.e.tquery',function(){function Filter(){tr.c.ScriptingObject.call(this);}
+Filter.normalizeFilterExpression=function(filterExpression){if(filterExpression instanceof String||typeof(filterExpression)==='string'||filterExpression instanceof RegExp){const filter=new tr.e.tquery.FilterHasTitle(filterExpression);return filter;}
+return filterExpression;};Filter.prototype={__proto__:tr.c.ScriptingObject.prototype,evaluate(context){throw new Error('Not implemented');},matchValue_(value,expected){if(expected instanceof RegExp){return expected.test(value);}else if(expected instanceof Function){return expected(value);}
+return value===expected;}};return{Filter,};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterAllOf(opt_subExpressions){tr.e.tquery.Filter.call(this);this.subExpressions=opt_subExpressions||[];}
+FilterAllOf.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpressions(exprs){this.subExpressions_=[];for(let i=0;i<exprs.length;i++){this.subExpressions_.push(tr.e.tquery.Filter.normalizeFilterExpression(exprs[i]));}},get subExpressions(){return this.subExpressions_;},evaluate(context){if(!this.subExpressions.length)return true;for(let i=0;i<this.subExpressions.length;i++){if(!this.subExpressions[i].evaluate(context)){return false;}}
+return true;}};tr.c.ScriptingObjectRegistry.register(function(){const exprs=[];for(let i=0;i<arguments.length;i++){exprs.push(arguments[i]);}
+return new FilterAllOf(exprs);},{name:'allOf'});return{FilterAllOf,};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterNot(subExpression){tr.e.tquery.Filter.call(this);this.subExpression=subExpression;}
+FilterNot.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpression(expr){this.subExpression_=tr.e.tquery.Filter.normalizeFilterExpression(expr);},get subExpression(){return this.subExpression_;},evaluate(context){return!this.subExpression.evaluate(context);}};tr.c.ScriptingObjectRegistry.register(function(){const exprs=Array.prototype.slice.call(arguments);if(exprs.length!==1){throw new Error('not() must have exactly one subexpression');}
+return new FilterNot(exprs[0]);},{name:'not'});return{FilterNot,};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterAnyOf(opt_subExpressions){tr.e.tquery.Filter.call(this);this.subExpressions=opt_subExpressions||[];}
+FilterAnyOf.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpressions(exprs){this.subExpressions_=[];for(let i=0;i<exprs.length;i++){this.subExpressions_.push(tr.e.tquery.Filter.normalizeFilterExpression(exprs[i]));}},get subExpressions(){return this.subExpressions_;},evaluate(context){if(!this.subExpressions.length)return true;for(let i=0;i<this.subExpressions.length;i++){if(this.subExpressions[i].evaluate(context))return true;}
+return false;}};tr.c.ScriptingObjectRegistry.register(function(){const exprs=Array.prototype.slice.call(arguments);return new FilterAnyOf(exprs);},{name:'anyOf'});tr.c.ScriptingObjectRegistry.register(function(){const exprs=Array.prototype.slice.call(arguments);return new tr.e.tquery.FilterNot(new FilterAnyOf(exprs));},{name:'noneOf'});return{FilterAnyOf,};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterHasAncestor(opt_subExpression){this.subExpression=opt_subExpression;}
+FilterHasAncestor.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpression(expr){this.subExpression_=tr.e.tquery.Filter.normalizeFilterExpression(expr);},get subExpression(){return this.subExpression_;},evaluate(context){if(!this.subExpression){return context.ancestors.length>0;}
+while(context.ancestors.length){context=context.pop();if(this.subExpression.evaluate(context))return true;}
+return false;}};tr.c.ScriptingObjectRegistry.register(function(subExpression){return new FilterHasAncestor(subExpression);},{name:'hasAncestor'});return{FilterHasAncestor,};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterHasDuration(minValueOrExpected,opt_maxValue){if(minValueOrExpected!==undefined&&opt_maxValue!==undefined){this.minValue=minValueOrExpected;this.maxValue=opt_maxValue;}else{this.expected=minValueOrExpected;}}
+FilterHasDuration.prototype={__proto__:tr.e.tquery.Filter.prototype,evaluate(context){if(context.event.duration===undefined)return false;if(this.minValue!==undefined&&this.maxValue!==undefined){return context.event.duration>=this.minValue&&context.event.duration<=this.maxValue;}
+return this.matchValue_(context.event.duration,this.expected);}};tr.c.ScriptingObjectRegistry.register(function(minValueOrExpected,opt_maxValue){return new FilterHasDuration(minValueOrExpected,opt_maxValue);},{name:'hasDuration'});return{FilterHasDuration,};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterHasTitle(expected){tr.e.tquery.Filter.call(this);this.expected=expected;}
+FilterHasTitle.prototype={__proto__:tr.e.tquery.Filter.prototype,evaluate(context){return this.matchValue_(context.event.title,this.expected);}};tr.c.ScriptingObjectRegistry.register(function(expected){const filter=new tr.e.tquery.FilterHasTitle(expected);return filter;},{name:'hasTitle'});return{FilterHasTitle,};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterIsTopLevel(opt_subExpression){this.subExpression=opt_subExpression;}
+FilterIsTopLevel.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpression(expr){this.subExpression_=tr.e.tquery.Filter.normalizeFilterExpression(expr);},get subExpression(){return this.subExpression_;},evaluate(context){if(context.ancestors.length>0)return false;if(!this.subExpression)return true;return this.subExpression.evaluate(context);}};tr.c.ScriptingObjectRegistry.register(function(subExpression){return new FilterIsTopLevel(subExpression);},{name:'isTopLevel'});return{FilterIsTopLevel,};});'use strict';tr.exportTo('tr.e.tquery',function(){function addEventTreeToSelection(selection,event){selection.push(event);if(!event.subSlices)return;event.subSlices.forEach(addEventTreeToSelection.bind(undefined,selection));}
+function TQuery(model){tr.c.ScriptingObject.call(this);this.model_=model;this.parent_=undefined;this.filterExpression_=undefined;this.selection_=undefined;}
+TQuery.prototype={__proto__:tr.c.ScriptingObject.prototype,onModelChanged(model){this.model_=model;this.selection_=undefined;},get brushingStateController(){return this.brushingStateController_;},filter(filterExpression){const result=new TQuery(this.model_);result.parent_=this;result.filterExpression_=tr.e.tquery.Filter.normalizeFilterExpression(filterExpression);return result;},createFilterTaskGraph_(){const nodes=[this];while(nodes[nodes.length-1].parent_){nodes.push(nodes[nodes.length-1].parent_);}
+const rootTask=new tr.b.Task();let lastTask=rootTask;let node;for(let i=nodes.length-1;i>=0;i--){node=nodes[i];if(node.selection_!==undefined)continue;node.selection_=new tr.model.EventSet();if(node.parent_===undefined){lastTask=lastTask.after(this.selectEverythingAsTask_(node.selection_));}else{const prevNode=nodes[i+1];lastTask=this.createFilterTaskForNode_(lastTask,node,prevNode);}}
+return{rootTask,lastTask,lastNode:node};},createFilterTaskForNode_(lastTask,node,prevNode){return lastTask.after(function(){node.evaluateFilterExpression_(prevNode.selection_,node.selection_);},this);},evaluateFilterExpression_(inputSelection,outputSelection){const seenEvents={};inputSelection.forEach(function(event){const context=new tr.e.tquery.Context();context.event=event;this.evaluateFilterExpressionForEvent_(context,inputSelection,outputSelection,seenEvents);}.bind(this));},evaluateFilterExpressionForEvent_(context,inputSelection,outputSelection,seenEvents){const event=context.event;if(inputSelection.contains(event)&&!seenEvents[event.guid]){seenEvents[event.guid]=true;if(!this.filterExpression_||this.filterExpression_.evaluate(context)){outputSelection.push(event);}}
+if(!event.subSlices)return;context=context.push(event);for(let i=0;i<event.subSlices.length;i++){context.event=event.subSlices[i];this.evaluateFilterExpressionForEvent_(context,inputSelection,outputSelection,seenEvents);}},selectEverythingAsTask_(selection){const filterTask=new tr.b.Task();for(const container of this.model_.getDescendantEventContainers()){filterTask.subTask(()=>{for(const event of container.childEvents()){addEventTreeToSelection(selection,event);}},this);}
+return filterTask;},ready(){return new Promise(function(resolve,reject){const graph=this.createFilterTaskGraph_();graph.lastTask=graph.lastTask.after(function(){resolve(this.selection_);},this);tr.b.Task.RunWhenIdle(graph.rootTask);}.bind(this));},get selection(){if(this.selection_===undefined){const graph=this.createFilterTaskGraph_();tr.b.Task.RunSynchronously(graph.rootTask);}
+return this.selection_;}};tr.c.ScriptingObjectRegistry.register(new TQuery(),{name:'$t'});return{TQuery,};});'use strict';Polymer({is:'tr-ui-scripting-control',isEnterKey_(event){return event.keyCode!==229&&(event.key==='Enter'||event.keyIdentifier==='Enter');},setFocus_(focused){const promptEl=this.$.prompt;if(focused){promptEl.focus();Polymer.dom(this.$.root).classList.add('focused');if(promptEl.value.length>0){const sel=window.getSelection();sel.collapse(Polymer.dom(promptEl).firstChild,promptEl.value.length);}}else{promptEl.blur();Polymer.dom(this.$.root).classList.remove('focused');const parent=promptEl.parentElement;const nextEl=Polymer.dom(promptEl).nextSibling;promptEl.remove();Polymer.dom(parent).insertBefore(promptEl,nextEl);}},onConsoleFocus(e){e.stopPropagation();this.setFocus_(true);},onConsoleBlur(e){e.stopPropagation();this.setFocus_(false);},promptKeyDown(e){e.stopPropagation();if(!this.isEnterKey_(e))return;e.preventDefault();const promptEl=this.$.prompt;const command=promptEl.value;if(command.length===0)return;promptEl.value='';this.addLine_(String.fromCharCode(187)+' '+command);let result;try{result=this.controller_.executeCommand(command);}catch(e){result=e.stack||e.stackTrace;}
 if(result instanceof tr.e.tquery.TQuery){result.ready().then(function(selection){this.addLine_(selection.length+' matches');this.controller_.brushingStateController.showScriptControlSelection(selection);}.bind(this));}else{this.addLine_(result);}
-promptEl.scrollIntoView();},addLine_:function(line){var historyEl=this.$.history;if(historyEl.innerText.length!==0)
-historyEl.innerText+='\n';historyEl.innerText+=line;},promptKeyPress:function(e){e.stopPropagation();},toggleVisibility:function(){var root=this.$.root;if(!this.visible){root.classList.remove('hidden');this._setFocused(true);}else{root.classList.add('hidden');this._setFocused(false);}},get hasFocus(){return this===document.activeElement;},get visible(){var root=this.$.root;return!root.classList.contains('hidden');},get controller(){return this.controller_;},set controller(c){this.controller_=c;}});'use strict';Polymer('tr-ui-side-panel-container',{ready:function(){this.activePanelContainer_=this.$.active_panel_container;this.tabStrip_=this.$.tab_strip;this.rangeOfInterest_=new tr.b.Range();this.brushingStateController_=undefined;this.onSelectionChanged_=this.onSelectionChanged_.bind(this);this.onModelChanged_=this.onModelChanged_.bind(this);},get brushingStateController(){return this.brushingStateController_;},set brushingStateController(brushingStateController){if(this.brushingStateController){this.brushingStateController_.removeEventListener('change',this.onSelectionChanged_);this.brushingStateController_.removeEventListener('model-changed',this.onModelChanged_);}
-this.brushingStateController_=brushingStateController;if(this.brushingStateController){this.brushingStateController_.addEventListener('change',this.onSelectionChanged_);this.brushingStateController_.addEventListener('model-changed',this.onModelChanged_);}},get selection(){return this.brushingStateController_.selection;},onSelectionChanged_:function(){if(this.activePanel)
-this.activePanel.selection=this.selection;},get model(){return this.brushingStateController_.model;},onModelChanged_:function(){this.activePanelType_=undefined;this.updateContents_();},get expanded(){this.hasAttribute('expanded');},get activePanel(){if(this.activePanelContainer_.children.length===0)
-return undefined;return this.activePanelContainer_.children[0];},get activePanelType(){return this.activePanelType_;},set activePanelType(panelType){if(this.model===undefined)
-throw new Error('Cannot activate panel without a model');var panel=undefined;if(panelType)
-panel=document.createElement(panelType);if(panel!==undefined&&!panel.supportsModel(this.model))
-throw new Error('Cannot activate panel: does not support this model');if(this.activePanelType){this.getLabelElementForPanelType_(this.activePanelType).removeAttribute('selected');}
-this.activePanelContainer_.textContent='';if(panelType===undefined){this.removeAttribute('expanded');this.activePanelType_=undefined;return;}
-this.getLabelElementForPanelType_(panelType).setAttribute('selected',true);this.setAttribute('expanded',true);this.activePanelContainer_.appendChild(panel);panel.rangeOfInterest=this.rangeOfInterest_;panel.selection=this.selection_;panel.model=this.model;this.activePanelType_=panelType;},getPanelTypeForConstructor_:function(constructor){for(var i=0;i<this.tabStrip_.children.length;i++){if(this.tabStrip_.children[i].panelType.constructor==constructor)
-return this.tabStrip_.children[i].panelType;}},getLabelElementForPanelType_:function(panelType){for(var i=0;i<this.tabStrip_.children.length;i++){if(this.tabStrip_.children[i].panelType==panelType)
-return this.tabStrip_.children[i];}
-return undefined;},updateContents_:function(){var previouslyActivePanelType=this.activePanelType;this.tabStrip_.textContent='';var supportedPanelTypes=[];var panelTypes=tr.ui.b.getPolymerElementsThatSubclass('tr-ui-side-panel');panelTypes.forEach(function(panelType){var labelEl=document.createElement('tab-strip-label');var panel=document.createElement(panelType);labelEl.textContent=panel.textLabel;labelEl.panelType=panelType;var supported=panel.supportsModel(this.model);if(this.model&&supported.supported){supportedPanelTypes.push(panelType);labelEl.setAttribute('enabled',true);labelEl.addEventListener('click',function(){this.activePanelType=this.activePanelType===panelType?undefined:panelType;}.bind(this));}else{labelEl.title='Not supported for the current trace: '+
-supported.reason;labelEl.style.display='none';}
-this.tabStrip_.appendChild(labelEl);},this);if(previouslyActivePanelType&&supportedPanelTypes.indexOf(previouslyActivePanelType)!=-1){this.activePanelType=previouslyActivePanelType;this.setAttribute('expanded',true);}else{this.activePanelContainer_.textContent='';this.removeAttribute('expanded');}},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(range){if(range==undefined)
-throw new Error('Must not be undefined');this.rangeOfInterest_=range;if(this.activePanel)
-this.activePanel.rangeOfInterest=range;}});'use strict';Polymer('tr-ui-timeline-view-help-overlay',{ready:function(){var mod=tr.isMac?'cmd ':'ctrl';var spans=this.shadowRoot.querySelectorAll('span.mod');for(var i=0;i<spans.length;i++){spans[i].textContent=mod;}}});'use strict';tr.exportTo('tr.v',function(){function GenericTable(items){if(items!==undefined)
-this.items=items;else
-this.items=[];};GenericTable.prototype={};return{GenericTable:GenericTable};});'use strict';tr.exportTo('tr.v.ui',function(){var ArrayOfNumbersSummaryModes={AVERAGE_MODE:'average-mode',TOTAL_MODE:'total-mode'};return{ArrayOfNumbersSummaryModes:ArrayOfNumbersSummaryModes};});'use strict';Polymer('tr-v-ui-array-of-numbers-span',{created:function(){this.numbers_=undefined;this.summaryMode_=tr.v.ui.ArrayOfNumbersSummaryModes.AVERAGE_MODE;},get summaryMode(){return this.summaryMode_;},set summaryMode(summaryMode){this.summaryMode_=summaryMode;this.updateContents_();},get numbers(){return this.numbers_;},set numbers(numbers){if(numbers===undefined){this.numbers_=undefined;this.updateContents_();return;}
-if(!(numbers instanceof Array))
-throw new Error('Must provide an array');this.numbers_=numbers;this.updateContents_();},updateContents_:function(){if(this.numbers_===undefined){this.shadowRoot.textContent='-';return;}
-var ArrayOfNumbersSummaryModes=tr.v.ui.ArrayOfNumbersSummaryModes;var value;if(this.summaryMode_===ArrayOfNumbersSummaryModes.AVERAGE_MODE)
-value=tr.b.Statistics.mean(this.numbers_);else
-value=tr.b.Statistics.sum(this.numbers_);var valueRounded=Math.round(value*1000.0)/1000.0;this.shadowRoot.textContent=valueRounded;}});'use strict';tr.exportTo('tr.v.ui',function(){var TEXT_COLUMN_MODE=1;var NUMERIC_COLUMN_MODE=2;var ELEMENT_COLUMN_MODE=3;function isNumeric(value){if((typeof value)==='number')
-return true;else if(value instanceof Number)
-return true;return false;}
-function GenericTableViewTotalsItem(opt_values){if(opt_values!==undefined)
-this.values=opt_values;else
-this.values=[];}
-function GenericTableViewColumnDescriptor(fieldName,firstFieldValue){this.title=fieldName;this.fieldName=fieldName;this.updateModeGivenValue(firstFieldValue);}
-GenericTableViewColumnDescriptor.prototype={get columnMode(){return this.columnMode_;},get isInNumericMode(){return this.columnMode_===NUMERIC_COLUMN_MODE;},cmp:function(a,b){if(this.columnMode_===ELEMENT_COLUMN_MODE)
-return 0;return tr.b.comparePossiblyUndefinedValues(a,b,function(a,b){var vA=a[this.fieldName];var vB=b[this.fieldName];return tr.b.comparePossiblyUndefinedValues(vA,vB,function(vA,vB){if(vA.localeCompare)
-return vA.localeCompare(vB);return vA-vB;},this);},this);},updateModeGivenValue:function(fieldValue){if(this.columnMode_===undefined){if(fieldValue===undefined||fieldValue===null)
-return;if(isNumeric(fieldValue)){this.columnMode_=NUMERIC_COLUMN_MODE;return;}
-if(fieldValue instanceof HTMLElement){this.columnMode_=ELEMENT_COLUMN_MODE;return;}
-this.columnMode_=TEXT_COLUMN_MODE;return;}
-if(fieldValue===undefined||fieldValue===null)
-return;if(isNumeric(fieldValue))
-return;if(fieldValue instanceof HTMLElement){this.columnMode_=ELEMENT_COLUMN_MODE;return;}
-if(this.columnMode_===NUMERIC_COLUMN_MODE)
-this.columnMode_=TEXT_COLUMN_MODE;},value:function(item){var fieldValue=item[this.fieldName];if(fieldValue instanceof GenericTableViewTotalsItem){var span=document.createElement('tr-v-ui-array-of-numbers-span');span.summaryMode=tr.v.ui.ArrayOfNumbersSummaryModes.TOTAL_MODE;span.numbers=fieldValue.values;return span;}
-if(fieldValue===undefined)
-return'-';if(fieldValue instanceof HTMLElement)
-return fieldValue;if(fieldValue instanceof Object){var gov=document.createElement('tr-ui-a-generic-object-view');gov.object=fieldValue;return gov;}
-return fieldValue;}};Polymer('tr-v-ui-generic-table-view',{created:function(){this.items_=undefined;this.importantColumNames_=[];},get items(){return this.items_;},set items(itemsOrGenericTable){if(itemsOrGenericTable===undefined){this.items_=undefined;}else if(itemsOrGenericTable instanceof Array){this.items_=itemsOrGenericTable;}else if(itemsOrGenericTable instanceof tr.v.GenericTable){this.items_=itemsOrGenericTable.items;}
-this.updateContents_();},get importantColumNames(){return this.importantColumNames_;},set importantColumNames(importantColumNames){this.importantColumNames_=importantColumNames;this.updateContents_();},createColumns_:function(){var columnsByName={};this.items_.forEach(function(item){tr.b.iterItems(item,function(itemFieldName,itemFieldValue){var colDesc=columnsByName[itemFieldName];if(colDesc!==undefined){colDesc.updateModeGivenValue(itemFieldValue);return;}
-colDesc=new GenericTableViewColumnDescriptor(itemFieldName,itemFieldValue);columnsByName[itemFieldName]=colDesc;},this);},this);var columns=tr.b.dictionaryValues(columnsByName);if(columns.length===0)
-return undefined;var isColumnNameImportant={};var importantColumNames=this.importantColumNames||[];importantColumNames.forEach(function(icn){isColumnNameImportant[icn]=true;});columns.sort(function(a,b){var iA=isColumnNameImportant[a.title]?1:0;var iB=isColumnNameImportant[b.title]?1:0;if((iB-iA)!==0)
-return iB-iA;return a.title.localeCompare(b.title);});var colWidthPercentage;if(columns.length==1)
-colWidthPercentage='100%';else
-colWidthPercentage=(100/(columns.length-1)).toFixed(3)+'%';columns[0].width='250px';for(var i=1;i<columns.length;i++)
-columns[i].width=colWidthPercentage;return columns;},createFooterRowsIfNeeded_:function(columns){var hasColumnThatIsNumeric=columns.some(function(column){return column.isInNumericMode;});if(!hasColumnThatIsNumeric)
-return[];var totalsItems={};columns.forEach(function(column){if(!column.isInNumericMode)
-return;var totalsItem=new GenericTableViewTotalsItem();this.items_.forEach(function(item){var fieldValue=item[column.fieldName];if(fieldValue===undefined||fieldValue===null)
-return;totalsItem.values.push(fieldValue);});totalsItems[column.fieldName]=totalsItem;},this);return[totalsItems];},updateContents_:function(){var columns;if(this.items_!==undefined)
-columns=this.createColumns_();if(!columns){this.$.table.tableColumns=[];this.$.table.tableRows=[];this.$.table.footerRows=[];return;}
-this.$.table.tableColumns=columns;this.$.table.tableRows=this.items_;this.$.table.footerRows=this.createFooterRowsIfNeeded_(columns);this.$.table.rebuild();},get selectionMode(){return this.$.table.selectionMode;},set selectionMode(selectionMode){this.$.table.selectionMode=selectionMode;},get rowHighlightStyle(){return this.$.table.rowHighlightStyle;},set rowHighlightStyle(rowHighlightStyle){this.$.table.rowHighlightStyle=rowHighlightStyle;},get cellHighlightStyle(){return this.$.table.cellHighlightStyle;},set cellHighlightStyle(cellHighlightStyle){this.$.table.cellHighlightStyle=cellHighlightStyle;}});return{GenericTableViewTotalsItem:GenericTableViewTotalsItem,GenericTableViewColumnDescriptor:GenericTableViewColumnDescriptor};});'use strict';Polymer('tr-ui-timeline-view-metadata-overlay',{created:function(){this.metadata_=undefined;},get metadata(){return this.metadata_;},set metadata(metadata){this.metadata_=metadata;this.$.gtv.items=this.metadata_;}});'use strict';Polymer('tr-v-ui-preferred-display-unit',{ready:function(){this.preferredTimeDisplayMode_=undefined;},attached:function(){tr.v.Unit.didPreferredTimeDisplayUnitChange();},detached:function(){tr.v.Unit.didPreferredTimeDisplayUnitChange();},get preferredTimeDisplayMode(){return this.preferredTimeDisplayMode_;},set preferredTimeDisplayMode(v){if(this.preferredTimeDisplayMode_===v)
-return;this.preferredTimeDisplayMode_=v;tr.v.Unit.didPreferredTimeDisplayUnitChange();}});'use strict';Polymer('tr-ui-timeline-view',{ready:function(){this.tabIndex=0;this.titleEl_=this.$.title;this.leftControlsEl_=this.$.left_controls;this.rightControlsEl_=this.$.right_controls;this.collapsingControlsEl_=this.$.collapsing_controls;this.sidePanelContainer_=this.$.side_panel_container;this.brushingStateController_=new tr.c.BrushingStateController(this);this.findCtl_=this.$.view_find_control;this.findCtl_.controller=new tr.ui.FindController(this.brushingStateController_);this.scriptingCtl_=document.createElement('tr-ui-scripting-control');this.scriptingCtl_.controller=new tr.c.ScriptingController(this.brushingStateController_);this.sidePanelContainer_.brushingStateController=this.brushingStateController_;if(window.tr.metrics&&window.tr.metrics.sh&&window.tr.metrics.sh.SystemHealthMetric){this.railScoreSpan_=document.createElement('tr-metrics-ui-sh-system-health-span');this.rightControls.appendChild(this.railScoreSpan_);}else{this.railScoreSpan_=undefined;}
-this.optionsDropdown_=this.$.view_options_dropdown;this.optionsDropdown_.iconElement.textContent='View Options';this.showFlowEvents_=false;this.optionsDropdown_.appendChild(tr.ui.b.createCheckBox(this,'showFlowEvents','tr.ui.TimelineView.showFlowEvents',false,'Flow events'));this.highlightVSync_=false;this.highlightVSyncCheckbox_=tr.ui.b.createCheckBox(this,'highlightVSync','tr.ui.TimelineView.highlightVSync',false,'Highlight VSync');this.optionsDropdown_.appendChild(this.highlightVSyncCheckbox_);this.initMetadataButton_();this.initConsoleButton_();this.initHelpButton_();this.collapsingControls.appendChild(this.scriptingCtl_);this.dragEl_=this.$.drag_handle;this.analysisEl_=this.$.analysis;this.analysisEl_.brushingStateController=this.brushingStateController_;this.addEventListener('requestSelectionChange',function(e){var sc=this.brushingStateController_;sc.changeSelectionFromRequestSelectionChangeEvent(e.selection);}.bind(this));this.onViewportChanged_=this.onViewportChanged_.bind(this);this.bindKeyListeners_();this.dragEl_.target=this.analysisEl_;},domReady:function(){this.trackViewContainer_=this.querySelector('#track_view_container');},get globalMode(){return this.hotkeyController.globalMode;},set globalMode(globalMode){globalMode=!!globalMode;this.brushingStateController_.historyEnabled=globalMode;this.hotkeyController.globalMode=globalMode;},get hotkeyController(){return this.$.hkc;},updateDocumentFavicon:function(){var hue;if(!this.model)
-hue='blue';else
-hue=this.model.faviconHue;var faviconData=tr.ui.b.FaviconsByHue[hue];if(faviconData===undefined)
-faviconData=tr.ui.b.FaviconsByHue['blue'];var link=document.head.querySelector('link[rel="shortcut icon"]');if(!link){link=document.createElement('link');link.rel='shortcut icon';document.head.appendChild(link);}
-link.href=faviconData;},get showFlowEvents(){return this.showFlowEvents_;},set showFlowEvents(showFlowEvents){this.showFlowEvents_=showFlowEvents;if(!this.trackView_)
-return;this.trackView_.viewport.showFlowEvents=showFlowEvents;},get highlightVSync(){return this.highlightVSync_;},set highlightVSync(highlightVSync){this.highlightVSync_=highlightVSync;if(!this.trackView_)
-return;this.trackView_.viewport.highlightVSync=highlightVSync;},initHelpButton_:function(){var helpButtonEl=this.$.view_help_button;function onClick(e){var dlg=new tr.ui.b.Overlay();dlg.title='Chrome Tracing Help';dlg.appendChild(document.createElement('tr-ui-timeline-view-help-overlay'));dlg.visible=true;e.stopPropagation();}
-helpButtonEl.addEventListener('click',onClick.bind(this));},initConsoleButton_:function(){var toggleEl=this.$.view_console_button;function onClick(e){this.scriptingCtl_.toggleVisibility();e.stopPropagation();return false;}
-toggleEl.addEventListener('click',onClick.bind(this));},initMetadataButton_:function(){var showEl=this.$.view_metadata_button;function onClick(e){var dlg=new tr.ui.b.Overlay();dlg.title='Metadata for trace';var metadataOverlay=document.createElement('tr-ui-timeline-view-metadata-overlay');metadataOverlay.metadata=this.model.metadata;dlg.appendChild(metadataOverlay);dlg.visible=true;e.stopPropagation();return false;}
-showEl.addEventListener('click',onClick.bind(this));this.updateMetadataButtonVisibility_();},updateMetadataButtonVisibility_:function(){var showEl=this.$.view_metadata_button;showEl.style.display=(this.model&&this.model.metadata.length)?'':'none';},get leftControls(){return this.leftControlsEl_;},get rightControls(){return this.rightControlsEl_;},get collapsingControls(){return this.collapsingControlsEl_;},get viewTitle(){return this.titleEl_.textContent.substring(this.titleEl_.textContent.length-2);},set viewTitle(text){if(text===undefined){this.titleEl_.textContent='';this.titleEl_.hidden=true;return;}
-this.titleEl_.hidden=false;this.titleEl_.textContent=text;},get model(){if(this.trackView_)
-return this.trackView_.model;return undefined;},set model(model){var modelInstanceChanged=model!=this.model;var modelValid=model&&!model.bounds.isEmpty;var importWarningsEl=this.shadowRoot.querySelector('#import-warnings');importWarningsEl.textContent='';if(modelInstanceChanged){if(this.railScoreSpan_)
-this.railScoreSpan_.model=undefined;this.trackViewContainer_.textContent='';if(this.trackView_){this.trackView_.viewport.removeEventListener('change',this.onViewportChanged_);this.trackView_.brushingStateController=undefined;this.trackView_.detach();this.trackView_=undefined;}
+promptEl.scrollIntoView();},addLine_(line){const historyEl=this.$.history;if(historyEl.innerText.length!==0){historyEl.innerText+='\n';}
+historyEl.innerText+=line;},promptKeyPress(e){e.stopPropagation();},toggleVisibility(){const root=this.$.root;if(!this.visible){Polymer.dom(root).classList.remove('hidden');this.setFocus_(true);}else{Polymer.dom(root).classList.add('hidden');this.setFocus_(false);}},get hasFocus(){return this===document.activeElement;},get visible(){const root=this.$.root;return!Polymer.dom(root).classList.contains('hidden');},get controller(){return this.controller_;},set controller(c){this.controller_=c;}});'use strict';Polymer({is:'tr-ui-side-panel-container',ready(){this.activePanelContainer_=this.$.active_panel_container;this.tabStrip_=this.$.tab_strip;this.dragHandle_=this.$.side_panel_drag_handle;this.dragHandle_.horizontal=false;this.dragHandle_.target=this.activePanelContainer_;this.rangeOfInterest_=new tr.b.math.Range();this.brushingStateController_=undefined;this.onSelectionChanged_=this.onSelectionChanged_.bind(this);this.onModelChanged_=this.onModelChanged_.bind(this);},get brushingStateController(){return this.brushingStateController_;},set brushingStateController(brushingStateController){if(this.brushingStateController){this.brushingStateController_.removeEventListener('change',this.onSelectionChanged_);this.brushingStateController_.removeEventListener('model-changed',this.onModelChanged_);}
+this.brushingStateController_=brushingStateController;if(this.brushingStateController){this.brushingStateController_.addEventListener('change',this.onSelectionChanged_);this.brushingStateController_.addEventListener('model-changed',this.onModelChanged_);if(this.model){this.onModelChanged_();}}},onSelectionChanged_(){if(this.activePanel){this.activePanel.selection=this.selection;}},get model(){return this.brushingStateController_.model;},onModelChanged_(){this.activePanelType_=undefined;this.updateContents_();},get expanded(){this.hasAttribute('expanded');},get activePanel(){return this.activePanelContainer_.children[0];},get activePanelType(){return this.activePanelType_;},set activePanelType(panelType){if(this.model===undefined){throw new Error('Cannot activate panel without a model');}
+let panel=undefined;if(panelType){panel=document.createElement(panelType);}
+if(panel!==undefined&&!panel.supportsModel(this.model)){throw new Error('Cannot activate panel: does not support this model');}
+if(this.activePanelType){Polymer.dom(this.getLabelElementForPanelType_(this.activePanelType)).removeAttribute('selected');}
+if(this.activePanelType){this.getLabelElementForPanelType_(this.activePanelType).removeAttribute('selected');}
+if(this.activePanel){this.activePanelContainer_.removeChild(this.activePanel);}
+if(panelType===undefined){Polymer.dom(this).removeAttribute('expanded');this.activePanelType_=undefined;return;}
+Polymer.dom(this.getLabelElementForPanelType_(panelType)).setAttribute('selected',true);Polymer.dom(this).setAttribute('expanded',true);Polymer.dom(this.activePanelContainer_).appendChild(panel);panel.rangeOfInterest=this.rangeOfInterest_;panel.selection=this.selection_;panel.model=this.model;this.activePanelType_=panelType;},getPanelTypeForConstructor_(constructor){for(let i=0;i<this.tabStrip_.children.length;i++){if(this.tabStrip_.children[i].panelType.constructor===constructor){return this.tabStrip_.children[i].panelType;}}},getLabelElementForPanelType_(panelType){for(let i=0;i<this.tabStrip_.children.length;i++){if(this.tabStrip_.children[i].panelType===panelType){return this.tabStrip_.children[i];}}
+return undefined;},updateContents_(){const previouslyActivePanelType=this.activePanelType;Polymer.dom(this.tabStrip_).textContent='';const supportedPanelTypes=[];const panelTypeInfos=tr.ui.side_panel.SidePanelRegistry.getAllRegisteredTypeInfos();const unsupportedLabelEls=[];for(const panelTypeInfo of panelTypeInfos){const labelEl=document.createElement('tab-strip-label');const panel=panelTypeInfo.constructor();const panelType=panel.tagName;Polymer.dom(labelEl).textContent=panel.textLabel;labelEl.panelType=panelType;const supported=panel.supportsModel(this.model);if(this.model&&supported.supported){supportedPanelTypes.push(panelType);Polymer.dom(labelEl).setAttribute('enabled',true);labelEl.addEventListener('click',function(panelType){this.activePanelType=this.activePanelType===panelType?undefined:panelType;}.bind(this,panelType));Polymer.dom(this.tabStrip_).appendChild(labelEl);}else{if(this.activePanel){this.activePanelContainer_.removeChild(this.activePanel);}
+this.removeAttribute('expanded');unsupportedLabelEls.push(labelEl);}}
+for(const labelEl of unsupportedLabelEls){Polymer.dom(this.tabStrip_).appendChild(labelEl);}
+if(previouslyActivePanelType&&supportedPanelTypes.includes(previouslyActivePanelType)){this.activePanelType=previouslyActivePanelType;Polymer.dom(this).setAttribute('expanded',true);}else{if(this.activePanel){Polymer.dom(this.activePanelContainer_).removeChild(this.activePanel);}
+Polymer.dom(this).removeAttribute('expanded');}},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(range){if(range===undefined){throw new Error('Must not be undefined');}
+this.rangeOfInterest_=range;if(this.activePanel){this.activePanel.rangeOfInterest=range;}}});'use strict';Polymer({is:'tr-ui-timeline-view-help-overlay',ready(){const mod=tr.isMac?'cmd ':'ctrl';const spans=Polymer.dom(this.root).querySelectorAll('span.mod');for(let i=0;i<spans.length;i++){Polymer.dom(spans[i]).textContent=mod;}}});'use strict';Polymer({is:'tr-ui-timeline-view-metadata-overlay',created(){this.metadata_=undefined;},ready(){this.$.table.tableColumns=[{title:'name',value:d=>d.name,},{title:'value',value:d=>{const gov=document.createElement('tr-ui-a-generic-object-view');gov.object=d.value;return gov;},}];},get metadata(){return this.metadata_;},set metadata(metadata){this.metadata_=metadata;this.$.table.tableRows=this.metadata_;this.$.table.rebuild();}});'use strict';Polymer({is:'tr-v-ui-preferred-display-unit',ready(){this.preferredTimeDisplayMode_=undefined;},attached(){tr.b.Unit.didPreferredTimeDisplayUnitChange();},detached(){tr.b.Unit.didPreferredTimeDisplayUnitChange();},get preferredTimeDisplayMode(){return this.preferredTimeDisplayMode_;},set preferredTimeDisplayMode(v){if(this.preferredTimeDisplayMode_===v)return;this.preferredTimeDisplayMode_=v;tr.b.Unit.didPreferredTimeDisplayUnitChange();}});'use strict';Polymer({is:'tr-ui-timeline-view',created(){this.trackViewContainer_=undefined;this.queuedModel_=undefined;this.builtPromise_=undefined;this.doneBuilding_=undefined;},attached(){this.async(function(){this.trackViewContainer_=Polymer.dom(this).querySelector('#track_view_container');if(!this.trackViewContainer_){throw new Error('missing trackviewContainer');}
+if(this.queuedModel_)this.updateContents_();});},ready(){this.tabIndex=0;this.titleEl_=this.$.title;this.leftControlsEl_=this.$.left_controls;this.rightControlsEl_=this.$.right_controls;this.collapsingControlsEl_=this.$.collapsing_controls;this.sidePanelContainer_=this.$.side_panel_container;this.brushingStateController_=new tr.c.BrushingStateController(this);this.findCtl_=this.$.view_find_control;this.findCtl_.controller=new tr.ui.FindController(this.brushingStateController_);this.scriptingCtl_=document.createElement('tr-ui-scripting-control');this.scriptingCtl_.controller=new tr.c.ScriptingController(this.brushingStateController_);this.sidePanelContainer_.brushingStateController=this.brushingStateController_;if(window.tr.metrics&&window.tr.metrics.sh&&window.tr.metrics.sh.SystemHealthMetric){this.railScoreSpan_=document.createElement('tr-metrics-ui-sh-system-health-span');Polymer.dom(this.rightControls).appendChild(this.railScoreSpan_);}else{this.railScoreSpan_=undefined;}
+this.processFilter_=this.$.process_filter_dropdown;this.optionsDropdown_=this.$.view_options_dropdown;Polymer.dom(this.optionsDropdown_.iconElement).textContent='View Options';this.showFlowEvents_=false;Polymer.dom(this.optionsDropdown_).appendChild(tr.ui.b.createCheckBox(this,'showFlowEvents','tr.ui.TimelineView.showFlowEvents',false,'Flow events'));this.highlightVSync_=false;this.highlightVSyncCheckbox_=tr.ui.b.createCheckBox(this,'highlightVSync','tr.ui.TimelineView.highlightVSync',false,'Highlight VSync');Polymer.dom(this.optionsDropdown_).appendChild(this.highlightVSyncCheckbox_);this.initMetadataButton_();this.initConsoleButton_();this.initHelpButton_();Polymer.dom(this.collapsingControls).appendChild(this.scriptingCtl_);this.dragEl_=this.$.drag_handle;this.analysisEl_=this.$.analysis;this.analysisEl_.brushingStateController=this.brushingStateController_;this.addEventListener('requestSelectionChange',function(e){const sc=this.brushingStateController_;sc.changeSelectionFromRequestSelectionChangeEvent(e.selection);}.bind(this));this.onViewportChanged_=this.onViewportChanged_.bind(this);this.bindKeyListeners_();this.dragEl_.target=this.analysisEl_;},get globalMode(){return this.hotkeyController.globalMode;},set globalMode(globalMode){globalMode=!!globalMode;this.brushingStateController_.historyEnabled=globalMode;this.hotkeyController.globalMode=globalMode;},get hotkeyController(){return this.$.hkc;},updateDocumentFavicon(){let hue;if(!this.model){hue='blue';}else{hue=this.model.faviconHue;}
+let faviconData=tr.ui.b.FaviconsByHue[hue];if(faviconData===undefined){faviconData=tr.ui.b.FaviconsByHue.blue;}
+let link=Polymer.dom(document.head).querySelector('link[rel="shortcut icon"]');if(!link){link=document.createElement('link');link.rel='shortcut icon';Polymer.dom(document.head).appendChild(link);}
+link.href=faviconData;},get showFlowEvents(){return this.showFlowEvents_;},set showFlowEvents(showFlowEvents){this.showFlowEvents_=showFlowEvents;if(!this.trackView_)return;this.trackView_.viewport.showFlowEvents=showFlowEvents;},get highlightVSync(){return this.highlightVSync_;},set highlightVSync(highlightVSync){this.highlightVSync_=highlightVSync;if(!this.trackView_)return;this.trackView_.viewport.highlightVSync=highlightVSync;},initHelpButton_(){const helpButtonEl=this.$.view_help_button;const dlg=new tr.ui.b.Overlay();dlg.title='Chrome Tracing Help';dlg.visible=false;dlg.appendChild(document.createElement('tr-ui-timeline-view-help-overlay'));function onClick(e){dlg.visible=!dlg.visible;e.stopPropagation();}
+helpButtonEl.addEventListener('click',onClick.bind(this));},initConsoleButton_(){const toggleEl=this.$.view_console_button;function onClick(e){this.scriptingCtl_.toggleVisibility();e.stopPropagation();return false;}
+toggleEl.addEventListener('click',onClick.bind(this));},initMetadataButton_(){const showEl=this.$.view_metadata_button;function onClick(e){const dlg=new tr.ui.b.Overlay();dlg.title='Metadata for trace';const metadataOverlay=document.createElement('tr-ui-timeline-view-metadata-overlay');metadataOverlay.metadata=this.model.metadata;Polymer.dom(dlg).appendChild(metadataOverlay);dlg.visible=true;e.stopPropagation();return false;}
+showEl.addEventListener('click',onClick.bind(this));this.updateMetadataButtonVisibility_();},updateMetadataButtonVisibility_(){const showEl=this.$.view_metadata_button;showEl.style.display=(this.model&&this.model.metadata.length)?'':'none';},updateProcessList_(){const dropdown=Polymer.dom(this.processFilter_);while(dropdown.firstChild){dropdown.removeChild(dropdown.firstChild);}
+if(!this.model)return;const trackView=this.trackViewContainer_.querySelector('tr-ui-timeline-track-view');const processViews=trackView.processViews;const cboxes=[];const updateAll=(checked)=>{for(const cbox of cboxes){cbox.checked=checked;}};dropdown.appendChild(tr.ui.b.createButton('All',()=>updateAll(true)));dropdown.appendChild(tr.ui.b.createButton('None',()=>updateAll(false)));for(const view of processViews){const cbox=tr.ui.b.createCheckBox(undefined,undefined,undefined,true,view.processBase.userFriendlyName,()=>view.visible=cbox.checked);cbox.checked=view.visible;cboxes.push(cbox);view.addEventListener('visibility',()=>cbox.checked=view.visible);dropdown.appendChild(cbox);}},get leftControls(){return this.leftControlsEl_;},get rightControls(){return this.rightControlsEl_;},get collapsingControls(){return this.collapsingControlsEl_;},get viewTitle(){return Polymer.dom(this.titleEl_).textContent.substring(Polymer.dom(this.titleEl_).textContent.length-2);},set viewTitle(text){if(text===undefined){Polymer.dom(this.titleEl_).textContent='';this.titleEl_.hidden=true;return;}
+this.titleEl_.hidden=false;Polymer.dom(this.titleEl_).textContent=text;},get model(){if(this.trackView_){return this.trackView_.model;}
+return undefined;},set model(model){this.build(model);},async build(model){this.queuedModel_=model;this.builtPromise_=new Promise((resolve,reject)=>{this.doneBuilding_=resolve;});if(this.trackViewContainer_)await this.updateContents_();},get builtPromise(){return this.builtPromise_;},async updateContents_(){if(this.trackViewContainer_===undefined){throw new Error('timeline-view.updateContents_ requires trackViewContainer_');}
+const model=this.queuedModel_;this.queuedModel_=undefined;const modelInstanceChanged=model!==this.model;const modelValid=model&&!model.bounds.isEmpty;const importWarningsEl=Polymer.dom(this.root).querySelector('#import-warnings');Polymer.dom(importWarningsEl).textContent='';if(modelInstanceChanged){if(this.railScoreSpan_){this.railScoreSpan_.model=undefined;}
+Polymer.dom(this.trackViewContainer_).textContent='';if(this.trackView_){this.trackView_.viewport.removeEventListener('change',this.onViewportChanged_);this.trackView_.brushingStateController=undefined;this.trackView_.detach();this.trackView_=undefined;}
 this.brushingStateController_.modelWillChange();}
-if(modelValid&&!this.trackView_){this.trackView_=document.createElement('tr-ui-timeline-track-view');this.trackView_.timelineView=this;this.trackView.brushingStateController=this.brushingStateController_;this.trackViewContainer_.appendChild(this.trackView_);this.trackView_.viewport.addEventListener('change',this.onViewportChanged_);}
-if(modelValid){this.trackView_.model=model;this.trackView_.viewport.showFlowEvents=this.showFlowEvents;this.trackView_.viewport.highlightVSync=this.highlightVSync;if(this.railScoreSpan_)
-this.railScoreSpan_.model=model;this.$.display_unit.preferredTimeDisplayMode=model.intrinsicTimeUnit;}
-if(model){model.importWarningsThatShouldBeShownToUser.forEach(function(importWarning){importWarningsEl.addMessage('Import Warning: '+importWarning.type+': '+
-importWarning.message);},this);}
-if(modelInstanceChanged){this.updateMetadataButtonVisibility_();this.brushingStateController_.modelDidChange();this.onViewportChanged_();}},get brushingStateController(){return this.brushingStateController_;},get trackView(){return this.trackView_;},get settings(){if(!this.settings_)
-this.settings_=new tr.b.Settings();return this.settings_;},set focusElement(value){throw new Error('This is deprecated. Please set globalMode to true.');},bindKeyListeners_:function(){var hkc=this.hotkeyController;hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'`'.charCodeAt(0),useCapture:true,thisArg:this,callback:function(e){this.scriptingCtl_.toggleVisibility();if(!this.scriptingCtl_.hasFocus)
-this.focus();e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'/'.charCodeAt(0),useCapture:true,thisArg:this,callback:function(e){if(this.scriptingCtl_.hasFocus)
-return;if(this.findCtl_.hasFocus)
-this.focus();else
-this.findCtl_.focus();e.preventDefault();e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'?'.charCodeAt(0),useCapture:false,thisArg:this,callback:function(e){this.$.view_help_button.click();e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'v'.charCodeAt(0),useCapture:false,thisArg:this,callback:function(e){this.toggleHighlightVSync_();e.stopPropagation();}}));},onViewportChanged_:function(e){var spc=this.sidePanelContainer_;if(!this.trackView_){spc.rangeOfInterest.reset();return;}
-var vr=this.trackView_.viewport.interestRange.asRangeObject();if(!spc.rangeOfInterest.equals(vr))
-spc.rangeOfInterest=vr;if(this.railScoreSpan_&&this.model)
-this.railScoreSpan_.model=this.model;},toggleHighlightVSync_:function(){this.highlightVSyncCheckbox_.checked=!this.highlightVSyncCheckbox_.checked;},setFindCtlText:function(string){this.findCtl_.setText(string);}});'use strict';tr.exportTo('tr.ui.e.highlighter',function(){var Highlighter=tr.ui.tracks.Highlighter;function VSyncHighlighter(viewport){Highlighter.call(this,viewport);this.times_=[];}
-VSyncHighlighter.VSYNC_HIGHLIGHT_COLOR=new tr.b.Color(0,0,255);VSyncHighlighter.VSYNC_HIGHLIGHT_ALPHA=0.1;VSyncHighlighter.VSYNC_DENSITY_TRANSPARENT=0.20;VSyncHighlighter.VSYNC_DENSITY_OPAQUE=0.10;VSyncHighlighter.VSYNC_DENSITY_RANGE=VSyncHighlighter.VSYNC_DENSITY_TRANSPARENT-
-VSyncHighlighter.VSYNC_DENSITY_OPAQUE;VSyncHighlighter.generateStripes=function(times,minTime,maxTime){if(times.length===0)
-return[];var stripes=[];var lowIndex=tr.b.findLowIndexInSortedArray(times,function(time){return time;},minTime);var highIndex=lowIndex-1;while(times[highIndex+1]<=maxTime){highIndex++;}
-for(var i=lowIndex-(lowIndex%2);i<=highIndex;i+=2){var left=i<lowIndex?minTime:times[i];var right=i+1>highIndex?maxTime:times[i+1];stripes.push([left,right]);}
-return stripes;}
-VSyncHighlighter.prototype={__proto__:Highlighter.prototype,processModel:function(model){this.times_=model.device.vSyncTimestamps;},drawHighlight:function(ctx,dt,viewLWorld,viewRWorld,viewHeight){if(!this.viewport_.highlightVSync){return;}
-var stripes=VSyncHighlighter.generateStripes(this.times_,viewLWorld,viewRWorld);if(stripes.length==0){return;}
-var stripeRange=stripes[stripes.length-1][1]-stripes[0][0];var stripeDensity=stripes.length/(dt.scaleX*stripeRange);var clampedStripeDensity=tr.b.clamp(stripeDensity,VSyncHighlighter.VSYNC_DENSITY_OPAQUE,VSyncHighlighter.VSYNC_DENSITY_TRANSPARENT);var opacity=(VSyncHighlighter.VSYNC_DENSITY_TRANSPARENT-clampedStripeDensity)/VSyncHighlighter.VSYNC_DENSITY_RANGE;if(opacity==0){return;}
-var pixelRatio=window.devicePixelRatio||1;var height=viewHeight*pixelRatio;var c=VSyncHighlighter.VSYNC_HIGHLIGHT_COLOR;ctx.fillStyle=c.toStringWithAlphaOverride(VSyncHighlighter.VSYNC_HIGHLIGHT_ALPHA*opacity);for(var i=0;i<stripes.length;i++){var xLeftView=dt.xWorldToView(stripes[i][0]);var xRightView=dt.xWorldToView(stripes[i][1]);ctx.fillRect(xLeftView,0,xRightView-xLeftView,height);}}};tr.ui.tracks.Highlighter.register(VSyncHighlighter);return{VSyncHighlighter:VSyncHighlighter};});'use strict';tr.exportTo('tr.ui.b',function(){function Row(title,data,groupingKeyFuncs,rowStatsConstructor){this.title=title;this.data_=data;if(groupingKeyFuncs===undefined)
-groupingKeyFuncs=[];this.groupingKeyFuncs_=groupingKeyFuncs;this.rowStatsConstructor_=rowStatsConstructor;this.subRowsBuilt_=false;this.subRows_=undefined;this.rowStats_=undefined;}
-Row.prototype={getCurrentGroupingKeyFunc_:function(){if(this.groupingKeyFuncs_.length===0)
-return undefined;return this.groupingKeyFuncs_[0];},get data(){return this.data_;},get rowStats(){if(this.rowStats_===undefined){this.rowStats_=new this.rowStatsConstructor_(this);}
-return this.rowStats_;},rebuildSubRowsIfNeeded_:function(){if(this.subRowsBuilt_)
-return;this.subRowsBuilt_=true;var groupingKeyFunc=this.getCurrentGroupingKeyFunc_();if(groupingKeyFunc===undefined){this.subRows_=undefined;return;}
-var dataByKey={};var hasValues=false;this.data_.forEach(function(datum){var key=groupingKeyFunc(datum);hasValues=hasValues||(key!==undefined);if(dataByKey[key]===undefined)
-dataByKey[key]=[];dataByKey[key].push(datum);});if(!hasValues){this.subRows_=undefined;return;}
-this.subRows_=[];for(var key in dataByKey){var row=new Row(key,dataByKey[key],this.groupingKeyFuncs_.slice(1),this.rowStatsConstructor_);this.subRows_.push(row);}},get isExpanded(){return(this.subRows&&(this.subRows.length>0)&&(this.subRows.length<5));},get subRows(){this.rebuildSubRowsIfNeeded_();return this.subRows_;}};Polymer('tr-ui-b-grouping-table',{created:function(){this.dataToGroup_=undefined;this.groupBy_=undefined;this.rowStatsConstructor_=undefined;},get tableColumns(){return this.$.table.tableColumns;},set tableColumns(tableColumns){this.$.table.tableColumns=tableColumns;},get tableRows(){return this.$.table.tableRows;},get sortColumnIndex(){return this.$.table.sortColumnIndex;},set sortColumnIndex(sortColumnIndex){this.$.table.sortColumnIndex=sortColumnIndex;},get sortDescending(){return this.$.table.sortDescending;},set sortDescending(sortDescending){this.$.table.sortDescending=sortDescending;},get selectionMode(){return this.$.table.selectionMode;},set selectionMode(selectionMode){this.$.table.selectionMode=selectionMode;},get rowHighlightStyle(){return this.$.table.rowHighlightStyle;},set rowHighlightStyle(rowHighlightStyle){this.$.table.rowHighlightStyle=rowHighlightStyle;},get cellHighlightStyle(){return this.$.table.cellHighlightStyle;},set cellHighlightStyle(cellHighlightStyle){this.$.table.cellHighlightStyle=cellHighlightStyle;},get selectedColumnIndex(){return this.$.table.selectedColumnIndex;},set selectedColumnIndex(selectedColumnIndex){this.$.table.selectedColumnIndex=selectedColumnIndex;},get selectedTableRow(){return this.$.table.selectedTableRow;},set selectedTableRow(selectedTableRow){this.$.table.selectedTableRow=selectedTableRow;},get groupBy(){return this.groupBy_;},set groupBy(groupBy){this.groupBy_=groupBy;this.updateContents_();},get dataToGroup(){return this.dataToGroup_;},set dataToGroup(dataToGroup){this.dataToGroup_=dataToGroup;this.updateContents_();},get rowStatsConstructor(){return this.rowStatsConstructor_;},set rowStatsConstructor(rowStatsConstructor){this.rowStatsConstructor_=rowStatsConstructor;this.updateContents_();},rebuild:function(){this.$.table.rebuild();},updateContents_:function(){var groupBy=this.groupBy_||[];var dataToGroup=this.dataToGroup_||[];var rowStatsConstructor=this.rowStatsConstructor_||function(){};var superRow=new Row('',dataToGroup,groupBy,rowStatsConstructor);this.$.table.tableRows=superRow.subRows||[];}});return{};});'use strict';tr.exportTo('tr.ui.b',function(){var THIS_DOC=document._currentScript.ownerDocument;Polymer('tr-ui-b-grouping-table-groupby-picker',{created:function(){this.needsInit_=true;this.defaultGroupKeys_=undefined;this.possibleGroups_=[];this.settingsKey_=[];this.currentGroupKeys_=undefined;this.dragging_=false;},get defaultGroupKeys(){return this.defaultGroupKeys_;},set defaultGroupKeys(defaultGroupKeys){if(!this.needsInit_)
-throw new Error('Already initialized.');this.defaultGroupKeys_=defaultGroupKeys;this.maybeInit_();},get possibleGroups(){return this.possibleGroups_;},set possibleGroups(possibleGroups){if(!this.needsInit_)
-throw new Error('Already initialized.');this.possibleGroups_=possibleGroups;this.maybeInit_();},get settingsKey(){return this.settingsKey_;},set settingsKey(settingsKey){if(!this.needsInit_)
-throw new Error('Already initialized.');this.settingsKey_=settingsKey;this.maybeInit_();},maybeInit_:function(){if(!this.needsInit_)
-return;if(this.settingsKey_===undefined)
-return;if(this.defaultGroupKeys_===undefined)
-return;if(this.possibleGroups_===undefined)
-return;this.needsInit_=false;var addGroupEl=this.shadowRoot.querySelector('#add-group');addGroupEl.iconElement.textContent='Add another...';this.currentGroupKeys=tr.b.Settings.get(this.settingsKey_,this.defaultGroupKeys_);},get currentGroupKeys(){return this.currentGroupKeys_;},get currentGroups(){var groupsByKey={};this.possibleGroups_.forEach(function(group){groupsByKey[group.key]=group;});return this.currentGroupKeys_.map(function(groupKey){return groupsByKey[groupKey];});},set currentGroupKeys(currentGroupKeys){if(this.currentGroupKeys_===currentGroupKeys)
-return;if(!(currentGroupKeys instanceof Array))
-throw new Error('Must be array');this.currentGroupKeys_=currentGroupKeys;this.updateGroups_();tr.b.Settings.set(this.settingsKey_,this.currentGroupKeys_);var e=new tr.b.Event('current-groups-changed');this.dispatchEvent(e);},updateGroups_:function(){var groupsEl=this.shadowRoot.querySelector('groups');var addGroupEl=this.shadowRoot.querySelector('#add-group');groupsEl.textContent='';addGroupEl.textContent='';var unusedGroups={};var groupsByKey={};this.possibleGroups_.forEach(function(group){unusedGroups[group.key]=group;groupsByKey[group.key]=group;});this.currentGroupKeys_.forEach(function(key){delete unusedGroups[key];});var groupTemplateEl=THIS_DOC.querySelector('#tr-ui-b-grouping-table-groupby-picker-group-template');this.currentGroupKeys_.forEach(function(key,index){var group=groupsByKey[key];var groupEl=document.createElement('group');groupEl.groupKey=key;groupEl.appendChild(document.importNode(groupTemplateEl.content,true));groupEl.querySelector('#key').textContent=group.label;groupsEl.appendChild(groupEl);this.configureRemoveButtonForGroup_(groupEl);this.configureDragAndDropForGroup_(groupEl);},this);tr.b.iterItems(unusedGroups,function(key,group){var groupEl=document.createElement('possible-group');groupEl.textContent=group.label;groupEl.addEventListener('click',function(){var newKeys=this.currentGroupKeys.slice();newKeys.push(key);this.currentGroupKeys=newKeys;addGroupEl.close();}.bind(this));addGroupEl.appendChild(groupEl);},this);if(tr.b.dictionaryLength(unusedGroups)==0){addGroupEl.style.display='none';}else{addGroupEl.style.display='';}},configureRemoveButtonForGroup_:function(groupEl){var removeEl=groupEl.querySelector('#remove');removeEl.addEventListener('click',function(){var newKeys=this.currentGroupKeys.slice();var i=newKeys.indexOf(groupEl.groupKey);newKeys.splice(i,1);this.currentGroupKeys=newKeys;}.bind(this));groupEl.addEventListener('mouseenter',function(){removeEl.setAttribute('hovered',true);});groupEl.addEventListener('mouseleave',function(){removeEl.removeAttribute('hovered');});},configureDragAndDropForGroup_:function(groupEl){var groupsEl=groupEl.parentElement;groupEl.setAttribute('draggable',true);groupEl.addEventListener('dragstart',function(e){e.dataTransfer.setData('groupKey',groupEl.groupKey);groupEl.querySelector('#remove').removeAttribute('hovered');groupEl.classList.add('dragging');this.dragging_=true;}.bind(this));groupEl.addEventListener('dragend',function(e){console.log(e.type,groupEl.groupKey);for(var i=0;i<groupsEl.children.length;i++)
-groupsEl.children[i].classList.remove('drop-targeted');groupEl.classList.remove('dragging');this.dragging_=false;}.bind(this));groupEl.addEventListener('dragenter',function(e){if(!this.dragging_)
-return;groupEl.classList.add('drop-targeted');if(this.dragging_)
-e.preventDefault();}.bind(this));groupEl.addEventListener('dragleave',function(e){if(!this.dragging_)
-return;groupEl.classList.remove('drop-targeted');e.preventDefault();}.bind(this));groupEl.addEventListener('dragover',function(e){if(!this.dragging_)
-return;e.preventDefault();groupEl.classList.add('drop-targeted');}.bind(this));groupEl.addEventListener('drop',function(e){if(!this.dragging_)
-return;var srcKey=e.dataTransfer.getData('groupKey');var dstKey=groupEl.groupKey;if(srcKey===dstKey)
-return;var newKeys=this.currentGroupKeys_.slice();var srcIndex=this.currentGroupKeys_.indexOf(srcKey);newKeys.splice(srcIndex,1);var dstIndex=this.currentGroupKeys_.indexOf(dstKey);newKeys.splice(dstIndex,0,srcKey);this.currentGroupKeys=newKeys;e.dataTransfer.clearData();e.preventDefault();e.stopPropagation();}.bind(this));}});return{};});'use strict';(function(){Polymer('tr-ui-sp-file-size-stats-side-panel',{ready:function(){this.model_=undefined;this.selection_=new tr.model.EventSet();this.$.picker.settingsKey='tr-ui-sp-file-size-stats-side-panel-picker';this.$.picker.possibleGroups=[{key:'phase',label:'Event Type',dataFn:function(eventStat){return eventStat.phase;}},{key:'category',label:'Category',dataFn:function(eventStat){return eventStat.category;}},{key:'title',label:'Title',dataFn:function(eventStat){return eventStat.title;}}];this.$.picker.defaultGroupKeys=['phase','title'];this.$.picker.addEventListener('current-groups-changed',this.updateContents_.bind(this));},get textLabel(){return'File Size Stats';},supportsModel:function(m){if(!m){return{supported:false,reason:'No stats were collected for this file.'};}
+if(modelValid&&!this.trackView_){this.trackView_=document.createElement('tr-ui-timeline-track-view');this.trackView_.timelineView=this;this.trackView.brushingStateController=this.brushingStateController_;Polymer.dom(this.trackViewContainer_).appendChild(this.trackView_);this.trackView_.viewport.addEventListener('change',this.onViewportChanged_);}
+if(modelValid){this.trackView_.model=model;this.trackView_.viewport.showFlowEvents=this.showFlowEvents;this.trackView_.viewport.highlightVSync=this.highlightVSync;if(this.railScoreSpan_){this.railScoreSpan_.model=model;}
+this.$.display_unit.preferredTimeDisplayMode=model.intrinsicTimeUnit;}
+if(model){for(const warning of model.importWarningsThatShouldBeShownToUser){importWarningsEl.addMessage(`Import Warning: ${warning.type}: ${warning.message}`,[{buttonText:'Dismiss',onClick(event,infobar){infobar.visible=false;}}]);}}
+if(modelInstanceChanged){this.updateProcessList_();this.updateMetadataButtonVisibility_();this.brushingStateController_.modelDidChange();this.onViewportChanged_();}
+this.doneBuilding_();},get brushingStateController(){return this.brushingStateController_;},get trackView(){return this.trackView_;},get settings(){if(!this.settings_){this.settings_=new tr.b.Settings();}
+return this.settings_;},set focusElement(value){throw new Error('This is deprecated. Please set globalMode to true.');},bindKeyListeners_(){const hkc=this.hotkeyController;hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'`'.charCodeAt(0),useCapture:true,thisArg:this,callback(e){this.scriptingCtl_.toggleVisibility();if(!this.scriptingCtl_.hasFocus){this.focus();}
+e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'/'.charCodeAt(0),useCapture:true,thisArg:this,callback(e){if(this.scriptingCtl_.hasFocus)return;if(this.findCtl_.hasFocus){this.focus();}else{this.findCtl_.focus();}
+e.preventDefault();e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'?'.charCodeAt(0),useCapture:false,thisArg:this,callback(e){this.$.view_help_button.click();e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'v'.charCodeAt(0),useCapture:false,thisArg:this,callback(e){this.toggleHighlightVSync_();e.stopPropagation();}}));},onViewportChanged_(e){const spc=this.sidePanelContainer_;if(!this.trackView_){spc.rangeOfInterest.reset();return;}
+const vr=this.trackView_.viewport.interestRange.asRangeObject();if(!spc.rangeOfInterest.equals(vr)){spc.rangeOfInterest=vr;}
+if(this.railScoreSpan_&&this.model){this.railScoreSpan_.model=this.model;}},toggleHighlightVSync_(){this.highlightVSyncCheckbox_.checked=!this.highlightVSyncCheckbox_.checked;},setFindCtlText(string){this.findCtl_.setText(string);}});'use strict';tr.exportTo('tr.ui.b',function(){function Row(title,data,groupingKeyFuncs,rowStatsConstructor){this.title=title;this.data_=data;if(groupingKeyFuncs===undefined){groupingKeyFuncs=[];}
+this.groupingKeyFuncs_=groupingKeyFuncs;this.rowStatsConstructor_=rowStatsConstructor;this.subRowsBuilt_=false;this.subRows_=undefined;this.rowStats_=undefined;}
+Row.prototype={getCurrentGroupingKeyFunc_(){if(this.groupingKeyFuncs_.length===0)return undefined;return this.groupingKeyFuncs_[0];},get data(){return this.data_;},get rowStats(){if(this.rowStats_===undefined){this.rowStats_=new this.rowStatsConstructor_(this);}
+return this.rowStats_;},rebuildSubRowsIfNeeded_(){if(this.subRowsBuilt_)return;this.subRowsBuilt_=true;const groupingKeyFunc=this.getCurrentGroupingKeyFunc_();if(groupingKeyFunc===undefined){this.subRows_=undefined;return;}
+const dataByKey={};let hasValues=false;this.data_.forEach(function(datum){const key=groupingKeyFunc(datum);hasValues=hasValues||(key!==undefined);if(dataByKey[key]===undefined){dataByKey[key]=[];}
+dataByKey[key].push(datum);});if(!hasValues){this.subRows_=undefined;return;}
+this.subRows_=[];for(const key in dataByKey){const row=new Row(key,dataByKey[key],this.groupingKeyFuncs_.slice(1),this.rowStatsConstructor_);this.subRows_.push(row);}},get isExpanded(){return(this.subRows&&(this.subRows.length>0)&&(this.subRows.length<5));},get subRows(){this.rebuildSubRowsIfNeeded_();return this.subRows_;}};Polymer({is:'tr-ui-b-grouping-table',created(){this.dataToGroup_=undefined;this.groupBy_=undefined;this.rowStatsConstructor_=undefined;},get tableColumns(){return this.$.table.tableColumns;},set tableColumns(tableColumns){this.$.table.tableColumns=tableColumns;},get tableRows(){return this.$.table.tableRows;},get sortColumnIndex(){return this.$.table.sortColumnIndex;},set sortColumnIndex(sortColumnIndex){this.$.table.sortColumnIndex=sortColumnIndex;},get sortDescending(){return this.$.table.sortDescending;},set sortDescending(sortDescending){this.$.table.sortDescending=sortDescending;},get selectionMode(){return this.$.table.selectionMode;},set selectionMode(selectionMode){this.$.table.selectionMode=selectionMode;},get rowHighlightStyle(){return this.$.table.rowHighlightStyle;},set rowHighlightStyle(rowHighlightStyle){this.$.table.rowHighlightStyle=rowHighlightStyle;},get cellHighlightStyle(){return this.$.table.cellHighlightStyle;},set cellHighlightStyle(cellHighlightStyle){this.$.table.cellHighlightStyle=cellHighlightStyle;},get selectedColumnIndex(){return this.$.table.selectedColumnIndex;},set selectedColumnIndex(selectedColumnIndex){this.$.table.selectedColumnIndex=selectedColumnIndex;},get selectedTableRow(){return this.$.table.selectedTableRow;},set selectedTableRow(selectedTableRow){this.$.table.selectedTableRow=selectedTableRow;},get groupBy(){return this.groupBy_;},set groupBy(groupBy){this.groupBy_=groupBy;this.updateContents_();},get dataToGroup(){return this.dataToGroup_;},set dataToGroup(dataToGroup){this.dataToGroup_=dataToGroup;this.updateContents_();},get rowStatsConstructor(){return this.rowStatsConstructor_;},set rowStatsConstructor(rowStatsConstructor){this.rowStatsConstructor_=rowStatsConstructor;this.updateContents_();},rebuild(){this.$.table.rebuild();},updateContents_(){const groupBy=this.groupBy_||[];const dataToGroup=this.dataToGroup_||[];const rowStatsConstructor=this.rowStatsConstructor_||function(){};const superRow=new Row('',dataToGroup,groupBy,rowStatsConstructor);this.$.table.tableRows=superRow.subRows||[];}});return{};});'use strict';tr.exportTo('tr.ui.b',function(){const THIS_DOC=document.currentScript.ownerDocument;Polymer({is:'tr-ui-b-grouping-table-groupby-picker-group',created(){this.picker_=undefined;this.group_=undefined;},get picker(){return this.picker_;},set picker(picker){this.picker_=picker;},get group(){return this.group_;},set group(g){this.group_=g;this.$.label.textContent=g.label;},get enabled(){return this.$.enabled.checked;},set enabled(enabled){this.$.enabled.checked=enabled;if(!this.enabled){this.$.left.style.display='none';this.$.right.style.display='none';}},set isFirst(isFirst){this.$.left.style.display=(!this.enabled||isFirst)?'none':'inline';},set isLast(isLast){this.$.right.style.display=(!this.enabled||isLast)?'none':'inline';},moveLeft_(){this.picker.moveLeft_(this);},moveRight_(){this.picker.moveRight_(this);},onEnableChanged_(){if(!this.enabled){this.$.left.style.display='none';this.$.right.style.display='none';}
+this.picker.onEnableChanged_(this);}});Polymer({is:'tr-ui-b-grouping-table-groupby-picker',created(){this.settingsKey_=undefined;},get settingsKey(){return this.settingsKey_;},set settingsKey(settingsKey){this.settingsKey_=settingsKey;if(this.$.container.children.length){this.restoreSetting_();}},restoreSetting_(){if(this.settingsKey_===undefined)return;this.currentGroupKeys=tr.b.Settings.get(this.settingsKey_,this.currentGroupKeys);},get possibleGroups(){return[...this.$.container.children].map(groupEl=>groupEl.group);},set possibleGroups(possibleGroups){Polymer.dom(this.$.container).textContent='';for(let i=0;i<possibleGroups.length;++i){const groupEl=document.createElement('tr-ui-b-grouping-table-groupby-picker-group');groupEl.picker=this;groupEl.group=possibleGroups[i];Polymer.dom(this.$.container).appendChild(groupEl);}
+this.restoreSetting_();this.updateFirstLast_();},updateFirstLast_(){const groupEls=this.$.container.children;const enabledGroupEls=[...groupEls].filter(el=>el.enabled);for(let i=0;i<enabledGroupEls.length;++i){enabledGroupEls[i].isFirst=i===0;enabledGroupEls[i].isLast=i===enabledGroupEls.length-1;}},get currentGroupKeys(){return this.currentGroups.map(group=>group.key);},get currentGroups(){const groups=[];for(const groupEl of this.$.container.children){if(groupEl.enabled){groups.push(groupEl.group);}}
+return groups;},set currentGroupKeys(newKeys){if(!tr.b.compareArrays(this.currentGroupKeys,newKeys,(x,y)=>x.localeCompare(y))){return;}
+const possibleGroups=new Map();for(const group of this.possibleGroups){possibleGroups.set(group.key,group);}
+const groupEls=this.$.container.children;let i=0;for(i=0;i<newKeys.length;++i){const group=possibleGroups.get(newKeys[i]);if(group===undefined){newKeys.splice(i,1);--i;continue;}
+groupEls[i].group=group;groupEls[i].enabled=true;possibleGroups.delete(newKeys[i]);}
+for(const group of possibleGroups.values()){groupEls[i].group=group;groupEls[i].enabled=false;++i;}
+this.updateFirstLast_();this.onCurrentGroupsChanged_();},moveLeft_(groupEl){const reference=groupEl.previousSibling;Polymer.dom(this.$.container).removeChild(groupEl);Polymer.dom(this.$.container).insertBefore(groupEl,reference);this.updateFirstLast_();if(groupEl.enabled){this.onCurrentGroupsChanged_();}},moveRight_(groupEl){const reference=groupEl.nextSibling.nextSibling;Polymer.dom(this.$.container).removeChild(groupEl);if(reference){Polymer.dom(this.$.container).insertBefore(groupEl,reference);}else{Polymer.dom(this.$.container).appendChild(groupEl);}
+this.updateFirstLast_();if(groupEl.enabled){this.onCurrentGroupsChanged_();}},onCurrentGroupsChanged_(){this.dispatchEvent(new tr.b.Event('current-groups-changed'));tr.b.Settings.set(this.settingsKey_,this.currentGroupKeys);},onEnableChanged_(groupEl){this.updateFirstLast_();this.onCurrentGroupsChanged_();}});return{};});'use strict';(function(){Polymer({is:'tr-ui-sp-file-size-stats-side-panel',behaviors:[tr.ui.behaviors.SidePanel],ready(){this.model_=undefined;this.selection_=new tr.model.EventSet();this.$.picker.settingsKey='tr-ui-sp-file-size-stats-side-panel-picker';this.$.picker.possibleGroups=[{key:'phase',label:'Event Type',dataFn(eventStat){return eventStat.phase;}},{key:'category',label:'Category',dataFn(eventStat){return eventStat.category;}},{key:'title',label:'Title',dataFn(eventStat){return eventStat.title;}}];if(this.$.picker.currentGroupKeys.length===0){this.$.picker.currentGroupKeys=['phase','title'];}
+this.$.picker.addEventListener('current-groups-changed',this.updateContents_.bind(this));},get textLabel(){return'File Size Stats';},supportsModel(m){if(!m){return{supported:false,reason:'No stats were collected for this file.'};}
 if(m.stats.allTraceEventStats.length===0){return{supported:false,reason:'No stats were collected for this file.'};}
-return{supported:true};},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(rangeOfInterest){this.rangeOfInterest_=rangeOfInterest;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;},createColumns_:function(stats){var columns=[{title:'Title',value:function(row){var titleEl=document.createElement('span');titleEl.textContent=row.title;titleEl.style.textOverflow='ellipsis';return titleEl;},cmp:function(a,b){return a.title.localeCompare(b.title);},width:'400px'},{title:'Num Events',textAlign:'right',value:function(row){return row.rowStats.numEvents;},cmp:function(a,b){return a.rowStats.numEvents-b.rowStats.numEvents;},width:'80px'}];if(stats&&stats.hasEventSizesinBytes){columns.push({title:'Bytes',textAlign:'right',value:function(row){var value=new tr.v.ScalarNumeric(tr.v.Unit.byName.sizeInBytes,row.rowStats.totalEventSizeinBytes);var spanEl=tr.v.ui.createScalarSpan(value);return spanEl;},cmp:function(a,b){return a.rowStats.totalEventSizeinBytes-
+return{supported:true};},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(rangeOfInterest){this.rangeOfInterest_=rangeOfInterest;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;},createColumns_(stats){const columns=[{title:'Title',value(row){const titleEl=document.createElement('span');Polymer.dom(titleEl).textContent=row.title;titleEl.style.textOverflow='ellipsis';return titleEl;},cmp(a,b){return a.title.localeCompare(b.title);},width:'400px'},{title:'Num Events',align:tr.ui.b.TableFormat.ColumnAlignment.RIGHT,value(row){return row.rowStats.numEvents;},cmp(a,b){return a.rowStats.numEvents-b.rowStats.numEvents;},width:'80px'}];if(stats&&stats.hasEventSizesinBytes){columns.push({title:'Bytes',value(row){const value=new tr.b.Scalar(tr.b.Unit.byName.sizeInBytes,row.rowStats.totalEventSizeinBytes);const spanEl=tr.v.ui.createScalarSpan(value);return spanEl;},cmp(a,b){return a.rowStats.totalEventSizeinBytes-
 b.rowStats.totalEventSizeinBytes;},width:'80px'});}
-return columns;},updateContents_:function(){var table=this.$.table;var columns=this.createColumns_(this.model.stats);table.rowStatsConstructor=function ModelStatsRowStats(row){var sum=tr.b.Statistics.sum(row.data,function(x){return x.numEvents;});var totalEventSizeinBytes=tr.b.Statistics.sum(row.data,function(x){return x.totalEventSizeinBytes;});return{numEvents:sum,totalEventSizeinBytes:totalEventSizeinBytes};};table.tableColumns=columns;table.sortColumnIndex=1;table.sortDescending=true;table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;table.groupBy=this.$.picker.currentGroups.map(function(group){return group.dataFn;});if(!this.model){table.dataToGroup=[];}else{table.dataToGroup=this.model.stats.allTraceEventStats;}
-this.$.table.rebuild();}});})();'use strict';Polymer('tr-ui-e-s-alerts-side-panel',{ready:function(){this.rangeOfInterest_=new tr.b.Range();this.selection_=undefined;},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();},set selection(selection){},set rangeOfInterest(rangeOfInterest){},selectAlertsOfType:function(alertTypeString){var alertsOfType=this.model_.alerts.filter(function(alert){return alert.title===alertTypeString;});var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(alertsOfType);this.dispatchEvent(event);},alertsByType_:function(alerts){var alertsByType={};alerts.forEach(function(alert){if(!alertsByType[alert.title])
-alertsByType[alert.title]=[];alertsByType[alert.title].push(alert);});return alertsByType;},alertsTableRows_:function(alertsByType){return Object.keys(alertsByType).map(function(key){return{alertType:key,count:alertsByType[key].length};});},alertsTableColumns_:function(){return[{title:'Alert type',value:function(row){return row.alertType;},width:'180px'},{title:'Count',width:'100%',value:function(row){return row.count;}}];},createAlertsTable_:function(alerts){var alertsByType=this.alertsByType_(alerts);var table=document.createElement('tr-ui-b-table');table.tableColumns=this.alertsTableColumns_();table.tableRows=this.alertsTableRows_(alertsByType);table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;table.addEventListener('selection-changed',function(e){var row=table.selectedTableRow;if(row)
-this.selectAlertsOfType(row.alertType);}.bind(this));return table;},updateContents_:function(){this.$.result_area.textContent='';if(this.model_===undefined)
-return;var panel=this.createAlertsTable_(this.model_.alerts);this.$.result_area.appendChild(panel);},supportsModel:function(m){if(m==undefined){return{supported:false,reason:'Unknown tracing model'};}else if(m.alerts.length===0){return{supported:false,reason:'No alerts in tracing model'};}
-return{supported:true};},get textLabel(){return'Alerts';}});
+return columns;},updateContents_(){const table=this.$.table;const columns=this.createColumns_(this.model.stats);table.rowStatsConstructor=function ModelStatsRowStats(row){const sum=tr.b.math.Statistics.sum(row.data,function(x){return x.numEvents;});const totalEventSizeinBytes=tr.b.math.Statistics.sum(row.data,x=>x.totalEventSizeinBytes);return{numEvents:sum,totalEventSizeinBytes};};table.tableColumns=columns;table.sortColumnIndex=1;table.sortDescending=true;table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;table.groupBy=this.$.picker.currentGroups.map(function(group){return group.dataFn;});if(!this.model){table.dataToGroup=[];}else{table.dataToGroup=this.model.stats.allTraceEventStats;}
+this.$.table.rebuild();}});tr.ui.side_panel.SidePanelRegistry.register(function(){return document.createElement('tr-ui-sp-file-size-stats-side-panel');});})();'use strict';tr.exportTo('tr.mre',function(){function Failure(job,functionHandleString,traceCanonicalUrl,failureTypeName,description,stack){this.job=job;this.functionHandleString=functionHandleString;this.traceCanonicalUrl=traceCanonicalUrl;this.failureTypeName=failureTypeName;this.description=description;this.stack=stack;}
+Failure.prototype={asDict(){return{function_handle_string:this.functionHandleString,trace_canonical_url:this.traceCanonicalUrl,type:this.failureTypeName,description:this.description,stack:this.stack};}};Failure.fromDict=function(failureDict){return new Failure(undefined,failureDict.function_handle_string,failureDict.trace_canonical_url,failureDict.type,failureDict.description,failureDict.stack);};return{Failure,};});'use strict';tr.exportTo('tr.mre',function(){const FunctionRegistry={allFunctions_:[],allFunctionsByName_:{},get allFunctions(){return this.allFunctions_;},get allFunctionsByName(){return this.allFunctionsByName_;}};FunctionRegistry.getFunction=function(name){return this.allFunctionsByName_[name];};FunctionRegistry.register=function(func){if(func.name===''){throw new Error('Registered functions must not be anonymous');}
+if(this.allFunctionsByName[func.name]!==undefined){throw new Error('Function named '+func.name+'is already registered.');}
+this.allFunctionsByName[func.name]=func;this.allFunctions.push(func);};function ModuleToLoad(href,filename){if((href!==undefined)?(filename!==undefined):(filename===undefined)){throw new Error('ModuleToLoad must specify exactly one of href or '+'filename');}
+this.href=href;this.filename=filename;}
+ModuleToLoad.prototype={asDict(){if(this.href!==undefined){return{'href':this.href};}
+return{'filename':this.filename};},toString(){if(this.href!==undefined){return'ModuleToLoad(href="'+this.href+'")';}
+return'ModuleToLoad(filename="'+this.filename+'")';}};ModuleToLoad.fromDict=function(moduleDict){return new ModuleToLoad(moduleDict.href,moduleDict.filename);};function FunctionHandle(modulesToLoad,functionName,opt_options){if(!(modulesToLoad instanceof Array)){throw new Error('modulesToLoad in FunctionHandle must be an array');}
+if(typeof(functionName)!=='string'){throw new Error('functionName in FunctionHandle must be a string');}
+this.modulesToLoad=modulesToLoad;this.functionName=functionName;this.options_=opt_options;}
+FunctionHandle.prototype={get options(){return this.options_;},asDict(){return{'modules_to_load':this.modulesToLoad.map(function(m){return m.asDict();}),'function_name':this.functionName,'options':this.options_};},asUserFriendlyString(){const parts=this.modulesToLoad.map(mtl=>mtl.filename);parts.push(this.functionName);parts.push(JSON.stringify(this.options_));return parts.join(',');},hasHrefs(){for(const module in this.modulesToLoad){if(this.modulesToLoad[module].href!==undefined){return true;}}
+return false;},load(){if(this.hasHrefs()){const err=new Error('FunctionHandle named '+this.functionName+' specifies hrefs, which cannot be loaded.');err.name='FunctionLoadingError';throw err;}
+for(const module in this.modulesToLoad){const filename=this.modulesToLoad[module].filename;try{HTMLImportsLoader.loadHTMLFile(filename);}catch(err){err.name='FunctionLoadingError';throw err;}}
+const func=FunctionRegistry.getFunction(this.functionName);if(func===undefined){const err=new Error('No registered function named '+this.functionName);err.name='FunctionNotDefinedError';throw err;}
+return func;},toString(){const modulesToLoadStr=this.modulesToLoad.map(function(module){return module.toString();});return'FunctionHandle(modulesToLoad=['+modulesToLoadStr+'], '+'functionName="'+this.functionName+'", options="'+
+JSON.stringify(this.options_)+'")';}};FunctionHandle.loadFromFilename_=function(filename){try{const numFunctionsBefore=FunctionRegistry.allFunctions.length;HTMLImportsLoader.loadHTMLFile(filename);}catch(err){err.name='FunctionLoadingError';throw err;}
+const numFunctionsNow=FunctionRegistry.allFunctions.length;if(numFunctionsNow!==(numFunctionsBefore+1)){const err=new Error(filename+' didn\'t call FunctionRegistry.register');err.name='FunctionNotDefinedError';throw err;}
+return FunctionRegistry.allFunctions[numFunctionsNow-1];};FunctionHandle.fromDict=function(handleDict){const options=handleDict.options;let modulesToLoad;if(handleDict.modules_to_load!==undefined){modulesToLoad=handleDict.modules_to_load.map(function(module){return ModuleToLoad.fromDict(module);});}
+return new FunctionHandle(modulesToLoad,handleDict.function_name,options);};return{FunctionHandle,ModuleToLoad,FunctionRegistry,};});'use strict';tr.exportTo('tr.metrics',function(){function runMetrics(model,options,addFailureCb){if(options===undefined){throw new Error('Options are required.');}
+const metricNames=options.metrics;if(!metricNames){throw new Error('Metric names should be specified.');}
+const allMetricsStart=new Date();const durationBreakdown=new tr.v.d.Breakdown();const categories=getTraceCategories(model);const histograms=new tr.v.HistogramSet();histograms.createHistogram('trace_import_duration',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,model.stats.traceImportDurationMs,{binBoundaries:tr.v.HistogramBinBoundaries.createExponential(1e-3,1e5,30),description:'Duration that trace viewer required to import the trace',summaryOptions:tr.v.Histogram.AVERAGE_ONLY_SUMMARY_OPTIONS,});for(const metricName of metricNames){const metricStart=new Date();const metric=tr.metrics.MetricRegistry.findTypeInfoWithName(metricName);if(metric===undefined){throw new Error(`"${metricName}" is not a registered metric.`);}
+validateTraceCategories(metric.metadata.requiredCategories,categories);try{metric.constructor(histograms,model,options);}catch(e){const err=tr.b.normalizeException(e);addFailureCb(new tr.mre.Failure(undefined,'metricMapFunction',model.canonicalUrl,err.typeName,err.message,err.stack));}
+const metricMs=new Date()-metricStart;histograms.createHistogram(metricName+'_duration',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[metricMs]);durationBreakdown.set(metricName,metricMs);}
+validateDiagnosticNames(histograms);const allMetricsMs=new Date()-allMetricsStart+
+model.stats.traceImportDurationMs;durationBreakdown.set('traceImport',model.stats.traceImportDurationMs);durationBreakdown.set('other',allMetricsMs-tr.b.math.Statistics.sum(durationBreakdown,([metricName,metricMs])=>metricMs));const breakdownNames=tr.v.d.RelatedNameMap.fromEntries(new Map(metricNames.map(metricName=>[metricName,metricName+'_duration'])));breakdownNames.set('traceImport','trace_import_duration');histograms.createHistogram('metrics_duration',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[{value:allMetricsMs,diagnostics:{breakdown:durationBreakdown},},],{diagnostics:{breakdown:breakdownNames},});return histograms;}
+function getTraceCategories(model){for(const metadata of model.metadata){let config;if(metadata.name==='TraceConfig'&&metadata.value){config=metadata.value;}
+if(metadata.name==='metadata'&&metadata.value&&metadata.value['trace-config']&&metadata.value['trace-config']!=='__stripped__'){config=JSON.parse(metadata.value['trace-config']);}
+if(config){return{excluded:config.excluded_categories||[],included:config.included_categories||[],};}}}
+function validateTraceCategories(requiredCategories,categories){if(!requiredCategories)return;if(!categories)throw new Error('Missing trace config metadata');for(const cat of requiredCategories){const isDisabledByDefault=(cat.indexOf('disabled-by-default')===0);let missing=false;if(isDisabledByDefault){if(!categories.included.includes(cat)){missing=true;}}else if(categories.excluded.includes(cat)){missing=true;}
+if(missing){throw new Error(`Trace is missing required category "${cat}"`);}}}
+function validateDiagnosticNames(histograms){for(const hist of histograms){for(const name of hist.diagnostics.keys()){if(tr.v.d.RESERVED_NAMES_SET.has(name)){throw new Error(`Illegal diagnostic name "${name}" on Histogram "${hist.name}"`);}}}}
+function addTelemetryInfo(histograms,model){for(const metadata of model.metadata){if(!metadata.value||!metadata.value.telemetry)continue;for(const[name,value]of Object.entries(metadata.value.telemetry)){const type=tr.v.d.RESERVED_NAMES_TO_TYPES.get(name);if(type===undefined){throw new Error(`Unexpected telemetry.${name}`);}
+histograms.addSharedDiagnosticToAllHistograms(name,new type(value));}}}
+function metricMapFunction(result,model,options){const histograms=runMetrics(model,options,result.addFailure.bind(result));addTelemetryInfo(histograms,model);if(model.canonicalUrl!==undefined){const info=tr.v.d.RESERVED_INFOS.TRACE_URLS;histograms.addSharedDiagnosticToAllHistograms(info.name,new info.type([model.canonicalUrl]));}
+result.addPair('histograms',histograms.asDicts());const scalarDicts=[];for(const value of histograms){for(const[statName,scalar]of value.statisticsScalars){scalarDicts.push({name:value.name+'_'+statName,numeric:scalar.asDict(),description:value.description,});}}
+result.addPair('scalars',scalarDicts);}
+tr.mre.FunctionRegistry.register(metricMapFunction);return{metricMapFunction,runMetrics,};});'use strict';tr.exportTo('tr.mre',function(){class MreResult{constructor(failures,pairs){if(failures===undefined){failures=[];}
+if(pairs===undefined){pairs={};}
+this.failures=failures;this.pairs=pairs;}
+addFailure(failure){this.failures.push(failure);}
+addPair(key,value){if(key in this.pairs){throw new Error('Key '+key+' already exists in result.');}
+this.pairs[key]=value;}
+asDict(){const d={pairs:this.pairs};if(this.failures){d.failures=this.failures.map(function(f){return f.asDict();});}
+return d;}
+hadFailures(){return this.failures.length>0;}
+static fromDict(resultDict){const failures=(resultDict.failures!==undefined)?resultDict.failures.map(tr.mre.Failure.fromDict):undefined;const pairs=resultDict.pairs;return new MreResult(failures,pairs);}}
+return{MreResult,};});'use strict';tr.exportTo('tr.ui',function(){class NullBrushingStateController extends tr.c.BrushingStateController{constructor(){super(undefined);this.parentController=undefined;}
+dispatchChangeEvent_(){if(this.parentController)this.parentController.dispatchChangeEvent_();}
+get model(){if(!this.parentController)return undefined;return this.parentController.model;}
+get trackView(){if(!this.parentController)return undefined;return this.parentController.trackView;}
+get viewport(){if(!this.parentController)return undefined;return this.parentController.viewport;}
+get historyEnabled(){if(!this.parentController)return undefined;return this.parentController.historyEnabled;}
+set historyEnabled(historyEnabled){if(this.parentController){this.parentController.historyEnabled=historyEnabled;}}
+modelWillChange(){if(this.parentController)this.parentController.modelWillChange();}
+modelDidChange(){if(this.parentController)this.parentController.modelDidChange();}
+onUserInitiatedSelectionChange_(){if(this.parentController){this.parentController.onUserInitiatedSelectionChange_();}}
+onPopState_(e){if(this.parentController)this.parentController.onPopState_(e);}
+get selection(){if(!this.parentController)return undefined;return this.parentController.selection;}
+get findMatches(){if(!this.parentController)return undefined;return this.parentController.findMatches;}
+get selectionOfInterest(){if(!this.parentController)return undefined;return this.parentController.selectionOfInterest;}
+get currentBrushingState(){if(!this.parentController)return undefined;return this.parentController.currentBrushingState;}
+set currentBrushingState(newBrushingState){if(this.parentController){this.parentController.currentBrushingState=newBrushingState;}}
+addAllEventsMatchingFilterToSelectionAsTask(filter,selection){if(this.parentController){this.parentController.addAllEventsMatchingFilterToSelectionAsTask(filter,selection);}}
+findTextChangedTo(allPossibleMatches){if(this.parentController){this.parentController.findTextChangedTo(allPossibleMatches);}}
+findFocusChangedTo(currentFocus){if(this.parentController){this.parentController.findFocusChangedTo(currentFocus);}}
+findTextCleared(){if(this.parentController){this.parentController.findTextCleared();}}
+uiStateFromString(string){if(this.parentController){this.parentController.uiStateFromString(string);}}
+navToPosition(uiState,showNavLine){if(this.parentController){this.parentController.navToPosition(uiState,showNavLine);}}
+changeSelectionFromTimeline(selection){if(this.parentController){this.parentController.changeSelectionFromTimeline(selection);}}
+showScriptControlSelection(selection){if(this.parentController){this.parentController.showScriptControlSelection(selection);}}
+changeSelectionFromRequestSelectionChangeEvent(selection){if(this.parentController){this.parentController.changeSelectionFromRequestSelectionChangeEvent(selection);}}
+changeAnalysisViewRelatedEvents(eventSet){if(this.parentController&&(eventSet instanceof tr.model.EventSet)){this.parentController.changeAnalysisViewRelatedEvents(eventSet);}}
+changeAnalysisLinkHoveredEvents(eventSet){if(this.parentController&&(eventSet instanceof tr.model.EventSet)){this.parentController.changeAnalysisLinkHoveredEvents(eventSet);}}
+getViewSpecificBrushingState(viewId){if(this.parentController){this.parentController.getViewSpecificBrushingState(viewId);}}
+changeViewSpecificBrushingState(viewId,newState){if(this.parentController){this.parentController.changeViewSpecificBrushingState(viewId,newState);}}}
+return{NullBrushingStateController,};});'use strict';tr.exportTo('tr.v',function(){const IGNORE_GROUPING_KEYS=['name','storyTags','testPath',];class CSVBuilder{constructor(histograms){this.histograms_=histograms;this.table_=[];this.statisticsNames_=new Set();this.groupings_=[];}
+build(){this.prepare_();this.buildHeader_();this.buildTable_();}
+prepare_(){for(const[key,grouping]of tr.v.HistogramGrouping.BY_KEY){if(IGNORE_GROUPING_KEYS.includes(key))continue;this.groupings_.push(grouping);}
+this.groupings_.push(new tr.v.GenericSetGrouping(tr.v.d.RESERVED_NAMES.TRACE_URLS));this.groupings_.sort((a,b)=>a.key.localeCompare(b.key));for(const hist of this.histograms_){for(const name of hist.statisticsNames){this.statisticsNames_.add(name);}}
+this.statisticsNames_=Array.from(this.statisticsNames_);this.statisticsNames_.sort();}
+buildHeader_(){const header=['name','unit'];for(const name of this.statisticsNames_){header.push(name);}
+for(const grouping of this.groupings_){header.push(grouping.key);}
+this.table_.push(header);}
+buildTable_(){for(const hist of this.histograms_){const row=[hist.name,hist.unit.unitString];this.table_.push(row);for(const name of this.statisticsNames_){const stat=hist.getStatisticScalar(name);if(stat){row.push(stat.value);}else{row.push('');}}
+for(const grouping of this.groupings_){row.push(grouping.callback(hist));}}}
+toString(){let str='';for(const row of this.table_){for(let i=0;i<row.length;++i){if(i>0){str+=',';}
+let cell=''+row[i];cell=cell.replace(/\n/g,' ');if(cell.indexOf(',')>=0||cell.indexOf('"')>=0){cell='"'+cell.replace(/"/g,'""')+'"';}
+str+=cell;}
+str+='\n';}
+return str;}}
+return{CSVBuilder,};});'use strict';tr.exportTo('tr.v',function(){const getDisplayLabel=tr.v.HistogramGrouping.DISPLAY_LABEL.callback;const DEFAULT_POSSIBLE_GROUPS=[];const EXCLUDED_GROUPING_KEYS=[tr.v.HistogramGrouping.DISPLAY_LABEL.key,];for(const group of tr.v.HistogramGrouping.BY_KEY.values()){if(EXCLUDED_GROUPING_KEYS.includes(group.key))continue;DEFAULT_POSSIBLE_GROUPS.push(group);}
+class HistogramParameterCollector{constructor(){this.statisticNames_=new Set(['avg']);this.labelsToStartTimes_=new Map();this.keysToGroupings_=new Map(DEFAULT_POSSIBLE_GROUPS.map(g=>[g.key,g]));this.keysToValues_=new Map(DEFAULT_POSSIBLE_GROUPS.map(g=>[g.key,new Set()]));this.keysToValues_.delete(tr.v.HistogramGrouping.HISTOGRAM_NAME.key);}
+process(histograms){const allStoryTags=new Set();let maxSampleCount=0;for(const hist of histograms){maxSampleCount=Math.max(maxSampleCount,hist.numValues);for(const statName of hist.statisticsNames){this.statisticNames_.add(statName);}
+let startTime=hist.diagnostics.get(tr.v.d.RESERVED_NAMES.BENCHMARK_START);if(startTime!==undefined)startTime=startTime.minDate.getTime();const displayLabel=getDisplayLabel(hist);if(this.labelsToStartTimes_.has(displayLabel)){startTime=Math.min(startTime,this.labelsToStartTimes_.get(displayLabel));}
+this.labelsToStartTimes_.set(displayLabel,startTime);for(const[groupingKey,values]of this.keysToValues_){const grouping=this.keysToGroupings_.get(groupingKey);const value=grouping.callback(hist);if(!value)continue;values.add(value);if(values.size>1){this.keysToValues_.delete(groupingKey);}}
+const storyTags=hist.diagnostics.get(tr.v.d.RESERVED_NAMES.STORY_TAGS);for(const tag of(storyTags||[])){allStoryTags.add(tag);}}
+tr.b.Timing.instant('HistogramParameterCollector','maxSampleCount',maxSampleCount);for(const tagGrouping of tr.v.HistogramGrouping.buildFromTags(allStoryTags,tr.v.d.RESERVED_NAMES.STORY_TAGS)){const values=new Set();for(const hist of histograms){values.add(tagGrouping.callback(hist));}
+if(values.size>1){this.keysToGroupings_.set(tagGrouping.key,tagGrouping);this.keysToValues_.set(tagGrouping.key,values);}}
+this.statisticNames_.add('pct_090');}
+get statisticNames(){return Array.from(this.statisticNames_);}
+get labels(){const displayLabels=Array.from(this.labelsToStartTimes_.keys());displayLabels.sort((x,y)=>this.labelsToStartTimes_.get(x)-this.labelsToStartTimes_.get(y));return displayLabels;}
+get possibleGroupings(){for(const[key,values]of this.keysToValues_){if(values.size>=2)continue;this.keysToGroupings_.delete(key);}
+return Array.from(this.keysToGroupings_.values());}}
+return{HistogramParameterCollector,};});'use strict';tr.exportTo('tr.v.ui',function(){Polymer({is:'tr-v-ui-histogram-set-controls-export',exportRawCsv_(){this.export_(false,'csv');},exportRawJson_(){this.export_(false,'json');},exportMergedCsv_(){this.export_(true,'csv');},exportMergedJson_(){this.export_(true,'json');},export_(merged,format){tr.b.dispatchSimpleEvent(this,'export',true,true,{merged,format});},});return{};});'use strict';tr.exportTo('tr.v.ui',function(){const ALPHA_OPTIONS=[];for(let i=1;i<10;++i)ALPHA_OPTIONS.push(i*1e-3);for(let i=1;i<10;++i)ALPHA_OPTIONS.push(i*1e-2);ALPHA_OPTIONS.push(0.1);Polymer({is:'tr-v-ui-histogram-set-controls',properties:{searchQuery:{type:String,value:'',observer:'onSearchQueryChange_',},showAll:{type:Boolean,value:true,observer:'onUserChange_',},referenceDisplayLabel:{type:String,value:'',observer:'onUserChange_',},displayStatisticName:{type:String,value:'',observer:'onUserChange_',},alphaString:{type:String,computed:'getAlphaString_(alphaIndex)',},alphaIndex:{type:Number,value:9,observer:'onUserChange_',},},created(){this.viewState_=undefined;this.rowListener_=this.onRowViewStateUpdate_.bind(this);this.baseStatisticNames_=[];this.isInOnViewStateUpdate_=false;this.searchQueryDebounceMs=200;},ready(){this.$.picker.addEventListener('current-groups-changed',this.onGroupsChanged_.bind(this));},get viewState(){return this.viewState_;},set viewState(vs){if(this.viewState_){throw new Error('viewState must be set exactly once.');}
+this.viewState_=vs;this.viewState.addUpdateListener(this.onViewStateUpdate_.bind(this));},async onSearchQueryChange_(){if(this.searchQueryDebounceMs===0)return this.onUserChange_();this.debounce('onSearchQueryDebounce',this.onUserChange_,this.searchQueryDebounceMs);},async onUserChange_(){if(!this.viewState)return;if(this.isInOnViewStateUpdate_)return;const marks=[];if(this.searchQuery!==this.viewState.searchQuery){marks.push(tr.b.Timing.mark('histogram-set-controls','search'));}
+if(this.showAll!==this.viewState.showAll){marks.push(tr.b.Timing.mark('histogram-set-controls','showAll'));}
+if(this.referenceDisplayLabel!==this.viewState.referenceDisplayLabel){marks.push(tr.b.Timing.mark('histogram-set-controls','referenceColumn'));}
+if(this.displayStatisticName!==this.viewState.displayStatisticName){marks.push(tr.b.Timing.mark('histogram-set-controls','statistic'));}
+if(parseInt(this.alphaIndex)!==this.getAlphaIndexFromViewState_()){marks.push(tr.b.Timing.mark('histogram-set-controls','alpha'));}
+this.$.clear_search.style.visibility=this.searchQuery?'visible':'hidden';let displayStatisticName=this.displayStatisticName;if(this.viewState.referenceDisplayLabel===''&&this.referenceDisplayLabel!==''&&this.baseStatisticNames.length){displayStatisticName=`%${tr.v.DELTA}${this.displayStatisticName}`;}
+if(this.referenceDisplayLabel===''&&this.viewState.referenceDisplayLabel!==''&&this.baseStatisticNames.length){const deltaIndex=displayStatisticName.indexOf(tr.v.DELTA);if(deltaIndex>=0){displayStatisticName=displayStatisticName.slice(deltaIndex+1);}else if(!this.baseStatisticNames.includes(displayStatisticName)){displayStatisticName='avg';}}
+await this.viewState.update({searchQuery:this.searchQuery,showAll:this.showAll,referenceDisplayLabel:this.referenceDisplayLabel,displayStatisticName,alpha:ALPHA_OPTIONS[this.alphaIndex],});if(this.referenceDisplayLabel&&this.statisticNames.length===this.baseStatisticNames.length){this.statisticNames=this.baseStatisticNames.concat(tr.v.Histogram.getDeltaStatisticsNames(this.baseStatisticNames));}else if(!this.referenceDisplayLabel&&this.statisticNames.length>this.baseStatisticNames.length){this.statisticNames=this.baseStatisticNames;}
+for(const mark of marks)mark.end();},onViewStateUpdate_(event){this.isInOnViewStateUpdate_=true;if(event.delta.searchQuery){this.searchQuery=this.viewState.searchQuery;}
+if(event.delta.showAll)this.showAll=this.viewState.showAll;if(event.delta.displayStatisticName){this.displayStatisticName=this.viewState.displayStatisticName;}
+if(event.delta.referenceDisplayLabel){this.referenceDisplayLabel=this.viewState.referenceDisplayLabel;this.$.alpha.style.display=this.referenceDisplayLabel?'inline':'';}
+if(event.delta.groupings){this.$.picker.currentGroupKeys=this.viewState.groupings.map(g=>g.key);}
+if(event.delta.tableRowStates){for(const row of tr.v.ui.HistogramSetTableRowState.walkAll(this.viewState.tableRowStates.values())){row.addUpdateListener(this.rowListener_);}
+const anyShowing=this.anyOverviewCharts_;this.$.hide_overview.style.display=anyShowing?'inline':'none';this.$.show_overview.style.display=anyShowing?'none':'inline';}
+if(event.delta.alpha){this.alphaIndex=this.getAlphaIndexFromViewState_();}
+this.isInOnViewStateUpdate_=false;this.onUserChange_();},onRowViewStateUpdate_(event){if(event.delta.isOverviewed){const anyShowing=event.delta.isOverviewed.current||this.anyOverviewCharts_;this.$.hide_overview.style.display=anyShowing?'inline':'none';this.$.show_overview.style.display=anyShowing?'none':'inline';}
+if(event.delta.subRows){for(const subRow of event.delta.subRows.previous){subRow.removeUpdateListener(this.rowListener_);}
+for(const subRow of event.delta.subRows.current){subRow.addUpdateListener(this.rowListener_);}}},onGroupsChanged_(){if(this.$.picker.currentGroups.length===0&&this.$.picker.possibleGroups.length>0){this.$.picker.currentGroupKeys=[this.$.picker.possibleGroups[0].key];}
+this.viewState.groupings=this.$.picker.currentGroups;},set showAllEnabled(enable){if(!enable)this.$.show_all.checked=true;this.$.show_all.disabled=!enable;},set possibleGroupings(groupings){this.$.picker.possibleGroups=groupings;this.$.picker.style.display=(groupings.length<2)?'none':'block';this.onGroupsChanged_();},set displayLabels(labels){this.$.reference_display_label.style.display=(labels.length<2)?'none':'inline';while(this.$.reference_display_label.children.length>1){this.$.reference_display_label.removeChild(this.$.reference_display_label.lastChild);}
+for(const displayLabel of labels){const option=document.createElement('option');option.textContent=displayLabel;option.value=displayLabel;this.$.reference_display_label.appendChild(option);}
+if(labels.includes(this.viewState.referenceDisplayLabel)){this.referenceDisplayLabel=this.viewState.referenceDisplayLabel;}else{this.viewState.referenceDisplayLabel='';}},get baseStatisticNames(){return this.baseStatisticNames_;},set baseStatisticNames(names){this.baseStatisticNames_=names;this.statisticNames=names;},get statisticNames(){return Array.from(this.$.statistic.options).map(o=>o.value);},set statisticNames(names){this.$.statistic.style.display=(names.length<2)?'none':'inline';while(this.$.statistic.children.length){this.$.statistic.removeChild(this.$.statistic.lastChild);}
+for(const name of names){const option=document.createElement('option');option.textContent=name;this.$.statistic.appendChild(option);}
+if(names.includes(this.viewState.displayStatisticName)){this.displayStatisticName=this.viewState.displayStatisticName;this.$.statistic.value=this.displayStatisticName;}else{this.viewState.displayStatisticName=names[0]||'';}},get anyOverviewCharts_(){for(const row of tr.v.ui.HistogramSetTableRowState.walkAll(this.viewState.tableRowStates.values())){if(row.isOverviewed)return true;}
+return false;},async toggleOverviewLineCharts_(){const showOverviews=!this.anyOverviewCharts_;const mark=tr.b.Timing.mark('histogram-set-controls',(showOverviews?'show':'hide')+'OverviewCharts');for(const row of tr.v.ui.HistogramSetTableRowState.walkAll(this.viewState.tableRowStates.values())){await row.update({isOverviewed:showOverviews});}
+this.$.hide_overview.style.display=showOverviews?'inline':'none';this.$.show_overview.style.display=showOverviews?'none':'inline';await tr.b.animationFrame();mark.end();},set helpHref(href){this.$.help.href=href;this.$.help.style.display='inline';},set feedbackHref(href){this.$.feedback.href=href;this.$.feedback.style.display='inline';},clearSearch_(){this.set('searchQuery','');this.$.search.focus();},getAlphaString_(alphaIndex){return(''+ALPHA_OPTIONS[alphaIndex]).substr(0,5);},openAlphaSlider_(){const alphaButtonRect=this.$.alpha.getBoundingClientRect();this.$.alpha_slider_container.style.display='flex';this.$.alpha_slider_container.style.top=alphaButtonRect.bottom+'px';this.$.alpha_slider_container.style.left=alphaButtonRect.left+'px';this.$.alpha_slider.focus();},closeAlphaSlider_(){this.$.alpha_slider_container.style.display='';},updateAlpha_(){this.alphaIndex=this.$.alpha_slider.value;},getAlphaIndexFromViewState_(){for(let i=0;i<ALPHA_OPTIONS.length;++i){if(ALPHA_OPTIONS[i]>=this.viewState.alpha)return i;}
+return ALPHA_OPTIONS.length-1;},set enableVisualization(enable){this.$.show_visualization.style.display=enable?'inline':'none';},loadVisualization_(){tr.b.dispatchSimpleEvent(this,'loadVisualization',true,true,{});},});return{};});'use strict';tr.exportTo('tr.v',function(){class HistogramSetHierarchy{constructor(name){this.name=name;this.description='';this.depth=0;this.subRows=[];this.columns=new Map();}*walk(){yield this;for(const row of this.subRows)yield*row.walk();}
+static*walkAll(rootRows){for(const rootRow of rootRows)yield*rootRow.walk();}
+static build(histogramArrayMap){const rootRows=[];HistogramSetHierarchy.buildInternal_(histogramArrayMap,[],rootRows);const histograms=new tr.v.HistogramSet();for(const row of HistogramSetHierarchy.walkAll(rootRows)){for(const hist of row.columns.values()){if(!(hist instanceof tr.v.Histogram))continue;histograms.addHistogram(hist);}}
+histograms.deduplicateDiagnostics();for(const row of HistogramSetHierarchy.walkAll(rootRows)){row.maybeRebin_();}
+return rootRows;}
+maybeRebin_(){const dataRange=new tr.b.math.Range();for(const hist of this.columns.values()){if(!(hist instanceof tr.v.Histogram))continue;if(hist.allBins.length>1)return;if(hist.numValues===0)continue;dataRange.addValue(hist.min);dataRange.addValue(hist.max);}
+dataRange.addValue(tr.b.math.lesserWholeNumber(dataRange.min));dataRange.addValue(tr.b.math.greaterWholeNumber(dataRange.max));if(dataRange.min===dataRange.max)return;const boundaries=tr.v.HistogramBinBoundaries.createLinear(dataRange.min,dataRange.max,tr.v.DEFAULT_REBINNED_COUNT);for(const[name,hist]of this.columns){if(!(hist instanceof tr.v.Histogram))continue;this.columns.set(name,hist.rebin(boundaries));}}
+static mergeHistogramDownHierarchy_(histogram,hierarchy,columnName){for(const row of hierarchy){if(!row.description){row.description=histogram.description;}
+const existing=row.columns.get(columnName);if(existing===undefined){row.columns.set(columnName,histogram.clone());continue;}
+if(existing instanceof tr.v.HistogramSet){existing.addHistogram(histogram);continue;}
+if(!existing.canAddHistogram(histogram)){const unmergeableHistograms=new tr.v.HistogramSet([histogram]);row.columns.set(columnName,unmergeableHistograms);continue;}
+existing.addHistogram(histogram);}}
+static buildInternal_(histogramArrayMap,hierarchy,rootRows){for(const[name,histograms]of histogramArrayMap){if(histograms instanceof Array){for(const histogram of histograms){HistogramSetHierarchy.mergeHistogramDownHierarchy_(histogram,hierarchy,name);}}else if(histograms instanceof Map){const row=new HistogramSetHierarchy(name);row.depth=hierarchy.length;hierarchy.push(row);HistogramSetHierarchy.buildInternal_(histograms,hierarchy,rootRows);hierarchy.pop();if(hierarchy.length===0){rootRows.push(row);}else{const parentRow=hierarchy[hierarchy.length-1];parentRow.subRows.push(row);}}}}}
+return{HistogramSetHierarchy};});'use strict';tr.exportTo('tr.v.ui',function(){Polymer({is:'tr-v-ui-histogram-set-table-cell',created(){this.viewState_=undefined;this.rootListener_=this.onRootStateUpdate_.bind(this);this.row_=undefined;this.displayLabel_='';this.histogram_=undefined;this.histogramSpan_=undefined;this.overviewChart_=undefined;this.mwuResult_=undefined;},ready(){this.addEventListener('click',this.onClick_.bind(this));},attached(){if(this.row){this.row.rootViewState.addUpdateListener(this.rootListener_);}},detached(){this.row.rootViewState.removeUpdateListener(this.rootListener_);},updateMwu_(){const referenceHistogram=this.referenceHistogram;this.mwuResult_=undefined;if(!(this.histogram instanceof tr.v.Histogram))return;if(!this.histogram.canCompare(referenceHistogram))return;this.mwuResult_=tr.b.math.Statistics.mwu(this.histogram.sampleValues,referenceHistogram.sampleValues,this.row.rootViewState.alpha);},build(row,displayLabel,viewState){this.row_=row;this.displayLabel_=displayLabel;this.viewState_=viewState;this.histogram_=this.row.columns.get(displayLabel);if(this.viewState){this.viewState.addUpdateListener(this.onViewStateUpdate_.bind(this));}
+this.row.viewState.addUpdateListener(this.onRowStateUpdate_.bind(this));if(this.isAttached){this.row.rootViewState.addUpdateListener(this.rootListener_);}
+this.updateMwu_();this.updateContents_();},updateSignificance_(){if(!this.mwuResult_)return;this.$.scalar.significance=this.mwuResult_.significance;},get viewState(){return this.viewState_;},get row(){return this.row_;},get histogram(){return this.histogram_;},get referenceHistogram(){const referenceDisplayLabel=this.row.rootViewState.referenceDisplayLabel;if(!referenceDisplayLabel)return undefined;if(referenceDisplayLabel===this.displayLabel_)return undefined;return this.row.columns.get(referenceDisplayLabel);},get isHistogramOpen(){return(this.histogramSpan_!==undefined)&&(this.$.histogram.style.display==='block');},set isHistogramOpen(open){if(!(this.histogram instanceof tr.v.Histogram)||(this.histogram.numValues===0)){return;}
+this.$.scalar.style.display=open?'none':'flex';this.$.open_histogram.style.display=open?'none':'block';this.$.close_histogram.style.display=open?'block':'none';this.$.histogram.style.display=open?'block':'none';if(open&&this.histogramSpan_===undefined){this.histogramSpan_=document.createElement('tr-v-ui-histogram-span');this.histogramSpan_.viewState=this.viewState;this.histogramSpan_.rowState=this.row.viewState;this.histogramSpan_.rootState=this.row.rootViewState;this.histogramSpan_.build(this.histogram,this.referenceHistogram);this.$.histogram.appendChild(this.histogramSpan_);}
+this.viewState.isOpen=open;},onViewStateUpdate_(event){if(event.delta.isOpen){this.isHistogramOpen=this.viewState.isOpen;}},onRowStateUpdate_(event){if(event.delta.isOverviewed===undefined)return;if(this.row.viewState.isOverviewed){this.showOverview();}else{this.hideOverview();}},onRootStateUpdate_(event){if(event.delta.referenceDisplayLabel&&this.histogramSpan_){this.histogramSpan_.build(this.histogram,this.referenceHistogram);}
+if(event.delta.displayStatisticName||event.delta.referenceDisplayLabel){this.updateMwu_();this.updateContents_();}else if(event.delta.alpha&&this.mwuResult_){this.mwuResult_.compare(this.row.rootViewState.alpha);this.updateSignificance_();}
+if(this.row.viewState.isOverviewed&&(event.delta.sortColumnIndex||event.delta.sortDescending||event.delta.displayStatisticName||event.delta.referenceDisplayLabel)){if(this.overviewChart_!==undefined){this.$.overview_container.removeChild(this.overviewChart_);this.overviewChart_=undefined;}
+this.showOverview();}},onClick_(event){event.stopPropagation();},openHistogram_(){this.isHistogramOpen=true;tr.b.Timing.instant('histogram-set-table-cell','open');},closeHistogram_(){this.isHistogramOpen=false;tr.b.Timing.instant('histogram-set-table-cell','close');},updateContents_(){const isOpen=this.isHistogramOpen;this.$.empty.style.display='none';this.$.unmergeable.style.display='none';this.$.scalar.style.display='none';this.$.histogram.style.display='none';this.$.close_histogram.style.display='none';this.$.open_histogram.style.visibility='hidden';if(!this.histogram){this.$.missing.style.display='block';return;}
+this.$.missing.style.display='none';if(this.histogram instanceof tr.v.HistogramSet){this.$.unmergeable.style.display='block';return;}
+if(!(this.histogram instanceof tr.v.Histogram)){throw new Error('Invalid Histogram: '+this.histogram);}
+if(this.histogram.numValues===0){this.$.empty.style.display='block';return;}
+this.$.open_histogram.style.display='block';this.$.open_histogram.style.visibility='visible';this.$.scalar.style.display='flex';this.updateSignificance_();const referenceHistogram=this.referenceHistogram;const statName=this.histogram.getAvailableStatisticName(this.row.rootViewState.displayStatisticName,referenceHistogram);const statisticScalar=this.histogram.getStatisticScalar(statName,referenceHistogram);this.$.scalar.setValueAndUnit(statisticScalar.value,statisticScalar.unit);this.isHistogramOpen=isOpen;},showOverview(){this.$.overview_container.style.display='block';if(this.overviewChart_!==undefined)return;this.row.sortSubRows();let referenceDisplayLabel=this.row.rootViewState.referenceDisplayLabel;if(referenceDisplayLabel===this.displayLabel_){referenceDisplayLabel=undefined;}
+const displayStatisticName=this.row.rootViewState.displayStatisticName;const data=[];let unit;for(const subRow of this.row.subRows){const subHist=subRow.columns.get(this.displayLabel_);if(!(subHist instanceof tr.v.Histogram))continue;if(unit===undefined){unit=subHist.unit;}else if(unit!==subHist.unit){data.splice(0);break;}
+const refHist=subRow.columns.get(referenceDisplayLabel);const statName=subHist.getAvailableStatisticName(displayStatisticName,refHist);const statScalar=subHist.getStatisticScalar(statName,refHist);if(statScalar!==undefined){data.push({x:subRow.name,y:statScalar.value,});}}
+if(data.length<2)return;this.overviewChart_=new tr.ui.b.NameLineChart();this.$.overview_container.appendChild(this.overviewChart_);this.overviewChart_.displayXInHover=true;this.overviewChart_.hideLegend=true;this.overviewChart_.unit=unit;this.overviewChart_.overrideDataRange=this.row.overviewDataRange;this.overviewChart_.data=data;},hideOverview(){this.$.overview_container.style.display='none';}});return{};});'use strict';tr.exportTo('tr.v.ui',function(){const NAME_COLUMN_WIDTH_PX=300;Polymer({is:'tr-v-ui-histogram-set-table-name-cell',created(){this.row_=undefined;this.overviewChart_=undefined;this.cellListener_=this.onCellStateUpdate_.bind(this);this.rootListener_=this.onRootStateUpdate_.bind(this);},attached(){if(this.row){this.row.rootViewState.addUpdateListener(this.rootListener_);}},detached(){this.row.rootViewState.removeUpdateListener(this.rootListener_);},get row(){return this.row_;},build(row){if(this.row_!==undefined){throw new Error('row must be set exactly once.');}
+this.row_=row;this.row.viewState.addUpdateListener(this.onRowStateUpdate_.bind(this));this.constrainWidth=this.row.rootViewState.constrainNameColumn;if(this.isAttached){this.row.rootViewState.addUpdateListener(this.rootListener_);}
+for(const cellState of this.row.viewState.cells.values()){cellState.addUpdateListener(this.cellListener_);}
+Polymer.dom(this.$.name).textContent=this.row.name;this.title=this.row.name;if(this.row.description){this.title+='\n'+this.row.description;}
+if(this.row.overviewDataRange.isEmpty||this.row.overviewDataRange.min===this.row.overviewDataRange.max){this.$.show_overview.style.display='none';}
+let histogramCount=0;for(const cell of this.row.columns.values()){if(cell instanceof tr.v.Histogram&&cell.numValues>0){++histogramCount;}}
+if(histogramCount<=1){this.$.open_histograms.style.display='none';}},set constrainWidth(constrain){this.$.name.style.maxWidth=constrain?(this.nameWidthPx+'px'):'none';},get nameWidthPx(){return NAME_COLUMN_WIDTH_PX-(16*this.row.depth);},get isOverflowing(){return this.$.name.style.maxWidth!=='none'&&this.$.name.getBoundingClientRect().width===this.nameWidthPx;},get isOverviewed(){return this.$.overview_container.style.display==='block';},set isOverviewed(isOverviewed){if(isOverviewed===this.isOverviewed)return;if(isOverviewed){this.showOverview_();}else{this.hideOverview_();}},hideOverview_(opt_event){this.$.overview_container.style.display='none';this.$.hide_overview.style.display='none';this.$.show_overview.style.display='block';if(opt_event!==undefined){opt_event.stopPropagation();tr.b.Timing.instant('histogram-set-table-name-cell','hideOverview');this.row.viewState.isOverviewed=this.isOverviewed;}},showOverview_(opt_event){if(opt_event!==undefined){opt_event.stopPropagation();tr.b.Timing.instant('histogram-set-table-name-cell','showOverview');this.row.viewState.isOverviewed=true;}
+this.$.overview_container.style.display='block';this.$.hide_overview.style.display='block';this.$.show_overview.style.display='none';if(this.overviewChart_===undefined){const displayStatisticName=this.row.rootViewState.displayStatisticName;const data=[];let unit;for(const[displayLabel,hist]of this.row.sortedColumns()){if(!(hist instanceof tr.v.Histogram))continue;if(unit===undefined){unit=hist.unit;}else if(unit!==hist.unit){data.splice(0);break;}
+const statName=hist.getAvailableStatisticName(displayStatisticName);const statScalar=hist.getStatisticScalar(statName);if(statScalar!==undefined){data.push({x:displayLabel,y:statScalar.value,});}}
+if(data.length<2){return;}
+this.overviewChart_=new tr.ui.b.NameLineChart();this.$.overview_container.appendChild(this.overviewChart_);this.overviewChart_.displayXInHover=true;this.overviewChart_.hideLegend=true;this.overviewChart_.unit=unit;this.overviewChart_.overrideDataRange=this.row.overviewDataRange;this.overviewChart_.data=data;}},openHistograms_(event){event.stopPropagation();tr.b.Timing.instant('histogram-set-table-name-cell','openHistograms');for(const cell of this.row.cells.values()){cell.isHistogramOpen=true;}
+this.$.close_histograms.style.display='block';this.$.open_histograms.style.display='none';},closeHistograms_(event){event.stopPropagation();tr.b.Timing.instant('histogram-set-table-name-cell','closeHistograms');for(const cell of this.row.cells.values()){cell.isHistogramOpen=false;}
+this.$.open_histograms.style.display='block';this.$.close_histograms.style.display='none';},onRootStateUpdate_(event){if(event.delta.constrainNameColumn){this.constrainWidth=this.row.rootViewState.constrainNameColumn;}
+if(this.row.viewState.isOverviewed&&event.delta.displayStatisticName){this.row.resetOverviewDataRange();if(this.overviewChart_!==undefined){this.$.overview_container.removeChild(this.overviewChart_);this.overviewChart_=undefined;}
+this.showOverview_();}},onRowStateUpdate_(event){if(event.delta.isOverviewed){this.isOverviewed=this.row.viewState.isOverviewed;}},onCellStateUpdate_(event){if(!event.delta.isOpen)return;let cellCount=0;let openCellCount=0;for(const cell of this.row.cells.values()){if(!(cell.histogram instanceof tr.v.Histogram)||(cell.histogram.numValues===0)){continue;}
+++cellCount;if(cell.isHistogramOpen)++openCellCount;}
+if(cellCount<=1)return;const mostlyOpen=openCellCount>(cellCount/2);this.$.open_histograms.style.display=mostlyOpen?'none':'block';this.$.close_histograms.style.display=mostlyOpen?'block':'none';}});return{NAME_COLUMN_WIDTH_PX,};});'use strict';tr.exportTo('tr.v.ui',function(){class HistogramSetTableRow{constructor(hierarchy,baseTable,rootViewState){this.hierarchy_=hierarchy;this.baseTable_=baseTable;this.rootViewState_=rootViewState;this.viewState_=new tr.v.ui.HistogramSetTableRowState();this.viewState_.addUpdateListener(this.onViewStateUpdate_.bind(this));this.overviewDataRange_=undefined;this.nameCell_=undefined;this.cells_=new Map();this.subRows_=[];for(const subHierarchy of hierarchy.subRows){const subRow=new HistogramSetTableRow(subHierarchy,baseTable,rootViewState);this.subRows_.push(subRow);this.viewState.subRows.set(subRow.name,subRow.viewState);}
+for(const columnName of this.columns.keys()){this.viewState.cells.set(columnName,new tr.v.ui.HistogramSetTableCellState());}}
+get name(){return this.hierarchy_.name;}
+get depth(){return this.hierarchy_.depth;}
+get description(){return this.hierarchy_.description;}
+get columns(){return this.hierarchy_.columns;}*sortedColumns(){for(const col of this.baseTable_.tableColumns){yield[col.displayLabel,this.hierarchy_.columns.get(col.displayLabel),];}}
+get overviewDataRange(){if(this.overviewDataRange_===undefined){this.overviewDataRange_=new tr.b.math.Range();const displayStatisticName=this.rootViewState.displayStatisticName;const referenceDisplayLabel=this.rootViewState.referenceDisplayLabel;for(const[displayLabel,hist]of this.columns){if(hist instanceof tr.v.Histogram){const statName=hist.getAvailableStatisticName(displayStatisticName);const statScalar=hist.getStatisticScalar(statName);if(statScalar!==undefined){this.overviewDataRange_.addValue(statScalar.value);}}
+for(const subRow of this.subRows){const subHist=subRow.columns.get(displayLabel);if(!(subHist instanceof tr.v.Histogram))continue;const refHist=subRow.columns.get(referenceDisplayLabel);const statName=subHist.getAvailableStatisticName(displayStatisticName,refHist);const statScalar=subHist.getStatisticScalar(statName,refHist);if(statScalar!==undefined){this.overviewDataRange_.addValue(statScalar.value);}}}}
+return this.overviewDataRange_;}
+resetOverviewDataRange(){this.overviewDataRange_=undefined;}
+get rootViewState(){return this.rootViewState_;}
+get cells(){return this.cells_;}
+get subRows(){return this.subRows_;}
+get viewState(){return this.viewState_;}*walk(){yield this;for(const row of this.subRows)yield*row.walk();}
+static*walkAll(rootRows){for(const rootRow of rootRows)yield*rootRow.walk();}
+get nameCell(){if(this.nameCell_===undefined){this.nameCell_=document.createElement('tr-v-ui-histogram-set-table-name-cell');this.nameCell_.build(this);}
+return this.nameCell_;}
+getCell(columnName){if(this.cells.has(columnName))return this.cells.get(columnName);const cell=document.createElement('tr-v-ui-histogram-set-table-cell');cell.build(this,columnName,this.viewState.cells.get(columnName));this.cells.set(columnName,cell);return cell;}
+compareNames(other){return this.name.localeCompare(other.name);}
+compareCells(other,displayLabel){const referenceDisplayLabel=this.rootViewState.referenceDisplayLabel;let referenceCellA;let referenceCellB;if(referenceDisplayLabel&&referenceDisplayLabel!==displayLabel){referenceCellA=this.columns.get(referenceDisplayLabel);referenceCellB=other.columns.get(referenceDisplayLabel);}
+const cellA=this.columns.get(displayLabel);let valueA=0;if(cellA instanceof tr.v.Histogram){const statisticA=cellA.getAvailableStatisticName(this.rootViewState.displayStatisticName,referenceCellA);const scalarA=cellA.getStatisticScalar(statisticA,referenceCellA);if(scalarA){valueA=scalarA.value;}}
+const cellB=other.columns.get(displayLabel);let valueB=0;if(cellB instanceof tr.v.Histogram){const statisticB=cellB.getAvailableStatisticName(this.rootViewState.displayStatisticName,referenceCellB);const scalarB=cellB.getStatisticScalar(statisticB,referenceCellB);if(scalarB){valueB=scalarB.value;}}
+return valueA-valueB;}
+onViewStateUpdate_(event){if(event.delta.isExpanded){this.baseTable_.setExpandedForTableRow(this,this.viewState.isExpanded);}
+if(event.delta.subRows){throw new Error('HistogramSetTableRow.subRows must not be reassigned.');}
+if(event.delta.cells){for(const[displayLabel,cell]of this.cells){if(cell.viewState!==this.viewState.cells.get(displayLabel)){throw new Error('Only HistogramSetTableRow may update cells');}}}}
+async restoreState(vs){await this.viewState.update({isExpanded:vs.isExpanded,isOverviewed:vs.isOverviewed,});for(const[displayLabel,cell]of this.cells){const previousState=vs.cells.get(displayLabel);if(!previousState)continue;await cell.viewState.updateFromViewState(previousState);}
+for(const row of this.subRows){const previousState=vs.subRows.get(row.name);if(!previousState)continue;await row.restoreState(previousState);}}
+sortSubRows(){const sortColumn=this.baseTable_.tableColumns[this.rootViewState_.sortColumnIndex];if(sortColumn===undefined)return;this.subRows_.sort(sortColumn.cmp);if(this.rootViewState_.sortDescending){this.subRows_.reverse();}}}
+return{HistogramSetTableRow,};});'use strict';tr.exportTo('tr.v.ui',function(){const MIDLINE_HORIZONTAL_ELLIPSIS=String.fromCharCode(0x22ef);function escapeRegExp(str){return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,'\\$&');}
+Polymer({is:'tr-v-ui-histogram-set-table',created(){this.viewState_=undefined;this.progress_=()=>Promise.resolve();this.nameColumnTitle_=undefined;this.displayLabels_=[];this.histograms_=undefined;this.sourceHistograms_=undefined;this.filteredHistograms_=undefined;this.groupedHistograms_=undefined;this.hierarchies_=undefined;this.tableRows_=undefined;this.sortColumnChangedListener_=e=>this.onSortColumnChanged_(e);},ready(){this.$.table.zebra=true;this.addEventListener('sort-column-changed',this.sortColumnChangedListener_);this.addEventListener('requestSelectionChange',this.onRequestSelectionChange_.bind(this));this.addEventListener('row-expanded-changed',this.onRowExpandedChanged_.bind(this));},get viewState(){return this.viewState_;},set viewState(vs){if(this.viewState_){throw new Error('viewState must be set exactly once.');}
+this.viewState_=vs;this.viewState.addUpdateListener(this.onViewStateUpdate_.bind(this));},get histograms(){return this.histograms_;},async build(histograms,sourceHistograms,displayLabels,opt_progress){this.histograms_=histograms;this.sourceHistograms_=sourceHistograms;this.filteredHistograms_=undefined;this.groupedHistograms_=undefined;this.displayLabels_=displayLabels;if(opt_progress!==undefined)this.progress_=opt_progress;if(histograms.length===0){throw new Error('histogram-set-table requires non-empty HistogramSet.');}
+await this.progress_('Building columns...');this.$.table.tableColumns=[{title:this.buildNameColumnTitle_(),value:row=>row.nameCell,cmp:(a,b)=>a.compareNames(b),}].concat(displayLabels.map(l=>this.buildColumn_(l)));tr.b.Timing.instant('histogram-set-table','columnCount',this.$.table.tableColumns.length);await this.updateContents_();this.fire('display-ready');this.progress_=()=>Promise.resolve();this.checkNameColumnOverflow_(tr.v.ui.HistogramSetTableRow.walkAll(this.$.table.tableRows));},buildNameColumnTitle_(){this.nameColumnTitle_=document.createElement('span');this.nameColumnTitle_.style.display='inline-flex';const nameEl=document.createElement('span');nameEl.textContent='Name';this.nameColumnTitle_.appendChild(nameEl);const toggleWidthEl=document.createElement('span');toggleWidthEl.style.fontWeight='bold';toggleWidthEl.style.background='#bbb';toggleWidthEl.style.color='#333';toggleWidthEl.style.padding='0px 3px';toggleWidthEl.style.marginRight='8px';toggleWidthEl.style.display='none';toggleWidthEl.textContent=MIDLINE_HORIZONTAL_ELLIPSIS;toggleWidthEl.addEventListener('click',this.toggleNameColumnWidth_.bind(this));this.nameColumnTitle_.appendChild(toggleWidthEl);return this.nameColumnTitle_;},toggleNameColumnWidth_(opt_event){this.viewState.update({constrainNameColumn:!this.viewState.constrainNameColumn,});if(opt_event!==undefined){opt_event.stopPropagation();opt_event.preventDefault();tr.b.Timing.instant('histogram-set-table','nameColumn'+
+(this.viewState.constrainNameColumn?'Constrained':'Unconstrained'));}},buildColumn_(displayLabel){const title=document.createElement('span');title.textContent=displayLabel;title.style.whiteSpace='pre';return{displayLabel,title,value:row=>row.getCell(displayLabel),cmp:(rowA,rowB)=>rowA.compareCells(rowB,displayLabel),};},async updateContents_(){const previousRowStates=this.viewState.tableRowStates;if(!this.filteredHistograms_){await this.progress_('Filtering rows...');this.filteredHistograms_=this.viewState.showAll?this.histograms:this.sourceHistograms_;if(this.viewState.searchQuery){let query;try{query=new RegExp(this.viewState.searchQuery);}catch(e){}
+if(query!==undefined){this.filteredHistograms_=new tr.v.HistogramSet([...this.filteredHistograms_].filter(hist=>hist.name.match(query)));if(this.filteredHistograms_.length===0&&!this.viewState.showAll){await this.viewState.update({showAll:true});return;}}}
+this.groupedHistograms_=undefined;}
+if(!this.groupedHistograms_){await this.progress_('Grouping Histograms...');this.groupHistograms_();}
+if(!this.hierarchies_){await this.progress_('Merging Histograms...');this.hierarchies_=tr.v.HistogramSetHierarchy.build(this.groupedHistograms_);this.tableRows_=undefined;}
+const tableRowsDirty=this.tableRows_===undefined;if(tableRowsDirty){this.tableRows_=this.hierarchies_.map(hierarchy=>new tr.v.ui.HistogramSetTableRow(hierarchy,this.$.table,this.viewState));tr.b.Timing.instant('histogram-set-table','rootRowCount',this.tableRows_.length);const namesToRowStates=new Map();for(const row of this.tableRows_){namesToRowStates.set(row.name,row.viewState);}
+await this.viewState.update({tableRowStates:namesToRowStates});}
+await this.progress_('Configuring table...');this.nameColumnTitle_.children[1].style.filter=this.viewState.constrainNameColumn?'invert(100%)':'';const referenceDisplayLabelIndex=this.displayLabels_.indexOf(this.viewState.referenceDisplayLabel);this.$.table.selectedTableColumnIndex=(referenceDisplayLabelIndex<0)?undefined:(1+referenceDisplayLabelIndex);this.removeEventListener('sort-column-changed',this.sortColumnChangedListener_);this.$.table.sortColumnIndex=this.viewState.sortColumnIndex;this.$.table.sortDescending=this.viewState.sortDescending;this.addEventListener('sort-column-changed',this.sortColumnChangedListener_);if(tableRowsDirty){await this.progress_('Building DOM...');this.$.table.tableRows=this.tableRows_;for(const row of this.tableRows_){const previousState=previousRowStates.get(row.name);if(!previousState)continue;await row.restoreState(previousState);}}
+this.$.table.rebuild();},async onRowExpandedChanged_(event){event.row.viewState.isExpanded=this.$.table.getExpandedForTableRow(event.row);tr.b.Timing.instant('histogram-set-table','row'+(event.row.viewState.isExpanded?'Expanded':'Collapsed'));if(this.nameColumnTitle_.children[1].style.display==='block')return;await tr.b.animationFrame();this.checkNameColumnOverflow_(event.row.subRows);},checkNameColumnOverflow_(rows){for(const row of rows){if(!row.nameCell.isOverflowing)continue;const[nameSpan,dots]=this.nameColumnTitle_.children;dots.style.display='block';const labelWidthPx=tr.v.ui.NAME_COLUMN_WIDTH_PX-
+dots.getBoundingClientRect().width;nameSpan.style.width=labelWidthPx+'px';return;}},groupHistograms_(){const groupings=this.viewState.groupings.slice();groupings.push(tr.v.HistogramGrouping.DISPLAY_LABEL);function canSkipGrouping(grouping,groupedHistograms){if(groupedHistograms.size>1)return false;if(grouping.key===groupings[0].key)return false;if(grouping.key===tr.v.HistogramGrouping.DISPLAY_LABEL.key){return false;}
+return true;}
+this.groupedHistograms_=this.filteredHistograms_.groupHistogramsRecursively(groupings,canSkipGrouping);this.hierarchies_=undefined;},async onViewStateUpdate_(event){if(this.histograms_===undefined)return;if(event.delta.searchQuery!==undefined||event.delta.showAll!==undefined){this.filteredHistograms_=undefined;}
+if(event.delta.groupings!==undefined){this.groupedHistograms_=undefined;}
+if(event.delta.displayStatistic!==undefined&&this.$.table.sortColumnIndex>0){this.$.table.sortColumnIndex=undefined;}
+if(event.delta.referenceDisplayLabel!==undefined||event.delta.displayStatisticName!==undefined){this.$.table.tableRows=this.$.table.tableRows;}
+if(event.delta.tableRowStates){if(this.tableRows_.length!==this.viewState.tableRowStates.size){throw new Error('Only histogram-set-table may update tableRowStates');}
+for(const row of this.tableRows_){if(this.viewState.tableRowStates.get(row.name)!==row.viewState){throw new Error('Only histogram-set-table may update tableRowStates');}}
+return;}
+await this.updateContents_();},onSortColumnChanged_(event){tr.b.Timing.instant('histogram-set-table','sortColumn');this.viewState.update({sortColumnIndex:event.sortColumnIndex,sortDescending:event.sortDescending,});},onRequestSelectionChange_(event){if(event.selection instanceof tr.model.EventSet)return;event.stopPropagation();tr.b.Timing.instant('histogram-set-table','selectHistogramNames');let histogramNames=event.selection;histogramNames.sort();histogramNames=histogramNames.map(escapeRegExp).join('|');this.viewState.update({showAll:true,searchQuery:`^(${histogramNames})$`,});},get leafHistograms(){const histograms=new tr.v.HistogramSet();for(const row of
+tr.v.ui.HistogramSetTableRow.walkAll(this.$.table.tableRows)){if(row.subRows.length)continue;for(const hist of row.columns.values()){if(!(hist instanceof tr.v.Histogram))continue;histograms.addHistogram(hist);}}
+return histograms;}});return{MIDLINE_HORIZONTAL_ELLIPSIS,};});'use strict';tr.exportTo('tr.v.ui',function(){const PAGE_BREAKDOWN_KEY='pageBreakdown';Polymer({is:'tr-v-ui-metrics-visualization',created(){this.charts_=new Map();},ready(){this.$.start.addEventListener('keydown',(e)=>{if(e.key==='Enter')this.filterByPercentile_();});this.$.end.addEventListener('keydown',(e)=>{if(e.key==='Enter')this.filterByPercentile_();});this.$.search_page.addEventListener('keydown',(e)=>{if(e.key==='Enter')this.searchByPage_();});},build(chartData){this.title_=chartData.title;this.aggregateData_=chartData.aggregate;this.data_=chartData.page;this.submetricsData_=chartData.submetrics;this.benchmarkCount_=chartData.aggregate.length;const aggregateChart=this.initializeColumnChart(this.title_);Polymer.dom(this.$.aggregateContainer).appendChild(aggregateChart);this.charts_.set(tr.v.ui.AGGREGATE_KEY,aggregateChart);this.setChartColors_(tr.v.ui.AGGREGATE_KEY);aggregateChart.data=chartData.aggregate;this.setChartSize_(tr.v.ui.AGGREGATE_KEY);const newChart=this.initializeColumnChart(this.title_+' Breakdown');newChart.enableToolTip=true;newChart.toolTipCallBack=(rect)=>this.openChildChart_(rect);Polymer.dom(this.$.pageByPageContainer).appendChild(newChart);this.charts_.set(PAGE_BREAKDOWN_KEY,newChart);this.setChartColors_(PAGE_BREAKDOWN_KEY);newChart.data=this.data_;this.setChartSize_(PAGE_BREAKDOWN_KEY);},setChartSize_(page){const chart=this.charts_.get(page);const pageCount=chart.data.length;chart.graphHeight=tr.b.math.clamp(pageCount*20,400,600);chart.graphWidth=tr.b.math.clamp(pageCount*30,200,1000);},setChartColors_(page){const chart=this.charts_.get(page);const metrics=tr.v.ui.METRICS.get(this.title_);for(let i=0;i<this.benchmarkCount_;++i){for(let j=0;j<metrics.length;++j){const mainColorIndex=j%tr.v.ui.COLORS.length;const subColorIndex=i%tr.v.ui.COLORS[mainColorIndex].length;const color=tr.v.ui.COLORS[mainColorIndex][subColorIndex];const series=metrics[j]+'-'+this.aggregateData_[i].x;chart.getDataSeries(series).color=color;if(i===0){chart.getDataSeries(series).title=metrics[j];}else{chart.getDataSeries(series).title='';}}}},initializeColumnChart(title){const newChart=new tr.ui.b.NameColumnChart();newChart.hideLegend=false;newChart.isStacked=true;newChart.yAxisLabel='ms';newChart.hideXAxis=true;newChart.displayXInHover=true;newChart.isGrouped=true;newChart.showTitleInLegend=true;newChart.chartTitle=title;newChart.titleHeight='14pt';return newChart;},initializeChildChart_(title,height,width){const div=document.createElement('div');div.classList.add('container');Polymer.dom(this.$.submetricsContainer).insertBefore(div,this.$.submetricsContainer.firstChild);const childChart=new tr.ui.b.NameBarChart();childChart.xAxisLabel='ms';childChart.chartTitle=title;childChart.graphHeight=height;childChart.graphWidth=width;childChart.titleHeight='14pt';childChart.isStacked=true;childChart.hideLegend=true;childChart.isGrouped=true;childChart.isWaterfall=true;div.appendChild(childChart);const button=this.initializeCloseButton_(div,this.$.submetricsContainer);div.appendChild(button);return childChart;},initializeCloseButton_(div,parent){const button=this.$.close.cloneNode(true);button.style.display='inline-block';button.addEventListener('click',()=>{Polymer.dom(parent).removeChild(div);});return button;},openChildChart_(rect){const metrics=tr.v.ui.METRICS.get(this.title_);let metric;let metricIndex;for(let i=0;i<metrics.length;++i){if(rect.key.startsWith(metrics[i])){metric=metrics[i];metricIndex=i;break;}}
+const page=rect.datum.group;const title=this.title_+' '+metric+': '+page;const submetrics=this.submetricsData_.get(page).get(metric);const width=tr.b.math.clamp(submetrics.size*150,300,700);const height=tr.b.math.clamp(submetrics.size*this.benchmarkCount_*50,300,700);const childChart=this.initializeChildChart_(title,height,width);childChart.data=this.processSubmetrics_(childChart,submetrics,0,metricIndex).data;},processSubmetrics_(chart,submetrics,hideValue,metricIndex){const finalData=[];let submetricIndex=0;for(const submetric of submetrics.values()){let benchmarkIndex=0;for(const benchmark of submetric.values()){benchmark.hide=!hideValue?0:hideValue;const series=benchmark.x+'-'+benchmark.group;const mainColorIndex=metricIndex%tr.v.ui.COLORS.length;const subColorIndex=benchmarkIndex%tr.v.ui.COLORS[mainColorIndex].length;chart.getDataSeries(series).color=tr.v.ui.COLORS[mainColorIndex][subColorIndex];if(benchmarkIndex===(this.benchmarkCount_-1)){hideValue+=benchmark[series];}
+finalData.push(benchmark);benchmarkIndex++;}
+submetricIndex++;}
+return{data:finalData,hide:hideValue};},filterByPercentile_(){const startPercentile=this.$.start.value;const endPercentile=this.$.end.value;if(startPercentile===''||endPercentile==='')return;const length=this.data_.length/(this.benchmarkCount_+1);const startIndex=this.getPercentileIndex_(startPercentile,length);const endIndex=this.getPercentileIndex_(endPercentile,length);this.charts_.get(PAGE_BREAKDOWN_KEY).data=this.data_.slice(startIndex,endIndex);},getPercentileIndex_(percentile,arrayLength){const index=Math.ceil(arrayLength*(percentile/100.0));if(index===-1)return 0;if(index>=arrayLength)return arrayLength;return index*this.benchmarkCount_;},searchByPage_(){const criteria=this.$.search_page.value;if(criteria==='')return;const query=new RegExp(criteria);const filteredData=[...this.data_].filter(group=>{if(group.group)return group.group.match(query);return false;});if(filteredData.length<1){this.$.search_error.style.display='block';return;}
+const page=filteredData[0].group;const title=this.title_+' Breakdown: '+page;const metricToSubmetricMap=this.submetricsData_.get(page);let totalSubmetrics=0;for(const submetrics of metricToSubmetricMap.values()){for(const benchmark of submetrics.values()){totalSubmetrics+=benchmark.length;}}
+const width=tr.b.math.clamp(totalSubmetrics*150,300,700);const height=tr.b.math.clamp(totalSubmetrics*this.benchmarkCount_*30,300,700);const childChart=this.initializeChildChart_(title,height,width);const childData=[];let hide=0;let metricIndex=0;for(const submetrics of metricToSubmetricMap.values()){const submetricsData=this.processSubmetrics_(childChart,submetrics,hide,metricIndex);childData.push(...submetricsData.data);hide=submetricsData.hide;metricIndex++;}
+childChart.data=childData;},});});'use strict';Polymer({is:'tr-v-ui-raster-visualization',ready(){this.$.pageSelector.addEventListener('click',()=>{this.selectPage_();});this.$.search_page.addEventListener('keydown',(e)=>{if(e.key==='Enter')this.searchByPage_();});this.$.search_button.addEventListener('click',()=>{this.searchByPage_();});},build(chartData){this.data_=chartData;const aggregateChart=this.createChart_('Aggregate Data by Run');Polymer.dom(this.$.aggregateContainer).appendChild(aggregateChart);aggregateChart.enableToolTip=true;aggregateChart.toolTipCallBack=(rect)=>this.openBenchmarkChart_(rect);this.setChartColors_(aggregateChart,this.data_.get(tr.v.ui.AGGREGATE_KEY));aggregateChart.data=this.data_.get(tr.v.ui.AGGREGATE_KEY);this.setChartSize_(aggregateChart,this.data_.get(tr.v.ui.AGGREGATE_KEY).length);for(const page of this.data_.keys()){if(page===tr.v.ui.AGGREGATE_KEY)continue;const option=document.createElement('option');option.textContent=page;option.value=page;this.$.pageSelector.appendChild(option);}},setChartSize_(chart,pageCount,dataLength){chart.graphHeight=tr.b.math.clamp(pageCount*25,175,1000);chart.graphWidth=tr.b.math.clamp(pageCount*25,500,1000);},setChartColors_(chart,data){const metrics=new Map();let count=0;for(const thread of tr.v.ui.FRAME.values()){for(const metric of thread.keys()){metrics.set(metric,count);count++;}}
+for(let i=0;i<Math.floor(data.length/tr.v.ui.FRAME.length);++i){let j=0;for(const[threadName,thread]of tr.v.ui.FRAME.entries()){for(const metric of thread.keys()){let color='transparent';if(thread.get(metric)){const mainColorIndex=metrics.get(metric)%tr.v.ui.COLORS.length;const subColorIndex=i%tr.v.ui.COLORS[mainColorIndex].length;color=tr.v.ui.COLORS[mainColorIndex][subColorIndex];}
+const series=metric+'-'+data[i*2+j].x+'-'+threadName;chart.getDataSeries(series).color=color;chart.getDataSeries(series).title=!i?metric:'';}
+j++;}}},createChart_(title){const newChart=new tr.ui.b.NameBarChart();newChart.chartTitle=title;newChart.xAxisLabel='ms';newChart.hideLegend=false;newChart.showTitleInLegend=true;newChart.hideYAxis=true;newChart.isStacked=true;newChart.displayXInHover=true;newChart.isGrouped=true;return newChart;},openBenchmarkChart_(rect){const benchmarkIndex=Math.floor(rect.index/tr.v.ui.FRAME.length);const title=rect.datum.x;const div=document.createElement('div');Polymer.dom(this.$.pageContainer).insertBefore(div,this.$.pageContainer.firstChild);const chart=this.createChart_(title);div.appendChild(chart);const button=this.initializeCloseButton_(div,this.$.pageContainer);div.appendChild(button);const newDataSet=[];for(const page of this.data_.keys()){if(page===tr.v.ui.AGGREGATE_KEY)continue;for(let i=0;i<tr.v.ui.FRAME.length;i++){newDataSet.push(this.data_.get(page)[benchmarkIndex*tr.v.ui.FRAME.length+i]);}}
+this.setChartColors_(chart,newDataSet);chart.data=newDataSet;this.setChartSize_(chart,newDataSet.length);},selectPage_(){const div=document.createElement('div');const page=this.$.pageSelector.value;if(page==='')return;Polymer.dom(this.$.pageContainer).insertBefore(div,this.$.pageContainer.firstChild);const pageChart=this.createChart_(page);div.appendChild(pageChart);const button=this.initializeCloseButton_(div,this.$.pageContainer);div.appendChild(button);const pageData=this.data_.get(page);this.setChartColors_(pageChart,pageData);pageChart.data=pageData;this.setChartSize_(pageChart,pageData.length);},searchByPage_(){const criteria=this.$.search_page.value;if(criteria==='')return;const query=new RegExp(criteria);const filteredData=[...this.data_.keys()].filter(page=>page.match(query));if(filteredData.length<1){this.$.search_error.style.display='block';return;}
+const page=filteredData[0];const div=document.createElement('div');Polymer.dom(this.$.pageContainer).insertBefore(div,this.$.pageContainer.firstChild);const pageChart=this.createChart_(page);div.appendChild(pageChart);const button=this.initializeCloseButton_(div,this.$.pageContainer);div.appendChild(button);const pageData=this.data_.get(page);this.setChartColors_(pageChart,pageData);pageChart.data=pageData;this.setChartSize_(pageChart,pageData.length);},initializeCloseButton_(div,parent){const button=this.$.close.cloneNode(true);button.style.display='inline-block';button.addEventListener('click',()=>{Polymer.dom(parent).removeChild(div);});return button;},});'use strict';tr.exportTo('tr.v.ui',function(){const STATISTICS_KEY='statistics';const SUBMETRICS_KEY='submetrics';const AGGREGATE_KEY='aggregate';const RASTER_START_METRIC_KEY='pipeline:begin_frame_to_raster_start';const COLORS=[['#FFD740','#FFC400','#FFAB00','#E29800'],['#FF6E40','#FF3D00','#DD2C00','#A32000'],['#40C4FF','#00B0FF','#0091EA','#006DAF'],['#89C641','#54B503','#4AA510','#377A0D'],['#B388FF','#7C4DFF','#651FFF','#6200EA'],['#FF80AB','#FF4081','#F50057','#C51162'],['#FFAB40','#FF9100','#FF6D00','#D65C02'],['#8C9EFF','#536DFE','#3D5AFE','#304FFE']];const FRAME=[new Map([['pipeline:begin_frame_to_raster_start',false],['pipeline:begin_frame_to_raster_end',true]]),new Map([['pipeline:begin_frame_transport',true],['pipeline:begin_frame_to_frame_submission',true],['pipeline:frame_submission_to_display',true],['pipeline:draw',true]])];const METRICS=new Map([['Pipeline',['pipeline:begin_frame_transport','pipeline:begin_frame_to_frame_submission','pipeline:frame_submission_to_display','pipeline:draw']],['Thread',['thread_browser_cpu_time_per_frame','thread_display_compositor_cpu_time_per_frame','thread_GPU_cpu_time_per_frame','thread_IO_cpu_time_per_frame','thread_other_cpu_time_per_frame','thread_raster_cpu_time_per_frame','thread_renderer_compositor_cpu_time_per_frame','thread_renderer_main_cpu_time_per_frame']]]);function getValueFromMap(key,map){let retrievedValue=map.get(key);if(!retrievedValue){retrievedValue=new Map();map.set(key,retrievedValue);}
+return retrievedValue;}
+Polymer({is:'tr-v-ui-visualizations-data-container',created(){this.orderedBenchmarks_=[];this.groupedData_=new Map();},build(leafHistograms,histograms){if(!leafHistograms||leafHistograms.length<1||!histograms||histograms.length<1){this.$.data_error.style.display='block';return;}
+this.processHistograms_(this.groupHistograms_(histograms),this.groupHistograms_(leafHistograms));this.buildCharts_();},processHistograms_(histograms,leafHistograms){const benchmarkStartGrouping=tr.v.HistogramGrouping.BY_KEY.get(tr.v.d.RESERVED_NAMES.BENCHMARK_START);const benchmarkToStartTime=new Map();for(const[metric,benchmarks]of histograms.entries()){for(const[benchmark,pages]of leafHistograms.get(metric).entries()){for(const[page,histograms]of pages.entries()){for(const histogram of histograms){const aggregateToBenchmarkMap=getValueFromMap(AGGREGATE_KEY,this.groupedData_);const benchmarkToMetricMap=getValueFromMap(benchmark,aggregateToBenchmarkMap);benchmarkToMetricMap.set(metric,new Map([[STATISTICS_KEY,histogram.running]]));}}}
+for(const[benchmark,pages]of benchmarks.entries()){for(const[page,histograms]of pages.entries()){for(const histogram of histograms){if(!benchmarkToStartTime.get(benchmark)){benchmarkToStartTime.set(benchmark,benchmarkStartGrouping.callback(histogram));}
+const pageToBenchmarkMap=getValueFromMap(page,this.groupedData_);const benchmarkToMetricMap=getValueFromMap(benchmark,pageToBenchmarkMap);const mergedSubmetrics=new tr.v.d.DiagnosticMap();for(const bin of histogram.allBins){for(const map of bin.diagnosticMaps){mergedSubmetrics.addDiagnostics(map);}}
+if(benchmarkToMetricMap.get(metric))continue;benchmarkToMetricMap.set(metric,new Map([[STATISTICS_KEY,histogram.running],[SUBMETRICS_KEY,mergedSubmetrics.get('breakdown')]]));}}}}
+this.orderedBenchmarks_=this.sortBenchmarks_(benchmarkToStartTime);},groupHistograms_(histograms){const groupings=[tr.v.HistogramGrouping.HISTOGRAM_NAME,tr.v.HistogramGrouping.DISPLAY_LABEL,tr.v.HistogramGrouping.BY_KEY.get(tr.v.d.RESERVED_NAMES.STORIES)];return histograms.groupHistogramsRecursively(groupings);},sortBenchmarks_(benchmarks){return Array.from(benchmarks.keys()).sort((a,b)=>{Date.parse(benchmarks.get(a))-Date.parse(benchmarks.get(b));});},getSeriesKey_(metric,benchmark){return metric+'-'+benchmark;},buildCharts_(){const rasterDataToBePassed=this.buildRasterChart_();this.$.rasterVisualization.build(rasterDataToBePassed);for(const chartName of METRICS.keys()){const metricsDataToBePassed=this.buildMetricsData_(chartName);const newChart=this.$.metricsVisualization.cloneNode(true);newChart.style.display='block';Polymer.dom(this.$.metrics_container).appendChild(newChart);newChart.build(metricsDataToBePassed);}},buildRasterChart_(){const orderedPages=[...this.groupedData_.keys()].filter((page)=>this.filterPagesWithoutRasterMetric_(page)).sort((a,b)=>this.sortByRasterStart_(a,b));const allChartData=new Map();for(const page of orderedPages){const pageMap=this.groupedData_.get(page);let chartData=[];for(const benchmark of this.orderedBenchmarks_){if(!pageMap.has(benchmark))continue;const benchmarkMap=pageMap.get(benchmark);const benchmarkData=[];if(benchmarkMap.get(RASTER_START_METRIC_KEY)===undefined){continue;}
+for(const[threadName,thread]of FRAME.entries()){const data={x:benchmark,hide:0};if(page!==AGGREGATE_KEY)data.group=page;let rasterBegin=0;for(const metric of thread.keys()){const metricMap=benchmarkMap.get(metric);const key=this.getSeriesKey_(metric,data.x+'-'+threadName);const stats=metricMap.get(STATISTICS_KEY);const mean=stats?stats.mean:0;let roundedMean=Math.round(mean*100)/100;if(metric===RASTER_START_METRIC_KEY){rasterBegin=roundedMean;}else if(metric==='pipeline:begin_frame_to_raster_end'){roundedMean-=rasterBegin;}
+data[key]=roundedMean;}
+benchmarkData.push(data);}
+chartData=chartData.concat(benchmarkData);}
+allChartData.set(page,chartData);}
+return allChartData;},buildMetricsData_(chartName){const orderedPages=[...this.groupedData_.keys()].sort((a,b)=>this.sortByTotal_(a,b,chartName));const chartData=[];const aggregateChart=[];for(const page of orderedPages){const pageMap=this.groupedData_.get(page);for(const benchmark of this.orderedBenchmarks_){if(!pageMap.has(benchmark))continue;const data={x:benchmark,group:page};const benchmarkMap=pageMap.get(benchmark);for(const metric of METRICS.get(chartName)){const metricMap=benchmarkMap.get(metric);const key=this.getSeriesKey_(metric,benchmark);const stats=metricMap.get(STATISTICS_KEY);const mean=stats?stats.mean:0;data[key]=Math.round(mean*100)/100;}
+if(page===AGGREGATE_KEY){aggregateChart.push(data);}else{chartData.push(data);}}
+chartData.push({});}
+chartData.shift();return{title:chartName,aggregate:aggregateChart,page:chartData,submetrics:this.processSubmetricsData_(chartName)};},submetricsHelper_(submetric,value,benchmark,metricToSubmetricMap){let submetricToBenchmarkMap=metricToSubmetricMap.get(submetric);if(!submetricToBenchmarkMap){submetricToBenchmarkMap=[];metricToSubmetricMap.set(submetric,submetricToBenchmarkMap);}
+const data={x:submetric,hide:0,group:benchmark};const mean=value;const roundedMean=Math.round(mean*100)/100;if(!roundedMean)return;data[this.getSeriesKey_(submetric,benchmark)]=roundedMean;submetricToBenchmarkMap.push(data);},processSubmetricsData_(chartName){const submetrics=new Map();for(const[page,pageMap]of this.groupedData_.entries()){if(page===AGGREGATE_KEY)continue;const pageToMetricMap=getValueFromMap(page,submetrics);for(const benchmark of this.orderedBenchmarks_){const benchmarkMap=pageMap.get(benchmark);if(!benchmarkMap)continue;for(const metric of METRICS.get(chartName)){const metricMap=benchmarkMap.get(metric);const metricToSubmetricMap=getValueFromMap(metric,pageToMetricMap);const submetrics=metricMap.get(SUBMETRICS_KEY);if(!submetrics){this.submetricsHelper_(metric,metricMap.get(STATISTICS_KEY),benchmark,metricToSubmetricMap);continue;}
+for(const[submetric,value]of[...submetrics]){this.submetricsHelper_(submetric,value,benchmark,metricToSubmetricMap);}}}}
+return submetrics;},sortByTotal_(a,b,chartName){if(a===AGGREGATE_KEY)return-1;if(b===AGGREGATE_KEY)return 1;let aValue=0;const aMap=this.groupedData_.get(a);if(aMap.get(this.orderedBenchmarks_[0])!==undefined){for(const metric of METRICS.get(chartName)){const aMetricMap=aMap.get(this.orderedBenchmarks_[0]).get(metric);const aStats=aMetricMap.get(STATISTICS_KEY);aValue+=aStats?aStats.mean:0;}}
+let bValue=0;const bMap=this.groupedData_.get(b);if(bMap.get(this.orderedBenchmarks_[0])!==undefined){for(const metric of METRICS.get(chartName)){const bMetricMap=bMap.get(this.orderedBenchmarks_[0]).get(metric);const bStats=bMetricMap.get(STATISTICS_KEY);bValue+=bStats?bStats.mean:0;}}
+return aValue-bValue;},filterPagesWithoutRasterMetric_(page){const pageMap=this.groupedData_.get(page);for(const benchmark of this.orderedBenchmarks_){const pageMetricMap=pageMap.get(benchmark);if(!pageMetricMap)continue;const wantedMetric=pageMetricMap.get(RASTER_START_METRIC_KEY);if(wantedMetric!==undefined)return true;}
+return false;},sortByRasterStart_(a,b){if(a===AGGREGATE_KEY)return 1;if(b===AGGREGATE_KEY)return-1;let aValue=0;const aMap=this.groupedData_.get(a);if(aMap.get(this.orderedBenchmarks_[0])!==undefined){const aMetricMap=aMap.get(this.orderedBenchmarks_[0]).get(RASTER_START_METRIC_KEY);const aStats=aMetricMap.get(STATISTICS_KEY);aValue=aStats?aStats.mean:0;}
+let bValue=0;const bMap=this.groupedData_.get(b);if(bMap.get(this.orderedBenchmarks_[0])!==undefined){const bMetricMap=bMap.get(this.orderedBenchmarks_[0]).get(RASTER_START_METRIC_KEY);const bStats=bMetricMap.get(STATISTICS_KEY);bValue=bStats?bStats.mean:0;}
+return bValue-aValue;},});return{STATISTICS_KEY,SUBMETRICS_KEY,AGGREGATE_KEY,COLORS,FRAME,METRICS,getValueFromMap,};});'use strict';tr.exportTo('tr.v.ui',function(){Polymer({is:'tr-v-ui-histogram-set-view',listeners:{export:'onExport_',loadVisualization:'onLoadVisualization_'},created(){this.brushingStateController_=new tr.ui.NullBrushingStateController();this.viewState_=new tr.v.ui.HistogramSetViewState();this.visualizationLoaded_=false;},ready(){this.$.table.viewState=this.viewState;this.$.controls.viewState=this.viewState;},attached(){this.brushingStateController.parentController=tr.c.BrushingStateController.getControllerForElement(this.parentNode);},get brushingStateController(){return this.brushingStateController_;},get viewState(){return this.viewState_;},get histograms(){return this.$.table.histograms;},async build(histograms,opt_options){const options=opt_options||{};const progress=options.progress||(()=>Promise.resolve());if(options.helpHref)this.$.controls.helpHref=options.helpHref;if(options.feedbackHref){this.$.controls.feedbackHref=options.feedbackHref;}
+if(histograms===undefined||histograms.length===0){this.$.container.style.display='none';this.$.zero.style.display='block';this.style.display='block';return;}
+this.$.zero.style.display='none';this.$.container.style.display='block';this.$.container.style.maxHeight=(window.innerHeight-16)+'px';const buildMark=tr.b.Timing.mark('histogram-set-view','build');await progress('Finding important Histograms...');const sourceHistogramsMark=tr.b.Timing.mark('histogram-set-view','sourceHistograms');const sourceHistograms=histograms.sourceHistograms;sourceHistogramsMark.end();this.$.controls.showAllEnabled=(sourceHistograms.length!==histograms.length);await progress('Collecting parameters...');const collectParametersMark=tr.b.Timing.mark('histogram-set-view','collectParameters');const parameterCollector=new tr.v.HistogramParameterCollector();parameterCollector.process(histograms);this.$.controls.baseStatisticNames=parameterCollector.statisticNames;this.$.controls.possibleGroupings=parameterCollector.possibleGroupings;const displayLabels=parameterCollector.labels;this.$.controls.displayLabels=displayLabels;collectParametersMark.end();const hist=[...histograms][0];const benchmarks=hist.diagnostics.get(tr.v.d.RESERVED_NAMES.BENCHMARKS);let enable=false;if(benchmarks!==undefined&&benchmarks.length>0){for(const benchmark of benchmarks){if(benchmark.includes('rendering')){enable=true;break;}}}
+this.$.controls.enableVisualization=enable;await this.$.table.build(histograms,sourceHistograms,displayLabels,progress);buildMark.end();},onExport_(event){const mark=tr.b.Timing.mark('histogram-set-view','export'+
+(event.merged?'Merged':'Raw')+event.format.toUpperCase());const histograms=event.merged?this.$.table.leafHistograms:this.histograms;let blob;if(event.format==='csv'){const csv=new tr.v.CSVBuilder(histograms);csv.build();blob=new window.Blob([csv.toString()],{type:'text/csv'});}else if(event.format==='json'){blob=new window.Blob([JSON.stringify(histograms.asDicts())],{type:'text/json'});}else{throw new Error(`Unable to export format "${event.format}"`);}
+const path=window.location.pathname.split('/');const basename=path[path.length-1].split('.')[0]||'histograms';const anchor=document.createElement('a');anchor.download=`${basename}.${event.format}`;anchor.href=window.URL.createObjectURL(blob);anchor.click();mark.end();},onLoadVisualization_(event){if(!this.visualizationLoaded_){this.$.visualizations.style.display='block';this.$.visualizations.build(this.$.table.leafHistograms,this.histograms);this.visualizationLoaded_=true;}else if(this.$.visualizations.style.display==='none'){this.$.visualizations.style.display='block';}else{this.$.visualizations.style.display='none';}},});return{};});'use strict';tr.exportTo('tr.ui',function(){Polymer({is:'tr-ui-sp-metrics-side-panel',behaviors:[tr.ui.behaviors.SidePanel],ready(){this.model_=undefined;this.rangeOfInterest_=undefined;this.metricLatenciesMs_=[];this.metrics_=[];tr.metrics.MetricRegistry.getAllRegisteredTypeInfos().forEach(function(m){if(m.constructor.name==='sampleMetric')return;this.metrics_.push({label:m.constructor.name,value:m.constructor.name});},this);this.metrics_.sort((x,y)=>x.label.localeCompare(y.label));this.settingsKey_='metrics-side-panel-metric-name';this.currentMetricName_='responsivenessMetric';const metricSelector=tr.ui.b.createSelector(this,'currentMetricName_',this.settingsKey_,this.currentMetricName_,this.metrics_);Polymer.dom(this.$.top_left_controls).appendChild(metricSelector);metricSelector.addEventListener('change',this.onMetricChange_.bind(this));this.currentMetricTypeInfo_=tr.metrics.MetricRegistry.findTypeInfoWithName(this.currentMetricName_);this.recomputeButton_=tr.ui.b.createButton('Recompute',this.onRecompute_,this);Polymer.dom(this.$.top_left_controls).appendChild(this.recomputeButton_);this.$.results.addEventListener('display-ready',()=>{this.$.results.style.display='';});},async build(model){this.model_=model;await this.updateContents_();},get metricLatencyMs(){return tr.b.math.Statistics.mean(this.metricLatenciesMs_);},onMetricChange_(){this.currentMetricTypeInfo_=tr.metrics.MetricRegistry.findTypeInfoWithName(this.currentMetricName_);this.metricLatenciesMs_=[];this.updateContents_();},onRecompute_(){this.updateContents_();},get textLabel(){return'Metrics';},supportsModel(m){if(!m){return{supported:false,reason:'No model available'};}
+return{supported:true};},get model(){return this.model_;},set model(model){this.build(model);},get selection(){},set selection(_){},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(range){this.rangeOfInterest_=range;if(this.currentMetricTypeInfo_&&this.currentMetricTypeInfo_.metadata.supportsRangeOfInterest){if((this.metricLatencyMs===undefined)||(this.metricLatencyMs<100)){this.updateContents_();}else{this.recomputeButton_.style.background='red';}}},async updateContents_(){Polymer.dom(this.$.error).textContent='';this.$.results.style.display='none';if(!this.model_){Polymer.dom(this.$.error).textContent='Missing model';return;}
+const options={metrics:[this.currentMetricName_]};if(this.currentMetricTypeInfo_&&this.currentMetricTypeInfo_.metadata.supportsRangeOfInterest&&this.rangeOfInterest&&!this.rangeOfInterest.isEmpty){options.rangeOfInterest=this.rangeOfInterest;}
+const startDate=new Date();const addFailureCb=failure=>{Polymer.dom(this.$.error).textContent=failure.description;};const histograms=tr.metrics.runMetrics(this.model_,options,addFailureCb);this.metricLatenciesMs_.push(new Date()-startDate);while(this.metricLatenciesMs_.length>20){this.metricLatenciesMs_.shift();}
+this.recomputeButton_.style.background='';await this.$.results.build(histograms);}});tr.ui.side_panel.SidePanelRegistry.register(function(){return document.createElement('tr-ui-sp-metrics-side-panel');});return{};});'use strict';Polymer({is:'tr-ui-e-s-alerts-side-panel',behaviors:[tr.ui.behaviors.SidePanel],ready(){this.rangeOfInterest_=new tr.b.math.Range();this.selection_=undefined;},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();},set selection(selection){},set rangeOfInterest(rangeOfInterest){},selectAlertsOfType(alertTypeString){const alertsOfType=this.model_.alerts.filter(function(alert){return alert.title===alertTypeString;});const event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(alertsOfType);this.dispatchEvent(event);},alertsByType_(alerts){const alertsByType={};alerts.forEach(function(alert){if(!alertsByType[alert.title]){alertsByType[alert.title]=[];}
+alertsByType[alert.title].push(alert);});return alertsByType;},alertsTableRows_(alertsByType){return Object.keys(alertsByType).map(function(key){return{alertType:key,count:alertsByType[key].length};});},alertsTableColumns_(){return[{title:'Alert type',value(row){return row.alertType;},width:'180px'},{title:'Count',width:'100%',value(row){return row.count;}}];},createAlertsTable_(alerts){const alertsByType=this.alertsByType_(alerts);const table=document.createElement('tr-ui-b-table');table.tableColumns=this.alertsTableColumns_();table.tableRows=this.alertsTableRows_(alertsByType);table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;table.addEventListener('selection-changed',function(e){const row=table.selectedTableRow;if(row){this.selectAlertsOfType(row.alertType);}}.bind(this));return table;},updateContents_(){Polymer.dom(this.$.result_area).textContent='';if(this.model_===undefined)return;const panel=this.createAlertsTable_(this.model_.alerts);Polymer.dom(this.$.result_area).appendChild(panel);},supportsModel(m){if(m===undefined){return{supported:false,reason:'Unknown tracing model'};}else if(m.alerts.length===0){return{supported:false,reason:'No alerts in tracing model'};}
+return{supported:true};},get textLabel(){return'Alerts';}});tr.ui.side_panel.SidePanelRegistry.register(function(){return document.createElement('tr-ui-e-s-alerts-side-panel');});
 </script>
 </head>
   <body>
diff --git a/runtime/platform/utils_macos.cc b/runtime/platform/utils_macos.cc
index eaab319..0c4762c 100644
--- a/runtime/platform/utils_macos.cc
+++ b/runtime/platform/utils_macos.cc
@@ -7,6 +7,9 @@
 
 #include "platform/utils.h"
 
+#include <errno.h>        // NOLINT
+#include <sys/utsname.h>  // NOLINT
+
 namespace dart {
 
 char* Utils::StrNDup(const char* s, intptr_t n) {
@@ -64,6 +67,76 @@
   return retval;
 }
 
+namespace internal {
+
+// Returns the running system's Darwin major version. Don't call this, it's
+// an implementation detail and its result is meant to be cached by
+// MacOSXMinorVersion.
+int32_t DarwinMajorVersionInternal() {
+  // uname is implemented as a simple series of sysctl system calls to
+  // obtain the relevant data from the kernel. The data is
+  // compiled right into the kernel, so no threads or blocking or other
+  // funny business is necessary.
+
+  struct utsname uname_info;
+  if (uname(&uname_info) != 0) {
+    FATAL("Fatal error in DarwinMajorVersionInternal : invalid return uname");
+    return 0;
+  }
+
+  if (strcmp(uname_info.sysname, "Darwin") != 0) {
+    FATAL1(
+        "Fatal error in DarwinMajorVersionInternal : unexpected uname"
+        " sysname '%s'",
+        uname_info.sysname);
+    return 0;
+  }
+
+  int32_t darwin_major_version = 0;
+  char* dot = strchr(uname_info.release, '.');
+  if (dot) {
+    errno = 0;
+    char* end_ptr = NULL;
+    darwin_major_version = strtol(uname_info.release, &end_ptr, 10);
+    if (errno != 0 || (end_ptr == uname_info.release)) {
+      dot = NULL;
+    }
+  }
+
+  if (!dot) {
+    FATAL1(
+        "Fatal error in DarwinMajorVersionInternal :"
+        " could not parse uname release '%s'",
+        uname_info.release);
+    return 0;
+  }
+
+  return darwin_major_version;
+}
+
+// Returns the running system's Mac OS X minor version. This is the |y| value
+// in 10.y or 10.y.z. Don't call this, it's an implementation detail and the
+// result is meant to be cached by MacOSXMinorVersion.
+int32_t MacOSXMinorVersionInternal() {
+  int darwin_major_version = DarwinMajorVersionInternal();
+
+  // The Darwin major version is always 4 greater than the Mac OS X minor
+  // version for Darwin versions beginning with 6, corresponding to Mac OS X
+  // 10.2. Since this correspondence may change in the future, warn when
+  // encountering a version higher than anything seen before. Older Darwin
+  // versions, or versions that can't be determined, result in
+  // immediate death.
+  ASSERT(darwin_major_version >= 6);
+  return (darwin_major_version - 4);
+}
+
+int32_t MacOSXMinorVersion() {
+  static int mac_os_x_minor_version = MacOSXMinorVersionInternal();
+  return mac_os_x_minor_version;
+}
+
+}  // namespace internal
+
 }  // namespace dart
 
 #endif  // defined(HOST_OS_MACOS)
diff --git a/runtime/platform/utils_macos.h b/runtime/platform/utils_macos.h
index 052352d..bc34193 100644
--- a/runtime/platform/utils_macos.h
+++ b/runtime/platform/utils_macos.h
@@ -5,10 +5,71 @@
 #ifndef RUNTIME_PLATFORM_UTILS_MACOS_H_
 #define RUNTIME_PLATFORM_UTILS_MACOS_H_
 
+#include <AvailabilityMacros.h>
 #include <libkern/OSByteOrder.h>  // NOLINT
 
 namespace dart {
 
+namespace internal {
+
+// Returns the system's Mac OS X minor version. This is the |y| value
+// in 10.y or 10.y.z.
+int32_t MacOSXMinorVersion();
+
+}  // namespace internal
+
+// Run-time OS version checks.
+#define DEFINE_IS_OS_FUNCS(V, TEST_DEPLOYMENT_TARGET)                          \
+  inline bool IsOS10_##V() {                                                   \
+    TEST_DEPLOYMENT_TARGET(>, V, false)                                        \
+    return internal::MacOSXMinorVersion() == V;                                \
+  }                                                                            \
+  inline bool IsAtLeastOS10_##V() {                                            \
+    TEST_DEPLOYMENT_TARGET(>=, V, true)                                        \
+    return internal::MacOSXMinorVersion() >= V;                                \
+  }                                                                            \
+  inline bool IsAtMostOS10_##V() {                                             \
+    TEST_DEPLOYMENT_TARGET(>, V, false)                                        \
+    return internal::MacOSXMinorVersion() <= V;                                \
+  }
+
+#define TEST_DEPLOYMENT_TARGET(OP, V, RET)                                     \
+  if (MAC_OS_X_VERSION_MIN_REQUIRED OP MAC_OS_X_VERSION_10_##V) return RET;
+#define IGNORE_DEPLOYMENT_TARGET(OP, V, RET)
+
+DEFINE_IS_OS_FUNCS(9, TEST_DEPLOYMENT_TARGET)
+DEFINE_IS_OS_FUNCS(10, TEST_DEPLOYMENT_TARGET)
+
+#ifdef MAC_OS_X_VERSION_10_11
+DEFINE_IS_OS_FUNCS(11, TEST_DEPLOYMENT_TARGET)
+#else
+DEFINE_IS_OS_FUNCS(11, IGNORE_DEPLOYMENT_TARGET)
+#endif
+
+#ifdef MAC_OS_X_VERSION_10_12
+DEFINE_IS_OS_FUNCS(12, TEST_DEPLOYMENT_TARGET)
+#else
+DEFINE_IS_OS_FUNCS(12, IGNORE_DEPLOYMENT_TARGET)
+#endif
+
+#ifdef MAC_OS_X_VERSION_10_13
+DEFINE_IS_OS_FUNCS(13, TEST_DEPLOYMENT_TARGET)
+#else
+DEFINE_IS_OS_FUNCS(13, IGNORE_DEPLOYMENT_TARGET)
+#endif
+
+#ifdef MAC_OS_X_VERSION_10_14
+DEFINE_IS_OS_FUNCS(14, TEST_DEPLOYMENT_TARGET)
+#else
+DEFINE_IS_OS_FUNCS(14, IGNORE_DEPLOYMENT_TARGET)
+#endif
+
+#ifdef MAC_OS_X_VERSION_10_15
+DEFINE_IS_OS_FUNCS(15, TEST_DEPLOYMENT_TARGET)
+#else
+DEFINE_IS_OS_FUNCS(15, IGNORE_DEPLOYMENT_TARGET)
+#endif
+
 inline int Utils::CountLeadingZeros(uword x) {
 #if defined(ARCH_IS_32_BIT)
   return __builtin_clzl(x);
diff --git a/runtime/tests/vm/dart/stacktrace_mixin_application_test.dart b/runtime/tests/vm/dart/stacktrace_mixin_application_test.dart
new file mode 100644
index 0000000..04371a3
--- /dev/null
+++ b/runtime/tests/vm/dart/stacktrace_mixin_application_test.dart
@@ -0,0 +1,28 @@
+// 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.
+import "package:expect/expect.dart";
+
+mixin Bar {
+  bar() => throw "bar";
+}
+
+mixin Baz {}
+
+class Foo with Baz, Bar {}
+
+main() {
+  final foo = Foo();
+  try {
+    foo.bar();
+  } catch (e, st) {
+    final stack = st.toString();
+    // Check that stack frames for methods defined in a mixin Bar actually show
+    // only the mixin name rather than some combination of the name of the class
+    // that mixed in Bar along with other mixin names.
+    //
+    // Prior to the fix for issue #36999, this frame would have been named
+    // Foo&Baz&Bar.bar rather than simply Bar.bar.
+    Expect.isTrue(stack.contains('#0      Bar.bar'));
+  }
+}
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index d26ca4f..da4d33f 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -30,9 +30,6 @@
 dart/redirection_type_shuffling_test/none: RuntimeError
 dart/snapshot_version_test: RuntimeError
 
-[ $compiler == dartkb ]
-cc/*: Skip # Too many timeouts and crashes for infrastructure to handle.
-
 [ $compiler == dartkp ]
 dart/v8_snapshot_profile_writer_test: Pass, Slow # Can be slow due to re-invoking the precompiler.
 
diff --git a/runtime/tools/dartfuzz/README.md b/runtime/tools/dartfuzz/README.md
index 9fe338d..0002b65 100644
--- a/runtime/tools/dartfuzz/README.md
+++ b/runtime/tools/dartfuzz/README.md
@@ -16,9 +16,10 @@
 
 where
 
-    --help    : prints help and exits
-    --seed    : defines random seed (system-set by default)
-    --[no-]fp : enables/disables floating-point operations
+    --help     : prints help and exits
+    --seed     : defines random seed (system-set by default)
+    --[no-]fp  : enables/disables floating-point operations (default: on)
+    --[no-]ffi : enables/disables FFI method calls (default: off)
 
 The tool provides a runnable main isolate. A typical single
 test run looks as:
diff --git a/runtime/tools/dartfuzz/dartfuzz.dart b/runtime/tools/dartfuzz/dartfuzz.dart
index 9af812a..73797d4 100644
--- a/runtime/tools/dartfuzz/dartfuzz.dart
+++ b/runtime/tools/dartfuzz/dartfuzz.dart
@@ -13,7 +13,7 @@
 // Version of DartFuzz. Increase this each time changes are made
 // to preserve the property that a given version of DartFuzz yields
 // the same fuzzed program for a deterministic random seed.
-const String version = '1.16';
+const String version = '1.19';
 
 // Restriction on statements and expressions.
 const int stmtLength = 2;
@@ -29,7 +29,7 @@
 
 /// Class that generates a random, but runnable Dart program for fuzz testing.
 class DartFuzz {
-  DartFuzz(this.seed, this.fp, this.file);
+  DartFuzz(this.seed, this.fp, this.ffi, this.file);
 
   void run() {
     // Initialize program variables.
@@ -40,15 +40,28 @@
     currentMethod = null;
     // Setup the types.
     localVars = new List<DartType>();
+    iterVars = new List<String>();
     globalVars = fillTypes1();
     globalVars.addAll(DartType.allTypes); // always one each
     globalMethods = fillTypes2();
     classFields = fillTypes2();
     classMethods = fillTypes3(classFields.length);
+    // Setup optional ffi methods and types.
+    List<bool> ffiStatus = new List<bool>();
+    for (var m in globalMethods) {
+      ffiStatus.add(false);
+    }
+    if (ffi) {
+      List<List<DartType>> globalMethodsFfi = fillTypes2(isFfi: true);
+      for (var m in globalMethodsFfi) {
+        globalMethods.add(m);
+        ffiStatus.add(true);
+      }
+    }
     // Generate.
     emitHeader();
     emitVarDecls(varName, globalVars);
-    emitMethods(methodName, globalMethods);
+    emitMethods(methodName, globalMethods, ffiStatus);
     emitClasses();
     emitMain();
     // Sanity.
@@ -66,7 +79,8 @@
   void emitHeader() {
     emitLn('// The Dart Project Fuzz Tester ($version).');
     emitLn('// Program generated as:');
-    emitLn('//   dart dartfuzz.dart --seed $seed --${fp ? "" : "no-"}fp');
+    emitLn('//   dart dartfuzz.dart --seed $seed --${fp ? "" : "no-"}fp ' +
+        '--${ffi ? "" : "no-"}ffi');
     emitLn('');
     emitLn("import 'dart:async';");
     emitLn("import 'dart:cli';");
@@ -77,13 +91,37 @@
     emitLn("import 'dart:isolate';");
     emitLn("import 'dart:math';");
     emitLn("import 'dart:typed_data';");
+    if (ffi) emitLn("import 'dart:ffi' as ffi;");
   }
 
-  void emitMethods(String name, List<List<DartType>> methods) {
+  void emitFfiCast(String dartFuncName, String ffiFuncName, String typeName,
+      List<DartType> pars) {
+    emit("${pars[0].name} Function(");
+    for (int i = 1; i < pars.length; i++) {
+      DartType tp = pars[i];
+      emit('${tp.name}');
+      if (i != (pars.length - 1)) {
+        emit(', ');
+      }
+    }
+    emit(') ${dartFuncName} = ' +
+        'ffi.Pointer.fromFunction<${typeName}>(${ffiFuncName}, ');
+    emitLiteral(0, pars[0]);
+    emitLn(').cast<ffi.NativeFunction<${typeName}>>().asFunction();');
+  }
+
+  void emitMethods(String name, List<List<DartType>> methods,
+      [List<bool> ffiStatus]) {
     for (int i = 0; i < methods.length; i++) {
       List<DartType> method = methods[i];
       currentMethod = i;
-      emitLn('${method[0].name} $name$i(', newline: false);
+      bool isFfiMethod = ffiStatus != null && ffiStatus[i];
+      if (isFfiMethod) {
+        emitFfiTypedef("${name}Ffi${i}Type", method);
+        emitLn('${method[0].name} ${name}Ffi$i(', newline: false);
+      } else {
+        emitLn('${method[0].name} $name$i(', newline: false);
+      }
       emitParDecls(method);
       emit(') {', newline: true);
       indent += 2;
@@ -94,6 +132,10 @@
       assert(localVars.length == 0);
       indent -= 2;
       emitLn('}');
+      if (isFfiMethod) {
+        emitFfiCast(
+            "${name}${i}", "${name}Ffi${i}", "${name}Ffi${i}Type", method);
+      }
       emit('', newline: true);
       currentMethod = null;
     }
@@ -208,7 +250,7 @@
   bool emitAssign() {
     DartType tp = getType();
     emitLn('', newline: false);
-    emitVar(0, tp);
+    emitVar(0, tp, isLhs: true);
     emitAssignOp(tp);
     emitExpr(0, tp);
     emit(';', newline: true);
@@ -282,9 +324,11 @@
     emit('; $localName$i++) {', newline: true);
     indent += 2;
     nest++;
+    iterVars.add("$localName$i");
     localVars.add(DartType.INT);
     emitStatements(depth + 1);
     localVars.removeLast();
+    iterVars.removeLast();
     nest--;
     indent -= 2;
     emitLn('}');
@@ -294,7 +338,7 @@
   // Emit a simple membership for-in-loop.
   bool emitForIn(int depth) {
     int i = localVars.length;
-    emitLn('for (var $localName$i in ', newline: false);
+    emitLn('for (int $localName$i in ', newline: false);
     emitExpr(0, rand.nextBool() ? DartType.INT_LIST : DartType.INT_SET);
     emit(') {', newline: true);
     indent += 2;
@@ -318,9 +362,11 @@
     emitLn('while (--$localName$i > 0) {');
     indent += 2;
     nest++;
+    iterVars.add("$localName$i");
     localVars.add(DartType.INT);
     emitStatements(depth + 1);
     localVars.removeLast();
+    iterVars.removeLast();
     nest--;
     indent -= 2;
     emitLn('}');
@@ -337,9 +383,11 @@
     emitLn('do {');
     indent += 2;
     nest++;
+    iterVars.add("$localName$i");
     localVars.add(DartType.INT);
     emitStatements(depth + 1);
     localVars.removeLast();
+    iterVars.removeLast();
     nest--;
     indent -= 2;
     emitLn('} while (++$localName$i < ', newline: false);
@@ -642,9 +690,9 @@
     }
   }
 
-  void emitScalarVar(DartType tp) {
+  void emitScalarVar(DartType tp, {bool isLhs = false}) {
     // Collect all choices from globals, fields, locals, and parameters.
-    List<String> choices = new List<String>();
+    Set<String> choices = new Set<String>();
     for (int i = 0; i < globalVars.length; i++) {
       if (tp == globalVars[i]) choices.add('$varName$i');
     }
@@ -663,34 +711,44 @@
         if (tp == proto[i]) choices.add('$paramName$i');
       }
     }
+    // Remove possible modification of the iteration variable from the loop
+    // body.
+    if (isLhs) {
+      if (rand.nextInt(10) != 0) {
+        Set<String> cleanChoices = choices.difference(Set.from(iterVars));
+        if (cleanChoices.length > 0) {
+          choices = cleanChoices;
+        }
+      }
+    }
     // Then pick one.
     assert(choices.length > 0);
-    emit('${choices[rand.nextInt(choices.length)]}');
+    emit('${choices.elementAt(rand.nextInt(choices.length))}');
   }
 
-  void emitSubscriptedVar(int depth, DartType tp) {
+  void emitSubscriptedVar(int depth, DartType tp, {bool isLhs = false}) {
     if (tp == DartType.INT) {
-      emitScalarVar(DartType.INT_LIST);
+      emitScalarVar(DartType.INT_LIST, isLhs: isLhs);
       emit('[');
       emitExpr(depth + 1, DartType.INT);
       emit(']');
     } else if (tp == DartType.STRING) {
-      emitScalarVar(DartType.INT_STRING_MAP);
+      emitScalarVar(DartType.INT_STRING_MAP, isLhs: isLhs);
       emit('[');
       emitExpr(depth + 1, DartType.INT);
       emit(']');
     } else {
-      emitScalarVar(tp); // resort to scalar
+      emitScalarVar(tp, isLhs: isLhs); // resort to scalar
     }
   }
 
-  void emitVar(int depth, DartType tp) {
+  void emitVar(int depth, DartType tp, {bool isLhs = false}) {
     switch (rand.nextInt(2)) {
       case 0:
-        emitScalarVar(tp);
+        emitScalarVar(tp, isLhs: isLhs);
         break;
       default:
-        emitSubscriptedVar(depth, tp);
+        emitSubscriptedVar(depth, tp, isLhs: isLhs);
         break;
     }
   }
@@ -778,7 +836,7 @@
       int r = rand.nextInt(2);
       emit('(');
       if (r == 0) emitPreOrPostOp(tp);
-      emitScalarVar(tp);
+      emitScalarVar(tp, isLhs: true);
       if (r == 1) emitPreOrPostOp(tp);
       emit(')');
     } else {
@@ -1059,18 +1117,21 @@
     }
   }
 
-  List<DartType> fillTypes1() {
+  List<DartType> fillTypes1({bool isFfi = false}) {
     List<DartType> list = new List<DartType>();
     for (int i = 0, n = 1 + rand.nextInt(4); i < n; i++) {
-      list.add(getType());
+      if (isFfi)
+        list.add(fp ? oneOf([DartType.INT, DartType.DOUBLE]) : DartType.INT);
+      else
+        list.add(getType());
     }
     return list;
   }
 
-  List<List<DartType>> fillTypes2() {
+  List<List<DartType>> fillTypes2({bool isFfi = false}) {
     List<List<DartType>> list = new List<List<DartType>>();
     for (int i = 0, n = 1 + rand.nextInt(4); i < n; i++) {
-      list.add(fillTypes1());
+      list.add(fillTypes1(isFfi: isFfi));
     }
     return list;
   }
@@ -1101,6 +1162,29 @@
     return null;
   }
 
+  String getFfiType(String name) {
+    switch (name) {
+      case 'int':
+        return 'ffi.Int32';
+      case 'double':
+        return 'ffi.Double';
+      default:
+        throw 'Invalid FFI type ${name}';
+    }
+  }
+
+  void emitFfiTypedef(String typeName, List<DartType> pars) {
+    emit("typedef ${typeName} = ${getFfiType(pars[0].name)} Function(");
+    for (int i = 1; i < pars.length; i++) {
+      DartType tp = pars[i];
+      emit('${getFfiType(tp.name)}');
+      if (i != (pars.length - 1)) {
+        emit(', ');
+      }
+    }
+    emitLn(');');
+  }
+
   //
   // Output.
   //
@@ -1130,6 +1214,9 @@
   // Enables floating-point operations.
   final bool fp;
 
+  // Enables FFI method calls.
+  final bool ffi;
+
   // File used for output.
   final RandomAccessFile file;
 
@@ -1146,6 +1233,11 @@
   // Types of global variables.
   List<DartType> globalVars;
 
+  // Names of currenty active iterator variables.
+  // These are tracked to avoid modifications within the loop body,
+  // which can lead to infinite loops.
+  List<String> iterVars;
+
   // Prototypes of all global methods (first element is return type).
   List<List<DartType>> globalMethods;
 
@@ -1175,14 +1267,16 @@
   final parser = new ArgParser()
     ..addOption('seed',
         help: 'random seed (0 forces time-based seed)', defaultsTo: '0')
-    ..addFlag('fp',
-        help: 'enables floating-point operations', defaultsTo: true);
+    ..addFlag('fp', help: 'enables floating-point operations', defaultsTo: true)
+    ..addFlag('ffi',
+        help: 'enables FFI method calls (default: off)', defaultsTo: false);
   try {
     final results = parser.parse(arguments);
     final seed = getSeed(results['seed']);
     final fp = results['fp'];
+    final ffi = results['ffi'];
     final file = new File(results.rest.single).openSync(mode: FileMode.write);
-    new DartFuzz(seed, fp, file).run();
+    new DartFuzz(seed, fp, ffi, file).run();
     file.closeSync();
   } catch (e) {
     print('Usage: dart dartfuzz.dart [OPTIONS] FILENAME\n${parser.usage}\n$e');
diff --git a/runtime/tools/dartfuzz/dartfuzz_test.dart b/runtime/tools/dartfuzz/dartfuzz_test.dart
index e135252..a78d9e1 100644
--- a/runtime/tools/dartfuzz/dartfuzz_test.dart
+++ b/runtime/tools/dartfuzz/dartfuzz_test.dart
@@ -293,7 +293,9 @@
     runner2 =
         TestRunner.getTestRunner(mode2, top, tmpDir.path, env, fileName, rand);
     fp = samePrecision(mode1, mode2);
-    isolate = 'Isolate (${tmpDir.path}) ${fp ? "" : "NO-"}FP : '
+    ffi = ffiCapable(mode1, mode2);
+    isolate =
+        'Isolate (${tmpDir.path}) ${ffi ? "" : "NO-"}FFI ${fp ? "" : "NO-"}FP : '
         '${runner1.description} - ${runner2.description}';
 
     start_time = new DateTime.now().millisecondsSinceEpoch;
@@ -308,9 +310,13 @@
     numDivergences = 0;
   }
 
-  bool samePrecision(String mode1, String mode2) {
-    return mode1.contains('64') == mode2.contains('64');
-  }
+  bool samePrecision(String mode1, String mode2) =>
+      mode1.contains('64') == mode2.contains('64');
+
+  bool ffiCapable(String mode1, String mode2) =>
+      (mode1.startsWith('jit') || mode1.startsWith('kbc')) &&
+      (mode2.startsWith('jit') || mode2.startsWith('kbc')) &&
+      (!mode1.contains('arm') && !mode2.contains('arm'));
 
   bool timeIsUp() {
     if (time > 0) {
@@ -339,7 +345,7 @@
 
   void generateTest() {
     final file = new File(fileName).openSync(mode: FileMode.write);
-    new DartFuzz(seed, fp, file).run();
+    new DartFuzz(seed, fp, ffi, file).run();
     file.closeSync();
   }
 
@@ -449,6 +455,7 @@
   TestRunner runner1;
   TestRunner runner2;
   bool fp;
+  bool ffi;
   String isolate;
   int seed;
 
diff --git a/runtime/vm/benchmark_test.cc b/runtime/vm/benchmark_test.cc
index 738478b..a95642a 100644
--- a/runtime/vm/benchmark_test.cc
+++ b/runtime/vm/benchmark_test.cc
@@ -9,6 +9,7 @@
 #include "bin/isolate_data.h"
 #include "bin/process.h"
 #include "bin/reference_counting.h"
+#include "bin/vmservice_impl.h"
 
 #include "platform/assert.h"
 #include "platform/globals.h"
@@ -117,6 +118,8 @@
   bin::Builtin::SetNativeResolver(bin::Builtin::kBuiltinLibrary);
   bin::Builtin::SetNativeResolver(bin::Builtin::kIOLibrary);
   bin::Builtin::SetNativeResolver(bin::Builtin::kCLILibrary);
+  bin::VmService::SetNativeResolver();
+
   char* dill_path = ComputeGenKernelKernelPath(Benchmark::Executable());
   File* file = File::Open(NULL, dill_path, File::kRead);
   EXPECT(file != NULL);
@@ -132,8 +135,7 @@
   // Enabling interpreter also does the trick, but it causes flaky crashes
   // as unoptimized background compiler (which is required for interpreter)
   // was not initialized when isolate was created.
-  const bool use_bytecode_compiler_orig = FLAG_use_bytecode_compiler;
-  FLAG_use_bytecode_compiler = true;
+  SetFlagScope<bool> sfs(&FLAG_use_bytecode_compiler, true);
 
   Timer timer(true, name);
   if (benchmark_load) {
@@ -158,7 +160,6 @@
 
   timer.Stop();
   int64_t elapsed_time = timer.TotalElapsedTime();
-  FLAG_use_bytecode_compiler = use_bytecode_compiler_orig;
   free(dill_path);
   free(kernel_buffer);
   return elapsed_time;
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index dba0451..386d4fb 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -389,6 +389,8 @@
   V(Ffi_dl_lookup, 2)                                                          \
   V(Ffi_dl_getHandle, 1)                                                       \
   V(Ffi_asExternalTypedData, 2)                                                \
+  V(Ffi_dl_processLibrary, 0)                                                  \
+  V(Ffi_dl_executableLibrary, 0)                                               \
   V(TransferableTypedData_factory, 2)                                          \
   V(TransferableTypedData_materialize, 1)
 
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 11f7881..afcc9f3 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -1689,6 +1689,7 @@
 void ClassFinalizer::ClearAllCode(bool including_nonchanging_cids) {
   class ClearCodeFunctionVisitor : public FunctionVisitor {
     void Visit(const Function& function) {
+      function.ClearBytecode();
       function.ClearCode();
       function.ClearICDataArray();
     }
diff --git a/runtime/vm/class_id.h b/runtime/vm/class_id.h
index ae9bfd0..7c129c1 100644
--- a/runtime/vm/class_id.h
+++ b/runtime/vm/class_id.h
@@ -165,10 +165,6 @@
   // Illegal class id.
   kIllegalCid = 0,
 
-  // A sentinel used by the vm service's heap snapshots to represent references
-  // from the stack.
-  kStackCid = 1,
-
   // The following entries describes classes for pseudo-objects in the heap
   // that should never be reachable from live objects. Free list elements
   // maintain the free list for old space, and forwarding corpses are used to
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 28983ba..b876776 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -4367,6 +4367,21 @@
     return new (Z) TypedDataSerializationCluster(cid);
   }
 
+  if (Snapshot::IncludesCode(kind_)) {
+    switch (cid) {
+      case kPcDescriptorsCid:
+        return new (Z) RODataSerializationCluster("(RO)PcDescriptors", cid);
+      case kCodeSourceMapCid:
+        return new (Z) RODataSerializationCluster("(RO)CodeSourceMap", cid);
+      case kStackMapCid:
+        return new (Z) RODataSerializationCluster("(RO)StackMap", cid);
+      case kOneByteStringCid:
+        return new (Z) RODataSerializationCluster("(RO)OneByteString", cid);
+      case kTwoByteStringCid:
+        return new (Z) RODataSerializationCluster("(RO)TwoByteString", cid);
+    }
+  }
+
   switch (cid) {
     case kClassCid:
       return new (Z) ClassSerializationCluster(num_cids_);
@@ -4402,14 +4417,6 @@
 #endif  // !DART_PRECOMPILED_RUNTIME
     case kObjectPoolCid:
       return new (Z) ObjectPoolSerializationCluster();
-    case kPcDescriptorsCid:
-      return new (Z)
-          RODataSerializationCluster("(RO)PcDescriptors", kPcDescriptorsCid);
-    case kCodeSourceMapCid:
-      return new (Z)
-          RODataSerializationCluster("(RO)CodeSourceMap", kCodeSourceMapCid);
-    case kStackMapCid:
-      return new (Z) RODataSerializationCluster("(RO)StackMap", kStackMapCid);
     case kExceptionHandlersCid:
       return new (Z) ExceptionHandlersSerializationCluster();
     case kContextCid:
@@ -4458,22 +4465,10 @@
       return new (Z) ArraySerializationCluster(kArrayCid);
     case kImmutableArrayCid:
       return new (Z) ArraySerializationCluster(kImmutableArrayCid);
-    case kOneByteStringCid: {
-      if (Snapshot::IncludesCode(kind_)) {
-        return new (Z)
-            RODataSerializationCluster("(RO)OneByteString", kOneByteStringCid);
-      } else {
-        return new (Z) OneByteStringSerializationCluster();
-      }
-    }
-    case kTwoByteStringCid: {
-      if (Snapshot::IncludesCode(kind_)) {
-        return new (Z)
-            RODataSerializationCluster("(RO)TwoByteString", kTwoByteStringCid);
-      } else {
-        return new (Z) TwoByteStringSerializationCluster();
-      }
-    }
+    case kOneByteStringCid:
+      return new (Z) OneByteStringSerializationCluster();
+    case kTwoByteStringCid:
+      return new (Z) TwoByteStringSerializationCluster();
     default:
       break;
   }
@@ -4575,12 +4570,6 @@
   }
 #endif  // !DART_PRECOMPILED_RUNTIME
 
-  if (object->IsSendPort()) {
-    // TODO(rmacnak): Do a better job of resetting fields in precompilation
-    // and assert this is unreachable.
-    return;  // Do not trace, will write null.
-  }
-
   intptr_t id = heap_->GetObjectId(object);
   if (id == 0) {
     // When discovering the transitive closure of objects reachable from the
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index a7359d1..f6cc489 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -10,7 +10,6 @@
 #include "vm/compiler/aot/aot_call_specializer.h"
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/assembler/disassembler.h"
-#include "vm/compiler/backend/block_scheduler.h"
 #include "vm/compiler/backend/branch_optimizer.h"
 #include "vm/compiler/backend/constant_propagator.h"
 #include "vm/compiler/backend/flow_graph.h"
@@ -2281,10 +2280,8 @@
         FlowGraphPrinter::PrintGraph("Unoptimized Compilation", flow_graph);
       }
 
-      BlockScheduler block_scheduler(flow_graph);
       CompilerPassState pass_state(thread(), flow_graph, &speculative_policy,
                                    precompiler_);
-      pass_state.block_scheduler = &block_scheduler;
       pass_state.reorder_blocks =
           FlowGraph::ShouldReorderBlocks(function, optimized());
 
diff --git a/runtime/vm/compiler/assembler/disassembler_kbc.cc b/runtime/vm/compiler/assembler/disassembler_kbc.cc
index 839c6e4..d2f0229 100644
--- a/runtime/vm/compiler/assembler/disassembler_kbc.cc
+++ b/runtime/vm/compiler/assembler/disassembler_kbc.cc
@@ -247,6 +247,8 @@
     case KernelBytecode::kPushConstant_Wide:
     case KernelBytecode::kStoreStaticTOS:
     case KernelBytecode::kStoreStaticTOS_Wide:
+    case KernelBytecode::kLoadStatic:
+    case KernelBytecode::kLoadStatic_Wide:
     case KernelBytecode::kPushStatic:
     case KernelBytecode::kPushStatic_Wide:
     case KernelBytecode::kAllocate:
diff --git a/runtime/vm/compiler/backend/bce_test.cc b/runtime/vm/compiler/backend/bce_test.cc
new file mode 100644
index 0000000..d7f508c
--- /dev/null
+++ b/runtime/vm/compiler/backend/bce_test.cc
@@ -0,0 +1,141 @@
+// 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.
+//
+// Unit tests specific to BCE (bounds check eliminaton),
+// which runs as part of range analysis optimizations.
+
+#include "vm/compiler/backend/range_analysis.h"
+
+#include "vm/compiler/backend/il.h"
+#include "vm/compiler/backend/il_printer.h"
+#include "vm/compiler/backend/il_test_helper.h"
+#include "vm/compiler/compiler_pass.h"
+#include "vm/object.h"
+#include "vm/unit_test.h"
+
+namespace dart {
+
+// Helper method to count number of bounds checks.
+static intptr_t CountBoundChecks(FlowGraph* flow_graph) {
+  intptr_t count = 0;
+  for (BlockIterator block_it = flow_graph->reverse_postorder_iterator();
+       !block_it.Done(); block_it.Advance()) {
+    for (ForwardInstructionIterator it(block_it.Current()); !it.Done();
+         it.Advance()) {
+      if (it.Current()->IsCheckBoundBase()) {
+        count++;
+      }
+    }
+  }
+  return count;
+}
+
+// Helper method to build CFG, run BCE, and count number of
+// before/after bounds checks.
+static std::pair<intptr_t, intptr_t> ApplyBCE(const char* script_chars,
+                                              CompilerPass::PipelineMode mode) {
+  // Load the script and exercise the code once
+  // while exercising the given compiler passes.
+  const auto& root_library = Library::Handle(LoadTestScript(script_chars));
+  Invoke(root_library, "main");
+  std::initializer_list<CompilerPass::Id> passes = {
+      CompilerPass::kComputeSSA,
+      CompilerPass::kTypePropagation,
+      CompilerPass::kApplyICData,
+      CompilerPass::kInlining,
+      CompilerPass::kTypePropagation,
+      CompilerPass::kApplyICData,
+      CompilerPass::kSelectRepresentations,
+      CompilerPass::kCanonicalize,
+      CompilerPass::kConstantPropagation,
+      CompilerPass::kCSE,
+      CompilerPass::kLICM,
+  };
+  const auto& function = Function::Handle(GetFunction(root_library, "foo"));
+  TestPipeline pipeline(function, mode);
+  FlowGraph* flow_graph = pipeline.RunPasses(passes);
+  // Count the number of before/after bounds checks.
+  const intptr_t num_bc_before = CountBoundChecks(flow_graph);
+  RangeAnalysis range_analysis(flow_graph);
+  range_analysis.Analyze();
+  const intptr_t num_bc_after = CountBoundChecks(flow_graph);
+  return {num_bc_before, num_bc_after};
+}
+
+static void TestScriptJIT(const char* script_chars,
+                          intptr_t expected_before,
+                          intptr_t expected_after) {
+  auto jit_result = ApplyBCE(script_chars, CompilerPass::kJIT);
+  EXPECT_STREQ(expected_before, jit_result.first);
+  EXPECT_STREQ(expected_after, jit_result.second);
+}
+
+//
+// BCE (bounds-check-elimination) tests.
+//
+
+ISOLATE_UNIT_TEST_CASE(BCECannotRemove) {
+  const char* kScriptChars =
+      R"(
+      import 'dart:typed_data';
+      foo(Float64List l) {
+        return l[0];
+      }
+      main() {
+        var l = new Float64List(1);
+        foo(l);
+      }
+    )";
+  TestScriptJIT(kScriptChars, 1, 1);
+}
+
+ISOLATE_UNIT_TEST_CASE(BCERemoveOne) {
+  const char* kScriptChars =
+      R"(
+      import 'dart:typed_data';
+      foo(Float64List l) {
+        return l[1] + l[0];
+      }
+      main() {
+        var l = new Float64List(2);
+        foo(l);
+      }
+    )";
+  TestScriptJIT(kScriptChars, 2, 1);
+}
+
+ISOLATE_UNIT_TEST_CASE(BCESimpleLoop) {
+  const char* kScriptChars =
+      R"(
+      import 'dart:typed_data';
+      foo(Float64List l) {
+        for (int i = 0; i < l.length; i++) {
+          l[i] = 0;
+        }
+      }
+      main() {
+        var l = new Float64List(100);
+        foo(l);
+      }
+    )";
+  TestScriptJIT(kScriptChars, 1, 0);
+}
+
+ISOLATE_UNIT_TEST_CASE(BCEModulo) {
+  const char* kScriptChars =
+      R"(
+      foo(int i) {
+        var l = new List<int>(3);
+        return l[i % 3] ?? l[i % (-3)];
+      }
+      main() {
+        foo(0);
+      }
+    )";
+  TestScriptJIT(kScriptChars, 2, 0);
+}
+
+// TODO(ajcbik): add more tests
+
+}  // namespace dart
diff --git a/runtime/vm/compiler/backend/block_scheduler.cc b/runtime/vm/compiler/backend/block_scheduler.cc
index 51eceea..055a1e1 100644
--- a/runtime/vm/compiler/backend/block_scheduler.cc
+++ b/runtime/vm/compiler/backend/block_scheduler.cc
@@ -51,7 +51,7 @@
   }
 }
 
-void BlockScheduler::AssignEdgeWeights() const {
+void BlockScheduler::AssignEdgeWeights(FlowGraph* flow_graph) {
   if (!FLAG_reorder_basic_blocks) {
     return;
   }
@@ -59,9 +59,9 @@
     return;
   }
 
-  const Function& function = flow_graph()->parsed_function().function();
+  const Function& function = flow_graph->parsed_function().function();
   const Array& ic_data_array =
-      Array::Handle(flow_graph()->zone(), function.ic_data_array());
+      Array::Handle(flow_graph->zone(), function.ic_data_array());
   if (Compiler::IsBackgroundCompilation() && ic_data_array.IsNull()) {
     // Deferred loading cleared ic_data_array.
     Compiler::AbortBackgroundCompilation(
@@ -75,7 +75,7 @@
   Array& edge_counters = Array::Handle();
   edge_counters ^= ic_data_array.At(0);
 
-  auto graph_entry = flow_graph()->graph_entry();
+  auto graph_entry = flow_graph->graph_entry();
   BlockEntryInstr* entry = graph_entry->normal_entry();
   if (entry == nullptr) {
     entry = graph_entry->osr_entry();
@@ -85,8 +85,8 @@
       GetEdgeCount(edge_counters, entry->preorder_number());
   graph_entry->set_entry_count(entry_count);
 
-  for (BlockIterator it = flow_graph()->reverse_postorder_iterator();
-       !it.Done(); it.Advance()) {
+  for (BlockIterator it = flow_graph->reverse_postorder_iterator(); !it.Done();
+       it.Advance()) {
     BlockEntryInstr* block = it.Current();
     Instruction* last = block->last_instruction();
     for (intptr_t i = 0; i < last->SuccessorCount(); ++i) {
@@ -158,22 +158,22 @@
   }
 }
 
-void BlockScheduler::ReorderBlocks() const {
+void BlockScheduler::ReorderBlocks(FlowGraph* flow_graph) {
   if (FLAG_precompiled_mode) {
-    ReorderBlocksAOT();
+    ReorderBlocksAOT(flow_graph);
   } else {
-    ReorderBlocksJIT();
+    ReorderBlocksJIT(flow_graph);
   }
 }
 
-void BlockScheduler::ReorderBlocksJIT() const {
+void BlockScheduler::ReorderBlocksJIT(FlowGraph* flow_graph) {
   if (!FLAG_reorder_basic_blocks) {
     return;
   }
 
   // Add every block to a chain of length 1 and compute a list of edges
   // sorted by weight.
-  intptr_t block_count = flow_graph()->preorder().length();
+  intptr_t block_count = flow_graph->preorder().length();
   GrowableArray<Edge> edges(2 * block_count);
 
   // A map from a block's postorder number to the chain it is in.  Used to
@@ -182,7 +182,7 @@
   // shared ones).  Find(n) is simply chains[n].
   GrowableArray<Chain*> chains(block_count);
 
-  for (BlockIterator it = flow_graph()->postorder_iterator(); !it.Done();
+  for (BlockIterator it = flow_graph->postorder_iterator(); !it.Done();
        it.Advance()) {
     BlockEntryInstr* block = it.Current();
     chains.Add(new Chain(block));
@@ -221,20 +221,20 @@
 
   // Ensure the checked entry remains first to avoid needing another offset on
   // Instructions, compare Code::EntryPoint.
-  GraphEntryInstr* graph_entry = flow_graph()->graph_entry();
-  flow_graph()->CodegenBlockOrder(true)->Add(graph_entry);
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  flow_graph->CodegenBlockOrder(true)->Add(graph_entry);
   FunctionEntryInstr* checked_entry = graph_entry->normal_entry();
   if (checked_entry != nullptr) {
-    flow_graph()->CodegenBlockOrder(true)->Add(checked_entry);
+    flow_graph->CodegenBlockOrder(true)->Add(checked_entry);
   }
   // Build a new block order.  Emit each chain when its first block occurs
   // in the original reverse postorder ordering (which gives a topological
   // sort of the blocks).
   for (intptr_t i = block_count - 1; i >= 0; --i) {
-    if (chains[i]->first->block == flow_graph()->postorder()[i]) {
+    if (chains[i]->first->block == flow_graph->postorder()[i]) {
       for (Link* link = chains[i]->first; link != NULL; link = link->next) {
         if ((link->block != checked_entry) && (link->block != graph_entry)) {
-          flow_graph()->CodegenBlockOrder(true)->Add(link->block);
+          flow_graph->CodegenBlockOrder(true)->Add(link->block);
         }
       }
     }
@@ -243,12 +243,12 @@
 
 // Moves blocks ending in a throw/rethrow, as well as any block post-dominated
 // by such a throwing block, to the end.
-void BlockScheduler::ReorderBlocksAOT() const {
+void BlockScheduler::ReorderBlocksAOT(FlowGraph* flow_graph) {
   if (!FLAG_reorder_basic_blocks) {
     return;
   }
 
-  auto& reverse_postorder = flow_graph()->reverse_postorder();
+  auto& reverse_postorder = flow_graph->reverse_postorder();
   const intptr_t block_count = reverse_postorder.length();
   GrowableArray<bool> is_terminating(block_count);
   is_terminating.FillWith(false, 0, block_count);
@@ -286,19 +286,19 @@
 
   // Emit code in reverse postorder but move any throwing blocks (except the
   // function entry, which needs to come first) to the very end.
-  auto& codegen_order = *flow_graph()->CodegenBlockOrder(true);
+  auto codegen_order = flow_graph->CodegenBlockOrder(true);
   for (intptr_t i = 0; i < block_count; ++i) {
     auto block = reverse_postorder[i];
     const intptr_t preorder_nr = block->preorder_number();
     if (!is_terminating[preorder_nr] || block->IsFunctionEntry()) {
-      codegen_order.Add(block);
+      codegen_order->Add(block);
     }
   }
   for (intptr_t i = 0; i < block_count; ++i) {
     auto block = reverse_postorder[i];
     const intptr_t preorder_nr = block->preorder_number();
     if (is_terminating[preorder_nr] && !block->IsFunctionEntry()) {
-      codegen_order.Add(block);
+      codegen_order->Add(block);
     }
   }
 }
diff --git a/runtime/vm/compiler/backend/block_scheduler.h b/runtime/vm/compiler/backend/block_scheduler.h
index 90308bc..4bcdf15 100644
--- a/runtime/vm/compiler/backend/block_scheduler.h
+++ b/runtime/vm/compiler/backend/block_scheduler.h
@@ -11,20 +11,14 @@
 
 class FlowGraph;
 
-class BlockScheduler : public ValueObject {
+class BlockScheduler : public AllStatic {
  public:
-  explicit BlockScheduler(FlowGraph* flow_graph) : flow_graph_(flow_graph) {}
-
-  FlowGraph* flow_graph() const { return flow_graph_; }
-
-  void AssignEdgeWeights() const;
-  void ReorderBlocks() const;
+  static void AssignEdgeWeights(FlowGraph* flow_graph);
+  static void ReorderBlocks(FlowGraph* flow_graph);
 
  private:
-  void ReorderBlocksAOT() const;
-  void ReorderBlocksJIT() const;
-
-  FlowGraph* const flow_graph_;
+  static void ReorderBlocksAOT(FlowGraph* flow_graph);
+  static void ReorderBlocksJIT(FlowGraph* flow_graph);
 };
 
 }  // namespace dart
diff --git a/runtime/vm/compiler/backend/flow_graph_checker.cc b/runtime/vm/compiler/backend/flow_graph_checker.cc
index d749aac..7e810b2 100644
--- a/runtime/vm/compiler/backend/flow_graph_checker.cc
+++ b/runtime/vm/compiler/backend/flow_graph_checker.cc
@@ -242,8 +242,13 @@
 }
 
 void FlowGraphChecker::VisitDefinition(Definition* def) {
-  // Used definitions must have an SSA name.
-  ASSERT(def->HasSSATemp() || def->input_use_list() == nullptr);
+  // Used definitions must have an SSA name, and the SSA name must
+  // be less than the current_ssa_temp_index.
+  if (def->HasSSATemp()) {
+    ASSERT(def->ssa_temp_index() < flow_graph_->current_ssa_temp_index());
+  } else {
+    ASSERT(def->input_use_list() == nullptr);
+  }
   // Check all regular uses.
   Value* prev = nullptr;
   for (Value* use = def->input_use_list(); use != nullptr;
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index 14151fb..e39e0fa 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -1271,17 +1271,28 @@
 }
 
 bool Value::NeedsWriteBarrier() {
-  if (Type()->IsNull() || (Type()->ToNullableCid() == kSmiCid) ||
-      (Type()->ToNullableCid() == kBoolCid)) {
-    return false;
-  }
+  Value* value = this;
+  do {
+    if (value->Type()->IsNull() ||
+        (value->Type()->ToNullableCid() == kSmiCid) ||
+        (value->Type()->ToNullableCid() == kBoolCid)) {
+      return false;
+    }
 
-  // Strictly speaking, the incremental barrier can only be skipped for
-  // immediate objects (Smis) or permanent objects (vm-isolate heap or
-  // image pages). Here we choose to skip the barrier for any constant on
-  // the assumption it will remain reachable through the object pool.
+    // Strictly speaking, the incremental barrier can only be skipped for
+    // immediate objects (Smis) or permanent objects (vm-isolate heap or
+    // image pages). Here we choose to skip the barrier for any constant on
+    // the assumption it will remain reachable through the object pool.
+    if (value->BindsToConstant()) {
+      return false;
+    }
 
-  return !BindsToConstant();
+    // Follow the chain of redefinitions as redefined value could have a more
+    // accurate type (for example, AssertAssignable of Smi to a generic T).
+    value = value->definition()->RedefinedValue();
+  } while (value != nullptr);
+
+  return true;
 }
 
 void JoinEntryInstr::AddPredecessor(BlockEntryInstr* predecessor) {
@@ -5176,9 +5187,7 @@
 }
 
 Definition* CheckArrayBoundInstr::Canonicalize(FlowGraph* flow_graph) {
-  return IsRedundant(RangeBoundary::FromDefinition(length()->definition()))
-             ? index()->definition()
-             : this;
+  return IsRedundant() ? index()->definition() : this;
 }
 
 intptr_t CheckArrayBoundInstr::LengthOffsetFor(intptr_t class_id) {
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 79a8e7d..ada13c7 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -7692,7 +7692,7 @@
 };
 
 // Base class for speculative [CheckArrayBoundInstr] and
-// [GenericCheckBoundInstr]
+// non-speculative [GenericCheckBoundInstr] bounds checking.
 class CheckBoundBase : public TemplateDefinition<2, NoThrow, Pure> {
  public:
   CheckBoundBase(Value* length, Value* index, intptr_t deopt_id)
@@ -7708,6 +7708,10 @@
   virtual CheckBoundBase* AsCheckBoundBase() { return this; }
   virtual Value* RedefinedValue() const;
 
+  // Returns true if the bounds check can be eliminated without
+  // changing the semantics (viz. 0 <= index < length).
+  bool IsRedundant();
+
   // Give a name to the location/input indices.
   enum { kLengthPos = 0, kIndexPos = 1 };
 
@@ -7734,8 +7738,6 @@
 
   virtual bool ComputeCanDeoptimize() const { return true; }
 
-  bool IsRedundant(const RangeBoundary& length);
-
   void mark_generalized() { generalized_ = true; }
 
   virtual Definition* Canonicalize(FlowGraph* flow_graph);
@@ -7777,8 +7779,6 @@
   // ArgumentError constructor), so it can lazily deopt.
   virtual bool ComputeCanDeoptimize() const { return true; }
 
-  bool IsRedundant(const RangeBoundary& length);
-
   virtual bool MayThrow() const { return true; }
 
  private:
diff --git a/runtime/vm/compiler/backend/il_test.cc b/runtime/vm/compiler/backend/il_test.cc
index 388136c..ff6ccd5 100644
--- a/runtime/vm/compiler/backend/il_test.cc
+++ b/runtime/vm/compiler/backend/il_test.cc
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/compiler/backend/il.h"
+#include "vm/compiler/backend/il_test_helper.h"
 #include "vm/unit_test.h"
 
 namespace dart {
@@ -40,4 +41,48 @@
   EXPECT(!c3->Equals(c1));
 }
 
+ISOLATE_UNIT_TEST_CASE(IRTest_EliminateWriteBarrier) {
+  const char* kScript =
+      R"(
+      class Container<T> {
+        operator []=(var index, var value) {
+          return data[index] = value;
+        }
+
+        List<T> data = new List<T>()..length = 10;
+      }
+
+      Container<int> x = new Container<int>();
+
+      foo() {
+        for (int i = 0; i < 10; ++i) {
+          x[i] = i;
+        }
+      }
+    )";
+
+  const auto& root_library = Library::Handle(LoadTestScript(kScript));
+  const auto& function = Function::Handle(GetFunction(root_library, "foo"));
+
+  Invoke(root_library, "foo");
+
+  TestPipeline pipeline(function, CompilerPass::kJIT);
+  FlowGraph* flow_graph = pipeline.RunPasses({});
+
+  auto entry = flow_graph->graph_entry()->normal_entry();
+  EXPECT(entry != nullptr);
+
+  StoreIndexedInstr* store_indexed = nullptr;
+
+  ILMatcher cursor(flow_graph, entry, true);
+  RELEASE_ASSERT(cursor.TryMatch({
+      kMoveGlob,
+      kMatchAndMoveBranchTrue,
+      kMoveGlob,
+      {kMatchStoreIndexed, &store_indexed},
+  }));
+
+  EXPECT(!store_indexed->value()->NeedsWriteBarrier());
+}
+
 }  // namespace dart
diff --git a/runtime/vm/compiler/backend/il_test_helper.cc b/runtime/vm/compiler/backend/il_test_helper.cc
index dea57a5..0bc24f1 100644
--- a/runtime/vm/compiler/backend/il_test_helper.cc
+++ b/runtime/vm/compiler/backend/il_test_helper.cc
@@ -84,16 +84,14 @@
     flow_graph_->PopulateWithICData(function_);
   }
 
-  BlockScheduler block_scheduler(flow_graph_);
   const bool reorder_blocks =
       FlowGraph::ShouldReorderBlocks(function_, optimized);
   if (mode_ == CompilerPass::kJIT && reorder_blocks) {
-    block_scheduler.AssignEdgeWeights();
+    BlockScheduler::AssignEdgeWeights(flow_graph_);
   }
 
   SpeculativeInliningPolicy speculative_policy(/*enable_blacklist=*/false);
   pass_state_ = new CompilerPassState(thread, flow_graph_, &speculative_policy);
-  pass_state_->block_scheduler = &block_scheduler;
   pass_state_->reorder_blocks = reorder_blocks;
 
   if (optimized) {
diff --git a/runtime/vm/compiler/backend/inliner.cc b/runtime/vm/compiler/backend/inliner.cc
index 0a0ba21..a71a380 100644
--- a/runtime/vm/compiler/backend/inliner.cc
+++ b/runtime/vm/compiler/backend/inliner.cc
@@ -433,10 +433,10 @@
       return;
     }
 
-    // Recognized methods are not treated as normal calls. They don't have
-    // calls in themselves, so we keep adding those even when at the threshold.
-    const bool inline_only_recognized_methods =
-        (depth == inlining_depth_threshold_);
+    // At the maximum inlining depth, only profitable methods
+    // are further considered for inlining.
+    const bool inline_only_profitable_methods =
+        (depth >= inlining_depth_threshold_);
 
     // In AOT, compute loop hierarchy.
     if (FLAG_precompiled_mode) {
@@ -454,13 +454,15 @@
         if (current->IsPolymorphicInstanceCall()) {
           PolymorphicInstanceCallInstr* instance_call =
               current->AsPolymorphicInstanceCall();
-          if (!inline_only_recognized_methods ||
+          if (!inline_only_profitable_methods ||
               instance_call->IsSureToCallSingleRecognizedTarget() ||
               instance_call->HasOnlyDispatcherOrImplicitAccessorTargets()) {
+            // Consider instance call for further inlining. Note that it will
+            // still be subject to all the inlining heuristics.
             instance_calls_.Add(InstanceCallInfo(instance_call, graph, depth));
           } else {
-            // Method not inlined because inlining too deep and method
-            // not recognized.
+            // No longer consider the instance call because inlining is too
+            // deep and the method is not deemed profitable by other criteria.
             if (FLAG_print_inlining_tree) {
               const Function* caller = &graph->function();
               const Function* target = &instance_call->targets().FirstTarget();
@@ -470,13 +472,16 @@
           }
         } else if (current->IsStaticCall()) {
           StaticCallInstr* static_call = current->AsStaticCall();
-          if (!inline_only_recognized_methods ||
-              static_call->function().IsRecognized() ||
-              static_call->function().IsDispatcherOrImplicitAccessor()) {
+          const Function& function = static_call->function();
+          if (!inline_only_profitable_methods || function.IsRecognized() ||
+              function.IsDispatcherOrImplicitAccessor() ||
+              (function.is_const() && function.IsGenerativeConstructor())) {
+            // Consider static call for further inlining. Note that it will
+            // still be subject to all the inlining heuristics.
             static_calls_.Add(StaticCallInfo(static_call, graph, depth));
           } else {
-            // Method not inlined because inlining too deep and method
-            // not recognized.
+            // No longer consider the static call because inlining is too
+            // deep and the method is not deemed profitable by other criteria.
             if (FLAG_print_inlining_tree) {
               const Function* caller = &graph->function();
               const Function* target = &static_call->function();
@@ -485,9 +490,13 @@
             }
           }
         } else if (current->IsClosureCall()) {
-          if (!inline_only_recognized_methods) {
+          if (!inline_only_profitable_methods) {
+            // Consider closure for further inlining. Note that it will
+            // still be subject to all the inlining heuristics.
             ClosureCallInstr* closure_call = current->AsClosureCall();
             closure_calls_.Add(ClosureCallInfo(closure_call, graph));
+          } else {
+            // No longer consider the closure because inlining is too deep.
           }
         }
       }
@@ -1111,8 +1120,7 @@
           }
         }
 
-        BlockScheduler block_scheduler(callee_graph);
-        block_scheduler.AssignEdgeWeights();
+        BlockScheduler::AssignEdgeWeights(callee_graph);
 
         {
           // Compute SSA on the callee graph, catching bailouts.
diff --git a/runtime/vm/compiler/backend/range_analysis.cc b/runtime/vm/compiler/backend/range_analysis.cc
index f99ae1f..b350e13 100644
--- a/runtime/vm/compiler/backend/range_analysis.cc
+++ b/runtime/vm/compiler/backend/range_analysis.cc
@@ -103,8 +103,8 @@
           }
         }
       }
-      if (current->IsCheckArrayBound() || current->IsGenericCheckBound()) {
-        bounds_checks_.Add(current);
+      if (auto check = current->AsCheckBoundBase()) {
+        bounds_checks_.Add(check);
       }
     }
   }
@@ -723,8 +723,7 @@
         flow_graph_(flow_graph),
         scheduler_(flow_graph) {}
 
-  void TryGeneralize(CheckArrayBoundInstr* check,
-                     const RangeBoundary& array_length) {
+  void TryGeneralize(CheckArrayBoundInstr* check) {
     Definition* upper_bound =
         ConstructUpperBound(check->index()->definition(), check);
     if (upper_bound == UnwrapConstraint(check->index()->definition())) {
@@ -837,7 +836,7 @@
         new Value(UnwrapConstraint(check->length()->definition())),
         new Value(upper_bound), DeoptId::kNone);
     new_check->mark_generalized();
-    if (new_check->IsRedundant(array_length)) {
+    if (new_check->IsRedundant()) {
       if (FLAG_trace_range_analysis) {
         THR_Print("  => generalized check is redundant\n");
       }
@@ -1307,38 +1306,20 @@
   if (FLAG_array_bounds_check_elimination) {
     const Function& function = flow_graph_->function();
     // Generalization only if we have not deoptimized on a generalized
-    // check earlier, or we're compiling precompiled code (no
-    // optimistic hoisting of checks possible)
+    // check earlier and we are not compiling precompiled code
+    // (no optimistic hoisting of checks possible)
     const bool try_generalization =
-        !function.ProhibitsBoundsCheckGeneralization() &&
-        !FLAG_precompiled_mode;
-
+        !FLAG_precompiled_mode &&
+        !function.ProhibitsBoundsCheckGeneralization();
     BoundsCheckGeneralizer generalizer(this, flow_graph_);
-
-    for (intptr_t i = 0; i < bounds_checks_.length(); i++) {
-      // Is this a non-speculative check bound?
-      auto aot_check = bounds_checks_[i]->AsGenericCheckBound();
-      if (aot_check != nullptr) {
-        auto length = aot_check->length()
-                          ->definition()
-                          ->OriginalDefinitionIgnoreBoxingAndConstraints();
-        auto array_length = RangeBoundary::FromDefinition(length);
-        if (aot_check->IsRedundant(array_length)) {
-          aot_check->ReplaceUsesWith(aot_check->index()->definition());
-          aot_check->RemoveFromGraph();
-        }
-        continue;
-      }
-      // Must be a speculative check bound.
-      CheckArrayBoundInstr* check = bounds_checks_[i]->AsCheckArrayBound();
-      ASSERT(check != nullptr);
-      RangeBoundary array_length =
-          RangeBoundary::FromDefinition(check->length()->definition());
-      if (check->IsRedundant(array_length)) {
+    for (CheckBoundBase* check : bounds_checks_) {
+      if (check->IsRedundant()) {
         check->ReplaceUsesWith(check->index()->definition());
         check->RemoveFromGraph();
       } else if (try_generalization) {
-        generalizer.TryGeneralize(check, array_length);
+        if (auto jit_check = check->AsCheckArrayBound()) {
+          generalizer.TryGeneralize(jit_check);
+        }
       }
     }
   }
@@ -2350,6 +2331,26 @@
   *result_max = RangeBoundary::PositiveInfinity();
 }
 
+void Range::Mod(const Range* right_range,
+                RangeBoundary* result_min,
+                RangeBoundary* result_max) {
+  ASSERT(right_range != nullptr);
+  ASSERT(result_min != nullptr);
+  ASSERT(result_max != nullptr);
+  // Each modulo result is positive and bounded by one less than
+  // the maximum of the right-hand-side (it is unlikely that the
+  // left-hand-side further refines this in typical programs).
+  // Note that x % MinInt can be MaxInt and x % 0 always throws.
+  const int64_t kModMin = 0;
+  int64_t mod_max = kMaxInt64;
+  if (Range::ConstantMin(right_range).ConstantValue() != kMinInt64) {
+    const int64_t right_max = ConstantAbsMax(right_range);
+    mod_max = Utils::Maximum(right_max - 1, kModMin);
+  }
+  *result_min = RangeBoundary::FromConstant(kModMin);
+  *result_max = RangeBoundary::FromConstant(mod_max);
+}
+
 // Both the a and b ranges are >= 0.
 bool Range::OnlyPositiveOrZero(const Range& a, const Range& b) {
   return a.OnlyGreaterThanOrEqualTo(0) && b.OnlyGreaterThanOrEqualTo(0);
@@ -2417,6 +2418,10 @@
       Range::TruncDiv(left_range, right_range, &min, &max);
       break;
 
+    case Token::kMOD:
+      Range::Mod(right_range, &min, &max);
+      break;
+
     case Token::kSHL:
       Range::Shl(left_range, right_range, &min, &max);
       break;
@@ -2931,21 +2936,19 @@
   }
 }
 
-bool CheckArrayBoundInstr::IsRedundant(const RangeBoundary& length) {
-  Range* index_range = index()->definition()->range();
-
+static bool IsRedundantBasedOnRangeInformation(Value* index, Value* length) {
   // Range of the index is unknown can't decide if the check is redundant.
-  if (index_range == NULL) {
-    if (!(index()->BindsToConstant() &&
-          compiler::target::IsSmi(index()->BoundConstant()))) {
+  Range* index_range = index->definition()->range();
+  if (index_range == nullptr) {
+    if (!(index->BindsToConstant() &&
+          compiler::target::IsSmi(index->BoundConstant()))) {
       return false;
     }
-
     Range range;
-    index()->definition()->InferRange(NULL, &range);
+    index->definition()->InferRange(nullptr, &range);
     ASSERT(!Range::IsUnknown(&range));
-    index()->definition()->set_range(range);
-    index_range = index()->definition()->range();
+    index->definition()->set_range(range);
+    index_range = index->definition()->range();
   }
 
   // Range of the index is not positive. Check can't be redundant.
@@ -2953,11 +2956,11 @@
     return false;
   }
 
-  RangeBoundary max = RangeBoundary::FromDefinition(index()->definition());
-
+  RangeBoundary max = RangeBoundary::FromDefinition(index->definition());
   RangeBoundary max_upper = max.UpperBound();
-  RangeBoundary length_lower = length.LowerBound();
-
+  RangeBoundary array_length =
+      RangeBoundary::FromDefinition(length->definition());
+  RangeBoundary length_lower = array_length.LowerBound();
   if (max_upper.OverflowedSmi() || length_lower.OverflowedSmi()) {
     return false;
   }
@@ -2968,7 +2971,7 @@
   }
 
   RangeBoundary canonical_length =
-      CanonicalizeBoundary(length, RangeBoundary::PositiveInfinity());
+      CanonicalizeBoundary(array_length, RangeBoundary::PositiveInfinity());
   if (canonical_length.OverflowedSmi()) {
     return false;
   }
@@ -3000,30 +3003,41 @@
   return false;
 }
 
-bool GenericCheckBoundInstr::IsRedundant(const RangeBoundary& length) {
-  // In loop, with index as induction?
-  LoopInfo* loop = GetBlock()->loop_info();
-  if (loop == nullptr) {
-    return false;
+bool CheckBoundBase::IsRedundant() {
+  // First, try to prove redundancy with the results of range analysis.
+  if (IsRedundantBasedOnRangeInformation(index(), length())) {
+    return true;
+  } else if (previous() == nullptr) {
+    return false;  // check is not in flow graph yet
   }
-  InductionVar* induc = loop->LookupInduction(index()->definition());
-  if (induc == nullptr) {
-    return false;
-  }
+  // Next, try to prove redundancy with the results of induction analysis.
   // Under 64-bit wrap-around arithmetic, it is always safe to remove the
-  // bounds check from the following, if initial >= 0 and the corresponding
+  // bounds check from the following loop, if initial >= 0 and the loop
   // exit branch dominates the bounds check:
+  //
   //   for (int i = initial; i < length; i++)
   //     .... a[i] ....
-  int64_t stride = 0;
-  int64_t initial = 0;
-  if (InductionVar::IsLinear(induc, &stride) &&
-      InductionVar::IsConstant(induc->initial(), &initial)) {
-    if (stride == 1 && initial >= 0) {
-      for (auto bound : induc->bounds()) {
-        if (IsSameBound(length, bound.limit_) &&
-            this->IsDominatedBy(bound.branch_)) {
-          return true;
+  //
+  LoopInfo* loop = GetBlock()->loop_info();
+  if (loop != nullptr) {
+    InductionVar* induc = loop->LookupInduction(index()->definition());
+    if (induc != nullptr) {
+      int64_t stride = 0;
+      int64_t initial = 0;
+      if (InductionVar::IsLinear(induc, &stride) &&
+          InductionVar::IsConstant(induc->initial(), &initial)) {
+        if (stride == 1 && initial >= 0) {
+          // Deeply trace back the range of the array length.
+          RangeBoundary deep_length = RangeBoundary::FromDefinition(
+              length()
+                  ->definition()
+                  ->OriginalDefinitionIgnoreBoxingAndConstraints());
+          for (auto bound : induc->bounds()) {
+            if (IsSameBound(deep_length, bound.limit_) &&
+                this->IsDominatedBy(bound.branch_)) {
+              return true;
+            }
+          }
         }
       }
     }
diff --git a/runtime/vm/compiler/backend/range_analysis.h b/runtime/vm/compiler/backend/range_analysis.h
index ef90ace..2b8bea7 100644
--- a/runtime/vm/compiler/backend/range_analysis.h
+++ b/runtime/vm/compiler/backend/range_analysis.h
@@ -450,6 +450,10 @@
                        RangeBoundary* min,
                        RangeBoundary* max);
 
+  static void Mod(const Range* right_range,
+                  RangeBoundary* min,
+                  RangeBoundary* max);
+
   static void Shr(const Range* left_range,
                   const Range* right_range,
                   RangeBoundary* min,
@@ -622,7 +626,7 @@
   GrowableArray<ShiftIntegerOpInstr*> shift_int64_ops_;
 
   // All CheckArrayBound/GenericCheckBound instructions.
-  GrowableArray<Instruction*> bounds_checks_;
+  GrowableArray<CheckBoundBase*> bounds_checks_;
 
   // All Constraints inserted during InsertConstraints phase. They are treated
   // as smi values.
diff --git a/runtime/vm/compiler/backend/redundancy_elimination_test.cc b/runtime/vm/compiler/backend/redundancy_elimination_test.cc
index 732b1dc..14d97be 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination_test.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination_test.cc
@@ -13,6 +13,7 @@
 #include "vm/compiler/backend/loops.h"
 #include "vm/compiler/backend/type_propagator.h"
 #include "vm/compiler/compiler_pass.h"
+#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/log.h"
@@ -57,6 +58,35 @@
   }
 }
 
+#if !defined(PRODUCT)
+void PopulateEnvironmentFromBytecodeLocalVariables(
+    const Function& function,
+    FlowGraph* graph,
+    GrowableArray<LocalVariable*>* env) {
+  const auto& bytecode = Bytecode::Handle(function.bytecode());
+  ASSERT(!bytecode.IsNull());
+
+  kernel::BytecodeLocalVariablesIterator iter(Thread::Current()->zone(),
+                                              bytecode);
+  while (iter.MoveNext()) {
+    if (iter.IsVariableDeclaration() && !iter.IsCaptured()) {
+      LocalVariable* const var = new LocalVariable(
+          TokenPosition::kNoSource, TokenPosition::kNoSource,
+          String::ZoneHandle(graph->zone(), iter.Name()),
+          AbstractType::ZoneHandle(graph->zone(), iter.Type()));
+      if (iter.Index() < 0) {  // Parameter.
+        var->set_index(VariableIndex(-iter.Index() - kKBCParamEndSlotFromFp));
+      } else {
+        var->set_index(VariableIndex(-iter.Index()));
+      }
+      const intptr_t env_index = graph->EnvIndex(var);
+      env->EnsureLength(env_index + 1, nullptr);
+      (*env)[env_index] = var;
+    }
+  }
+}
+#endif
+
 // Run TryCatchAnalyzer optimization on the function foo from the given script
 // and check that the only variables from the given list are synchronized
 // on catch entry.
@@ -86,7 +116,17 @@
   auto scope = graph->parsed_function().scope();
 
   GrowableArray<LocalVariable*> env;
-  FlattenScopeIntoEnvironment(graph, scope, &env);
+  if (function.is_declared_in_bytecode()) {
+#if defined(PRODUCT)
+    // In product mode information about local variables is not retained in
+    // bytecode, so we can't find variables by names.
+    return;
+#else
+    PopulateEnvironmentFromBytecodeLocalVariables(function, graph, &env);
+#endif
+  } else {
+    FlattenScopeIntoEnvironment(graph, scope, &env);
+  }
 
   for (intptr_t i = 0; i < env.length(); i++) {
     bool found = false;
diff --git a/runtime/vm/compiler/call_specializer.h b/runtime/vm/compiler/call_specializer.h
index e9a0a6d..2b1e4ee 100644
--- a/runtime/vm/compiler/call_specializer.h
+++ b/runtime/vm/compiler/call_specializer.h
@@ -117,12 +117,6 @@
  protected:
   void InlineImplicitInstanceGetter(Definition* call, const Field& field);
 
-  SpeculativeInliningPolicy* speculative_policy_;
-  const bool should_clone_fields_;
-
- private:
-  bool TypeCheckAsClassEquality(const AbstractType& type);
-
   // Insert a check of 'to_check' determined by 'unary_checks'.  If the
   // check fails it will deoptimize to 'deopt_id' using the deoptimization
   // environment 'deopt_environment'.  The check is inserted immediately
@@ -133,6 +127,12 @@
                      Environment* deopt_environment,
                      Instruction* insert_before);
 
+  SpeculativeInliningPolicy* speculative_policy_;
+  const bool should_clone_fields_;
+
+ private:
+  bool TypeCheckAsClassEquality(const AbstractType& type);
+
   // Insert a Smi check if needed.
   void AddCheckSmi(Definition* to_check,
                    intptr_t deopt_id,
diff --git a/runtime/vm/compiler/compiler_pass.cc b/runtime/vm/compiler/compiler_pass.cc
index 7692c29..6aba24a 100644
--- a/runtime/vm/compiler/compiler_pass.cc
+++ b/runtime/vm/compiler/compiler_pass.cc
@@ -449,7 +449,7 @@
 
 COMPILER_PASS(ReorderBlocks, {
   if (state->reorder_blocks) {
-    state->block_scheduler->ReorderBlocks();
+    BlockScheduler::ReorderBlocks(flow_graph);
   }
 });
 
diff --git a/runtime/vm/compiler/compiler_pass.h b/runtime/vm/compiler/compiler_pass.h
index 6f9b948..b8475d1 100644
--- a/runtime/vm/compiler/compiler_pass.h
+++ b/runtime/vm/compiler/compiler_pass.h
@@ -72,7 +72,6 @@
         call_specializer(NULL),
         speculative_policy(speculative_policy),
         reorder_blocks(false),
-        block_scheduler(NULL),
         sticky_flags(0) {
   }
 
@@ -95,7 +94,6 @@
   SpeculativeInliningPolicy* speculative_policy;
 
   bool reorder_blocks;
-  BlockScheduler* block_scheduler;
 
   intptr_t sticky_flags;
 };
diff --git a/runtime/vm/compiler/compiler_sources.gni b/runtime/vm/compiler/compiler_sources.gni
index 6a27c2a..321a629 100644
--- a/runtime/vm/compiler/compiler_sources.gni
+++ b/runtime/vm/compiler/compiler_sources.gni
@@ -101,6 +101,8 @@
   "ffi.h",
   "frontend/base_flow_graph_builder.cc",
   "frontend/base_flow_graph_builder.h",
+  "frontend/bytecode_fingerprints.cc",
+  "frontend/bytecode_fingerprints.h",
   "frontend/bytecode_flow_graph_builder.cc",
   "frontend/bytecode_flow_graph_builder.h",
   "frontend/bytecode_reader.cc",
@@ -169,6 +171,7 @@
   "assembler/assembler_test.cc",
   "assembler/assembler_x64_test.cc",
   "assembler/disassembler_test.cc",
+  "backend/bce_test.cc",
   "backend/il_test.cc",
   "backend/il_test_helper.h",
   "backend/il_test_helper.cc",
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
index a717c3b..2b70b9d 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
@@ -993,6 +993,18 @@
   return Fragment(interpolate);
 }
 
+void BaseFlowGraphBuilder::reset_context_depth_for_deopt_id(intptr_t deopt_id) {
+  if (is_recording_context_levels()) {
+    for (intptr_t i = 0, n = context_level_array_->length(); i < n; i += 2) {
+      if (context_level_array_->At(i) == deopt_id) {
+        (*context_level_array_)[i + 1] = context_depth_;
+        return;
+      }
+      ASSERT(context_level_array_->At(i) < deopt_id);
+    }
+  }
+}
+
 }  // namespace kernel
 }  // namespace dart
 
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.h b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
index 8f79aeb..dbd2b68 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.h
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
@@ -361,6 +361,21 @@
   // _StringBase._interpolate call.
   Fragment StringInterpolate(TokenPosition position);
 
+  // Returns true if we're currently recording deopt_id -> context level
+  // mapping.
+  bool is_recording_context_levels() const {
+    return context_level_array_ != nullptr;
+  }
+
+  // Sets current context level. It will be recorded for all subsequent
+  // deopt ids (until it is adjusted again).
+  void set_context_depth(intptr_t context_level) {
+    context_depth_ = context_level;
+  }
+
+  // Reset context level for the given deopt id (which was allocated earlier).
+  void reset_context_depth_for_deopt_id(intptr_t deopt_id);
+
  protected:
   intptr_t AllocateBlockId() { return ++last_used_block_id_; }
 
diff --git a/runtime/vm/compiler/frontend/bytecode_fingerprints.cc b/runtime/vm/compiler/frontend/bytecode_fingerprints.cc
new file mode 100644
index 0000000..aa3e4b7
--- /dev/null
+++ b/runtime/vm/compiler/frontend/bytecode_fingerprints.cc
@@ -0,0 +1,209 @@
+// 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.
+
+#include "vm/compiler/frontend/bytecode_fingerprints.h"
+
+#include "vm/compiler/frontend/bytecode_reader.h"
+#include "vm/constants_kbc.h"
+#include "vm/hash.h"
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+
+namespace dart {
+namespace kernel {
+
+static uint32_t CombineObject(uint32_t hash, const Object& obj) {
+  if (obj.IsAbstractType()) {
+    return CombineHashes(hash, AbstractType::Cast(obj).Hash());
+  } else if (obj.IsClass()) {
+    return CombineHashes(hash, Class::Cast(obj).id());
+  } else if (obj.IsFunction()) {
+    return CombineHashes(
+        hash, AbstractType::Handle(Function::Cast(obj).result_type()).Hash());
+  } else if (obj.IsField()) {
+    return CombineHashes(hash,
+                         AbstractType::Handle(Field::Cast(obj).type()).Hash());
+  } else {
+    return CombineHashes(hash, static_cast<uint32_t>(obj.GetClassId()));
+  }
+}
+
+typedef uint32_t (*Fp)(uint32_t fp,
+                       const KBCInstr* instr,
+                       const ObjectPool& pool,
+                       int32_t value);
+
+static uint32_t Fp___(uint32_t fp,
+                      const KBCInstr* instr,
+                      const ObjectPool& pool,
+                      int32_t value) {
+  return fp;
+}
+
+static uint32_t Fptgt(uint32_t fp,
+                      const KBCInstr* instr,
+                      const ObjectPool& pool,
+                      int32_t value) {
+  return CombineHashes(fp, value);
+}
+
+static uint32_t Fplit(uint32_t fp,
+                      const KBCInstr* instr,
+                      const ObjectPool& pool,
+                      int32_t value) {
+  return CombineObject(fp, Object::Handle(pool.ObjectAt(value)));
+}
+
+static uint32_t Fpreg(uint32_t fp,
+                      const KBCInstr* instr,
+                      const ObjectPool& pool,
+                      int32_t value) {
+  return CombineHashes(fp, value);
+}
+
+static uint32_t Fpxeg(uint32_t fp,
+                      const KBCInstr* instr,
+                      const ObjectPool& pool,
+                      int32_t value) {
+  return CombineHashes(fp, value);
+}
+
+static uint32_t Fpnum(uint32_t fp,
+                      const KBCInstr* instr,
+                      const ObjectPool& pool,
+                      int32_t value) {
+  return CombineHashes(fp, value);
+}
+
+static uint32_t Fingerprint0(uint32_t fp,
+                             const KBCInstr* instr,
+                             const ObjectPool& pool,
+                             Fp op1,
+                             Fp op2,
+                             Fp op3) {
+  return fp;
+}
+
+static uint32_t FingerprintA(uint32_t fp,
+                             const KBCInstr* instr,
+                             const ObjectPool& pool,
+                             Fp op1,
+                             Fp op2,
+                             Fp op3) {
+  fp = op1(fp, instr, pool, KernelBytecode::DecodeA(instr));
+  return fp;
+}
+
+static uint32_t FingerprintD(uint32_t fp,
+                             const KBCInstr* instr,
+                             const ObjectPool& pool,
+                             Fp op1,
+                             Fp op2,
+                             Fp op3) {
+  fp = op1(fp, instr, pool, KernelBytecode::DecodeD(instr));
+  return fp;
+}
+
+static uint32_t FingerprintX(uint32_t fp,
+                             const KBCInstr* instr,
+                             const ObjectPool& pool,
+                             Fp op1,
+                             Fp op2,
+                             Fp op3) {
+  fp = op1(fp, instr, pool, KernelBytecode::DecodeX(instr));
+  return fp;
+}
+
+static uint32_t FingerprintT(uint32_t fp,
+                             const KBCInstr* instr,
+                             const ObjectPool& pool,
+                             Fp op1,
+                             Fp op2,
+                             Fp op3) {
+  fp = op1(fp, instr, pool, KernelBytecode::DecodeT(instr));
+  return fp;
+}
+
+static uint32_t FingerprintA_E(uint32_t fp,
+                               const KBCInstr* instr,
+                               const ObjectPool& pool,
+                               Fp op1,
+                               Fp op2,
+                               Fp op3) {
+  fp = op1(fp, instr, pool, KernelBytecode::DecodeA(instr));
+  fp = op2(fp, instr, pool, KernelBytecode::DecodeE(instr));
+  return fp;
+}
+
+static uint32_t FingerprintA_Y(uint32_t fp,
+                               const KBCInstr* instr,
+                               const ObjectPool& pool,
+                               Fp op1,
+                               Fp op2,
+                               Fp op3) {
+  fp = op1(fp, instr, pool, KernelBytecode::DecodeA(instr));
+  fp = op2(fp, instr, pool, KernelBytecode::DecodeY(instr));
+  return fp;
+}
+
+static uint32_t FingerprintD_F(uint32_t fp,
+                               const KBCInstr* instr,
+                               const ObjectPool& pool,
+                               Fp op1,
+                               Fp op2,
+                               Fp op3) {
+  fp = op1(fp, instr, pool, KernelBytecode::DecodeD(instr));
+  fp = op2(fp, instr, pool, KernelBytecode::DecodeF(instr));
+  return fp;
+}
+
+static uint32_t FingerprintA_B_C(uint32_t fp,
+                                 const KBCInstr* instr,
+                                 const ObjectPool& pool,
+                                 Fp op1,
+                                 Fp op2,
+                                 Fp op3) {
+  fp = op1(fp, instr, pool, KernelBytecode::DecodeA(instr));
+  fp = op2(fp, instr, pool, KernelBytecode::DecodeB(instr));
+  fp = op3(fp, instr, pool, KernelBytecode::DecodeC(instr));
+  return fp;
+}
+
+uint32_t BytecodeFingerprintHelper::CalculateFunctionFingerprint(
+    const Function& function) {
+  ASSERT(function.is_declared_in_bytecode());
+  if (function.is_abstract()) {
+    return 0;
+  }
+  if (!function.HasBytecode()) {
+    kernel::BytecodeReader::ReadFunctionBytecode(Thread::Current(), function);
+  }
+  const Bytecode& code = Bytecode::Handle(function.bytecode());
+  const ObjectPool& pool = ObjectPool::Handle(code.object_pool());
+  uint32_t fp = 0;
+  const KBCInstr* const start =
+      reinterpret_cast<const KBCInstr*>(code.instructions());
+  for (const KBCInstr* instr = start; (instr - start) < code.Size();
+       instr = KernelBytecode::Next(instr)) {
+    const KernelBytecode::Opcode opcode = KernelBytecode::DecodeOpcode(instr);
+    fp = CombineHashes(fp, opcode);
+    switch (opcode) {
+#define FINGERPRINT_BYTECODE(name, encoding, kind, op1, op2, op3)              \
+  case KernelBytecode::k##name:                                                \
+    fp = Fingerprint##encoding(fp, instr, pool, Fp##op1, Fp##op2, Fp##op3);    \
+    break;
+      KERNEL_BYTECODES_LIST(FINGERPRINT_BYTECODE)
+#undef FINGERPRINT_BYTECODE
+      default:
+        UNREACHABLE();
+    }
+  }
+
+  return FinalizeHash(fp, 30);
+}
+
+}  // namespace kernel
+}  // namespace dart
+
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/frontend/bytecode_fingerprints.h b/runtime/vm/compiler/frontend/bytecode_fingerprints.h
new file mode 100644
index 0000000..ea79a92
--- /dev/null
+++ b/runtime/vm/compiler/frontend/bytecode_fingerprints.h
@@ -0,0 +1,25 @@
+// 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.
+
+#ifndef RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_FINGERPRINTS_H_
+#define RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_FINGERPRINTS_H_
+
+#include "platform/allocation.h"
+#include "vm/object.h"
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+
+namespace dart {
+namespace kernel {
+
+class BytecodeFingerprintHelper : public AllStatic {
+ public:
+  static uint32_t CalculateFunctionFingerprint(const Function& func);
+};
+
+}  // namespace kernel
+}  // namespace dart
+
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_FINGERPRINTS_H_
diff --git a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
index 2fb99e5..e745986 100644
--- a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
@@ -742,7 +742,12 @@
   if (is_generating_interpreter()) {
     UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
   }
-  code_ += B->DebugStepCheck(position_);
+  // DebugStepCheck instructions are emitted for all explicit DebugCheck
+  // opcodes as well as for implicit DEBUG_CHECK executed by the interpreter
+  // for some opcodes, but not before the first explicit DebugCheck opcode is
+  // encountered.
+  build_debug_step_checks_ = true;
+  BuildDebugStepCheck();
 }
 
 void BytecodeFlowGraphBuilder::BuildPushConstant() {
@@ -789,6 +794,8 @@
     UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
   }
 
+  // A DebugStepCheck is performed as part of the calling stub.
+
   const Function& target = Function::Cast(ConstantAt(DecodeOperandD()).value());
   const intptr_t argc = DecodeOperandF().value();
 
@@ -855,6 +862,8 @@
     UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
   }
 
+  // A DebugStepCheck is performed as part of the calling stub.
+
   const Function& interface_target =
       Function::Cast(ConstantAt(DecodeOperandD()).value());
   const String& name = String::ZoneHandle(Z, interface_target.name());
@@ -929,6 +938,8 @@
     UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
   }
 
+  BuildDebugStepCheck();
+
   const Array& arg_desc_array =
       Array::Cast(ConstantAt(DecodeOperandD()).value());
   const ArgumentsDescriptor arg_desc(arg_desc_array);
@@ -958,8 +969,17 @@
     UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
   }
 
+  // A DebugStepCheck is performed as part of the calling stub.
+
   const ICData& icdata = ICData::Cast(ConstantAt(DecodeOperandD()).value());
-  ASSERT(ic_data_array_->At(icdata.deopt_id())->Original() == icdata.raw());
+  const intptr_t deopt_id = icdata.deopt_id();
+  ic_data_array_->EnsureLength(deopt_id + 1, nullptr);
+  if (ic_data_array_->At(deopt_id) == nullptr) {
+    (*ic_data_array_)[deopt_id] = &icdata;
+  } else {
+    ASSERT(ic_data_array_->At(deopt_id)->Original() == icdata.raw());
+  }
+  B->reset_context_depth_for_deopt_id(deopt_id);
 
   const intptr_t argc = DecodeOperandF().value();
   const ArgumentsDescriptor arg_desc(
@@ -1193,6 +1213,8 @@
     UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
   }
 
+  BuildDebugStepCheck();
+
   LoadStackSlots(1);
   Operand cp_index = DecodeOperandD();
 
@@ -1201,6 +1223,25 @@
   code_ += B->StoreStaticField(position_, field);
 }
 
+void BytecodeFlowGraphBuilder::BuildLoadStatic() {
+  const Constant operand = ConstantAt(DecodeOperandD());
+  const auto& field = Field::Cast(operand.value());
+  // All constant expressions (including access to const fields) are evaluated
+  // in bytecode. However, values of injected cid fields are only available in
+  // the VM. In such case, evaluate const fields with known value here.
+  if (field.is_const() && !field.has_initializer()) {
+    const auto& value = Object::ZoneHandle(Z, field.StaticValue());
+    ASSERT((value.raw() != Object::sentinel().raw()) &&
+           (value.raw() != Object::transition_sentinel().raw()));
+    code_ += B->Constant(value);
+    return;
+  }
+  PushConstant(operand);
+  code_ += B->LoadStaticField();
+}
+
+static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 19,
+              "Cleanup PushStatic bytecode instruction");
 void BytecodeFlowGraphBuilder::BuildPushStatic() {
   // Note: Field object is both pushed into the stack and
   // available in constant pool entry D.
@@ -1509,6 +1550,7 @@
 }
 
 void BytecodeFlowGraphBuilder::BuildReturnTOS() {
+  BuildDebugStepCheck();
   LoadStackSlots(1);
   ASSERT(code_.is_open());
   code_ += B->Return(position_);
@@ -1524,6 +1566,8 @@
     UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
   }
 
+  BuildDebugStepCheck();
+
   if (DecodeOperandA().value() == 0) {
     // throw
     LoadStackSlots(1);
@@ -1580,6 +1624,8 @@
 }
 
 void BytecodeFlowGraphBuilder::BuildEqualsNull() {
+  BuildDebugStepCheck();
+
   ASSERT(scratch_var_ != nullptr);
   LoadStackSlots(1);
 
@@ -1613,6 +1659,8 @@
   ASSERT((num_args == 1) || (num_args == 2));
   ASSERT(MethodTokenRecognizer::RecognizeTokenKind(name) == token_kind);
 
+  // A DebugStepCheck is performed as part of the calling stub.
+
   LoadStackSlots(num_args);
   const ArgumentArray arguments = GetArguments(num_args);
 
@@ -1769,6 +1817,14 @@
   code_ += B->BuildFfiAsFunctionInternalCall(type_args);
 }
 
+void BytecodeFlowGraphBuilder::BuildDebugStepCheck() {
+#if !defined(PRODUCT)
+  if (build_debug_step_checks_) {
+    code_ += B->DebugStepCheck(position_);
+  }
+#endif  // !defined(PRODUCT)
+}
+
 static bool IsICDataEntry(const ObjectPool& object_pool, intptr_t index) {
   if (object_pool.TypeAt(index) != ObjectPool::EntryType::kTaggedObject) {
     return false;
@@ -1781,30 +1837,14 @@
 // pre-populate ic_data_array_.
 void BytecodeFlowGraphBuilder::ProcessICDataInObjectPool(
     const ObjectPool& object_pool) {
-  CompilerState& compiler_state = thread()->compiler_state();
-  ASSERT(compiler_state.deopt_id() == 0);
+  ASSERT(thread()->compiler_state().deopt_id() == 0);
 
   const intptr_t pool_length = object_pool.Length();
   for (intptr_t i = 0; i < pool_length; ++i) {
     if (IsICDataEntry(object_pool, i)) {
       const ICData& icdata = ICData::CheckedHandle(Z, object_pool.ObjectAt(i));
-      const intptr_t deopt_id = compiler_state.GetNextDeoptId();
-
+      const intptr_t deopt_id = B->GetNextDeoptId();
       ASSERT(icdata.deopt_id() == deopt_id);
-      ASSERT(ic_data_array_->is_empty() ||
-             (ic_data_array_->At(deopt_id)->Original() == icdata.raw()));
-    }
-  }
-
-  if (ic_data_array_->is_empty()) {
-    const intptr_t len = compiler_state.deopt_id();
-    ic_data_array_->EnsureLength(len, nullptr);
-    for (intptr_t i = 0; i < pool_length; ++i) {
-      if (IsICDataEntry(object_pool, i)) {
-        const ICData& icdata =
-            ICData::CheckedHandle(Z, object_pool.ObjectAt(i));
-        (*ic_data_array_)[icdata.deopt_id()] = &icdata;
-      }
     }
   }
 }
@@ -2007,6 +2047,35 @@
   }
 }
 
+#if !defined(PRODUCT)
+intptr_t BytecodeFlowGraphBuilder::UpdateContextLevel(const Bytecode& bytecode,
+                                                      intptr_t pc) {
+  ASSERT(B->is_recording_context_levels());
+
+  kernel::BytecodeLocalVariablesIterator iter(Z, bytecode);
+  intptr_t context_level = 0;
+  intptr_t next_pc = bytecode_length_;
+  while (iter.MoveNext()) {
+    if (iter.IsScope()) {
+      if (iter.StartPC() <= pc) {
+        if (pc < iter.EndPC()) {
+          // Found enclosing scope. Keep looking as we might find more
+          // scopes (the last one is the most specific).
+          context_level = iter.ContextLevel();
+          next_pc = iter.EndPC();
+        }
+      } else {
+        next_pc = Utils::Minimum(next_pc, iter.StartPC());
+        break;
+      }
+    }
+  }
+
+  B->set_context_depth(context_level);
+  return next_pc;
+}
+#endif  // !defined(PRODUCT)
+
 FlowGraph* BytecodeFlowGraphBuilder::BuildGraph() {
   const Bytecode& bytecode = Bytecode::Handle(Z, function().bytecode());
 
@@ -2031,6 +2100,11 @@
   kernel::BytecodeSourcePositionsIterator source_pos_iter(Z, bytecode);
   bool update_position = source_pos_iter.MoveNext();
 
+#if !defined(PRODUCT)
+  intptr_t next_pc_to_update_context_level =
+      B->is_recording_context_levels() ? 0 : bytecode_length_;
+#endif
+
   code_ = Fragment(normal_entry);
 
   for (pc_ = 0; pc_ < bytecode_length_; pc_ = next_pc_) {
@@ -2063,6 +2137,12 @@
       update_position = source_pos_iter.MoveNext();
     }
 
+#if !defined(PRODUCT)
+    if (pc_ >= next_pc_to_update_context_level) {
+      next_pc_to_update_context_level = UpdateContextLevel(bytecode, pc_);
+    }
+#endif
+
     BuildInstruction(KernelBytecode::DecodeOpcode(bytecode_instr_));
 
     if (code_.is_closed()) {
diff --git a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h
index 1373875..ec78290 100644
--- a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h
+++ b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h
@@ -152,6 +152,7 @@
 
   void BuildInstruction(KernelBytecode::Opcode opcode);
   void BuildFfiAsFunction();
+  void BuildDebugStepCheck();
 
 #define DECLARE_BUILD_METHOD(name, encoding, kind, op1, op2, op3)              \
   void Build##name();
@@ -167,6 +168,12 @@
                           const ExceptionHandlers& handlers,
                           GraphEntryInstr* graph_entry);
 
+#if !defined(PRODUCT)
+  // Update context level for the given bytecode PC. returns
+  // next PC where context level might need an update.
+  intptr_t UpdateContextLevel(const Bytecode& bytecode, intptr_t pc);
+#endif
+
   // Figure out entry points style.
   UncheckedEntryPointStyle ChooseEntryPointStyle(
       const KBCInstr* jump_if_unchecked);
@@ -207,6 +214,7 @@
   JoinEntryInstr* throw_no_such_method_;
   GraphEntryInstr* graph_entry_ = nullptr;
   UncheckedEntryPointStyle entry_point_style_ = UncheckedEntryPointStyle::kNone;
+  bool build_debug_step_checks_ = false;
 };
 
 }  // namespace kernel
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.cc b/runtime/vm/compiler/frontend/bytecode_reader.cc
index 147544b..5c7a623 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.cc
+++ b/runtime/vm/compiler/frontend/bytecode_reader.cc
@@ -14,9 +14,11 @@
 #include "vm/dart_api_impl.h"  // For Api::IsFfiEnabled().
 #include "vm/dart_entry.h"
 #include "vm/debugger.h"
+#include "vm/hash.h"
 #include "vm/longjump.h"
 #include "vm/object_store.h"
 #include "vm/reusable_handles.h"
+#include "vm/scopes.h"
 #include "vm/stack_frame_kbc.h"
 #include "vm/timeline.h"
 
@@ -142,6 +144,37 @@
       library, bytecode_component.GetNumLibraries());
 }
 
+bool BytecodeMetadataHelper::FindModifiedLibrariesForHotReload(
+    BitVector* modified_libs,
+    bool* is_empty_program,
+    intptr_t* p_num_classes,
+    intptr_t* p_num_procedures) {
+  ASSERT(Thread::Current()->IsMutatorThread());
+
+  if (translation_helper_.GetBytecodeComponent() == Array::null()) {
+    return false;
+  }
+
+  BytecodeComponentData bytecode_component(
+      &Array::Handle(helper_->zone_, GetBytecodeComponent()));
+  BytecodeReaderHelper bytecode_reader(&H, active_class_, &bytecode_component);
+  AlternativeReadingScope alt(&bytecode_reader.reader(),
+                              bytecode_component.GetLibraryIndexOffset());
+  bytecode_reader.FindModifiedLibrariesForHotReload(
+      modified_libs, bytecode_component.GetNumLibraries());
+
+  if (is_empty_program != nullptr) {
+    *is_empty_program = (bytecode_component.GetNumLibraries() == 0);
+  }
+  if (p_num_classes != nullptr) {
+    *p_num_classes = (bytecode_component.GetNumClasses() == 0);
+  }
+  if (p_num_procedures != nullptr) {
+    *p_num_procedures = (bytecode_component.GetNumCodes() == 0);
+  }
+  return true;
+}
+
 RawLibrary* BytecodeMetadataHelper::GetMainLibrary() {
   const intptr_t md_offset = GetComponentMetadataPayloadOffset();
   if (md_offset < 0) {
@@ -1148,6 +1181,7 @@
   intptr_t num_libraries = 0;
   intptr_t library_index_offset = 0;
   intptr_t libraries_offset = 0;
+  intptr_t num_classes = 0;
   intptr_t classes_offset = 0;
   static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 10,
                 "Cleanup condition");
@@ -1158,14 +1192,14 @@
     reader_.ReadUInt32();  // Skip libraries.numItems
     libraries_offset = start_offset + reader_.ReadUInt32();
 
-    reader_.ReadUInt32();  // Skip classes.numItems
+    num_classes = reader_.ReadUInt32();
     classes_offset = start_offset + reader_.ReadUInt32();
   }
 
   reader_.ReadUInt32();  // Skip members.numItems
   const intptr_t members_offset = start_offset + reader_.ReadUInt32();
 
-  reader_.ReadUInt32();  // Skip codes.numItems
+  const intptr_t num_codes = reader_.ReadUInt32();
   const intptr_t codes_offset = start_offset + reader_.ReadUInt32();
 
   reader_.ReadUInt32();  // Skip sourcePositions.numItems
@@ -1214,8 +1248,8 @@
       Z, BytecodeComponentData::New(
              Z, version, num_objects, string_table_offset,
              strings_contents_offset, objects_contents_offset, main_offset,
-             num_libraries, library_index_offset, libraries_offset,
-             classes_offset, members_offset, codes_offset,
+             num_libraries, library_index_offset, libraries_offset, num_classes,
+             classes_offset, members_offset, num_codes, codes_offset,
              source_positions_offset, source_files_offset, line_starts_offset,
              local_variables_offset, annotations_offset, Heap::kOld));
 
@@ -2663,6 +2697,23 @@
   }
 }
 
+void BytecodeReaderHelper::FindModifiedLibrariesForHotReload(
+    BitVector* modified_libs,
+    intptr_t num_libraries) {
+  auto& uri = String::Handle(Z);
+  auto& lib = Library::Handle(Z);
+  for (intptr_t i = 0; i < num_libraries; ++i) {
+    uri ^= ReadObject();
+    reader_.ReadUInt();  // Skip offset.
+
+    lib = Library::LookupLibrary(thread_, uri);
+    if (!lib.IsNull() && !lib.is_dart_scheme()) {
+      // This is a library that already exists so mark it as being modified.
+      modified_libs->Add(lib.index());
+    }
+  }
+}
+
 void BytecodeReaderHelper::ReadParameterCovariance(
     const Function& function,
     BitVector* is_covariant,
@@ -3028,6 +3079,10 @@
   return Smi::Value(Smi::RawCast(data_.At(kLibrariesOffset)));
 }
 
+intptr_t BytecodeComponentData::GetNumClasses() const {
+  return Smi::Value(Smi::RawCast(data_.At(kNumClasses)));
+}
+
 intptr_t BytecodeComponentData::GetClassesOffset() const {
   return Smi::Value(Smi::RawCast(data_.At(kClassesOffset)));
 }
@@ -3036,6 +3091,10 @@
   return Smi::Value(Smi::RawCast(data_.At(kMembersOffset)));
 }
 
+intptr_t BytecodeComponentData::GetNumCodes() const {
+  return Smi::Value(Smi::RawCast(data_.At(kNumCodes)));
+}
+
 intptr_t BytecodeComponentData::GetCodesOffset() const {
   return Smi::Value(Smi::RawCast(data_.At(kCodesOffset)));
 }
@@ -3078,8 +3137,10 @@
                                      intptr_t num_libraries,
                                      intptr_t library_index_offset,
                                      intptr_t libraries_offset,
+                                     intptr_t num_classes,
                                      intptr_t classes_offset,
                                      intptr_t members_offset,
+                                     intptr_t num_codes,
                                      intptr_t codes_offset,
                                      intptr_t source_positions_offset,
                                      intptr_t source_files_offset,
@@ -3115,12 +3176,18 @@
   smi_handle = Smi::New(libraries_offset);
   data.SetAt(kLibrariesOffset, smi_handle);
 
+  smi_handle = Smi::New(num_classes);
+  data.SetAt(kNumClasses, smi_handle);
+
   smi_handle = Smi::New(classes_offset);
   data.SetAt(kClassesOffset, smi_handle);
 
   smi_handle = Smi::New(members_offset);
   data.SetAt(kMembersOffset, smi_handle);
 
+  smi_handle = Smi::New(num_codes);
+  data.SetAt(kNumCodes, smi_handle);
+
   smi_handle = Smi::New(codes_offset);
   data.SetAt(kCodesOffset, smi_handle);
 
@@ -3394,11 +3461,7 @@
   ASSERT(!bytecode.IsNull());
   ASSERT(function.bytecode() == bytecode.raw());
 
-  struct VarDesc {
-    const String* name;
-    RawLocalVarDescriptors::VarInfo info;
-  };
-  GrowableArray<VarDesc> vars(8);
+  LocalVarDescriptorsBuilder vars;
 
   if (function.IsLocalFunction()) {
     const auto& parent = Function::Handle(zone, function.parent_function());
@@ -3419,8 +3482,8 @@
             function.token_pos() <= var_info.end_pos) ||
            (function.token_pos() <= var_info.begin_pos &&
             var_info.begin_pos <= function.end_token_pos()))) {
-        vars.Add(
-            VarDesc{&String::Handle(zone, parent_vars.GetName(i)), var_info});
+        vars.Add(LocalVarDescriptorsBuilder::VarDesc{
+            &String::Handle(zone, parent_vars.GetName(i)), var_info});
       }
     }
   }
@@ -3436,7 +3499,7 @@
           context_level = local_vars.ContextLevel();
         } break;
         case BytecodeLocalVariablesIterator::kVariableDeclaration: {
-          VarDesc desc;
+          LocalVarDescriptorsBuilder::VarDesc desc;
           desc.name = &String::Handle(zone, local_vars.Name());
           if (local_vars.IsCaptured()) {
             desc.info.set_kind(RawLocalVarDescriptors::kContextVar);
@@ -3461,7 +3524,7 @@
         case BytecodeLocalVariablesIterator::kContextVariable: {
           ASSERT(local_vars.Index() >= 0);
           const intptr_t context_variable_index = -local_vars.Index();
-          VarDesc desc;
+          LocalVarDescriptorsBuilder::VarDesc desc;
           desc.name = &Symbols::CurrentContextVar();
           desc.info.set_kind(RawLocalVarDescriptors::kSavedCurrentContext);
           desc.info.scope_id = 0;
@@ -3475,15 +3538,7 @@
     }
   }
 
-  if (vars.is_empty()) {
-    return Object::empty_var_descriptors().raw();
-  }
-  const LocalVarDescriptors& var_desc = LocalVarDescriptors::Handle(
-      zone, LocalVarDescriptors::New(vars.length()));
-  for (intptr_t i = 0; i < vars.length(); i++) {
-    var_desc.SetVar(i, *(vars[i].name), &vars[i].info);
-  }
-  return var_desc.raw();
+  return vars.Done();
 }
 #endif  // !defined(PRODUCT)
 
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.h b/runtime/vm/compiler/frontend/bytecode_reader.h
index 27d0922..a3ad88a 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.h
+++ b/runtime/vm/compiler/frontend/bytecode_reader.h
@@ -37,6 +37,14 @@
   // Read specific library declaration.
   void ReadLibrary(const Library& library);
 
+  // Scan through libraries in the bytecode component and figure out if any of
+  // them will replace libraries which are already loaded.
+  // Return true if bytecode component is found.
+  bool FindModifiedLibrariesForHotReload(BitVector* modified_libs,
+                                         bool* is_empty_program,
+                                         intptr_t* p_num_classes,
+                                         intptr_t* p_num_procedures);
+
   RawLibrary* GetMainLibrary();
 
   RawArray* GetBytecodeComponent();
@@ -70,6 +78,8 @@
   void ReadLibraryDeclarations(intptr_t num_libraries);
   void FindAndReadSpecificLibrary(const Library& library,
                                   intptr_t num_libraries);
+  void FindModifiedLibrariesForHotReload(BitVector* modified_libs,
+                                         intptr_t num_libraries);
 
   void ParseBytecodeFunction(ParsedFunction* parsed_function,
                              const Function& function);
@@ -252,8 +262,10 @@
     kNumLibraries,
     kLibraryIndexOffset,
     kLibrariesOffset,
+    kNumClasses,
     kClassesOffset,
     kMembersOffset,
+    kNumCodes,
     kCodesOffset,
     kSourcePositionsOffset,
     kSourceFilesOffset,
@@ -275,8 +287,10 @@
   intptr_t GetNumLibraries() const;
   intptr_t GetLibraryIndexOffset() const;
   intptr_t GetLibrariesOffset() const;
+  intptr_t GetNumClasses() const;
   intptr_t GetClassesOffset() const;
   intptr_t GetMembersOffset() const;
+  intptr_t GetNumCodes() const;
   intptr_t GetCodesOffset() const;
   intptr_t GetSourcePositionsOffset() const;
   intptr_t GetSourceFilesOffset() const;
@@ -298,8 +312,10 @@
                        intptr_t num_libraries,
                        intptr_t library_index_offset,
                        intptr_t libraries_offset,
+                       intptr_t num_classes,
                        intptr_t classes_offset,
                        intptr_t members_offset,
+                       intptr_t num_codes,
                        intptr_t codes_offset,
                        intptr_t source_positions_offset,
                        intptr_t source_files_offset,
diff --git a/runtime/vm/compiler/frontend/kernel_fingerprints.cc b/runtime/vm/compiler/frontend/kernel_fingerprints.cc
index a7b1a1d..bed6c0f 100644
--- a/runtime/vm/compiler/frontend/kernel_fingerprints.cc
+++ b/runtime/vm/compiler/frontend/kernel_fingerprints.cc
@@ -298,6 +298,9 @@
       // read string reference (i.e. named_parameters[i].name).
       CalculateStringReferenceFingerprint();
       CalculateDartTypeFingerprint();  // read named_parameters[i].type.
+      if (translation_helper_.info().kernel_binary_version() >= 29) {
+        BuildHash(ReadFlags());  // read flags.
+      }
     }
   }
 
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index 5e0e452..90b63be 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -577,6 +577,9 @@
       Class::Handle(Z, library.LookupClassAllowPrivate(class_name));
   CheckStaticLookup(klass);
   ASSERT(!klass.IsNull());
+  if (klass.is_declared_in_bytecode()) {
+    klass.EnsureDeclarationLoaded();
+  }
   name_index_handle_ = Smi::New(kernel_class);
   return info_.InsertClass(thread_, name_index_handle_, klass);
 }
@@ -1002,7 +1005,11 @@
       if (++next_read_ == field) return;
       FALL_THROUGH;
     case kFlags:
-      flags_ = helper_->ReadFlags();
+      if (helper_->translation_helper_.info().kernel_binary_version() >= 29) {
+        flags_ = helper_->ReadUInt();
+      } else {
+        flags_ = helper_->ReadFlags();
+      }
       if (++next_read_ == field) return;
       FALL_THROUGH;
     case kName:
@@ -1070,7 +1077,11 @@
       if (++next_read_ == field) return;
       FALL_THROUGH;
     case kFlags:
-      flags_ = helper_->ReadFlags();
+      if (helper_->translation_helper_.info().kernel_binary_version() >= 29) {
+        flags_ = helper_->ReadUInt();
+      } else {
+        flags_ = helper_->ReadFlags();
+      }
       if (++next_read_ == field) return;
       FALL_THROUGH;
     case kName:
@@ -2023,6 +2034,9 @@
       // read string reference (i.e. named_parameters[i].name).
       SkipStringReference();
       SkipDartType();  // read named_parameters[i].type.
+      if (translation_helper_.info().kernel_binary_version() >= 29) {
+        SkipBytes(1);  // read flags
+      }
     }
   }
 
@@ -2887,6 +2901,10 @@
       // read string reference (i.e. named_parameters[i].name).
       String& name = H.DartSymbolObfuscate(helper_->ReadStringReference());
       BuildTypeInternal();  // read named_parameters[i].type.
+      if (translation_helper_.info().kernel_binary_version() >= 29) {
+        // TODO(markov): Store 'required' bit.
+        helper_->ReadFlags();  // read flags
+      }
       parameter_types.SetAt(pos, result_);
       parameter_names.SetAt(pos, name);
     }
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h
index 0cc2ee4..f529feb 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.h
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h
@@ -469,7 +469,7 @@
   NameIndex canonical_name_;
   TokenPosition position_;
   TokenPosition end_position_;
-  uint8_t flags_ = 0;
+  uint32_t flags_ = 0;
   intptr_t source_uri_index_ = 0;
   intptr_t annotation_count_ = 0;
 
@@ -555,7 +555,7 @@
   TokenPosition position_;
   TokenPosition end_position_;
   Kind kind_;
-  uint8_t flags_ = 0;
+  uint32_t flags_ = 0;
   intptr_t source_uri_index_ = 0;
   intptr_t annotation_count_ = 0;
 
diff --git a/runtime/vm/compiler/frontend/scope_builder.cc b/runtime/vm/compiler/frontend/scope_builder.cc
index 6cd7bb6..fcf01e8 100644
--- a/runtime/vm/compiler/frontend/scope_builder.cc
+++ b/runtime/vm/compiler/frontend/scope_builder.cc
@@ -1362,6 +1362,9 @@
       // read string reference (i.e. named_parameters[i].name).
       helper_.SkipStringReference();
       VisitDartType();  // read named_parameters[i].type.
+      if (helper_.translation_helper_.info().kernel_binary_version() >= 29) {
+        helper_.ReadByte();  // read flags
+      }
     }
   }
 
diff --git a/runtime/vm/compiler/graph_intrinsifier.cc b/runtime/vm/compiler/graph_intrinsifier.cc
index db4e7dc..d251b3e 100644
--- a/runtime/vm/compiler/graph_intrinsifier.cc
+++ b/runtime/vm/compiler/graph_intrinsifier.cc
@@ -285,6 +285,8 @@
     case kTypedDataUint16ArrayCid:
     case kExternalTypedDataUint8ArrayCid:
     case kExternalTypedDataUint8ClampedArrayCid:
+      builder.AddInstruction(new CheckSmiInstr(new Value(value), DeoptId::kNone,
+                                               builder.TokenPos()));
       value = builder.AddUnboxInstr(kUnboxedIntPtr, new Value(value),
                                     /* is_checked = */ false);
       value->AsUnboxInteger()->mark_truncating();
diff --git a/runtime/vm/compiler/jit/compiler.cc b/runtime/vm/compiler/jit/compiler.cc
index 05a9a88..b2b2c29 100644
--- a/runtime/vm/compiler/jit/compiler.cc
+++ b/runtime/vm/compiler/jit/compiler.cc
@@ -618,17 +618,15 @@
         FlowGraphPrinter::PrintGraph("Unoptimized Compilation", flow_graph);
       }
 
-      BlockScheduler block_scheduler(flow_graph);
       const bool reorder_blocks =
           FlowGraph::ShouldReorderBlocks(function, optimized());
       if (reorder_blocks) {
         TIMELINE_DURATION(thread(), CompilerVerbose,
                           "BlockScheduler::AssignEdgeWeights");
-        block_scheduler.AssignEdgeWeights();
+        BlockScheduler::AssignEdgeWeights(flow_graph);
       }
 
       CompilerPassState pass_state(thread(), flow_graph, &speculative_policy);
-      pass_state.block_scheduler = &block_scheduler;
       pass_state.reorder_blocks = reorder_blocks;
 
       if (optimized()) {
@@ -998,38 +996,43 @@
   ASSERT(code.var_descriptors() == Object::null());
   // IsIrregexpFunction have eager var descriptors generation.
   ASSERT(!function.IsIrregexpFunction());
-  if (function.is_declared_in_bytecode()) {
-    auto& var_descs = LocalVarDescriptors::Handle();
-    if (function.HasBytecode()) {
-      const auto& bytecode = Bytecode::Handle(function.bytecode());
-      var_descs = bytecode.GetLocalVarDescriptors();
-    } else {
-      var_descs = Object::empty_var_descriptors().raw();
-    }
-    code.set_var_descriptors(var_descs);
-    return;
-  }
   // In background compilation, parser can produce 'errors": bailouts
   // if state changed while compiling in background.
-  CompilerState state(Thread::Current());
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
+  CompilerState state(thread);
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
-    ParsedFunction* parsed_function = new ParsedFunction(
-        Thread::Current(), Function::ZoneHandle(function.raw()));
+    ParsedFunction* parsed_function =
+        new ParsedFunction(thread, Function::ZoneHandle(zone, function.raw()));
     ZoneGrowableArray<const ICData*>* ic_data_array =
         new ZoneGrowableArray<const ICData*>();
     ZoneGrowableArray<intptr_t>* context_level_array =
         new ZoneGrowableArray<intptr_t>();
 
-    parsed_function->EnsureKernelScopes();
     kernel::FlowGraphBuilder builder(
         parsed_function, ic_data_array, context_level_array,
         /* not inlining */ NULL, false, Compiler::kNoOSRDeoptId);
     builder.BuildGraph();
 
-    const LocalVarDescriptors& var_descs =
-        LocalVarDescriptors::Handle(parsed_function->scope()->GetVarDescriptors(
-            function, context_level_array));
+    auto& var_descs = LocalVarDescriptors::Handle(zone);
+
+    if (function.is_declared_in_bytecode()) {
+      if (function.HasBytecode()) {
+        const auto& bytecode = Bytecode::Handle(zone, function.bytecode());
+        var_descs = bytecode.GetLocalVarDescriptors();
+        LocalVarDescriptorsBuilder builder;
+        builder.AddDeoptIdToContextLevelMappings(context_level_array);
+        builder.AddAll(zone, var_descs);
+        var_descs = builder.Done();
+      } else {
+        var_descs = Object::empty_var_descriptors().raw();
+      }
+    } else {
+      var_descs = parsed_function->scope()->GetVarDescriptors(
+          function, context_level_array);
+    }
+
     ASSERT(!var_descs.IsNull());
     code.set_var_descriptors(var_descs);
   } else {
diff --git a/runtime/vm/compiler/jit/jit_call_specializer.cc b/runtime/vm/compiler/jit/jit_call_specializer.cc
index e605176..4abf730 100644
--- a/runtime/vm/compiler/jit/jit_call_specializer.cc
+++ b/runtime/vm/compiler/jit/jit_call_specializer.cc
@@ -167,7 +167,21 @@
     // Type propagation has not run yet, we cannot eliminate the check.
     // TODO(erikcorry): The receiver check should use the off-heap targets
     // array, not the IC array.
-    AddReceiverCheck(instr);
+
+    // After we determined `targets.HasSingleTarget()` the mutator might have
+    // updated the megamorphic cache by adding more entries with *different*
+    // targets.
+    //
+    // We therefore have to ensure the class check we insert is only valid for
+    // precisely the [targets] classes we have based our decision upon.
+    //
+    // (i.e. we cannot use [AddReceiverCheck]/[AddCheckClass], since it
+    //  internally consults megmorphic cache again, which can return a superset
+    //  of the classes - possibly with different targets)
+    //
+    AddCheckClass(instr->Receiver()->definition(), targets, instr->deopt_id(),
+                  instr->env(), instr);
+
     // Call can still deoptimize, do not detach environment from instr.
     const Function& target =
         Function::ZoneHandle(Z, unary_checks.GetTargetAt(0));
diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc
index b5362e8..22e9f07 100644
--- a/runtime/vm/compiler/runtime_api.cc
+++ b/runtime/vm/compiler/runtime_api.cc
@@ -330,6 +330,10 @@
     case kByteBufferCid:
     case kByteDataViewCid:
     case kFfiPointerCid:
+    case kFfiDynamicLibraryCid:
+#define HANDLE_CASE(clazz) case kFfi##clazz##Cid:
+      CLASS_LIST_FFI_TYPE_MARKER(HANDLE_CASE)
+#undef HANDLE_CASE
 #define HANDLE_CASE(clazz)                                                     \
   case kTypedData##clazz##Cid:                                                 \
   case kTypedData##clazz##ViewCid:                                             \
diff --git a/runtime/vm/constants_kbc.h b/runtime/vm/constants_kbc.h
index 1f972f9..bda63cc 100644
--- a/runtime/vm/constants_kbc.h
+++ b/runtime/vm/constants_kbc.h
@@ -615,8 +615,8 @@
   V(Unused17,                              0, RESV, ___, ___, ___)             \
   V(PopLocal,                              X, ORDN, xeg, ___, ___)             \
   V(PopLocal_Wide,                         X, WIDE, xeg, ___, ___)             \
-  V(Unused18,                              0, RESV, ___, ___, ___)             \
-  V(Unused19,                              0, RESV, ___, ___, ___)             \
+  V(LoadStatic,                            D, ORDN, lit, ___, ___)             \
+  V(LoadStatic_Wide,                       D, WIDE, lit, ___, ___)             \
   V(StoreLocal,                            X, ORDN, xeg, ___, ___)             \
   V(StoreLocal_Wide,                       X, WIDE, xeg, ___, ___)             \
   V(LoadFieldTOS,                          D, ORDN, lit, ___, ___)             \
@@ -749,7 +749,7 @@
   // Maximum bytecode format version supported by VM.
   // The range of supported versions should include version produced by bytecode
   // generator (currentBytecodeFormatVersion in pkg/vm/lib/bytecode/dbc.dart).
-  static const intptr_t kMaxSupportedBytecodeFormatVersion = 18;
+  static const intptr_t kMaxSupportedBytecodeFormatVersion = 19;
 
   enum Opcode {
 #define DECLARE_BYTECODE(name, encoding, kind, op1, op2, op3) k##name,
@@ -970,14 +970,14 @@
     return DecodeOpcode(instr) == KernelBytecode::kDebugCheck;
   }
 
-  // The interpreter, the bytecode generator, and this function must agree on
-  // this list of opcodes.
-  // The interpreter checks for a debug break at each instruction with listed
-  // opcode and the bytecode generator emits a source position at each
-  // instruction with listed opcode.
+  // The interpreter, the bytecode generator, the bytecode compiler, and this
+  // function must agree on this list of opcodes.
+  // For each instruction with listed opcode:
+  // - The interpreter checks for a debug break.
+  // - The bytecode generator emits a source position.
+  // - The bytecode compiler may emit a DebugStepCheck call.
   DART_FORCE_INLINE static bool IsDebugCheckedOpcode(const KBCInstr* instr) {
     switch (DecodeOpcode(instr)) {
-      case KernelBytecode::kAllocate:
       case KernelBytecode::kStoreStaticTOS:
       case KernelBytecode::kStoreStaticTOS_Wide:
       case KernelBytecode::kDebugCheck:
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 17fa83c..72ab506 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -136,7 +136,7 @@
                  Dart_IsolateGroupCreateCallback create_group,
                  Dart_InitializeIsolateCallback initialize_isolate,
                  Dart_IsolateShutdownCallback shutdown,
-                 Dart_IsolateShutdownCallback cleanup,
+                 Dart_IsolateCleanupCallback cleanup,
                  Dart_IsolateGroupCleanupCallback cleanup_group,
                  Dart_ThreadExitCallback thread_exit,
                  Dart_FileOpenCallback file_open,
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 406e1e0..14f3026 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -789,8 +789,10 @@
       while (local_vars.MoveNext()) {
         if (local_vars.Kind() ==
             kernel::BytecodeLocalVariablesIterator::kScope) {
-          if (local_vars.StartPC() <= pc_offset &&
-              pc_offset <= local_vars.EndPC()) {
+          if (local_vars.StartPC() > pc_offset) {
+            break;
+          }
+          if (pc_offset <= local_vars.EndPC()) {
             ASSERT(context_level_ <= local_vars.ContextLevel());
             context_level_ = local_vars.ContextLevel();
           }
@@ -858,7 +860,7 @@
           // Bytecode uses absolute context levels, i.e. the frame context level
           // on entry must be calculated.
           const intptr_t frame_ctx_level =
-              IsInterpreted() ? ctx_.GetLevel() : 0;
+              function().is_declared_in_bytecode() ? ctx_.GetLevel() : 0;
           return GetRelativeContextVar(var_info.scope_id,
                                        variable_index.value(), frame_ctx_level);
         }
@@ -992,6 +994,13 @@
     if (var_descriptors_.GetName(i) == Symbols::AwaitJumpVar().raw()) {
       ASSERT(kind == RawLocalVarDescriptors::kContextVar);
       ASSERT(!ctx_.IsNull());
+      // Variable descriptors constructed from bytecode have all variables of
+      // enclosing functions, even shadowed by the current function.
+      // Check context level in order to pick correct :await_jump_var variable.
+      if (function().is_declared_in_bytecode() &&
+          (ctx_.GetLevel() != var_info.scope_id)) {
+        continue;
+      }
       Object& await_jump_index = Object::Handle(ctx_.At(var_info.index()));
       ASSERT(await_jump_index.IsSmi());
       await_jump_var = Smi::Cast(await_jump_index).Value();
diff --git a/runtime/vm/globals.h b/runtime/vm/globals.h
index 682ee90..aa436e1 100644
--- a/runtime/vm/globals.h
+++ b/runtime/vm/globals.h
@@ -36,7 +36,11 @@
 const intptr_t kBytesPerBigIntDigit = 4;
 
 // The default old gen heap size in MB, where 0 == unlimited.
-const intptr_t kDefaultMaxOldGenHeapSize = (kWordSize <= 4) ? 1536 : 0;
+// 32-bit: OS limit is 2 or 3 GB
+// 64-bit: OS limit is 2^16 page table entries * 256 KB HeapPages = 16 GB
+// Set the VM limit below the OS limit to increase the likelihood of failing
+// gracefully with a Dart OutOfMemory exception instead of SIGABORT.
+const intptr_t kDefaultMaxOldGenHeapSize = (kWordSize <= 4) ? 1536 : 15360;
 
 #define kPosInfinity bit_cast<double>(DART_UINT64_C(0x7ff0000000000000))
 #define kNegInfinity bit_cast<double>(DART_UINT64_C(0xfff0000000000000))
diff --git a/runtime/vm/hash.h b/runtime/vm/hash.h
index aa9c28d..b4fc808 100644
--- a/runtime/vm/hash.h
+++ b/runtime/vm/hash.h
@@ -7,14 +7,14 @@
 
 namespace dart {
 
-static uint32_t CombineHashes(uint32_t hash, uint32_t other_hash) {
+inline uint32_t CombineHashes(uint32_t hash, uint32_t other_hash) {
   hash += other_hash;
   hash += hash << 10;
   hash ^= hash >> 6;  // Logical shift, unsigned hash.
   return hash;
 }
 
-static uint32_t FinalizeHash(uint32_t hash, intptr_t hashbits) {
+inline uint32_t FinalizeHash(uint32_t hash, intptr_t hashbits) {
   hash += hash << 3;
   hash ^= hash >> 11;  // Logical shift, unsigned hash.
   hash += hash << 15;
diff --git a/runtime/vm/hash_map.h b/runtime/vm/hash_map.h
index 1582c79..4f2efda 100644
--- a/runtime/vm/hash_map.h
+++ b/runtime/vm/hash_map.h
@@ -114,6 +114,9 @@
   HashMapListElement* lists_;  // The linked lists containing hash collisions.
   intptr_t free_list_head_;  // Unused elements in lists_ are on the free list.
   Allocator* allocator_;
+
+ private:
+  void operator=(const BaseDirectChainedHashMap& other) = delete;
 };
 
 template <typename KeyValueTrait, typename B, typename Allocator>
@@ -379,6 +382,15 @@
   explicit DirectChainedHashMap(Zone* zone)
       : BaseDirectChainedHashMap<KeyValueTrait, ValueObject>(
             ASSERT_NOTNULL(zone)) {}
+
+  // There is a current use of the copy constructor in CSEInstructionMap
+  // (compiler/backend/redundancy_elimination.cc), so work is needed if we
+  // want to disallow it.
+  DirectChainedHashMap(const DirectChainedHashMap& other)
+      : BaseDirectChainedHashMap<KeyValueTrait, ValueObject>(other) {}
+
+ private:
+  void operator=(const DirectChainedHashMap& other) = delete;
 };
 
 template <typename KeyValueTrait>
@@ -387,6 +399,14 @@
  public:
   MallocDirectChainedHashMap()
       : BaseDirectChainedHashMap<KeyValueTrait, EmptyBase, Malloc>(NULL) {}
+
+  // The only use of the copy constructor seems to be in hash_map_test.cc.
+  // Not disallowing it for now just in case there are other users.
+  MallocDirectChainedHashMap(const MallocDirectChainedHashMap& other)
+      : BaseDirectChainedHashMap<KeyValueTrait, EmptyBase, Malloc>(other) {}
+
+ private:
+  void operator=(const MallocDirectChainedHashMap& other) = delete;
 };
 
 template <typename T>
@@ -461,6 +481,10 @@
 template <typename V>
 class IntMap : public DirectChainedHashMap<IntKeyRawPointerValueTrait<V> > {
  public:
+  IntMap() : DirectChainedHashMap<IntKeyRawPointerValueTrait<V>>() {}
+  explicit IntMap(Zone* zone)
+      : DirectChainedHashMap<IntKeyRawPointerValueTrait<V>>(zone) {}
+
   typedef typename IntKeyRawPointerValueTrait<V>::Key Key;
   typedef typename IntKeyRawPointerValueTrait<V>::Value Value;
   typedef typename IntKeyRawPointerValueTrait<V>::Pair Pair;
@@ -483,6 +507,9 @@
   inline Pair* LookupPair(const Key& key) {
     return DirectChainedHashMap<IntKeyRawPointerValueTrait<V> >::Lookup(key);
   }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(IntMap);
 };
 
 }  // namespace dart
diff --git a/runtime/vm/heap/compactor.cc b/runtime/vm/heap/compactor.cc
index 45f566e..6a0bfbf 100644
--- a/runtime/vm/heap/compactor.cc
+++ b/runtime/vm/heap/compactor.cc
@@ -213,11 +213,19 @@
     // objects move and all pages that used to have an object are released.
     // This can be helpful for finding untracked pointers because it prevents
     // an untracked pointer from getting lucky with its target not moving.
-    for (intptr_t task_index = 0; task_index < num_tasks; task_index++) {
+    bool oom = false;
+    for (intptr_t task_index = 0; task_index < num_tasks && !oom;
+         task_index++) {
       const intptr_t pages_per_task = num_pages / num_tasks;
       for (intptr_t j = 0; j < pages_per_task; j++) {
         HeapPage* page = heap_->old_space()->AllocatePage(HeapPage::kData,
                                                           /* link */ false);
+
+        if (page == nullptr) {
+          oom = true;
+          break;
+        }
+
         FreeListElement::AsElement(page->object_start(),
                                    page->object_end() - page->object_start());
 
diff --git a/runtime/vm/interpreter.cc b/runtime/vm/interpreter.cc
index aafaf7d..84c7eec 100644
--- a/runtime/vm/interpreter.cc
+++ b/runtime/vm/interpreter.cc
@@ -2362,6 +2362,8 @@
   }
 
   {
+    static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 19,
+                  "Cleanup PushStatic bytecode instruction");
     BYTECODE(PushStatic, D);
     RawField* field = reinterpret_cast<RawField*>(LOAD_CONSTANT(rD));
     // Note: field is also on the stack, hence no increment.
@@ -2370,6 +2372,16 @@
   }
 
   {
+    BYTECODE(LoadStatic, D);
+    RawField* field = reinterpret_cast<RawField*>(LOAD_CONSTANT(rD));
+    RawInstance* value = field->ptr()->value_.static_value_;
+    ASSERT((value != Object::sentinel().raw()) &&
+           (value != Object::transition_sentinel().raw()));
+    *++SP = value;
+    DISPATCH();
+  }
+
+  {
     BYTECODE(StoreFieldTOS, D);
     RawField* field = RAW_CAST(Field, LOAD_CONSTANT(rD + 1));
     RawInstance* instance = reinterpret_cast<RawInstance*>(SP[-1]);
@@ -2544,7 +2556,6 @@
 
   {
     BYTECODE(Allocate, D);
-    DEBUG_CHECK;
     RawClass* cls = Class::RawCast(LOAD_CONSTANT(rD));
     if (LIKELY(InterpreterHelpers::IsFinalized(cls))) {
       const intptr_t class_id = cls->ptr()->id_;
@@ -2574,7 +2585,6 @@
 
   {
     BYTECODE(AllocateT, 0);
-    DEBUG_CHECK;
     RawClass* cls = Class::RawCast(SP[0]);
     RawTypeArguments* type_args = TypeArguments::RawCast(SP[-1]);
     if (LIKELY(InterpreterHelpers::IsFinalized(cls))) {
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 4872ac4..12d341c 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -1219,6 +1219,7 @@
   friend class GCMarker;  // VisitObjectPointers
   friend class SafepointHandler;
   friend class ObjectGraph;  // VisitObjectPointers
+  friend class HeapSnapshotWriter;  // VisitObjectPointers
   friend class Scavenger;    // VisitObjectPointers
   friend class HeapIterationScope;  // VisitObjectPointers
   friend class ServiceIsolate;
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index b931cd7..5fe3c39 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -1377,6 +1377,10 @@
     return;
   }
 
+  if (old_cls.IsTopLevel()) {
+    return;
+  }
+
   ASSERT(new_cls.is_finalized() == old_cls.is_finalized());
   if (!new_cls.is_finalized()) {
     if (new_cls.SourceFingerprint() == old_cls.SourceFingerprint()) {
@@ -1435,6 +1439,36 @@
   VerifyMaps();
 #endif
 
+  // Copy over certain properties of libraries, e.g. is the library
+  // debuggable?
+  {
+    TIMELINE_SCOPE(CopyLibraryBits);
+    Library& lib = Library::Handle();
+    Library& new_lib = Library::Handle();
+
+    UnorderedHashMap<LibraryMapTraits> lib_map(library_map_storage_);
+
+    {
+      // Reload existing libraries.
+      UnorderedHashMap<LibraryMapTraits>::Iterator it(&lib_map);
+
+      while (it.MoveNext()) {
+        const intptr_t entry = it.Current();
+        ASSERT(entry != -1);
+        new_lib = Library::RawCast(lib_map.GetKey(entry));
+        lib = Library::RawCast(lib_map.GetPayload(entry, 0));
+        new_lib.set_debuggable(lib.IsDebuggable());
+        // Native extension support.
+        new_lib.set_native_entry_resolver(lib.native_entry_resolver());
+        new_lib.set_native_entry_symbol_resolver(
+            lib.native_entry_symbol_resolver());
+      }
+    }
+
+    // Release the library map.
+    lib_map.Release();
+  }
+
   const GrowableObjectArray& changed_in_last_reload =
       GrowableObjectArray::Handle(GrowableObjectArray::New());
 
@@ -1491,36 +1525,6 @@
   }
   I->object_store()->set_changed_in_last_reload(changed_in_last_reload);
 
-  // Copy over certain properties of libraries, e.g. is the library
-  // debuggable?
-  {
-    TIMELINE_SCOPE(CopyLibraryBits);
-    Library& lib = Library::Handle();
-    Library& new_lib = Library::Handle();
-
-    UnorderedHashMap<LibraryMapTraits> lib_map(library_map_storage_);
-
-    {
-      // Reload existing libraries.
-      UnorderedHashMap<LibraryMapTraits>::Iterator it(&lib_map);
-
-      while (it.MoveNext()) {
-        const intptr_t entry = it.Current();
-        ASSERT(entry != -1);
-        new_lib = Library::RawCast(lib_map.GetKey(entry));
-        lib = Library::RawCast(lib_map.GetPayload(entry, 0));
-        new_lib.set_debuggable(lib.IsDebuggable());
-        // Native extension support.
-        new_lib.set_native_entry_resolver(lib.native_entry_resolver());
-        new_lib.set_native_entry_symbol_resolver(
-            lib.native_entry_symbol_resolver());
-      }
-    }
-
-    // Release the library map.
-    lib_map.Release();
-  }
-
   {
     TIMELINE_SCOPE(UpdateLibrariesArray);
     // Update the libraries array.
@@ -2004,30 +2008,30 @@
     const bool clear_code = IsDirty(owning_lib);
     const bool stub_code = code.IsStubCode();
 
-    // Zero edge counters.
+    // Zero edge counters, before clearing the ICDataArray, since that's where
+    // they're held.
     func.ZeroEdgeCounters();
 
-    if (!stub_code || !bytecode.IsNull()) {
-      if (clear_code) {
-        VTIR_Print("Marking %s for recompilation, clearing code\n",
-                   func.ToCString());
-        // Null out the ICData array and code.
-        func.ClearICDataArray();
-        func.ClearCode();
-        func.SetWasCompiled(false);
-      } else {
-        if (!stub_code) {
-          // We are preserving the unoptimized code, fill all ICData arrays with
-          // the sentinel values so that we have no stale type feedback.
-          code.ResetSwitchableCalls(zone);
-          code.ResetICDatas(zone);
-        }
-        if (!bytecode.IsNull()) {
-          // We are preserving the bytecode, fill all ICData arrays with
-          // the sentinel values so that we have no stale type feedback.
-          bytecode.ResetICDatas(zone);
-        }
-      }
+    if (!bytecode.IsNull()) {
+      // We are preserving the bytecode, fill all ICData arrays with
+      // the sentinel values so that we have no stale type feedback.
+      bytecode.ResetICDatas(zone);
+    }
+
+    if (stub_code) {
+      // Nothing to reset.
+    } else if (clear_code) {
+      VTIR_Print("Marking %s for recompilation, clearing code\n",
+                 func.ToCString());
+      // Null out the ICData array and code.
+      func.ClearICDataArray();
+      func.ClearCode();
+      func.SetWasCompiled(false);
+    } else {
+      // We are preserving the unoptimized code, fill all ICData arrays with
+      // the sentinel values so that we have no stale type feedback.
+      code.ResetSwitchableCalls(zone);
+      code.ResetICDatas(zone);
     }
 
     // Clear counters.
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index 3cfe46e..bad2258 100644
--- a/runtime/vm/kernel_binary.h
+++ b/runtime/vm/kernel_binary.h
@@ -20,7 +20,7 @@
 
 // Both version numbers are inclusive.
 static const uint32_t kMinSupportedKernelFormatVersion = 18;
-static const uint32_t kMaxSupportedKernelFormatVersion = 28;
+static const uint32_t kMaxSupportedKernelFormatVersion = 29;
 
 // Keep in sync with package:kernel/lib/binary/tag.dart
 #define KERNEL_TAG_LIST(V)                                                     \
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index 661a2e1..18c135f 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -915,6 +915,12 @@
                                            bool* is_empty_program,
                                            intptr_t* p_num_classes,
                                            intptr_t* p_num_procedures) {
+  if (FLAG_enable_interpreter || FLAG_use_bytecode_compiler) {
+    if (bytecode_metadata_helper_.FindModifiedLibrariesForHotReload(
+            modified_libs, is_empty_program, p_num_classes, p_num_procedures)) {
+      return;
+    }
+  }
   intptr_t length = program_->library_count();
   *is_empty_program = *is_empty_program && (length == 0);
   bool collect_library_stats =
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 2261ace..1a07cc9 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -17,6 +17,7 @@
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/assembler/disassembler.h"
 #include "vm/compiler/assembler/disassembler_kbc.h"
+#include "vm/compiler/frontend/bytecode_fingerprints.h"
 #include "vm/compiler/frontend/bytecode_reader.h"
 #include "vm/compiler/frontend/kernel_fingerprints.h"
 #include "vm/compiler/frontend/kernel_translation_helper.h"
@@ -2283,6 +2284,16 @@
   return GenerateUserVisibleName();  // No caching in PRODUCT, regenerate.
 }
 
+RawClass* Class::Mixin() const {
+  if (is_transformed_mixin_application()) {
+    const Array& interfaces = Array::Handle(this->interfaces());
+    const Type& mixin_type =
+        Type::Handle(Type::RawCast(interfaces.At(interfaces.Length() - 1)));
+    return mixin_type.type_class();
+  }
+  return raw();
+}
+
 bool Class::IsInFullSnapshot() const {
   NoSafepointScope no_safepoint;
   return raw_ptr()->library_->ptr()->is_in_fullsnapshot_;
@@ -3088,6 +3099,7 @@
   forwarder.set_is_visible(false);
 
   forwarder.ClearICDataArray();
+  forwarder.ClearBytecode();
   forwarder.ClearCode();
   forwarder.set_usage_counter(0);
   forwarder.set_deoptimization_counter(0);
@@ -5752,9 +5764,20 @@
   ASSERT(Thread::Current()->IsMutatorThread());
 
   StorePointer(&raw_ptr()->unoptimized_code_, Code::null());
-  StorePointer(&raw_ptr()->bytecode_, Bytecode::null());
 
-  SetInstructions(StubCode::LazyCompile());
+  if (FLAG_enable_interpreter && HasBytecode()) {
+    SetInstructions(StubCode::InterpretCall());
+  } else {
+    SetInstructions(StubCode::LazyCompile());
+  }
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+}
+
+void Function::ClearBytecode() const {
+#if defined(DART_PRECOMPILED_RUNTIME)
+  UNREACHABLE();
+#else
+  StorePointer(&raw_ptr()->bytecode_, Bytecode::null());
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
 }
 
@@ -7905,10 +7928,11 @@
       result = String::Concat(Symbols::ConstructorStacktracePrefix(), result,
                               Heap::kOld);
     } else {
+      const Class& mixin = Class::Handle(cls.Mixin());
       result = String::Concat(Symbols::Dot(), result, Heap::kOld);
       const String& cls_name = String::Handle(name_visibility == kScrubbedName
                                                   ? cls.ScrubbedName()
-                                                  : cls.UserVisibleName());
+                                                  : mixin.UserVisibleName());
       result = String::Concat(cls_name, result, Heap::kOld);
     }
   }
@@ -7970,7 +7994,8 @@
 int32_t Function::SourceFingerprint() const {
 #if !defined(DART_PRECOMPILED_RUNTIME)
   if (is_declared_in_bytecode()) {
-    return 0;  // TODO(37353): Implement or remove.
+    return kernel::BytecodeFingerprintHelper::CalculateFunctionFingerprint(
+        *this);
   }
   return kernel::KernelSourceFingerprintHelper::CalculateFunctionFingerprint(
       *this);
@@ -15039,6 +15064,7 @@
                                const Code& code,
                                bool optimized) {
 #if !defined(PRODUCT)
+  ASSERT(!function.IsNull());
   ASSERT(!Thread::Current()->IsAtSafepoint());
   // Calling ToLibNamePrefixedQualifiedCString is very expensive,
   // try to avoid it.
@@ -15053,6 +15079,8 @@
                                const Code& code,
                                bool optimized) {
 #if !defined(PRODUCT)
+  ASSERT(name != nullptr);
+  ASSERT(!code.IsNull());
   ASSERT(!Thread::Current()->IsAtSafepoint());
   if (CodeObservers::AreActive()) {
     const auto& instrs = Instructions::Handle(code.instructions());
@@ -15187,7 +15215,7 @@
   if (obj.IsFunction()) {
     const char* opt = is_optimized() ? "[Optimized]" : "[Unoptimized]";
     const char* function_name =
-        String::Handle(zone, Function::Cast(obj).QualifiedScrubbedName())
+        String::Handle(zone, Function::Cast(obj).QualifiedUserVisibleName())
             .ToCString();
     return zone->PrintToString("%s %s", opt, function_name);
   }
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 7557b53..09a7c02 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -349,6 +349,8 @@
     return *obj;
   }
 
+  static Object& ZoneHandle(Zone* zone) { return ZoneHandle(zone, null_); }
+
   static Object& ZoneHandle() {
     return ZoneHandle(Thread::Current()->zone(), null_);
   }
@@ -857,6 +859,11 @@
   RawString* Name() const;
   RawString* ScrubbedName() const;
   RawString* UserVisibleName() const;
+
+  // The mixin for this class if one exists. Otherwise, returns a raw pointer
+  // to this class.
+  RawClass* Mixin() const;
+
   bool IsInFullSnapshot() const;
 
   virtual RawString* DictionaryName() const { return Name(); }
@@ -2243,6 +2250,7 @@
   void AttachCode(const Code& value) const;
   void SetInstructions(const Code& value) const;
   void ClearCode() const;
+  void ClearBytecode() const;
 
   // Disables optimized code and switches to unoptimized code.
   void SwitchToUnoptimizedCode() const;
@@ -7813,6 +7821,7 @@
   friend class ExternalTwoByteString;
   friend class RawOneByteString;
   friend class RODataSerializationCluster;  // SetHash
+  friend class Pass2Visitor;                // Stack "handle"
 };
 
 class OneByteString : public AllStatic {
diff --git a/runtime/vm/object_graph.cc b/runtime/vm/object_graph.cc
index 54203ed..26b607b 100644
--- a/runtime/vm/object_graph.cc
+++ b/runtime/vm/object_graph.cc
@@ -8,14 +8,18 @@
 #include "vm/dart_api_state.h"
 #include "vm/growable_array.h"
 #include "vm/isolate.h"
+#include "vm/native_symbol.h"
 #include "vm/object.h"
 #include "vm/object_store.h"
 #include "vm/raw_object.h"
+#include "vm/raw_object_fields.h"
 #include "vm/reusable_handles.h"
 #include "vm/visitor.h"
 
 namespace dart {
 
+#if !defined(PRODUCT)
+
 static bool IsUserClass(intptr_t cid) {
   if (cid == kContextCid) return true;
   if (cid == kTypeArgumentsCid) return false;
@@ -514,101 +518,107 @@
   return visitor.length();
 }
 
-static void WritePtr(RawObject* raw, WriteStream* stream) {
-  ASSERT(raw->IsHeapObject());
-  ASSERT(raw->IsOldObject());
-  uword addr = RawObject::ToAddr(raw);
-  ASSERT(Utils::IsAligned(addr, kObjectAlignment));
-  // Using units of kObjectAlignment makes the ids fit into Smis when parsed
-  // in the Dart code of the Observatory.
-  // TODO(koda): Use delta-encoding/back-references to further compress this.
-  stream->WriteUnsigned(addr / kObjectAlignment);
+void HeapSnapshotWriter::EnsureAvailable(intptr_t needed) {
+  intptr_t available = capacity_ - size_;
+  if (available >= needed) {
+    return;
+  }
+
+  if (buffer_ != nullptr) {
+    Flush();
+  }
+  ASSERT(buffer_ == nullptr);
+
+  intptr_t chunk_size = kPreferredChunkSize;
+  if (chunk_size < needed + kMetadataReservation) {
+    chunk_size = needed + kMetadataReservation;
+  }
+  buffer_ = reinterpret_cast<uint8_t*>(malloc(chunk_size));
+  size_ = kMetadataReservation;
+  capacity_ = chunk_size;
 }
 
-class WritePointerVisitor : public ObjectPointerVisitor {
- public:
-  WritePointerVisitor(Isolate* isolate,
-                      WriteStream* stream,
-                      bool only_instances)
-      : ObjectPointerVisitor(isolate),
-        stream_(stream),
-        only_instances_(only_instances),
-        count_(0) {}
-  virtual void VisitPointers(RawObject** first, RawObject** last) {
-    for (RawObject** current = first; current <= last; ++current) {
-      RawObject* object = *current;
-      if (!object->IsHeapObject() || object->InVMIsolateHeap()) {
-        // Ignore smis and objects in the VM isolate for now.
-        // TODO(koda): To track which field each pointer corresponds to,
-        // we'll need to encode which fields were omitted here.
-        continue;
+void HeapSnapshotWriter::Flush(bool last) {
+  if (size_ == 0 && !last) {
+    return;
+  }
+
+  JSONStream js;
+  {
+    JSONObject jsobj(&js);
+    jsobj.AddProperty("jsonrpc", "2.0");
+    jsobj.AddProperty("method", "streamNotify");
+    {
+      JSONObject params(&jsobj, "params");
+      params.AddProperty("streamId", Service::heapsnapshot_stream.id());
+      {
+        JSONObject event(&params, "event");
+        event.AddProperty("type", "Event");
+        event.AddProperty("kind", "HeapSnapshot");
+        event.AddProperty("isolate", thread()->isolate());
+        event.AddPropertyTimeMillis("timestamp", OS::GetCurrentTimeMillis());
+        event.AddProperty("last", last);
       }
-      if (only_instances_ && !IsUserClass(object->GetClassId())) {
-        continue;
-      }
-      WritePtr(object, stream_);
-      ++count_;
     }
   }
 
-  intptr_t count() const { return count_; }
-
- private:
-  WriteStream* stream_;
-  bool only_instances_;
-  intptr_t count_;
-};
-
-static void WriteHeader(RawObject* raw,
-                        intptr_t size,
-                        intptr_t cid,
-                        WriteStream* stream) {
-  WritePtr(raw, stream);
-  ASSERT(Utils::IsAligned(size, kObjectAlignment));
-  stream->WriteUnsigned(size);
-  stream->WriteUnsigned(cid);
+  Service::SendEventWithData(Service::heapsnapshot_stream.id(), "HeapSnapshot",
+                             kMetadataReservation, js.buffer()->buf(),
+                             js.buffer()->length(), buffer_, size_);
+  buffer_ = nullptr;
+  size_ = 0;
+  capacity_ = 0;
 }
 
-class WriteGraphVisitor : public ObjectGraph::Visitor {
- public:
-  WriteGraphVisitor(Isolate* isolate,
-                    WriteStream* stream,
-                    ObjectGraph::SnapshotRoots roots)
-      : stream_(stream),
-        ptr_writer_(isolate, stream, roots == ObjectGraph::kUser),
-        roots_(roots),
-        count_(0) {}
+void HeapSnapshotWriter::AssignObjectId(RawObject* obj) {
+  // TODO(rmacnak): We're assigning IDs in iteration order, so we can use the
+  // compator's trick of using a finger table with bit counting to make the
+  // mapping much smaller.
+  ASSERT(obj->IsHeapObject());
+  thread()->heap()->SetObjectId(obj, ++object_count_);
+}
 
-  virtual Direction VisitObject(ObjectGraph::StackIterator* it) {
-    RawObject* raw_obj = it->Get();
-    Thread* thread = Thread::Current();
-    REUSABLE_OBJECT_HANDLESCOPE(thread);
-    Object& obj = thread->ObjectHandle();
-    obj = raw_obj;
-    if ((roots_ == ObjectGraph::kVM) || obj.IsField() || obj.IsInstance() ||
-        obj.IsContext()) {
-      // Each object is a header + a zero-terminated list of its neighbors.
-      WriteHeader(raw_obj, raw_obj->HeapSize(), obj.GetClassId(), stream_);
-      raw_obj->VisitPointers(&ptr_writer_);
-      stream_->WriteUnsigned(0);
-      ++count_;
-    }
-    return kProceed;
+intptr_t HeapSnapshotWriter::GetObjectId(RawObject* obj) {
+  if (!obj->IsHeapObject()) {
+    return 0;
+  }
+  return thread()->heap()->GetObjectId(obj);
+}
+
+void HeapSnapshotWriter::ClearObjectIds() {
+  thread()->heap()->ResetObjectIdTable();
+}
+
+void HeapSnapshotWriter::CountReferences(intptr_t count) {
+  reference_count_ += count;
+}
+
+void HeapSnapshotWriter::CountExternalProperty() {
+  external_property_count_ += 1;
+}
+
+class Pass1Visitor : public ObjectVisitor,
+                     public ObjectPointerVisitor,
+                     public HandleVisitor {
+ public:
+  explicit Pass1Visitor(HeapSnapshotWriter* writer)
+      : ObjectVisitor(),
+        ObjectPointerVisitor(Isolate::Current()),
+        HandleVisitor(Thread::Current()),
+        writer_(writer) {}
+
+  void VisitObject(RawObject* obj) {
+    if (obj->IsPseudoObject()) return;
+
+    writer_->AssignObjectId(obj);
+    obj->VisitPointers(this);
   }
 
-  intptr_t count() const { return count_; }
-
- private:
-  WriteStream* stream_;
-  WritePointerVisitor ptr_writer_;
-  ObjectGraph::SnapshotRoots roots_;
-  intptr_t count_;
-};
-
-class WriteGraphExternalSizesVisitor : public HandleVisitor {
- public:
-  WriteGraphExternalSizesVisitor(Thread* thread, WriteStream* stream)
-      : HandleVisitor(thread), stream_(stream) {}
+  void VisitPointers(RawObject** from, RawObject** to) {
+    intptr_t count = to - from + 1;
+    ASSERT(count >= 0);
+    writer_->CountReferences(count);
+  }
 
   void VisitHandle(uword addr) {
     FinalizablePersistentHandle* weak_persistent_handle =
@@ -617,76 +627,389 @@
       return;  // Free handle.
     }
 
-    WritePtr(weak_persistent_handle->raw(), stream_);
-    stream_->WriteUnsigned(weak_persistent_handle->external_size());
+    writer_->CountExternalProperty();
   }
 
  private:
-  WriteStream* stream_;
+  HeapSnapshotWriter* const writer_;
+
+  DISALLOW_COPY_AND_ASSIGN(Pass1Visitor);
 };
 
-intptr_t ObjectGraph::Serialize(WriteStream* stream,
-                                SnapshotRoots roots,
-                                bool collect_garbage) {
-  if (collect_garbage) {
-    isolate()->heap()->CollectAllGarbage();
+enum NonReferenceDataTags {
+  kNoData = 0,
+  kNullData,
+  kBoolData,
+  kIntData,
+  kDoubleData,
+  kLatin1Data,
+  kUTF16Data,
+  kLengthData,
+  kNameData,
+};
+
+static const intptr_t kMaxStringElements = 128;
+
+class Pass2Visitor : public ObjectVisitor,
+                     public ObjectPointerVisitor,
+                     public HandleVisitor {
+ public:
+  explicit Pass2Visitor(HeapSnapshotWriter* writer)
+      : ObjectVisitor(),
+        ObjectPointerVisitor(Isolate::Current()),
+        HandleVisitor(Thread::Current()),
+        writer_(writer) {}
+
+  void VisitObject(RawObject* obj) {
+    if (obj->IsPseudoObject()) return;
+
+    intptr_t cid = obj->GetClassId();
+    writer_->WriteUnsigned(cid);
+    writer_->WriteUnsigned(discount_sizes_ ? 0 : obj->HeapSize());
+
+    if (cid == kNullCid) {
+      writer_->WriteUnsigned(kNullData);
+    } else if (cid == kBoolCid) {
+      writer_->WriteUnsigned(kBoolData);
+      writer_->WriteUnsigned(static_cast<RawBool*>(obj)->ptr()->value_);
+    } else if (cid == kSmiCid) {
+      UNREACHABLE();
+    } else if (cid == kMintCid) {
+      writer_->WriteUnsigned(kIntData);
+      writer_->WriteSigned(static_cast<RawMint*>(obj)->ptr()->value_);
+    } else if (cid == kDoubleCid) {
+      writer_->WriteUnsigned(kDoubleData);
+      writer_->WriteBytes(&(static_cast<RawDouble*>(obj)->ptr()->value_),
+                          sizeof(double));
+    } else if (cid == kOneByteStringCid) {
+      RawOneByteString* str = static_cast<RawOneByteString*>(obj);
+      intptr_t len = Smi::Value(str->ptr()->length_);
+      intptr_t trunc_len = Utils::Minimum(len, kMaxStringElements);
+      writer_->WriteUnsigned(kLatin1Data);
+      writer_->WriteUnsigned(len);
+      writer_->WriteUnsigned(trunc_len);
+      writer_->WriteBytes(&str->ptr()->data()[0], trunc_len);
+    } else if (cid == kExternalOneByteStringCid) {
+      RawExternalOneByteString* str =
+          static_cast<RawExternalOneByteString*>(obj);
+      intptr_t len = Smi::Value(str->ptr()->length_);
+      intptr_t trunc_len = Utils::Minimum(len, kMaxStringElements);
+      writer_->WriteUnsigned(kLatin1Data);
+      writer_->WriteUnsigned(len);
+      writer_->WriteUnsigned(trunc_len);
+      writer_->WriteBytes(&str->ptr()->external_data_[0], trunc_len);
+    } else if (cid == kTwoByteStringCid) {
+      RawTwoByteString* str = static_cast<RawTwoByteString*>(obj);
+      intptr_t len = Smi::Value(str->ptr()->length_);
+      intptr_t trunc_len = Utils::Minimum(len, kMaxStringElements);
+      writer_->WriteUnsigned(kUTF16Data);
+      writer_->WriteUnsigned(len);
+      writer_->WriteUnsigned(trunc_len);
+      writer_->WriteBytes(&str->ptr()->data()[0], trunc_len * 2);
+    } else if (cid == kExternalTwoByteStringCid) {
+      RawExternalTwoByteString* str =
+          static_cast<RawExternalTwoByteString*>(obj);
+      intptr_t len = Smi::Value(str->ptr()->length_);
+      intptr_t trunc_len = Utils::Minimum(len, kMaxStringElements);
+      writer_->WriteUnsigned(kUTF16Data);
+      writer_->WriteUnsigned(len);
+      writer_->WriteUnsigned(trunc_len);
+      writer_->WriteBytes(&str->ptr()->external_data_[0], trunc_len * 2);
+    } else if (cid == kArrayCid || cid == kImmutableArrayCid) {
+      writer_->WriteUnsigned(kLengthData);
+      writer_->WriteUnsigned(
+          Smi::Value(static_cast<RawArray*>(obj)->ptr()->length_));
+    } else if (cid == kGrowableObjectArrayCid) {
+      writer_->WriteUnsigned(kLengthData);
+      writer_->WriteUnsigned(Smi::Value(
+          static_cast<RawGrowableObjectArray*>(obj)->ptr()->length_));
+    } else if (cid == kLinkedHashMapCid) {
+      writer_->WriteUnsigned(kLengthData);
+      writer_->WriteUnsigned(
+          Smi::Value(static_cast<RawLinkedHashMap*>(obj)->ptr()->used_data_));
+    } else if (cid == kObjectPoolCid) {
+      writer_->WriteUnsigned(kLengthData);
+      writer_->WriteUnsigned(static_cast<RawObjectPool*>(obj)->ptr()->length_);
+    } else if (RawObject::IsTypedDataClassId(cid)) {
+      writer_->WriteUnsigned(kLengthData);
+      writer_->WriteUnsigned(
+          Smi::Value(static_cast<RawTypedData*>(obj)->ptr()->length_));
+    } else if (RawObject::IsExternalTypedDataClassId(cid)) {
+      writer_->WriteUnsigned(kLengthData);
+      writer_->WriteUnsigned(
+          Smi::Value(static_cast<RawExternalTypedData*>(obj)->ptr()->length_));
+    } else if (cid == kFunctionCid) {
+      writer_->WriteUnsigned(kNameData);
+      ScrubAndWriteUtf8(static_cast<RawFunction*>(obj)->ptr()->name_);
+    } else if (cid == kCodeCid) {
+      RawObject* owner = static_cast<RawCode*>(obj)->ptr()->owner_;
+      if (owner->IsFunction()) {
+        writer_->WriteUnsigned(kNameData);
+        ScrubAndWriteUtf8(static_cast<RawFunction*>(owner)->ptr()->name_);
+      } else if (owner->IsClass()) {
+        writer_->WriteUnsigned(kNameData);
+        ScrubAndWriteUtf8(static_cast<RawClass*>(owner)->ptr()->name_);
+      } else {
+        writer_->WriteUnsigned(kNoData);
+      }
+    } else if (cid == kFieldCid) {
+      writer_->WriteUnsigned(kNameData);
+      ScrubAndWriteUtf8(static_cast<RawField*>(obj)->ptr()->name_);
+    } else if (cid == kClassCid) {
+      writer_->WriteUnsigned(kNameData);
+      ScrubAndWriteUtf8(static_cast<RawClass*>(obj)->ptr()->name_);
+    } else if (cid == kLibraryCid) {
+      writer_->WriteUnsigned(kNameData);
+      ScrubAndWriteUtf8(static_cast<RawLibrary*>(obj)->ptr()->url_);
+    } else if (cid == kScriptCid) {
+      writer_->WriteUnsigned(kNameData);
+      ScrubAndWriteUtf8(static_cast<RawScript*>(obj)->ptr()->url_);
+    } else {
+      writer_->WriteUnsigned(kNoData);
+    }
+
+    DoCount();
+    obj->VisitPointersPrecise(this);
+    DoWrite();
+    obj->VisitPointersPrecise(this);
   }
-  // Current encoding assumes objects do not move, so promote everything to old.
-  isolate()->heap()->new_space()->Evacuate();
-  HeapIterationScope iteration_scope(Thread::Current(), true);
 
-  RawObject* kRootAddress = reinterpret_cast<RawObject*>(kHeapObjectTag);
-  const intptr_t kRootCid = kIllegalCid;
-  RawObject* kStackAddress =
-      reinterpret_cast<RawObject*>(kObjectAlignment + kHeapObjectTag);
+  void ScrubAndWriteUtf8(RawString* str) {
+    if (str == String::null()) {
+      writer_->WriteUtf8("null");
+    } else {
+      String handle;
+      handle = str;
+      char* value = handle.ToMallocCString();
+      writer_->ScrubAndWriteUtf8(value);
+      free(value);
+    }
+  }
 
-  stream->WriteUnsigned(kObjectAlignment);
-  stream->WriteUnsigned(kStackCid);
-  stream->WriteUnsigned(kFieldCid);
-  stream->WriteUnsigned(isolate()->class_table()->NumCids());
+  void set_discount_sizes(bool value) { discount_sizes_ = value; }
 
-  if (roots == kVM) {
-    // Write root "object".
-    WriteHeader(kRootAddress, 0, kRootCid, stream);
-    WritePointerVisitor ptr_writer(isolate(), stream, false);
-    isolate()->VisitObjectPointers(&ptr_writer,
+  void DoCount() {
+    writing_ = false;
+    counted_ = 0;
+    written_ = 0;
+  }
+  void DoWrite() {
+    writing_ = true;
+    writer_->WriteUnsigned(counted_);
+  }
+
+  void VisitPointers(RawObject** from, RawObject** to) {
+    if (writing_) {
+      for (RawObject** ptr = from; ptr <= to; ptr++) {
+        RawObject* target = *ptr;
+        written_++;
+        total_++;
+        writer_->WriteUnsigned(writer_->GetObjectId(target));
+      }
+    } else {
+      intptr_t count = to - from + 1;
+      ASSERT(count >= 0);
+      counted_ += count;
+    }
+  }
+
+  void VisitHandle(uword addr) {
+    FinalizablePersistentHandle* weak_persistent_handle =
+        reinterpret_cast<FinalizablePersistentHandle*>(addr);
+    if (!weak_persistent_handle->raw()->IsHeapObject()) {
+      return;  // Free handle.
+    }
+
+    writer_->WriteUnsigned(writer_->GetObjectId(weak_persistent_handle->raw()));
+    writer_->WriteUnsigned(weak_persistent_handle->external_size());
+    // Attempt to include a native symbol name.
+    char* name = NativeSymbolResolver::LookupSymbolName(
+        reinterpret_cast<uintptr_t>(weak_persistent_handle->callback()), NULL);
+    writer_->WriteUtf8((name == NULL) ? "Unknown native function" : name);
+    if (name != NULL) {
+      NativeSymbolResolver::FreeSymbolName(name);
+    }
+  }
+
+ private:
+  HeapSnapshotWriter* const writer_;
+  bool writing_ = false;
+  intptr_t counted_ = 0;
+  intptr_t written_ = 0;
+  intptr_t total_ = 0;
+  bool discount_sizes_ = false;
+
+  DISALLOW_COPY_AND_ASSIGN(Pass2Visitor);
+};
+
+void HeapSnapshotWriter::Write() {
+  HeapIterationScope iteration(thread());
+
+  WriteBytes("dartheap", 8);  // Magic value.
+  WriteUnsigned(0);           // Flags.
+  WriteUtf8(isolate()->name());
+  Heap* H = thread()->heap();
+  WriteUnsigned(
+      (H->new_space()->UsedInWords() + H->old_space()->UsedInWords()) *
+      kWordSize);
+  WriteUnsigned(
+      (H->new_space()->CapacityInWords() + H->old_space()->CapacityInWords()) *
+      kWordSize);
+  WriteUnsigned(
+      (H->new_space()->ExternalInWords() + H->old_space()->ExternalInWords()) *
+      kWordSize);
+
+  {
+    HANDLESCOPE(thread());
+    ClassTable* class_table = isolate()->class_table();
+    class_count_ = class_table->NumCids() - 1;
+
+    Class& cls = Class::Handle();
+    Library& lib = Library::Handle();
+    String& str = String::Handle();
+    Array& fields = Array::Handle();
+    Field& field = Field::Handle();
+
+    WriteUnsigned(class_count_);
+    for (intptr_t cid = 1; cid <= class_count_; cid++) {
+      if (!class_table->HasValidClassAt(cid)) {
+        WriteUnsigned(0);  // Flags
+        WriteUtf8("");     // Name
+        WriteUtf8("");     // Library name
+        WriteUtf8("");     // Library uri
+        WriteUtf8("");     // Reserved
+        WriteUnsigned(0);  // Field count
+      } else {
+        cls = class_table->At(cid);
+        WriteUnsigned(0);  // Flags
+        str = cls.Name();
+        ScrubAndWriteUtf8(const_cast<char*>(str.ToCString()));
+        lib = cls.library();
+        if (lib.IsNull()) {
+          WriteUtf8("");
+          WriteUtf8("");
+        } else {
+          str = lib.name();
+          ScrubAndWriteUtf8(const_cast<char*>(str.ToCString()));
+          str = lib.url();
+          ScrubAndWriteUtf8(const_cast<char*>(str.ToCString()));
+        }
+        WriteUtf8("");  // Reserved
+
+        intptr_t field_count = 0;
+        intptr_t min_offset = kIntptrMax;
+        for (intptr_t j = 0; OffsetsTable::offsets_table[j].class_id != -1;
+             j++) {
+          if (OffsetsTable::offsets_table[j].class_id == cid) {
+            field_count++;
+            intptr_t offset = OffsetsTable::offsets_table[j].offset;
+            min_offset = Utils::Minimum(min_offset, offset);
+          }
+        }
+        if (cls.is_finalized()) {
+          do {
+            fields = cls.fields();
+            if (!fields.IsNull()) {
+              for (intptr_t i = 0; i < fields.Length(); i++) {
+                field ^= fields.At(i);
+                if (field.is_instance()) {
+                  field_count++;
+                }
+              }
+            }
+            cls = cls.SuperClass();
+          } while (!cls.IsNull());
+          cls = class_table->At(cid);
+        }
+
+        WriteUnsigned(field_count);
+        for (intptr_t j = 0; OffsetsTable::offsets_table[j].class_id != -1;
+             j++) {
+          if (OffsetsTable::offsets_table[j].class_id == cid) {
+            intptr_t flags = 1;  // Strong.
+            WriteUnsigned(flags);
+            intptr_t offset = OffsetsTable::offsets_table[j].offset;
+            intptr_t index = (offset - min_offset) / kWordSize;
+            ASSERT(index >= 0);
+            WriteUnsigned(index);
+            WriteUtf8(OffsetsTable::offsets_table[j].field_name);
+            WriteUtf8("");  // Reserved
+          }
+        }
+        if (cls.is_finalized()) {
+          do {
+            fields = cls.fields();
+            if (!fields.IsNull()) {
+              for (intptr_t i = 0; i < fields.Length(); i++) {
+                field ^= fields.At(i);
+                if (field.is_instance()) {
+                  intptr_t flags = 1;  // Strong.
+                  WriteUnsigned(flags);
+                  intptr_t index = field.Offset() / kWordSize - 1;
+                  ASSERT(index >= 0);
+                  WriteUnsigned(index);
+                  str = field.name();
+                  ScrubAndWriteUtf8(const_cast<char*>(str.ToCString()));
+                  WriteUtf8("");  // Reserved
+                }
+              }
+            }
+            cls = cls.SuperClass();
+          } while (!cls.IsNull());
+          cls = class_table->At(cid);
+        }
+      }
+    }
+  }
+
+  {
+    Pass1Visitor visitor(this);
+
+    // Root "object".
+    ++object_count_;
+    isolate()->VisitObjectPointers(&visitor,
                                    ValidationPolicy::kDontValidateFrames);
-    stream->WriteUnsigned(0);
-  } else {
-    {
-      // Write root "object".
-      WriteHeader(kRootAddress, 0, kRootCid, stream);
-      WritePointerVisitor ptr_writer(isolate(), stream, false);
-      IterateUserFields(&ptr_writer);
-      WritePtr(kStackAddress, stream);
-      stream->WriteUnsigned(0);
-    }
 
-    {
-      // Write stack "object".
-      WriteHeader(kStackAddress, 0, kStackCid, stream);
-      WritePointerVisitor ptr_writer(isolate(), stream, true);
-      isolate()->VisitStackPointers(&ptr_writer,
-                                    ValidationPolicy::kDontValidateFrames);
-      stream->WriteUnsigned(0);
-    }
+    // Heap objects.
+    iteration.IterateVMIsolateObjects(&visitor);
+    iteration.IterateObjects(&visitor);
+
+    // External properties.
+    isolate()->VisitWeakPersistentHandles(&visitor);
   }
 
-  WriteGraphVisitor visitor(isolate(), stream, roots);
-  IterateObjects(&visitor);
-  stream->WriteUnsigned(0);
+  {
+    Pass2Visitor visitor(this);
 
-  WriteGraphExternalSizesVisitor external_visitor(Thread::Current(), stream);
-  isolate()->VisitWeakPersistentHandles(&external_visitor);
-  stream->WriteUnsigned(0);
+    WriteUnsigned(reference_count_);
+    WriteUnsigned(object_count_);
 
-  intptr_t object_count = visitor.count();
-  if (roots == kVM) {
-    object_count += 1;  // root
-  } else {
-    object_count += 2;  // root and stack
+    // Root "object".
+    WriteUnsigned(0);  // cid
+    WriteUnsigned(0);  // shallowSize
+    WriteUnsigned(kNoData);
+    visitor.DoCount();
+    isolate()->VisitObjectPointers(&visitor,
+                                   ValidationPolicy::kDontValidateFrames);
+    visitor.DoWrite();
+    isolate()->VisitObjectPointers(&visitor,
+                                   ValidationPolicy::kDontValidateFrames);
+
+    // Heap objects.
+    visitor.set_discount_sizes(true);
+    iteration.IterateVMIsolateObjects(&visitor);
+    visitor.set_discount_sizes(false);
+    iteration.IterateObjects(&visitor);
+
+    // External properties.
+    WriteUnsigned(external_property_count_);
+    isolate()->VisitWeakPersistentHandles(&visitor);
   }
-  return object_count;
+
+  ClearObjectIds();
+  Flush(true);
 }
 
+#endif  // !defined(PRODUCT)
+
 }  // namespace dart
diff --git a/runtime/vm/object_graph.h b/runtime/vm/object_graph.h
index dabb03a..8be3382 100644
--- a/runtime/vm/object_graph.h
+++ b/runtime/vm/object_graph.h
@@ -11,10 +11,10 @@
 namespace dart {
 
 class Array;
-class Isolate;
 class Object;
 class RawObject;
-class WriteStream;
+
+#if !defined(PRODUCT)
 
 // Utility to traverse the object graph in an ordered fashion.
 // Example uses:
@@ -108,21 +108,100 @@
   // be live due to references from the stack or embedder handles.
   intptr_t InboundReferences(Object* obj, const Array& references);
 
-  enum SnapshotRoots { kVM, kUser };
-
-  // Write the isolate's object graph to 'stream'. Smis and nulls are omitted.
-  // Returns the number of nodes in the stream, including the root.
-  // If collect_garbage is false, the graph will include weakly-reachable
-  // objects.
-  // TODO(koda): Document format; support streaming/chunking.
-  intptr_t Serialize(WriteStream* stream,
-                     SnapshotRoots roots,
-                     bool collect_garbage);
-
  private:
   DISALLOW_IMPLICIT_CONSTRUCTORS(ObjectGraph);
 };
 
+// Generates a dump of the heap, whose format is described in
+// runtime/vm/service/heap_snapshot.md.
+class HeapSnapshotWriter : public ThreadStackResource {
+ public:
+  explicit HeapSnapshotWriter(Thread* thread) : ThreadStackResource(thread) {}
+
+  void WriteSigned(int64_t value) {
+    EnsureAvailable((sizeof(value) * kBitsPerByte) / 7 + 1);
+
+    bool is_last_part = false;
+    while (!is_last_part) {
+      uint8_t part = value & 0x7F;
+      value >>= 7;
+      if ((value == 0 && (part & 0x40) == 0) ||
+          (value == static_cast<intptr_t>(-1) && (part & 0x40) != 0)) {
+        is_last_part = true;
+      } else {
+        part |= 0x80;
+      }
+      buffer_[size_++] = part;
+    }
+  }
+
+  void WriteUnsigned(uintptr_t value) {
+    EnsureAvailable((sizeof(value) * kBitsPerByte) / 7 + 1);
+
+    bool is_last_part = false;
+    while (!is_last_part) {
+      uint8_t part = value & 0x7F;
+      value >>= 7;
+      if (value == 0) {
+        is_last_part = true;
+      } else {
+        part |= 0x80;
+      }
+      buffer_[size_++] = part;
+    }
+  }
+
+  void WriteBytes(const void* bytes, intptr_t len) {
+    EnsureAvailable(len);
+    memmove(&buffer_[size_], bytes, len);
+    size_ += len;
+  }
+
+  void ScrubAndWriteUtf8(char* value) {
+    intptr_t len = strlen(value);
+    for (intptr_t i = len - 1; i >= 0; i--) {
+      if (value[i] == '@') {
+        value[i] = '\0';
+      }
+    }
+    WriteUtf8(value);
+  }
+
+  void WriteUtf8(const char* value) {
+    intptr_t len = strlen(value);
+    WriteUnsigned(len);
+    WriteBytes(value, len);
+  }
+
+  void AssignObjectId(RawObject* obj);
+  intptr_t GetObjectId(RawObject* obj);
+  void ClearObjectIds();
+  void CountReferences(intptr_t count);
+  void CountExternalProperty();
+
+  void Write();
+
+ private:
+  static const intptr_t kMetadataReservation = 512;
+  static const intptr_t kPreferredChunkSize = MB;
+
+  void EnsureAvailable(intptr_t needed);
+  void Flush(bool last = false);
+
+  uint8_t* buffer_ = nullptr;
+  intptr_t size_ = 0;
+  intptr_t capacity_ = 0;
+
+  intptr_t class_count_ = 0;
+  intptr_t object_count_ = 0;
+  intptr_t reference_count_ = 0;
+  intptr_t external_property_count_ = 0;
+
+  DISALLOW_COPY_AND_ASSIGN(HeapSnapshotWriter);
+};
+
+#endif  // !defined(PRODUCT)
+
 }  // namespace dart
 
 #endif  // RUNTIME_VM_OBJECT_GRAPH_H_
diff --git a/runtime/vm/object_graph_test.cc b/runtime/vm/object_graph_test.cc
index 238e5b4..c5b6f67 100644
--- a/runtime/vm/object_graph_test.cc
+++ b/runtime/vm/object_graph_test.cc
@@ -8,6 +8,8 @@
 
 namespace dart {
 
+#if !defined(PRODUCT)
+
 class CounterVisitor : public ObjectGraph::Visitor {
  public:
   // Records the number of objects and total size visited, excluding 'skip'
@@ -192,4 +194,6 @@
   EXPECT_STREQ(result.gc_root_type, "local handle");
 }
 
+#endif  // !defined(PRODUCT)
+
 }  // namespace dart
diff --git a/runtime/vm/object_reload.cc b/runtime/vm/object_reload.cc
index fa15e86..f3faad4 100644
--- a/runtime/vm/object_reload.cc
+++ b/runtime/vm/object_reload.cc
@@ -92,6 +92,31 @@
 #endif
 }
 
+#if !defined(TARGET_ARCH_DBC)
+static void FindICData(const Array& ic_data_array,
+                       intptr_t deopt_id,
+                       ICData* ic_data) {
+  // ic_data_array is sorted because of how it is constructed in
+  // Function::SaveICDataMap.
+  intptr_t lo = 1;
+  intptr_t hi = ic_data_array.Length() - 1;
+  while (lo <= hi) {
+    intptr_t mid = (hi - lo + 1) / 2 + lo;
+    ASSERT(mid >= lo);
+    ASSERT(mid <= hi);
+    *ic_data ^= ic_data_array.At(mid);
+    if (ic_data->deopt_id() == deopt_id) {
+      return;
+    } else if (ic_data->deopt_id() > deopt_id) {
+      hi = mid - 1;
+    } else {
+      lo = mid + 1;
+    }
+  }
+  FATAL1("Missing deopt id %" Pd "\n", deopt_id);
+}
+#endif  // !defined(TARGET_ARCH_DBC)
+
 void Code::ResetSwitchableCalls(Zone* zone) const {
 #if !defined(TARGET_ARCH_DBC)
   if (is_optimized()) {
@@ -128,21 +153,21 @@
 #endif
     return;
   }
+
   ICData& ic_data = ICData::Handle(zone);
   Object& data = Object::Handle(zone);
-  for (intptr_t i = 1; i < ic_data_array.Length(); i++) {
-    ic_data ^= ic_data_array.At(i);
-    if (ic_data.rebind_rule() != ICData::kInstance) {
-      continue;
-    }
-    if (ic_data.NumArgsTested() != 1) {
-      continue;
-    }
-    uword pc = GetPcForDeoptId(ic_data.deopt_id(), RawPcDescriptors::kIcCall);
+  const PcDescriptors& descriptors =
+      PcDescriptors::Handle(zone, pc_descriptors());
+  PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kIcCall);
+  while (iter.MoveNext()) {
+    uword pc = PayloadStart() + iter.PcOffset();
     CodePatcher::GetInstanceCallAt(pc, *this, &data);
     // This check both avoids unnecessary patching to reduce log spam and
     // prevents patching over breakpoint stubs.
     if (!data.IsICData()) {
+      FindICData(ic_data_array, iter.DeoptId(), &ic_data);
+      ASSERT(ic_data.rebind_rule() == ICData::kInstance);
+      ASSERT(ic_data.NumArgsTested() == 1);
       const Code& stub =
           ic_data.is_tracking_exactness()
               ? StubCode::OneArgCheckInlineCacheWithExactnessCheck()
@@ -163,12 +188,60 @@
   const ObjectPool& pool = ObjectPool::Handle(zone, object_pool());
   ASSERT(!pool.IsNull());
   pool.ResetICDatas(zone);
+
+  Object& object = Object::Handle(zone);
+  String& name = String::Handle(zone);
+  Class& new_cls = Class::Handle(zone);
+  Library& new_lib = Library::Handle(zone);
+  Function& new_function = Function::Handle(zone);
+  Field& new_field = Field::Handle(zone);
+  for (intptr_t i = 0; i < pool.Length(); i++) {
+    ObjectPool::EntryType entry_type = pool.TypeAt(i);
+    if (entry_type != ObjectPool::EntryType::kTaggedObject) {
+      continue;
+    }
+    object = pool.ObjectAt(i);
+    if (object.IsFunction()) {
+      const Function& old_function = Function::Cast(object);
+      if (old_function.IsClosureFunction()) {
+        continue;
+      }
+      name = old_function.name();
+      new_cls = old_function.Owner();
+      if (new_cls.IsTopLevel()) {
+        new_lib = new_cls.library();
+        new_function = new_lib.LookupLocalFunction(name);
+      } else {
+        new_function = new_cls.LookupFunction(name);
+      }
+      if (!new_function.IsNull() &&
+          (new_function.is_static() == old_function.is_static()) &&
+          (new_function.kind() == old_function.kind())) {
+        pool.SetObjectAt(i, new_function);
+      } else {
+        VTIR_Print("Cannot rebind function %s\n", old_function.ToCString());
+      }
+    } else if (object.IsField()) {
+      const Field& old_field = Field::Cast(object);
+      name = old_field.name();
+      new_cls = old_field.Owner();
+      if (new_cls.IsTopLevel()) {
+        new_lib = new_cls.library();
+        new_field = new_lib.LookupLocalField(name);
+      } else {
+        new_field = new_cls.LookupField(name);
+      }
+      if (!new_field.IsNull() &&
+          (new_field.is_static() == old_field.is_static())) {
+        pool.SetObjectAt(i, new_field);
+      } else {
+        VTIR_Print("Cannot rebind field %s\n", old_field.ToCString());
+      }
+    }
+  }
 }
 
 void ObjectPool::ResetICDatas(Zone* zone) const {
-#ifdef TARGET_ARCH_IA32
-  UNREACHABLE();
-#else
   Object& object = Object::Handle(zone);
   for (intptr_t i = 0; i < Length(); i++) {
     ObjectPool::EntryType entry_type = TypeAt(i);
@@ -180,7 +253,6 @@
       ICData::Cast(object).Reset(zone);
     }
   }
-#endif
 }
 
 void Class::CopyStaticFieldValues(IsolateReloadContext* reload_context,
@@ -863,4 +935,4 @@
 
 #endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
 
-}  // namespace dart.
+}  // namespace dart
diff --git a/runtime/vm/profiler_test.cc b/runtime/vm/profiler_test.cc
index 32d3096..497954e 100644
--- a/runtime/vm/profiler_test.cc
+++ b/runtime/vm/profiler_test.cc
@@ -160,6 +160,7 @@
   {
     TransitionVMToNative transition(Thread::Current());
     api_lib = TestCase::LoadTestScript(script, NULL);
+    EXPECT_VALID(api_lib);
   }
   Library& lib = Library::Handle();
   lib ^= Api::UnwrapHandle(api_lib);
@@ -992,9 +993,9 @@
     } else {
       EXPECT_STREQ("Double_add", walker.CurrentName());
       EXPECT(walker.Down());
-      EXPECT_STREQ("[Unoptimized] _Double._add", walker.CurrentName());
+      EXPECT_STREQ("[Unoptimized] double._add", walker.CurrentName());
       EXPECT(walker.Down());
-      EXPECT_STREQ("[Unoptimized] _Double.+", walker.CurrentName());
+      EXPECT_STREQ("[Unoptimized] double.+", walker.CurrentName());
       EXPECT(walker.Down());
       EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName());
       EXPECT(!walker.Down());
@@ -1483,11 +1484,9 @@
       EXPECT_STREQ("[Bytecode] foo", walker.CurrentName());
       EXPECT(!walker.Down());
     } else {
-      EXPECT_STREQ("[Unoptimized] _OneByteString._allocate",
-                   walker.CurrentName());
+      EXPECT_STREQ("[Unoptimized] String._allocate", walker.CurrentName());
       EXPECT(walker.Down());
-      EXPECT_STREQ("[Unoptimized] _OneByteString._concatAll",
-                   walker.CurrentName());
+      EXPECT_STREQ("[Unoptimized] String._concatAll", walker.CurrentName());
       EXPECT(walker.Down());
       EXPECT_STREQ("[Unoptimized] _StringBase._interpolate",
                    walker.CurrentName());
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index 24a79f8..d937e14 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -302,6 +302,13 @@
       size = RawDynamicLibrary::VisitDynamicLibraryPointers(raw_obj, visitor);
       break;
     }
+#define RAW_VISITPOINTERS(clazz) case kFfi##clazz##Cid:
+      CLASS_LIST_FFI_TYPE_MARKER(RAW_VISITPOINTERS) {
+        // NativeType do not have any fields or type arguments.
+        size = HeapSize();
+        break;
+      }
+#undef RAW_VISITPOINTERS
     case kFreeListElement: {
       uword addr = RawObject::ToAddr(this);
       FreeListElement* element = reinterpret_cast<FreeListElement*>(addr);
@@ -340,6 +347,27 @@
 #endif
 }
 
+void RawObject::VisitPointersPrecise(ObjectPointerVisitor* visitor) {
+  intptr_t class_id = GetClassId();
+  if (class_id < kNumPredefinedCids) {
+    VisitPointersPredefined(visitor, class_id);
+    return;
+  }
+
+  // N.B.: Not using the heap size!
+  uword next_field_offset = visitor->isolate()
+                                ->GetClassForHeapWalkAt(class_id)
+                                ->ptr()
+                                ->next_field_offset_in_words_
+                            << kWordSizeLog2;
+  ASSERT(next_field_offset > 0);
+  uword obj_addr = RawObject::ToAddr(this);
+  uword from = obj_addr + sizeof(RawObject);
+  uword to = obj_addr + next_field_offset - kWordSize;
+  visitor->VisitPointers(reinterpret_cast<RawObject**>(from),
+                         reinterpret_cast<RawObject**>(to));
+}
+
 bool RawObject::FindObject(FindObjectVisitor* visitor) {
   ASSERT(visitor != NULL);
   return visitor->FindObject(this);
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index f951261..50a922e 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -106,7 +106,8 @@
   friend class object##SerializationCluster;                                   \
   friend class object##DeserializationCluster;                                 \
   friend class Serializer;                                                     \
-  friend class Deserializer;
+  friend class Deserializer;                                                   \
+  friend class Pass2Visitor;
 
 // RawObject is the base class of all raw objects; even though it carries the
 // tags_ field not all raw objects are allocated in the heap and thus cannot
@@ -444,6 +445,10 @@
     return instance_size;
   }
 
+  // This variant ensures that we do not visit the extra slot created from
+  // rounding up instance sizes up to the allocation unit.
+  void VisitPointersPrecise(ObjectPointerVisitor* visitor);
+
   static RawObject* FromAddr(uword addr) {
     // We expect the untagged address here.
     ASSERT((addr & kSmiTagMask) != kHeapObjectTag);
diff --git a/runtime/vm/raw_object_fields.cc b/runtime/vm/raw_object_fields.cc
index 007e59b..f90a01d 100644
--- a/runtime/vm/raw_object_fields.cc
+++ b/runtime/vm/raw_object_fields.cc
@@ -6,9 +6,9 @@
 
 namespace dart {
 
-#if defined(DART_PRECOMPILER)
+#if defined(DART_PRECOMPILER) || !defined(DART_PRODUCT)
 
-#define RAW_CLASSES_AND_FIELDS(F)                                              \
+#define COMMON_CLASSES_AND_FIELDS(F)                                           \
   F(Class, name_)                                                              \
   F(Class, user_name_)                                                         \
   F(Class, functions_)                                                         \
@@ -55,7 +55,6 @@
   F(Field, type_)                                                              \
   F(Field, guarded_list_length_)                                               \
   F(Field, dependent_code_)                                                    \
-  F(Field, type_test_cache_)                                                   \
   F(Field, initializer_function_)                                              \
   F(Script, url_)                                                              \
   F(Script, resolved_url_)                                                     \
@@ -205,6 +204,18 @@
   F(TypedDataView, typed_data_)                                                \
   F(TypedDataView, offset_in_bytes_)
 
+#define AOT_CLASSES_AND_FIELDS(F)
+
+#define JIT_CLASSES_AND_FIELDS(F)                                              \
+  F(Code, active_instructions_)                                                \
+  F(Code, deopt_info_array_)                                                   \
+  F(Code, static_calls_target_table_)                                          \
+  F(ICData, receivers_static_type_)                                            \
+  F(Function, bytecode_)                                                       \
+  F(Function, unoptimized_code_)                                               \
+  F(Field, type_test_cache_)                                                   \
+  F(Field, saved_initial_value_)
+
 OffsetsTable::OffsetsTable(Zone* zone) : cached_offsets_(zone) {
   for (intptr_t i = 0; offsets_table[i].class_id != -1; ++i) {
     OffsetsTableEntry entry = offsets_table[i];
@@ -222,7 +233,12 @@
 
 // clang-format off
 OffsetsTable::OffsetsTableEntry OffsetsTable::offsets_table[] = {
-    RAW_CLASSES_AND_FIELDS(DEFINE_OFFSETS_TABLE_ENTRY)
+    COMMON_CLASSES_AND_FIELDS(DEFINE_OFFSETS_TABLE_ENTRY)
+#if defined(DART_PRECOMPILED_RUNTIME)
+    AOT_CLASSES_AND_FIELDS(DEFINE_OFFSETS_TABLE_ENTRY)
+#else
+    JIT_CLASSES_AND_FIELDS(DEFINE_OFFSETS_TABLE_ENTRY)
+#endif
     {-1, nullptr, -1}
 };
 // clang-format on
diff --git a/runtime/vm/raw_object_fields.h b/runtime/vm/raw_object_fields.h
index 9f67643..54a7a27 100644
--- a/runtime/vm/raw_object_fields.h
+++ b/runtime/vm/raw_object_fields.h
@@ -19,7 +19,7 @@
 
 namespace dart {
 
-#if defined(DART_PRECOMPILER)
+#if defined(DART_PRECOMPILER) || !defined(DART_PRODUCT)
 
 class OffsetsTable : public ZoneAllocated {
  public:
@@ -29,7 +29,6 @@
   // Otherwise, the returned string is allocated in global static memory.
   const char* FieldNameForOffset(intptr_t cid, intptr_t offset);
 
- private:
   struct OffsetsTableEntry {
     const intptr_t class_id;
     const char* field_name;
@@ -38,6 +37,7 @@
 
   static OffsetsTableEntry offsets_table[];
 
+ private:
   struct IntAndIntToStringMapTraits {
     typedef std::pair<intptr_t, intptr_t> Key;
     typedef const char* Value;
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index 1fc7deb..032bfd1 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -82,6 +82,10 @@
             unopt_megamorphic_calls,
             true,
             "Enable specializing megamorphic calls from unoptimized code.");
+DEFINE_FLAG(bool,
+            verbose_stack_overflow,
+            false,
+            "Print additional details about stack overflow.");
 
 DECLARE_FLAG(int, reload_every);
 DECLARE_FLAG(bool, reload_every_optimized);
@@ -2260,6 +2264,38 @@
   // TODO(regis): Warning: IsCalleeFrameOf is overridden in stack_frame_dbc.h.
   if (interpreter_stack_overflow || !thread->os_thread()->HasStackHeadroom() ||
       IsCalleeFrameOf(thread->saved_stack_limit(), stack_pos)) {
+    if (FLAG_verbose_stack_overflow) {
+      OS::PrintErr("Stack overflow in %s\n",
+                   interpreter_stack_overflow ? "interpreter" : "native code");
+      OS::PrintErr("  Native SP = %" Px ", stack limit = %" Px "\n", stack_pos,
+                   thread->saved_stack_limit());
+#if !defined(DART_PRECOMPILED_RUNTIME)
+      if (thread->interpreter() != nullptr) {
+        OS::PrintErr("  Interpreter SP = %" Px ", stack limit = %" Px "\n",
+                     thread->interpreter()->get_sp(),
+                     thread->interpreter()->overflow_stack_limit());
+      }
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
+      OS::PrintErr("Call stack:\n");
+      OS::PrintErr("size | frame\n");
+      StackFrameIterator frames(ValidationPolicy::kDontValidateFrames, thread,
+                                StackFrameIterator::kNoCrossThreadIteration);
+      uword fp = stack_pos;
+      StackFrame* frame = frames.NextFrame();
+      while (frame != NULL) {
+        if (frame->is_interpreted() == interpreter_stack_overflow) {
+          uword delta = interpreter_stack_overflow ? (fp - frame->fp())
+                                                   : (frame->fp() - fp);
+          fp = frame->fp();
+          OS::PrintErr("%4" Pd " %s\n", delta, frame->ToCString());
+        } else {
+          OS::PrintErr("     %s\n", frame->ToCString());
+        }
+        frame = frames.NextFrame();
+      }
+    }
+
     // Use the preallocated stack overflow exception to avoid calling
     // into dart code.
     const Instance& exception =
diff --git a/runtime/vm/scopes.cc b/runtime/vm/scopes.cc
index b29e821..6264031 100644
--- a/runtime/vm/scopes.cc
+++ b/runtime/vm/scopes.cc
@@ -296,38 +296,8 @@
 RawLocalVarDescriptors* LocalScope::GetVarDescriptors(
     const Function& func,
     ZoneGrowableArray<intptr_t>* context_level_array) {
-  GrowableArray<VarDesc> vars(8);
-
-  // Record deopt-id -> context-level mappings, using ranges of deopt-ids with
-  // the same context-level. [context_level_array] contains (deopt_id,
-  // context_level) tuples.
-  for (intptr_t start = 0; start < context_level_array->length();) {
-    intptr_t start_deopt_id = (*context_level_array)[start];
-    intptr_t start_context_level = (*context_level_array)[start + 1];
-    intptr_t end = start;
-    intptr_t end_deopt_id = start_deopt_id;
-    for (intptr_t peek = start + 2; peek < context_level_array->length();
-         peek += 2) {
-      intptr_t peek_deopt_id = (*context_level_array)[peek];
-      intptr_t peek_context_level = (*context_level_array)[peek + 1];
-      // The range encoding assumes the tuples have ascending deopt_ids.
-      ASSERT(peek_deopt_id > end_deopt_id);
-      if (peek_context_level != start_context_level) break;
-      end = peek;
-      end_deopt_id = peek_deopt_id;
-    }
-
-    VarDesc desc;
-    desc.name = &Symbols::Empty();  // No name.
-    desc.info.set_kind(RawLocalVarDescriptors::kContextLevel);
-    desc.info.scope_id = 0;
-    desc.info.begin_pos = TokenPosition(start_deopt_id);
-    desc.info.end_pos = TokenPosition(end_deopt_id);
-    desc.info.set_index(start_context_level);
-    vars.Add(desc);
-
-    start = end + 2;
-  }
+  LocalVarDescriptorsBuilder vars;
+  vars.AddDeoptIdToContextLevelMappings(context_level_array);
 
   // First enter all variables from scopes of outer functions.
   const ContextScope& context_scope =
@@ -343,7 +313,7 @@
         continue;
       }
 
-      VarDesc desc;
+      LocalVarDescriptorsBuilder::VarDesc desc;
       desc.name = &name;
       desc.info.set_kind(kind);
       desc.info.scope_id = context_scope.ContextLevelAt(i);
@@ -359,20 +329,12 @@
   int16_t scope_id = 0;
   CollectLocalVariables(&vars, &scope_id);
 
-  if (vars.length() == 0) {
-    return Object::empty_var_descriptors().raw();
-  }
-  const LocalVarDescriptors& var_desc =
-      LocalVarDescriptors::Handle(LocalVarDescriptors::New(vars.length()));
-  for (int i = 0; i < vars.length(); i++) {
-    var_desc.SetVar(i, *(vars[i].name), &vars[i].info);
-  }
-  return var_desc.raw();
+  return vars.Done();
 }
 
 // Add visible variables that are declared in this scope to vars, then
 // collect visible variables of children, followed by siblings.
-void LocalScope::CollectLocalVariables(GrowableArray<VarDesc>* vars,
+void LocalScope::CollectLocalVariables(LocalVarDescriptorsBuilder* vars,
                                        int16_t* scope_id) {
   (*scope_id)++;
   for (int i = 0; i < this->variables_.length(); i++) {
@@ -381,7 +343,7 @@
       if (var->name().raw() == Symbols::CurrentContextVar().raw()) {
         // This is the local variable in which the function saves its
         // own context before calling a closure function.
-        VarDesc desc;
+        LocalVarDescriptorsBuilder::VarDesc desc;
         desc.name = &var->name();
         desc.info.set_kind(RawLocalVarDescriptors::kSavedCurrentContext);
         desc.info.scope_id = 0;
@@ -392,7 +354,7 @@
         vars->Add(desc);
       } else if (!IsFilteredIdentifier(var->name())) {
         // This is a regular Dart variable, either stack-based or captured.
-        VarDesc desc;
+        LocalVarDescriptorsBuilder::VarDesc desc;
         desc.name = &var->name();
         if (var->is_captured()) {
           desc.info.set_kind(RawLocalVarDescriptors::kContextVar);
@@ -713,6 +675,62 @@
   return false;
 }
 
+void LocalVarDescriptorsBuilder::AddAll(Zone* zone,
+                                        const LocalVarDescriptors& var_descs) {
+  for (intptr_t i = 0, n = var_descs.Length(); i < n; ++i) {
+    VarDesc desc;
+    desc.name = &String::Handle(zone, var_descs.GetName(i));
+    var_descs.GetInfo(i, &desc.info);
+    Add(desc);
+  }
+}
+
+void LocalVarDescriptorsBuilder::AddDeoptIdToContextLevelMappings(
+    ZoneGrowableArray<intptr_t>* context_level_array) {
+  // Record deopt-id -> context-level mappings, using ranges of deopt-ids with
+  // the same context-level. [context_level_array] contains (deopt_id,
+  // context_level) tuples.
+  for (intptr_t start = 0; start < context_level_array->length();) {
+    intptr_t start_deopt_id = (*context_level_array)[start];
+    intptr_t start_context_level = (*context_level_array)[start + 1];
+    intptr_t end = start;
+    intptr_t end_deopt_id = start_deopt_id;
+    for (intptr_t peek = start + 2; peek < context_level_array->length();
+         peek += 2) {
+      intptr_t peek_deopt_id = (*context_level_array)[peek];
+      intptr_t peek_context_level = (*context_level_array)[peek + 1];
+      // The range encoding assumes the tuples have ascending deopt_ids.
+      ASSERT(peek_deopt_id > end_deopt_id);
+      if (peek_context_level != start_context_level) break;
+      end = peek;
+      end_deopt_id = peek_deopt_id;
+    }
+
+    VarDesc desc;
+    desc.name = &Symbols::Empty();  // No name.
+    desc.info.set_kind(RawLocalVarDescriptors::kContextLevel);
+    desc.info.scope_id = 0;
+    desc.info.begin_pos = TokenPosition(start_deopt_id);
+    desc.info.end_pos = TokenPosition(end_deopt_id);
+    desc.info.set_index(start_context_level);
+    Add(desc);
+
+    start = end + 2;
+  }
+}
+
+RawLocalVarDescriptors* LocalVarDescriptorsBuilder::Done() {
+  if (vars_.is_empty()) {
+    return Object::empty_var_descriptors().raw();
+  }
+  const LocalVarDescriptors& var_desc =
+      LocalVarDescriptors::Handle(LocalVarDescriptors::New(vars_.length()));
+  for (int i = 0; i < vars_.length(); i++) {
+    var_desc.SetVar(i, *(vars_[i].name), &vars_[i].info);
+  }
+  return var_desc.raw();
+}
+
 }  // namespace dart
 
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/scopes.h b/runtime/vm/scopes.h
index 7a0bde6..71ef849 100644
--- a/runtime/vm/scopes.h
+++ b/runtime/vm/scopes.h
@@ -215,6 +215,36 @@
   DISALLOW_COPY_AND_ASSIGN(LocalVariable);
 };
 
+// Accumulates local variable descriptors while building
+// LocalVarDescriptors object.
+class LocalVarDescriptorsBuilder : public ValueObject {
+ public:
+  struct VarDesc {
+    const String* name;
+    RawLocalVarDescriptors::VarInfo info;
+  };
+
+  LocalVarDescriptorsBuilder() : vars_(8) {}
+
+  // Add variable descriptor.
+  void Add(const VarDesc& var_desc) { vars_.Add(var_desc); }
+
+  // Add all variable descriptors from given [LocalVarDescriptors] object.
+  void AddAll(Zone* zone, const LocalVarDescriptors& var_descs);
+
+  // Record deopt-id -> context-level mappings, using ranges of deopt-ids with
+  // the same context-level. [context_level_array] contains (deopt_id,
+  // context_level) tuples.
+  void AddDeoptIdToContextLevelMappings(
+      ZoneGrowableArray<intptr_t>* context_level_array);
+
+  // Finish building LocalVarDescriptor object.
+  RawLocalVarDescriptors* Done();
+
+ private:
+  GrowableArray<VarDesc> vars_;
+};
+
 class NameReference : public ZoneAllocated {
  public:
   NameReference(TokenPosition token_pos, const String& name)
@@ -439,11 +469,6 @@
   static RawContextScope* CreateImplicitClosureScope(const Function& func);
 
  private:
-  struct VarDesc {
-    const String* name;
-    RawLocalVarDescriptors::VarInfo info;
-  };
-
   // Allocate the variable in the current context, possibly updating the current
   // context owner scope, if the variable is the first one to be allocated at
   // this loop level.
@@ -452,7 +477,8 @@
   void AllocateContextVariable(LocalVariable* variable,
                                LocalScope** context_owner);
 
-  void CollectLocalVariables(GrowableArray<VarDesc>* vars, int16_t* scope_id);
+  void CollectLocalVariables(LocalVarDescriptorsBuilder* vars,
+                             int16_t* scope_id);
 
   NameReference* FindReference(const String& name) const;
 
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index f5c0619..7981794 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -120,7 +120,7 @@
 StreamInfo Service::debug_stream("Debug");
 StreamInfo Service::gc_stream("GC");
 StreamInfo Service::echo_stream("_Echo");
-StreamInfo Service::graph_stream("_Graph");
+StreamInfo Service::heapsnapshot_stream("HeapSnapshot");
 StreamInfo Service::logging_stream("Logging");
 StreamInfo Service::extension_stream("Extension");
 StreamInfo Service::timeline_stream("Timeline");
@@ -131,7 +131,7 @@
 static StreamInfo* streams_[] = {
     &Service::vm_stream,      &Service::isolate_stream,
     &Service::debug_stream,   &Service::gc_stream,
-    &Service::echo_stream,    &Service::graph_stream,
+    &Service::echo_stream,    &Service::heapsnapshot_stream,
     &Service::logging_stream, &Service::extension_stream,
     &Service::timeline_stream};
 
@@ -213,14 +213,6 @@
   return object.raw();
 }
 
-static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) {
-  void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size);
-  if (new_ptr == NULL) {
-    OUT_OF_MEMORY();
-  }
-  return reinterpret_cast<uint8_t*>(new_ptr);
-}
-
 static void PrintMissingParamError(JSONStream* js, const char* param) {
   js->PrintError(kInvalidParams, "%s expects the '%s' parameter", js->method(),
                  param);
@@ -972,8 +964,6 @@
 
   bool result;
   {
-    TransitionVMToNative transition(thread);
-
     Dart_CObject cbytes;
     cbytes.type = Dart_CObject_kExternalTypedData;
     cbytes.value.as_external_typed_data.type = Dart_TypedData_kUint8;
@@ -994,7 +984,14 @@
     message.value.as_array.length = 2;
     message.value.as_array.values = elements;
 
-    result = Dart_PostCObject(ServiceIsolate::Port(), &message);
+    ApiMessageWriter writer;
+    std::unique_ptr<Message> msg = writer.WriteCMessage(
+        &message, ServiceIsolate::Port(), Message::kNormalPriority);
+    if (msg == nullptr) {
+      result = false;
+    } else {
+      result = PortMap::PostMessage(std::move(msg));
+    }
   }
 
   if (!result) {
@@ -1004,34 +1001,20 @@
 
 void Service::SendEventWithData(const char* stream_id,
                                 const char* event_type,
+                                intptr_t reservation,
                                 const char* metadata,
                                 intptr_t metadata_size,
-                                const uint8_t* data,
+                                uint8_t* data,
                                 intptr_t data_size) {
-  // Bitstream: [metadata size (big-endian 64 bit)] [metadata (UTF-8)] [data]
-  const intptr_t total_bytes = sizeof(uint64_t) + metadata_size + data_size;
-
-  uint8_t* message = static_cast<uint8_t*>(malloc(total_bytes));
-  if (message == NULL) {
-    OUT_OF_MEMORY();
-  }
-  intptr_t offset = 0;
-
-  // Metadata size.
-  reinterpret_cast<uint64_t*>(message)[0] =
-      Utils::HostToBigEndian64(metadata_size);
-  offset += sizeof(uint64_t);
-
-  // Metadata.
-  memmove(&message[offset], metadata, metadata_size);
-  offset += metadata_size;
-
-  // Data.
-  memmove(&message[offset], data, data_size);
-  offset += data_size;
-
-  ASSERT(offset == total_bytes);
-  SendEvent(stream_id, event_type, message, total_bytes);
+  ASSERT(kInt32Size + metadata_size <= reservation);
+  // Using a SPACE creates valid JSON. Our goal here is to prevent the memory
+  // overhead of copying to concatenate metadata and payload together by
+  // over-allocating to underlying buffer before we know how long the metadata
+  // will be.
+  memset(data, ' ', reservation);
+  reinterpret_cast<uint32_t*>(data)[0] = reservation;
+  memmove(&(reinterpret_cast<uint32_t*>(data)[1]), metadata, metadata_size);
+  Service::SendEvent(stream_id, event_type, data, data_size);
 }
 
 static void ReportPauseOnConsole(ServiceEvent* event) {
@@ -1586,9 +1569,15 @@
       }
     }
   }
-  uint8_t data[] = {0, 128, 255};
-  SendEventWithData(echo_stream.id(), "_Echo", js.buffer()->buf(),
-                    js.buffer()->length(), data, sizeof(data));
+
+  intptr_t reservation = js.buffer()->length() + sizeof(int32_t);
+  intptr_t data_size = reservation + 3;
+  uint8_t* data = reinterpret_cast<uint8_t*>(malloc(data_size));
+  data[reservation + 0] = 0;
+  data[reservation + 1] = 128;
+  data[reservation + 2] = 255;
+  SendEventWithData(echo_stream.id(), "_Echo", reservation, js.buffer()->buf(),
+                    js.buffer()->length(), data, data_size);
 }
 
 static bool TriggerEchoEvent(Thread* thread, JSONStream* js) {
@@ -4073,82 +4062,20 @@
   return true;
 }
 
-static const char* snapshot_roots_names[] = {
-    "User", "VM", NULL,
-};
-
-static ObjectGraph::SnapshotRoots snapshot_roots_values[] = {
-    ObjectGraph::kUser, ObjectGraph::kVM,
-};
-
 static const MethodParameter* request_heap_snapshot_params[] = {
     RUNNABLE_ISOLATE_PARAMETER,
-    new EnumParameter("roots", false /* not required */, snapshot_roots_names),
-    new BoolParameter("collectGarbage", false /* not required */), NULL,
 };
 
 static bool RequestHeapSnapshot(Thread* thread, JSONStream* js) {
-  ObjectGraph::SnapshotRoots roots = ObjectGraph::kVM;
-  const char* roots_arg = js->LookupParam("roots");
-  if (roots_arg != NULL) {
-    roots = EnumMapper(roots_arg, snapshot_roots_names, snapshot_roots_values);
-  }
-  const bool collect_garbage =
-      BoolParameter::Parse(js->LookupParam("collectGarbage"), true);
-  if (Service::graph_stream.enabled()) {
-    Service::SendGraphEvent(thread, roots, collect_garbage);
+  if (Service::heapsnapshot_stream.enabled()) {
+    HeapSnapshotWriter writer(thread);
+    writer.Write();
   }
   // TODO(koda): Provide some id that ties this request to async response(s).
   PrintSuccess(js);
   return true;
 }
 
-void Service::SendGraphEvent(Thread* thread,
-                             ObjectGraph::SnapshotRoots roots,
-                             bool collect_garbage) {
-  uint8_t* buffer = NULL;
-  WriteStream stream(&buffer, &allocator, 1 * MB);
-  ObjectGraph graph(thread);
-  intptr_t node_count = graph.Serialize(&stream, roots, collect_garbage);
-
-  // Chrome crashes receiving a single tens-of-megabytes blob, so send the
-  // snapshot in megabyte-sized chunks instead.
-  const intptr_t kChunkSize = 1 * MB;
-  intptr_t num_chunks =
-      (stream.bytes_written() + (kChunkSize - 1)) / kChunkSize;
-  for (intptr_t i = 0; i < num_chunks; i++) {
-    JSONStream js;
-    {
-      JSONObject jsobj(&js);
-      jsobj.AddProperty("jsonrpc", "2.0");
-      jsobj.AddProperty("method", "streamNotify");
-      {
-        JSONObject params(&jsobj, "params");
-        params.AddProperty("streamId", graph_stream.id());
-        {
-          JSONObject event(&params, "event");
-          event.AddProperty("type", "Event");
-          event.AddProperty("kind", "_Graph");
-          event.AddProperty("isolate", thread->isolate());
-          event.AddPropertyTimeMillis("timestamp", OS::GetCurrentTimeMillis());
-
-          event.AddProperty("chunkIndex", i);
-          event.AddProperty("chunkCount", num_chunks);
-          event.AddProperty("nodeCount", node_count);
-        }
-      }
-    }
-
-    uint8_t* chunk_start = buffer + (i * kChunkSize);
-    intptr_t chunk_size = (i + 1 == num_chunks)
-                              ? stream.bytes_written() - (i * kChunkSize)
-                              : kChunkSize;
-
-    SendEventWithData(graph_stream.id(), "_Graph", js.buffer()->buf(),
-                      js.buffer()->length(), chunk_start, chunk_size);
-  }
-}
-
 void Service::SendInspectEvent(Isolate* isolate, const Object& inspectee) {
   if (!Service::debug_stream.enabled()) {
     return;
@@ -4213,78 +4140,6 @@
   Service::HandleEvent(&event);
 }
 
-class ContainsAddressVisitor : public FindObjectVisitor {
- public:
-  explicit ContainsAddressVisitor(uword addr) : addr_(addr) {}
-  virtual ~ContainsAddressVisitor() {}
-
-  virtual uword filter_addr() const { return addr_; }
-
-  virtual bool FindObject(RawObject* obj) const {
-    if (obj->IsPseudoObject()) {
-      return false;
-    }
-    uword obj_begin = RawObject::ToAddr(obj);
-    uword obj_end = obj_begin + obj->HeapSize();
-    return obj_begin <= addr_ && addr_ < obj_end;
-  }
-
- private:
-  uword addr_;
-};
-
-static const MethodParameter* get_object_by_address_params[] = {
-    RUNNABLE_ISOLATE_PARAMETER, NULL,
-};
-
-static RawObject* GetObjectHelper(Thread* thread, uword addr) {
-  HeapIterationScope iteration(thread);
-  Object& object = Object::Handle(thread->zone());
-
-  {
-    NoSafepointScope no_safepoint;
-    Isolate* isolate = thread->isolate();
-    ContainsAddressVisitor visitor(addr);
-    object = isolate->heap()->FindObject(&visitor);
-  }
-
-  if (!object.IsNull()) {
-    return object.raw();
-  }
-
-  {
-    NoSafepointScope no_safepoint;
-    ContainsAddressVisitor visitor(addr);
-    object = Dart::vm_isolate()->heap()->FindObject(&visitor);
-  }
-
-  return object.raw();
-}
-
-static bool GetObjectByAddress(Thread* thread, JSONStream* js) {
-  const char* addr_str = js->LookupParam("address");
-  if (addr_str == NULL) {
-    PrintMissingParamError(js, "address");
-    return true;
-  }
-
-  // Handle heap objects.
-  uword addr = 0;
-  if (!GetUnsignedIntegerId(addr_str, &addr, 16)) {
-    PrintInvalidParamError(js, "address");
-    return true;
-  }
-  bool ref = js->HasParam("ref") && js->ParamIs("ref", "true");
-  const Object& obj =
-      Object::Handle(thread->zone(), GetObjectHelper(thread, addr));
-  if (obj.IsNull()) {
-    PrintSentinel(js, kFreeSentinel);
-  } else {
-    obj.PrintJSON(js, ref);
-  }
-  return true;
-}
-
 static const MethodParameter* get_persistent_handles_params[] = {
     ISOLATE_PARAMETER, NULL,
 };
@@ -4969,8 +4824,6 @@
     get_object_params },
   { "_getObjectStore", GetObjectStore,
     get_object_store_params },
-  { "_getObjectByAddress", GetObjectByAddress,
-    get_object_by_address_params },
   { "_getPersistentHandles", GetPersistentHandles,
       get_persistent_handles_params, },
   { "_getPorts", GetPorts,
@@ -5019,7 +4872,7 @@
     reload_sources_params },
   { "resume", Resume,
     resume_params },
-  { "_requestHeapSnapshot", RequestHeapSnapshot,
+  { "requestHeapSnapshot", RequestHeapSnapshot,
     request_heap_snapshot_params },
   { "_evaluateCompiledExpression", EvaluateCompiledExpression,
     evaluate_compiled_expression_params },
diff --git a/runtime/vm/service.h b/runtime/vm/service.h
index 972e587..453e872 100644
--- a/runtime/vm/service.h
+++ b/runtime/vm/service.h
@@ -15,7 +15,7 @@
 namespace dart {
 
 #define SERVICE_PROTOCOL_MAJOR_VERSION 3
-#define SERVICE_PROTOCOL_MINOR_VERSION 25
+#define SERVICE_PROTOCOL_MINOR_VERSION 26
 
 class Array;
 class EmbedderServiceHandler;
@@ -121,9 +121,6 @@
       Dart_GetVMServiceAssetsArchive get_service_assets);
 
   static void SendEchoEvent(Isolate* isolate, const char* text);
-  static void SendGraphEvent(Thread* thread,
-                             ObjectGraph::SnapshotRoots roots,
-                             bool collect_garbage);
   static void SendInspectEvent(Isolate* isolate, const Object& inspectee);
 
   static void SendEmbedderEvent(Isolate* isolate,
@@ -146,6 +143,15 @@
                                  const String& event_kind,
                                  const String& event_data);
 
+  // Takes ownership of 'data'.
+  static void SendEventWithData(const char* stream_id,
+                                const char* event_type,
+                                intptr_t reservation,
+                                const char* metadata,
+                                intptr_t metadata_size,
+                                uint8_t* data,
+                                intptr_t data_size);
+
   static void PostError(const String& method_name,
                         const Array& parameter_keys,
                         const Array& parameter_values,
@@ -159,7 +165,7 @@
   static StreamInfo debug_stream;
   static StreamInfo gc_stream;
   static StreamInfo echo_stream;
-  static StreamInfo graph_stream;
+  static StreamInfo heapsnapshot_stream;
   static StreamInfo logging_stream;
   static StreamInfo extension_stream;
   static StreamInfo timeline_stream;
@@ -212,20 +218,13 @@
                                        const Array& parameter_values,
                                        const Instance& reply_port,
                                        const Instance& id);
+
   // Takes ownership of 'bytes'.
   static void SendEvent(const char* stream_id,
                         const char* event_type,
                         uint8_t* bytes,
                         intptr_t bytes_length);
 
-  // Does not take ownership of 'data'.
-  static void SendEventWithData(const char* stream_id,
-                                const char* event_type,
-                                const char* metadata,
-                                intptr_t metadata_size,
-                                const uint8_t* data,
-                                intptr_t data_size);
-
   static void PostEvent(Isolate* isolate,
                         const char* stream_id,
                         const char* kind,
diff --git a/runtime/vm/service/heap_snapshot.md b/runtime/vm/service/heap_snapshot.md
new file mode 100644
index 0000000..c32d562
--- /dev/null
+++ b/runtime/vm/service/heap_snapshot.md
@@ -0,0 +1,183 @@
+# Dart VM Service Heap Snapshot
+
+A snapshot of a heap in the Dart VM that allows for arbitrary analysis of memory usage.
+
+## Object IDs
+
+An object id is a 1-origin index into SnapshotGraph.objects.
+
+Object id 0 is a sentinel value. It indicates target of a reference has been omitted from the snapshot.
+
+The root object is has object id 1.
+
+This notion of id is unrelated to the id used by the rest of the VM service and cannot, for example, be used as a argument to getObject.
+
+## Class IDs
+
+A class id is a 1-origin index into SnapshotGraph.classes.
+
+Class id 0 is a sentinel value.
+
+This notion of id is unrelated to the id used by the rest of the VM service and cannot, for example, be used as a argument to getObject.
+
+## Graph properties
+
+The graph may contain unreachable objects.
+
+The graph may references without a corresponding SnapshotField.
+
+## Format
+
+```
+type SnapshotGraph {
+  magic : uint8[8] = "dartheap",
+
+  flags : uleb128,
+  name : Utf8String,
+
+  // The sum of shallow sizes of all objects in this graph.
+  shallowSize : uleb128,
+
+  // The amount of memory reserved for this heap. At least as large as |shallowSize|.
+  capacity : uleb128,
+
+  // The sum of sizes of all external properites in this graph.
+  externalSize : uleb128,
+
+  classCount : uleb128,
+  classes : SnapshotClass[classCount],
+
+  // At least as big as the sum of SnapshotObject.referenceCount.
+  referenceCount : uleb128,
+  objectCount : uleb128,
+  objects : SnapshotObject[objectCount],
+
+  externalPropertyCount : uleb128,
+  externalProperties : SnapshotExternalProperty[externalPropertyCount],
+}
+```
+
+```
+type SnapshotClass {
+  // Reserved.
+  flags : uleb128,
+
+  // The simple (not qualified) name of the class.
+  name : Utf8String,
+
+  // The name of the class's library.
+  libraryName : Utf8String,
+
+  // The URI of the class's library.
+  libraryUri : Utf8String,
+
+  reserved : Utf8String,
+
+  fieldCount : uleb128,
+  fields : SnapshotField[fieldCount],
+}
+```
+
+```
+type SnapshotField {
+  // Reserved.
+  flags : uleb128,
+
+  // A 0-origin index into SnapshotObject.references.
+  index : uleb128,
+
+  name : Utf8String,
+
+  reserved : Utf8String,
+}
+```
+
+```
+type SnapshotObject {
+  // A 1-origin index into SnapshotGraph.classes.
+  classId : uleb128,
+
+  // The space used by this object in bytes.
+  shallowSize : uleb128,
+
+  data : NonReferenceData,
+
+  referenceCount : uleb128,
+  // A list of 1-origin indicies into SnapshotGraph.objects
+  references : uleb128[referenceCount],
+}
+```
+
+```
+type NonReferenceData {
+  tag : uleb128,
+}
+
+type NoData extends NonReferenceData {
+  tag : uleb128 = 0,
+}
+
+type NullData extends NonReferenceData {
+  tag : uleb128 = 1,
+}
+
+type BoolData extends NonReferenceData {
+  tag : uleb128 = 2,
+  value : uleb128,
+}
+
+type IntegerData extends NonReferenceData {
+  tag : uleb128 = 3,
+  value : uleb128,
+}
+
+type DoubleData extends NonReferenceData {
+  tag: uleb128 = 4,
+  value: float64,
+}
+
+type Latin1StringData extends NonReferenceData {
+  tag : uleb128 = 5,
+  length : uleb128,
+  truncatedLength : uleb128,
+  codeUnits : uint8[truncatedLength],
+}
+
+type Utf16StringData extends NonReferenceData {
+  tag : uleb128 = 6,
+  length : uleb128,
+  truncatedLength : uleb128,
+  codeUnits : uint16[truncatedLength],
+}
+
+// Indicates the object is variable length, such as a known implementation
+// of List, Map or Set.
+type LengthData extends NonReferenceData {
+  tag : uleb128 = 7,
+  length : uleb128,
+}
+
+// Indicates the object has some name, such as Function, Field, Class or Library.
+type NameData extends NonReferenceData {
+  tag : uleb128 = 7,
+  name : Utf8String,
+}
+```
+
+```
+type SnapshotExternalProperty {
+  // A 1-origin index into SnapshotGraph.objects.
+  object : uleb128,
+
+  externalSize : uleb128,
+
+  name : Utf8String,
+}
+```
+
+```
+type Utf8String {
+  length : uleb128,
+  codeUnits : uint8[length],
+}
+```
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index bf8ba6e..6d65362 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -1,4 +1,4 @@
-# Dart VM Service Protocol 3.25
+# Dart VM Service Protocol 3.26
 
 > Please post feedback to the [observatory-discuss group][discuss-list]
 
@@ -261,7 +261,20 @@
 It is considered a _backwards compatible_ change to add a new type of event to an existing stream.
 Clients should be written to handle this gracefully.
 
+### Binary Events
 
+Some events are associated with bulk binary data. These events are delivered as
+WebSocket binary frames instead of text frames. A binary event's metadata
+should be interpreted as UTF-8 encoded JSON, with the same properties as
+described above for ordinary events.
+
+```
+type BinaryEvent {
+  dataOffset : uint32,
+  metadata : uint8[dataOffset-4],
+  data : uint8[],
+}
+```
 
 ## Types
 
@@ -1003,6 +1016,20 @@
 
 See [Success](#success).
 
+### requestHeapSnapshot
+
+```
+Success requestHeapSnapshot(string isolateId)
+```
+
+Requests a dump of the Dart heap of the given isolate.
+
+This method immediately returns success. The VM will then begin delivering
+binary events on the `HeapSnapshot` event stream. The binary data in these
+events, when concatenated together, conforms to the SnapshotGraph type. The
+splitting of the SnapshotGraph into events can happen at any byte offset,
+including the middle of scalar fields.
+
 ### resume
 
 ```
@@ -1160,6 +1187,7 @@
 Timeline | TimelineEvents
 Logging | Logging
 Service | ServiceRegistered, ServiceUnregistered
+HeapSnapshot | HeapSnapshot
 
 Additionally, some embedders provide the _Stdout_ and _Stderr_
 streams.  These streams allow the client to subscribe to writes to
@@ -3294,5 +3322,6 @@
 3.23 | Add `VMFlagUpdate` event kind to the `VM` stream.
 3.24 | Add `operatingSystem` property to `VM` object.
 3.25 | Add 'getInboundReferences', 'getRetainingPath' RPCs, and 'InboundReferences', 'InboundReference', 'RetainingPath', and 'RetainingObject' objects.
+3.26 | Add 'requestHeapSnapshot'.
 
 [discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/runtime/vm/service/service_dev.md b/runtime/vm/service/service_dev.md
deleted file mode 100644
index 4c69a3c..0000000
--- a/runtime/vm/service/service_dev.md
+++ /dev/null
@@ -1,3298 +0,0 @@
-# Dart VM Service Protocol 3.26-dev
-
-> Please post feedback to the [observatory-discuss group][discuss-list]
-
-This document describes of _version 3.26-dev_ of the Dart VM Service Protocol. This
-protocol is used to communicate with a running Dart Virtual Machine.
-
-To use the Service Protocol, start the VM with the *--observe* flag.
-The VM will start a webserver which services protocol requests via WebSocket.
-It is possible to make HTTP (non-WebSocket) requests,
-but this does not allow access to VM _events_ and is not documented
-here.
-
-The Service Protocol uses [JSON-RPC 2.0][].
-
-[JSON-RPC 2.0]: http://www.jsonrpc.org/specification
-
-**Table of Contents**
-
-- [RPCs, Requests, and Responses](#rpcs-requests-and-responses)
-- [Events](#events)
-- [Types](#types)
-- [IDs and Names](#ids-and-names)
-- [Versioning](#versioning)
-- [Private RPCs, Types, and Properties](#private-rpcs-types-and-properties)
-- [Public RPCs](#public-rpcs)
-  - [addBreakpoint](#addbreakpoint)
-  - [addBreakpointWithScriptUri](#addbreakpointwithscripturi)
-  - [addBreakpointAtEntry](#addbreakpointatentry)
-  - [clearVMTimeline](#clearvmtimeline)
-  - [evaluate](#evaluate)
-  - [evaluateInFrame](#evaluateinframe)
-  - [getAllocationProfile](#getallocationprofile)
-  - [getFlagList](#getflaglist)
-  - [getInstances](#getinstances)
-  - [getInboundReferences](#getinboundreferences)
-  - [getIsolate](#getisolate)
-  - [getMemoryUsage](#getmemoryusage)
-  - [getObject](#getobject)
-  - [getRetainingPath](#getretainingpath)
-  - [getScripts](#getscripts)
-  - [getSourceReport](#getsourcereport)
-  - [getStack](#getstack)
-  - [getVersion](#getversion)
-  - [getVM](#getvm)
-  - [getVMTimeline](#getvmtimeline)
-  - [getVMTimelineFlags](#getvmtimelineflags)
-  - [getVMTimelineMicros](#getvmtimelinemicros)
-  - [invoke](#invoke)
-  - [pause](#pause)
-  - [kill](#kill)
-  - [registerService](#registerService)
-  - [reloadSources](#reloadsources)
-  - [removeBreakpoint](#removebreakpoint)
-  - [resume](#resume)
-  - [setExceptionPauseMode](#setexceptionpausemode)
-  - [setFlag](#setflag)
-  - [setLibraryDebuggable](#setlibrarydebuggable)
-  - [setName](#setname)
-  - [setVMName](#setvmname)
-  - [setVMTimelineFlags](#setvmtimelineflags)
-  - [streamCancel](#streamcancel)
-  - [streamListen](#streamlisten)
-- [Public Types](#public-types)
-  - [AllocationProfile](#allocationprofile)
-  - [BoundField](#boundfield)
-  - [BoundVariable](#boundvariable)
-  - [Breakpoint](#breakpoint)
-  - [Class](#class)
-  - [ClassHeapStats](#classheapstats)
-  - [ClassList](#classlist)
-  - [Code](#code)
-  - [CodeKind](#codekind)
-  - [Context](#context)
-  - [ContextElement](#contextelement)
-  - [Error](#error)
-  - [ErrorKind](#errorkind)
-  - [Event](#event)
-  - [EventKind](#eventkind)
-  - [ExtensionData](#extensiondata)
-  - [Field](#field)
-  - [Flag](#flag)
-  - [FlagList](#flaglist)
-  - [Frame](#frame)
-  - [Function](#function)
-  - [InboundReferences](#inboundreferences)
-  - [InboundReference](#inboundreference)
-  - [Instance](#instance)
-  - [InstanceSet](#instanceset)
-  - [Isolate](#isolate)
-  - [Library](#library)
-  - [LibraryDependency](#librarydependency)
-  - [LogRecord](#logrecord)
-  - [MapAssociation](#mapassociation)
-  - [MemoryUsage](#memoryusage)
-  - [Message](#message)
-  - [Null](#null)
-  - [Object](#object)
-  - [ReloadReport](#reloadreport)
-  - [Response](#response)
-  - [RetainingObject](#retainingobject)
-  - [RetainingPath](#retainingpath)
-  - [Sentinel](#sentinel)
-  - [SentinelKind](#sentinelkind)
-  - [Script](#script)
-  - [ScriptList](#scriptlist)
-  - [SourceLocation](#sourcelocation)
-  - [SourceReport](#sourcereport)
-  - [SourceReportCoverage](#sourcereportcoverage)
-  - [SourceReportKind](#sourcereportkind)
-  - [SourceReportRange](#sourcereportrange)
-  - [Stack](#stack)
-  - [StepOption](#stepoption)
-  - [Success](#success)
-  - [Timeline](#timeline)
-  - [TimelineEvent](#timelineevent)
-  - [TimelineFlags](#timelineflags)
-  - [Timestamp](#timestamp)
-  - [TypeArguments](#typearguments)
-  - [UresolvedSourceLocation](#unresolvedsourcelocation)
-  - [Version](#version)
-  - [VM](#vm)
-- [Revision History](#revision-history)
-
-## RPCs, Requests, and Responses
-
-An RPC request is a JSON object sent to the server. Here is an
-example [getVersion](#getversion) request:
-
-```
-{
-  "jsonrpc": "2.0",
-  "method": "getVersion",
-  "params": {},
-  "id": "1"
-}
-```
-
-The _id_ property must be a string, number, or `null`. The Service Protocol
-optionally accepts requests without the _jsonprc_ property.
-
-An RPC response is a JSON object (http://json.org/). The response always specifies an
-_id_ property to pair it with the corresponding request. If the RPC
-was successful, the _result_ property provides the result.
-
-Here is an example response for our [getVersion](#getversion) request above:
-
-```
-{
-  "jsonrpc": "2.0",
-  "result": {
-    "type": "Version",
-    "major": 3,
-    "minor": 5
-  }
-  "id": "1"
-}
-```
-
-Parameters for RPC requests are always provided as _named_ parameters.
-The JSON-RPC spec provides for _positional_ parameters as well, but they
-are not supported by the Dart VM.
-
-By convention, every response returned by the Service Protocol is a subtype
-of [Response](#response) and provides a _type_ parameter which can be used
-to distinguish the exact return type. In the example above, the
-[Version](#version) type is returned.
-
-Here is an example [streamListen](#streamlisten) request which provides
-a parameter:
-
-```
-{
-  "jsonrpc": "2.0",
-  "method": "streamListen",
-  "params": {
-    "streamId": "GC"
-  },
-  "id": "2"
-}
-```
-
-<a name="rpc-error"></a>
-When an RPC encounters an error, it is provided in the _error_
-property of the response object. JSON-RPC errors always provide
-_code_, _message_, and _data_ properties.
-
-Here is an example error response for our [streamListen](#streamlisten)
-request above. This error would be generated if we were attempting to
-subscribe to the _GC_ stream multiple times from the same client.
-
-```
-{
-  "jsonrpc": "2.0",
-  "error": {
-    "code": 103,
-    "message": "Stream already subscribed",
-    "data": {
-      "details": "The stream 'GC' is already subscribed"
-    }
-  }
-  "id": "2"
-}
-```
-
-In addition to the [error codes](http://www.jsonrpc.org/specification#error_object) specified in the JSON-RPC spec, we use the following application specific error codes:
-
-code | message | meaning
----- | ------- | -------
-100 | Feature is disabled | The operation is unable to complete because a feature is disabled
-101 | VM must be paused | This operation is only valid when the VM is paused
-102 | Cannot add breakpoint | The VM is unable to add a breakpoint at the specified line or function
-103 | Stream already subscribed | The client is already subscribed to the specified _streamId_
-104 | Stream not subscribed | The client is not subscribed to the specified _streamId_
-105 | Isolate must be runnable | This operation cannot happen until the isolate is runnable
-106 | Isolate must be paused | This operation is only valid when the isolate is paused
-107 | Cannot resume execution | The isolate could not be resumed
-108 | Isolate is reloading | The isolate is currently processing another reload request
-109 | Isolate cannot be reloaded | The isolate has an unhandled exception and can no longer be reloaded
-110 | Isolate must have reloaded | Failed to find differences in last hot reload request
-111 | Service already registered | Service with such name has already been registered by this client
-112 | Service disappeared | Failed to fulfill service request, likely service handler is no longer available
-113 | Expression compilation error | Request to compile expression failed
-114 | Invalid timeline request | The timeline related request could not be completed due to the current configuration
-
-## Events
-
-By using the [streamListen](#streamlisten) and [streamCancel](#streamcancel) RPCs, a client may
-request to be notified when an _event_ is posted to a specific
-_stream_ in the VM. Every stream has an associated _stream id_ which
-is used to name that stream.
-
-Each stream provides access to certain kinds of events. For example the _Isolate_ stream provides
-access to events pertaining to isolate births, deaths, and name changes. See [streamListen](#streamlisten)
-for a list of the well-known stream ids and their associated events.
-
-Stream events arrive asynchronously over the WebSocket. They're structured as
-JSON-RPC 2.0 requests with no _id_ property. The _method_ property will be
-_streamNotify_, and the _params_ will have _streamId_ and _event_ properties:
-
-```json
-{
-  "json-rpc": "2.0",
-  "method": "streamNotify",
-  "params": {
-    "streamId": "Isolate",
-    "event": {
-      "type": "Event",
-      "kind": "IsolateExit",
-      "isolate": {
-        "type": "@Isolate",
-        "id": "isolates/33",
-        "number": "51048743613",
-        "name": "worker-isolate"
-      }
-    }
-  }
-}
-```
-
-It is considered a _backwards compatible_ change to add a new type of event to an existing stream.
-Clients should be written to handle this gracefully.
-
-
-
-## Types
-
-By convention, every result and event provided by the Service Protocol
-is a subtype of [Response](#response) and has the _type_ property.
-This allows the client to distinguish different kinds of responses. For example,
-information about a Dart function is returned using the [Function](#function) type.
-
-If the type of a response begins with the _@_ character, then that
-response is a _reference_. If the type name of a response does not
-begin with the _@_ character, it is an _object_. A reference is
-intended to be a subset of an object which provides enough information
-to generate a reasonable looking reference to the object.
-
-For example, an [@Isolate](#isolate) reference has the _type_, _id_, _name_ and
-_number_ properties:
-
-```
-  "result": {
-    "type": "@Isolate",
-    "id": "isolates/33",
-    "number": "51048743613"
-    "name": "worker-isolate"
-  }
-```
-
-But an [Isolate](#isolate) object has more information:
-
-```
-  "result": {
-    "type": "Isolate",
-    "id": "isolates/33",
-    "number": "51048743613"
-    "name": "worker-isolate"
-    "rootLib": { ... }
-    "entry": ...
-    "heaps": ...
-     ...
-  }
-```
-
-## IDs and Names
-
-Many responses returned by the Service Protocol have an _id_ property.
-This is an identifier used to request an object from an isolate using
-the [getObject](#getobject) RPC. If two responses have the same _id_ then they
-refer to the same object. The converse is not true: the same object
-may sometimes be returned with two different values for _id_.
-
-The _id_ property should be treated as an opaque string by the client:
-it is not meant to be parsed.
-
-An id can be either _temporary_ or _fixed_:
-
-* A _temporary_ id can expire over time. The VM allocates certain ids
-  in a ring which evicts old ids over time.
-
-* A _fixed_ id will never expire, but the object it refers to may
-  be collected. The VM uses fixed ids for objects like scripts,
-  libraries, and classes.
-
-If an id is fixed, the _fixedId_ property will be true. If an id is temporary
-the _fixedId_ property will be omitted.
-
-Sometimes a temporary id may expire. In this case, some RPCs may return
-an _Expired_ [Sentinel](#sentinel) to indicate this.
-
-The object referred to by an id may be collected by the VM's garbage
-collector. In this case, some RPCs may return a _Collected_ [Sentinel](#sentinel)
-to indicate this.
-
-Many objects also have a _name_ property. This is provided so that
-objects can be displayed in a way that a Dart language programmer
-would find familiar. Names are not unique.
-
-## Versioning
-
-The [getVersion](#getversion) RPC can be used to find the version of the protocol
-returned by a VM. The _Version_ response has a major and a minor
-version number:
-
-```
-  "result": {
-    "type": "Version",
-    "major": 3,
-    "minor": 5
-  }
-```
-
-The major version number is incremented when the protocol is changed
-in a potentially _incompatible_ way. An example of an incompatible
-change is removing a non-optional property from a result.
-
-The minor version number is incremented when the protocol is changed
-in a _backwards compatible_ way. An example of a backwards compatible
-change is adding a property to a result.
-
-Certain changes that would normally not be backwards compatible are
-considered backwards compatible for the purposes of versioning.
-Specifically, additions can be made to the [EventKind](#eventkind) and
-[InstanceKind](#instancekind) enumerated types and the client must
-handle this gracefully. See the notes on these enumerated types for more
-information.
-
-## Private RPCs, Types, and Properties
-
-Any RPC, type, or property which begins with an underscore is said to
-be _private_. These RPCs, types, and fields can be changed at any
-time without changing major or minor version numbers.
-
-The intention is that the Service Protocol will evolve by adding
-private RPCs which may, over time, migrate to the public api as they
-become stable. Some private types and properties expose VM specific
-implementation state and will never be appropriate to add to
-the public api.
-
-## Public RPCs
-
-The following is a list of all public RPCs supported by the Service Protocol.
-
-An RPC is described using the following format:
-
-```
-ReturnType methodName(parameterType1 parameterName1,
-                      parameterType2 parameterName2,
-                      ...)
-```
-
-If an RPC says it returns type _T_ it may actually return _T_ or any
-[subtype](#public-types) of _T_. For example, an
-RPC which is declared to return [@Object](#object) may actually
-return [@Instance](#instance).
-
-If an RPC can return one or more independent types, this is indicated
-with the vertical bar:
-
-```
-ReturnType1|ReturnType2
-```
-
-Any RPC may return an _error_ response as [described above](#rpc-error).
-
-Some parameters are optional. This is indicated by the text
-_[optional]_ following the parameter name:
-
-```
-ReturnType methodName(parameterType parameterName [optional])
-```
-
-A description of the return types and parameter types is provided
-in the section on [public types](#public-types).
-
-### addBreakpoint
-
-```
-Breakpoint addBreakpoint(string isolateId,
-                         string scriptId,
-                         int line,
-                         int column [optional])
-```
-
-The _addBreakpoint_ RPC is used to add a breakpoint at a specific line
-of some script.
-
-The _scriptId_ parameter is used to specify the target script.
-
-The _line_ parameter is used to specify the target line for the
-breakpoint. If there are multiple possible breakpoints on the target
-line, then the VM will place the breakpoint at the location which
-would execute soonest. If it is not possible to set a breakpoint at
-the target line, the breakpoint will be added at the next possible
-breakpoint location within the same function.
-
-The _column_ parameter may be optionally specified.  This is useful
-for targeting a specific breakpoint on a line with multiple possible
-breakpoints.
-
-If no breakpoint is possible at that line, the _102_ (Cannot add
-breakpoint) error code is returned.
-
-Note that breakpoints are added and removed on a per-isolate basis.
-
-See [Breakpoint](#breakpoint).
-
-### addBreakpointWithScriptUri
-
-```
-Breakpoint addBreakpointWithScriptUri(string isolateId,
-                                      string scriptUri,
-                                      int line,
-                                      int column [optional])
-```
-
-The _addBreakpoint_ RPC is used to add a breakpoint at a specific line
-of some script.  This RPC is useful when a script has not yet been
-assigned an id, for example, if a script is in a deferred library
-which has not yet been loaded.
-
-The _scriptUri_ parameter is used to specify the target script.
-
-The _line_ parameter is used to specify the target line for the
-breakpoint. If there are multiple possible breakpoints on the target
-line, then the VM will place the breakpoint at the location which
-would execute soonest. If it is not possible to set a breakpoint at
-the target line, the breakpoint will be added at the next possible
-breakpoint location within the same function.
-
-The _column_ parameter may be optionally specified.  This is useful
-for targeting a specific breakpoint on a line with multiple possible
-breakpoints.
-
-If no breakpoint is possible at that line, the _102_ (Cannot add
-breakpoint) error code is returned.
-
-Note that breakpoints are added and removed on a per-isolate basis.
-
-See [Breakpoint](#breakpoint).
-
-### addBreakpointAtEntry
-
-```
-Breakpoint addBreakpointAtEntry(string isolateId,
-                                string functionId)
-```
-The _addBreakpointAtEntry_ RPC is used to add a breakpoint at the
-entrypoint of some function.
-
-If no breakpoint is possible at the function entry, the _102_ (Cannot add
-breakpoint) error code is returned.
-
-See [Breakpoint](#breakpoint).
-
-Note that breakpoints are added and removed on a per-isolate basis.
-
-
-### clearVMTimeline
-
-```
-Success clearVMTimeline()
-```
-
-Clears all VM timeline events.
-
-See [Success](#success).
-
-### invoke
-
-```
-@Instance|@Error|Sentinel invoke(string isolateId,
-                                 string targetId,
-                                 string selector,
-                                 string[] argumentIds,
-                                 bool disableBreakpoints [optional])
-```
-
-The _invoke_ RPC is used to perform regular method invocation on some receiver,
-as if by dart:mirror's ObjectMirror.invoke. Note this does not provide a way to
-perform getter, setter or constructor invocation.
-
-_targetId_ may refer to a [Library](#library), [Class](#class), or
-[Instance](#instance).
-
-Each elements of _argumentId_ may refer to an [Instance](#instance).
-
-If _disableBreakpoints_ is provided and set to true, any breakpoints hit as a
-result of this invocation are ignored, including pauses resulting from a call
-to `debugger()` from `dart:developer`. Defaults to false if not provided.
-
-If _targetId_ or any element of _argumentIds_ is a temporary id which has
-expired, then the _Expired_ [Sentinel](#sentinel) is returned.
-
-If _targetId_ or any element of _argumentIds_ refers to an object which has been
-collected by the VM's garbage collector, then the _Collected_
-[Sentinel](#sentinel) is returned.
-
-If invocation triggers a failed compilation then [rpc error](#rpc-error) 113
-"Expression compilation error" is returned.
-
-If an runtime error occurs while evaluating the invocation, an [@Error](#error)
-reference will be returned.
-
-If the invocation is evaluated successfully, an [@Instance](#instance)
-reference will be returned.
-
-### evaluate
-
-```
-@Instance|@Error|Sentinel evaluate(string isolateId,
-                                   string targetId,
-                                   string expression,
-                                   map<string,string> scope [optional],
-                                   bool disableBreakpoints [optional])
-```
-
-The _evaluate_ RPC is used to evaluate an expression in the context of
-some target.
-
-_targetId_ may refer to a [Library](#library), [Class](#class), or
-[Instance](#instance).
-
-If _targetId_ is a temporary id which has expired, then the _Expired_
-[Sentinel](#sentinel) is returned.
-
-If _targetId_ refers to an object which has been collected by the VM's
-garbage collector, then the _Collected_ [Sentinel](#sentinel) is
-returned.
-
-If _scope_ is provided, it should be a map from identifiers to object ids.
-These bindings will be added to the scope in which the expression is evaluated,
-which is a child scope of the class or library for instance/class or library
-targets respectively. This means bindings provided in _scope_ may shadow
-instance members, class members and top-level members.
-
-If _disableBreakpoints_ is provided and set to true, any breakpoints hit as a
-result of this evaluation are ignored. Defaults to false if not provided.
-
-If the expression fails to parse and compile, then [rpc error](#rpc-error) 113
-"Expression compilation error" is returned.
-
-If an error occurs while evaluating the expression, an [@Error](#error)
-reference will be returned.
-
-If the expression is evaluated successfully, an [@Instance](#instance)
-reference will be returned.
-
-### evaluateInFrame
-
-```
-@Instance|@Error|Sentinel evaluateInFrame(string isolateId,
-                                          int frameIndex,
-                                          string expression,
-                                          map<string,string> scope [optional],
-                                          bool disableBreakpoints [optional])
-```
-
-The _evaluateInFrame_ RPC is used to evaluate an expression in the
-context of a particular stack frame. _frameIndex_ is the index of the
-desired [Frame](#frame), with an index of _0_ indicating the top (most
-recent) frame.
-
-If _scope_ is provided, it should be a map from identifiers to object ids.
-These bindings will be added to the scope in which the expression is evaluated,
-which is a child scope of the frame's current scope. This means bindings
-provided in _scope_ may shadow instance members, class members, top-level
-members, parameters and locals.
-
-If _disableBreakpoints_ is provided and set to true, any breakpoints hit as a
-result of this evaluation are ignored. Defaults to false if not provided.
-
-If the expression fails to parse and compile, then [rpc error](#rpc-error) 113
-"Expression compilation error" is returned.
-
-If an error occurs while evaluating the expression, an [@Error](#error)
-reference will be returned.
-
-If the expression is evaluated successfully, an [@Instance](#instance)
-reference will be returned.
-
-### getAllocationProfile
-
-```
-AllocationProfile getAllocationProfile(string isolateId,
-                                       bool reset [optional],
-                                       bool gc [optional])
-```
-
-The _getAllocationProfile_ RPC is used to retrieve allocation information for a
-given isolate.
-
-If _reset_ is provided and is set to true, the allocation accumulators will be reset
-before collecting allocation information.
-
-If _gc_ is provided and is set to true, a garbage collection will be attempted
-before collecting allocation information. There is no guarantee that a garbage
-collection will be actually be performed.
-
-### getFlagList
-
-```
-FlagList getFlagList()
-```
-
-The _getFlagList_ RPC returns a list of all command line flags in the
-VM along with their current values.
-
-See [FlagList](#flaglist).
-
-### getInboundReferences
-
-```
-InboundReferences|Sentinel getInboundReferences(string isolateId,
-                                                string targetId,
-                                                int limit)
-```
-
-Returns a set of inbound references to the object specified by _targetId_. Up to
-_limit_ references will be returned.
-
-The order of the references is undefined (i.e., not related to allocation order)
-and unstable (i.e., multiple invocations of this method against the same object
-can give different answers even if no Dart code has executed between the invocations).
-
-The references may include multiple `objectId`s that designate the same object.
-
-The references may include objects that are unreachable but have not yet been garbage collected.
-
-If _targetId_ is a temporary id which has expired, then the _Expired_
-[Sentinel](#sentinel) is returned.
-
-If _targetId_ refers to an object which has been collected by the VM's
-garbage collector, then the _Collected_ [Sentinel](#sentinel) is
-returned.
-
-See [InboundReferences](#inboundreferences).
-
-### getInstances
-
-```
-InstanceSet getInstances(string isolateId,
-                         string objectId,
-                         int limit)
-```
-
-The _getInstances_ RPC is used to retrieve a set of instances which are of a
-specific class. This does not include instances of subclasses of the given
-class.
-
-The order of the instances is undefined (i.e., not related to allocation order)
-and unstable (i.e., multiple invocations of this method against the same class
-can give different answers even if no Dart code has executed between the
-invocations).
-
-The set of instances may include objects that are unreachable but have not yet
-been garbage collected.
-
-_objectId_ is the ID of the `Class` to retrieve instances for. _objectId_ must
-be the ID of a `Class`, otherwise an error is returned.
-
-_limit_ is the maximum number of instances to be returned.
-
-See [InstanceSet](#instanceset).
-
-### getIsolate
-
-```
-Isolate|Sentinel getIsolate(string isolateId)
-```
-
-The _getIsolate_ RPC is used to lookup an _Isolate_ object by its _id_.
-
-If _isolateId_ refers to an isolate which has exited, then the
-_Collected_ [Sentinel](#sentinel) is returned.
-
-See [Isolate](#isolate).
-
-### getMemoryUsage
-
-```
-MemoryUsage|Sentinel getMemoryUsage(string isolateId)
-```
-
-The _getMemoryUsage_ RPC is used to lookup an isolate's memory usage
-statistics by its _id_.
-
-If _isolateId_ refers to an isolate which has exited, then the
-_Collected_ [Sentinel](#sentinel) is returned.
-
-See [Isolate](#isolate).
-
-### getScripts
-
-```
-ScriptList getScripts(string isolateId)
-```
-
-The _getScripts_ RPC is used to retrieve a _ScriptList_ containing all
-scripts for an isolate based on the isolate's _isolateId_.
-
-See [ScriptList](#scriptlist).
-
-### getObject
-
-```
-Object|Sentinel getObject(string isolateId,
-                          string objectId,
-                          int offset [optional],
-                          int count [optional])
-```
-
-The _getObject_ RPC is used to lookup an _object_ from some isolate by
-its _id_.
-
-If _objectId_ is a temporary id which has expired, then the _Expired_
-[Sentinel](#sentinel) is returned.
-
-If _objectId_ refers to a heap object which has been collected by the VM's
-garbage collector, then the _Collected_ [Sentinel](#sentinel) is
-returned.
-
-If _objectId_ refers to a non-heap object which has been deleted, then
-the _Collected_ [Sentinel](#sentinel) is returned.
-
-If the object handle has not expired and the object has not been
-collected, then an [Object](#object) will be returned.
-
-The _offset_ and _count_ parameters are used to request subranges of
-Instance objects with the kinds: String, List, Map, Uint8ClampedList,
-Uint8List, Uint16List, Uint32List, Uint64List, Int8List, Int16List,
-Int32List, Int64List, Flooat32List, Float64List, Inst32x3List,
-Float32x4List, and Float64x2List.  These parameters are otherwise
-ignored.
-
-### getRetainingPath
-
-```
-RetainingPath getRetainingPath(string isolateId,
-                               string targetId,
-                               int limit)
-```
-
-The _getRetainingPath_ RPC is used to lookup a path from an object specified by
-_targetId_ to a GC root (i.e., the object which is preventing this object from
-being garbage collected).
-
-If _targetId_ refers to a heap object which has been collected by the VM's
-garbage collector, then the _Collected_ [Sentinel](#sentinel) is returned.
-
-If _targetId_ refers to a non-heap object which has been deleted, then the
-_Collected_ [Sentinel](#sentinel) is returned.
-
-If the object handle has not expired and the object has not been collected, then
-an [RetainingPath](#retainingpath) will be returned.
-
-The _limit_ parameter specifies the maximum path length to be reported as part
-of the retaining path. If a path is longer than _limit_, it will be truncated at
-the root end of the path.
-
-See [RetainingPath](#retainingpath).
-
-### getStack
-
-```
-Stack getStack(string isolateId)
-```
-
-The _getStack_ RPC is used to retrieve the current execution stack and
-message queue for an isolate. The isolate does not need to be paused.
-
-See [Stack](#stack).
-
-### getSourceReport
-
-```
-SourceReport getSourceReport(string isolateId,
-                             SourceReportKind[] reports,
-                             string scriptId [optional],
-                             int tokenPos [optional],
-                             int endTokenPos [optional],
-                             bool forceCompile [optional])
-```
-
-The _getSourceReport_ RPC is used to generate a set of reports tied to
-source locations in an isolate.
-
-The _reports_ parameter is used to specify which reports should be
-generated.  The _reports_ parameter is a list, which allows multiple
-reports to be generated simultaneously from a consistent isolate
-state.  The _reports_ parameter is allowed to be empty (this might be
-used to force compilation of a particular subrange of some script).
-
-The available report kinds are:
-
-report kind | meaning
------------ | -------
-Coverage | Provide code coverage information
-PossibleBreakpoints | Provide a list of token positions which correspond to possible breakpoints.
-
-The _scriptId_ parameter is used to restrict the report to a
-particular script.  When analyzing a particular script, either or both
-of the _tokenPos_ and _endTokenPos_ parameters may be provided to
-restrict the analysis to a subrange of a script (for example, these
-can be used to restrict the report to the range of a particular class
-or function).
-
-If the _scriptId_ parameter is not provided then the reports are
-generated for all loaded scripts and the _tokenPos_ and _endTokenPos_
-parameters are disallowed.
-
-The _forceCompilation_ parameter can be used to force compilation of
-all functions in the range of the report.  Forcing compilation can
-cause a compilation error, which could terminate the running Dart
-program.  If this parameter is not provided, it is considered to have
-the value _false_.
-
-See [SourceReport](#sourcereport).
-
-### getVersion
-
-```
-Version getVersion()
-```
-
-The _getVersion_ RPC is used to determine what version of the Service Protocol is served by a VM.
-
-See [Version](#version).
-
-### getVM
-
-```
-VM getVM()
-```
-
-The _getVM_ RPC returns global information about a Dart virtual machine.
-
-See [VM](#vm).
-
-
-### getVMTimeline
-
-```
-Timeline getVMTimeline(int timeOriginMicros [optional],
-                       int timeExtentMicros [optional])
-```
-
-The _getVMTimeline_ RPC is used to retrieve an object which contains VM timeline
-events.
-
-The _timeOriginMicros_ parameter is the beginning of the time range used to filter
-timeline events. It uses the same monotonic clock as dart:developer's `Timeline.now`
-and the VM embedding API's `Dart_TimelineGetMicros`. See [getVMTimelineMicros](#getvmtimelinemicros)
-for access to this clock through the service protocol.
-
-The _timeExtentMicros_ parameter specifies how large the time range used to filter
-timeline events should be.
-
-For example, given _timeOriginMicros_ and _timeExtentMicros_, only timeline events
-from the following time range will be returned: `(timeOriginMicros, timeOriginMicros + timeExtentMicros)`.
-
-If _getVMTimeline_ is invoked while the current recorder is one of Fuchsia or
-Systrace, the _114_ error code, invalid timeline request, will be returned as
-timeline events are handled by the OS in these modes.
-
-### getVMTimelineFlags
-
-```
-TimelineFlags getVMTimelineFlags()
-```
-
-The _getVMTimelineFlags_ RPC returns information about the current VM timeline configuration.
-
-To change which timeline streams are currently enabled, see [setVMTimelineFlags](#setvmtimelineflags).
-
-See [TimelineFlags](#timelineflags).
-
-### getVMTimelineMicros
-
-```
-Timestamp getVMTimelineMicros()
-```
-
-The _getVMTimelineMicros_ RPC returns the current time stamp from the clock used by the timeline,
-similar to `Timeline.now` in `dart:developer` and `Dart_TimelineGetMicros` in the VM embedding API.
-
-See [Timestamp](#timestamp) and [getVMTimeline](#getvmtimeline).
-
-### pause
-
-```
-Success pause(string isolateId)
-```
-
-The _pause_ RPC is used to interrupt a running isolate. The RPC enqueues the interrupt request and potentially returns before the isolate is paused.
-
-When the isolate is paused an event will be sent on the _Debug_ stream.
-
-See [Success](#success).
-
-### kill
-
-```
-Success kill(string isolateId)
-```
-
-The _kill_ RPC is used to kill an isolate as if by dart:isolate's `Isolate.kill(IMMEDIATE)`.
-
-The isolate is killed regardless of whether it is paused or running.
-
-See [Success](#success).
-
-### registerService
-
-```
-Success registerService(string service, string alias)
-```
-
-Registers a service that can be invoked by other VM service clients, where
-`service` is the name of the service to advertise and `alias` is an alternative
-name for the registered service.
-
-Requests made to the new service will be forwarded to the client which originally
-registered the service.
-
-See [Success](#success).
-
-### reloadSources
-
-```
-ReloadReport reloadSources(string isolateId,
-                           bool force [optional],
-                           bool pause [optional],
-                           string rootLibUri [optional],
-                           string packagesUri [optional])
-```
-
-The _reloadSources_ RPC is used to perform a hot reload of an Isolate's sources.
-
-if the _force_ parameter is provided, it indicates that all of the Isolate's
-sources should be reloaded regardless of modification time.
-
-if the _pause_ parameter is provided, the isolate will pause immediately
-after the reload.
-
-if the _rootLibUri_ parameter is provided, it indicates the new uri to the
-Isolate's root library.
-
-if the _packagesUri_ parameter is provided, it indicates the new uri to the
-Isolate's package map (.packages) file.
-
-### removeBreakpoint
-
-```
-Success removeBreakpoint(string isolateId,
-                         string breakpointId)
-```
-
-The _removeBreakpoint_ RPC is used to remove a breakpoint by its _id_.
-
-Note that breakpoints are added and removed on a per-isolate basis.
-
-See [Success](#success).
-
-### resume
-
-```
-Success resume(string isolateId,
-               StepOption step [optional],
-               int frameIndex [optional])
-```
-
-The _resume_ RPC is used to resume execution of a paused isolate.
-
-If the _step_ parameter is not provided, the program will resume
-regular execution.
-
-If the _step_ parameter is provided, it indicates what form of
-single-stepping to use.
-
-step | meaning
----- | -------
-Into | Single step, entering function calls
-Over | Single step, skipping over function calls
-Out | Single step until the current function exits
-Rewind | Immediately exit the top frame(s) without executing any code. Isolate will be paused at the call of the last exited function.
-
-The _frameIndex_ parameter is only used when the _step_ parameter is Rewind. It
-specifies the stack frame to rewind to. Stack frame 0 is the currently executing
-function, so _frameIndex_ must be at least 1.
-
-If the _frameIndex_ parameter is not provided, it defaults to 1.
-
-See [Success](#success), [StepOption](#StepOption).
-
-### setExceptionPauseMode
-
-```
-Success setExceptionPauseMode(string isolateId,
-                              ExceptionPauseMode mode)
-```
-
-The _setExceptionPauseMode_ RPC is used to control if an isolate pauses when
-an exception is thrown.
-
-mode | meaning
----- | -------
-None | Do not pause isolate on thrown exceptions
-Unhandled | Pause isolate on unhandled exceptions
-All  | Pause isolate on all thrown exceptions
-
-### setFlag
-
-```
-Success setFlag(string name,
-                string value)
-```
-
-The _setFlag_ RPC is used to set a VM flag at runtime. Returns an error if the
-named flag does not exist, the flag may not be set at runtime, or the value is
-of the wrong type for the flag.
-
-The following flags may be set at runtime:
-
- * pause_isolates_on_start
- * pause_isolates_on_exit
- * pause_isolates_on_unhandled_exceptions
- * profile_period
-
-Note: `profile_period` can be set to a minimum value of 50. Attempting to set
-`profile_period` to a lower value will result in a value of 50 being set.
-
-See [Success](#success).
-
-### setLibraryDebuggable
-
-```
-Success setLibraryDebuggable(string isolateId,
-                             string libraryId,
-                             bool isDebuggable)
-```
-
-The _setLibraryDebuggable_ RPC is used to enable or disable whether
-breakpoints and stepping work for a given library.
-
-See [Success](#success).
-
-### setName
-
-```
-Success setName(string isolateId,
-                string name)
-```
-
-The _setName_ RPC is used to change the debugging name for an isolate.
-
-See [Success](#success).
-
-### setVMName
-
-```
-Success setVMName(string name)
-```
-
-The _setVMName_ RPC is used to change the debugging name for the vm.
-
-See [Success](#success).
-
-### setVMTimelineFlags
-
-```
-Success setVMTimelineFlags(string[] recordedStreams)
-```
-
-The _setVMTimelineFlags_ RPC is used to set which timeline streams are enabled.
-
-The _recordedStreams_ parameter is the list of all timeline streams which are
-to be enabled. Streams not explicitly specified will be disabled. Invalid stream
-names are ignored.
-
-To get the list of currently enabled timeline streams, see [getVMTimelineFlags](#getvmtimelineflags).
-
-See [Success](#success).
-
-### streamCancel
-
-```
-Success streamCancel(string streamId)
-```
-
-The _streamCancel_ RPC cancels a stream subscription in the VM.
-
-If the client is not subscribed to the stream, the _104_ (Stream not
-subscribed) error code is returned.
-
-See [Success](#success).
-
-### streamListen
-
-```
-Success streamListen(string streamId)
-```
-
-The _streamListen_ RPC subscribes to a stream in the VM. Once
-subscribed, the client will begin receiving events from the stream.
-
-If the client is already subscribed to the stream, the _103_ (Stream already
-subscribed) error code is returned.
-
-The _streamId_ parameter may have the following published values:
-
-streamId | event types provided
--------- | -----------
-VM | VMUpdate, VMFlagUpdate
-Isolate | IsolateStart, IsolateRunnable, IsolateExit, IsolateUpdate, IsolateReload, ServiceExtensionAdded
-Debug | PauseStart, PauseExit, PauseBreakpoint, PauseInterrupted, PauseException, PausePostRequest, Resume, BreakpointAdded, BreakpointResolved, BreakpointRemoved, Inspect, None
-GC | GC
-Extension | Extension
-Timeline | TimelineEvents
-Logging | Logging
-Service | ServiceRegistered, ServiceUnregistered
-
-Additionally, some embedders provide the _Stdout_ and _Stderr_
-streams.  These streams allow the client to subscribe to writes to
-stdout and stderr.
-
-streamId | event types provided
--------- | -----------
-Stdout | WriteEvent
-Stderr | WriteEvent
-
-It is considered a _backwards compatible_ change to add a new type of event to an existing stream.
-Clients should be written to handle this gracefully, perhaps by warning and ignoring.
-
-See [Success](#success).
-
-## Public Types
-
-The following is a list of all public types produced by the Service Protocol.
-
-We define a small set of primitive types, based on JSON equivalents.
-
-type | meaning
----- | -------
-string | JSON string values
-bool | JSON _true_, _false_
-int | JSON numbers without fractions or exponents
-float | any JSON number
-
-Note that the Service Protocol does not use JSON _null_.
-
-We describe the format of our JSON objects with the following class format:
-
-```
-class T {
-  string name;
-  int count;
-  ...
-}
-```
-
-This describes a JSON object type _T_ with some set of expected properties.
-
-Types are organized into an inheritance hierarchy. If type _T_
-extends type _S_...
-
-```
-class S {
-  string a;
-}
-
-class T extends S {
-  string b;
-}
-```
-
-...then that means that all properties of _S_ are also present in type
-_T_. In the example above, type _T_ would have the expected
-properties _a_ and _b_.
-
-If a property has an _Array_ type, it is written with brackets:
-
-```
-  PropertyType[] arrayProperty;
-```
-
-If a property is optional, it is suffixed with the text _[optional]_:
-
-```
-  PropertyType optionalProperty [optional];
-```
-
-If a property can have multiple independent types, we denote this with
-a vertical bar:
-
-```
-  PropertyType1|PropertyType2 complexProperty;
-```
-
-We also allow parenthesis on type expressions.  This is useful when a property
-is an _Array_ of multiple independent types:
-
-```
-  (PropertyType1|PropertyType2)[]
-```
-
-When a string is only permitted to take one of a certain set of values,
-we indicate this by the use of the _enum_ format:
-
-```
-enum PermittedValues {
-  Value1,
-  Value2
-}
-```
-
-This means that _PermittedValues_ is a _string_ with two potential values,
-_Value1_ and _Value2_.
-
-### AllocationProfile
-
-```
-class AllocationProfile extends Response {
-  // Allocation information for all class types.
-  ClassHeapStats[] members;
-
-  // Information about memory usage for the isolate.
-  MemoryUsage memoryUsage;
-
-  // The timestamp of the last accumulator reset.
-  //
-  // If the accumulators have not been reset, this field is not present.
-  int dateLastAccumulatorReset [optional];
-
-  // The timestamp of the last manually triggered GC.
-  //
-  // If a GC has not been triggered manually, this field is not present.
-  int dateLastServiceGC [optional];
-}
-```
-
-### BoundField
-
-```
-class BoundField {
-  @Field decl;
-  @Instance|Sentinel value;
-}
-```
-
-A _BoundField_ represents a field bound to a particular value in an
-_Instance_.
-
-If the field is uninitialized, the _value_ will be the
-_NotInitialized_ [Sentinel](#sentinel).
-
-If the field is being initialized, the _value_ will be the
-_BeingInitialized_ [Sentinel](#sentinel).
-
-### BoundVariable
-
-```
-class BoundVariable extends Response {
-  string name;
-  @Instance|@TypeArguments|Sentinel value;
-
-  // The token position where this variable was declared.
-  int declarationTokenPos;
-
-  // The first token position where this variable is visible to the scope.
-  int scopeStartTokenPos;
-
-  // The last token position where this variable is visible to the scope.
-  int scopeEndTokenPos;
-}
-```
-
-A _BoundVariable_ represents a local variable bound to a particular value
-in a _Frame_.
-
-If the variable is uninitialized, the _value_ will be the
-_NotInitialized_ [Sentinel](#sentinel).
-
-If the variable is being initialized, the _value_ will be the
-_BeingInitialized_ [Sentinel](#sentinel).
-
-If the variable has been optimized out by the compiler, the _value_
-will be the _OptimizedOut_ [Sentinel](#sentinel).
-
-### Breakpoint
-
-```
-class Breakpoint extends Object {
-  // A number identifying this breakpoint to the user.
-  int breakpointNumber;
-
-  // Has this breakpoint been assigned to a specific program location?
-  bool resolved;
-
-  // Is this a breakpoint that was added synthetically as part of a step
-  // OverAsyncSuspension resume command?
-  bool isSyntheticAsyncContinuation [optional];
-
-  // SourceLocation when breakpoint is resolved, UnresolvedSourceLocation
-  // when a breakpoint is not resolved.
-  SourceLocation|UnresolvedSourceLocation location;
-}
-```
-
-A _Breakpoint_ describes a debugger breakpoint.
-
-A breakpoint is _resolved_ when it has been assigned to a specific
-program location.  A breakpoint my remain unresolved when it is in
-code which has not yet been compiled or in a library which has not
-been loaded (i.e. a deferred library).
-
-### Class
-
-```
-class @Class extends @Object {
-  // The name of this class.
-  string name;
-}
-```
-
-_@Class_ is a reference to a _Class_.
-
-```
-class Class extends Object {
-  // The name of this class.
-  string name;
-
-  // The error which occurred during class finalization, if it exists.
-  @Error error [optional];
-
-  // Is this an abstract class?
-  bool abstract;
-
-  // Is this a const class?
-  bool const;
-
-  // The library which contains this class.
-  @Library library;
-
-  // The location of this class in the source code.
-  SourceLocation location [optional];
-
-  // The superclass of this class, if any.
-  @Class super [optional];
-
-  // The supertype for this class, if any.
-  //
-  // The value will be of the kind: Type.
-  @Instance superType [optional];
-
-  // A list of interface types for this class.
-  //
-  // The values will be of the kind: Type.
-  @Instance[] interfaces;
-
-  // The mixin type for this class, if any.
-  //
-  // The value will be of the kind: Type.
-  @Instance mixin [optional];
-
-  // A list of fields in this class. Does not include fields from
-  // superclasses.
-  @Field[] fields;
-
-  // A list of functions in this class. Does not include functions
-  // from superclasses.
-  @Function[] functions;
-
-  // A list of subclasses of this class.
-  @Class[] subclasses;
-}
-```
-
-A _Class_ provides information about a Dart language class.
-
-### ClassHeapStats
-
-```
-class ClassHeapStats extends Response {
-  // The class for which this memory information is associated.
-  @Class class;
-
-  // The number of bytes allocated for instances of class since the
-  // accumulator was last reset.
-  int accumulatedSize;
-
-  // The number of bytes currently allocated for instances of class.
-  int bytesCurrent;
-
-  // The number of instances of class which have been allocated since
-  // the accumulator was last reset.
-  int instancesAccumulated;
-
-  // The number of instances of class which are currently alive.
-  int instancesCurrent;
-}
-```
-
-### ClassList
-
-```
-class ClassList extends Response {
-  @Class[] classes;
-}
-```
-
-### Code
-
-```
-class @Code extends @Object {
-  // A name for this code object.
-  string name;
-
-  // What kind of code object is this?
-  CodeKind kind;
-}
-```
-
-_@Code_ is a reference to a _Code_ object.
-
-```
-class Code extends @Object {
-  // A name for this code object.
-  string name;
-
-  // What kind of code object is this?
-  CodeKind kind;
-}
-```
-
-A _Code_ object represents compiled code in the Dart VM.
-
-### CodeKind
-
-```
-enum CodeKind {
-  Dart,
-  Native,
-  Stub,
-  Tag,
-  Collected
-}
-```
-
-### Context
-
-```
-class @Context extends @Object {
-  // The number of variables in this context.
-  int length;
-}
-```
-
-```
-class Context extends Object {
-  // The number of variables in this context.
-  int length;
-
-  // The enclosing context for this context.
-  Context parent [optional];
-
-  // The variables in this context object.
-  ContextElement[] variables;
-}
-```
-
-A _Context_ is a data structure which holds the captured variables for
-some closure.
-
-### ContextElement
-
-```
-class ContextElement {
-  @Instance|Sentinel value;
-}
-```
-
-### Error
-
-```
-class @Error extends @Object {
-  // What kind of error is this?
-  ErrorKind kind;
-
-  // A description of the error.
-  string message;
-}
-```
-
-_@Error_ is a reference to an _Error_.
-
-```
-class Error extends Object {
-  // What kind of error is this?
-  ErrorKind kind;
-
-  // A description of the error.
-  string message;
-
-  // If this error is due to an unhandled exception, this
-  // is the exception thrown.
-  @Instance exception [optional];
-
-  // If this error is due to an unhandled exception, this
-  // is the stacktrace object.
-  @Instance stacktrace [optional];
-}
-```
-
-An _Error_ represents a Dart language level error. This is distinct from an
-[rpc error](#rpc-error).
-
-### ErrorKind
-
-```
-enum ErrorKind {
-  // The isolate has encountered an unhandled Dart exception.
-  UnhandledException,
-
-  // The isolate has encountered a Dart language error in the program.
-  LanguageError,
-
-  // The isolate has encountered an internal error. These errors should be
-  // reported as bugs.
-  InternalError,
-
-  // The isolate has been terminated by an external source.
-  TerminationError
-}
-```
-
-### Event
-
-```
-class Event extends Response {
-  // What kind of event is this?
-  EventKind kind;
-
-  // The isolate with which this event is associated.
-  //
-  // This is provided for all event kinds except for:
-  //   VMUpdate, VMFlagUpdate
-  @Isolate isolate [optional];
-
-  // The vm with which this event is associated.
-  //
-  // This is provided for the event kind:
-  //   VMUpdate, VMFlagUpdate
-  @VM vm [optional];
-
-  // The timestamp (in milliseconds since the epoch) associated with this event.
-  // For some isolate pause events, the timestamp is from when the isolate was
-  // paused. For other events, the timestamp is from when the event was created.
-  int timestamp;
-
-  // The breakpoint which was added, removed, or resolved.
-  //
-  // This is provided for the event kinds:
-  //   PauseBreakpoint
-  //   BreakpointAdded
-  //   BreakpointRemoved
-  //   BreakpointResolved
-  Breakpoint breakpoint [optional];
-
-  // The list of breakpoints at which we are currently paused
-  // for a PauseBreakpoint event.
-  //
-  // This list may be empty. For example, while single-stepping, the
-  // VM sends a PauseBreakpoint event with no breakpoints.
-  //
-  // If there is more than one breakpoint set at the program position,
-  // then all of them will be provided.
-  //
-  // This is provided for the event kinds:
-  //   PauseBreakpoint
-  Breakpoint[] pauseBreakpoints [optional];
-
-  // The top stack frame associated with this event, if applicable.
-  //
-  // This is provided for the event kinds:
-  //   PauseBreakpoint
-  //   PauseInterrupted
-  //   PauseException
-  //
-  // For PauseInterrupted events, there will be no top frame if the
-  // isolate is idle (waiting in the message loop).
-  //
-  // For the Resume event, the top frame is provided at
-  // all times except for the initial resume event that is delivered
-  // when an isolate begins execution.
-  Frame topFrame [optional];
-
-  // The exception associated with this event, if this is a
-  // PauseException event.
-  @Instance exception [optional];
-
-  // An array of bytes, encoded as a base64 string.
-  //
-  // This is provided for the WriteEvent event.
-  string bytes [optional];
-
-  // The argument passed to dart:developer.inspect.
-  //
-  // This is provided for the Inspect event.
-  @Instance inspectee [optional];
-
-  // The RPC name of the extension that was added.
-  //
-  // This is provided for the ServiceExtensionAdded event.
-  string extensionRPC [optional];
-
-  // The extension event kind.
-  //
-  // This is provided for the Extension event.
-  string extensionKind [optional];
-
-  // The extension event data.
-  //
-  // This is provided for the Extension event.
-  ExtensionData extensionData [optional];
-
-  // An array of TimelineEvents
-  //
-  // This is provided for the TimelineEvents event.
-  TimelineEvent[] timelineEvents [optional];
-
-  // Is the isolate paused at an await, yield, or yield* statement?
-  //
-  // This is provided for the event kinds:
-  //   PauseBreakpoint
-  //   PauseInterrupted
-  bool atAsyncSuspension [optional];
-
-  // The status (success or failure) related to the event.
-  // This is provided for the event kinds:
-  //   IsolateReloaded
-  //   IsolateSpawn
-  string status [optional];
-
-  // LogRecord data.
-  //
-  // This is provided for the Logging event.
-  LogRecord logRecord [optional];
-
-  // The service identifier.
-  //
-  // This is provided for the event kinds:
-  //   ServiceRegistered
-  //   ServiceUnregistered
-  String service [optional];
-
-  // The RPC method that should be used to invoke the service.
-  //
-  // This is provided for the event kinds:
-  //   ServiceRegistered
-  //   ServiceUnregistered
-  String method [optional];
-
-  // The alias of the registered service.
-  //
-  // This is provided for the event kinds:
-  //   ServiceRegistered
-  String alias [optional];
-
-  // The name of the changed flag.
-  //
-  // This is provided for the event kinds:
-  //   VMFlagUpdate
-  String flag [optional];
-
-  // The new value of the changed flag.
-  //
-  // This is provided for the event kinds:
-  //   VMFlagUpdate
-  String newValue [optional];
-}
-```
-
-An _Event_ is an asynchronous notification from the VM. It is delivered
-only when the client has subscribed to an event stream using the
-[streamListen](#streamListen) RPC.
-
-For more information, see [events](#events).
-
-### EventKind
-
-```
-enum EventKind {
-  // Notification that VM identifying information has changed. Currently used
-  // to notify of changes to the VM debugging name via setVMName.
-  VMUpdate,
-
-  // Notification that a VM flag has been changed via the service protocol.
-  VMFlagUpdate,
-
-  // Notification that a new isolate has started.
-  IsolateStart,
-
-  // Notification that an isolate is ready to run.
-  IsolateRunnable,
-
-  // Notification that an isolate has exited.
-  IsolateExit,
-
-  // Notification that isolate identifying information has changed.
-  // Currently used to notify of changes to the isolate debugging name
-  // via setName.
-  IsolateUpdate,
-
-  // Notification that an isolate has been reloaded.
-  IsolateReload,
-
-  // Notification that an extension RPC was registered on an isolate.
-  ServiceExtensionAdded,
-
-  // An isolate has paused at start, before executing code.
-  PauseStart,
-
-  // An isolate has paused at exit, before terminating.
-  PauseExit,
-
-  // An isolate has paused at a breakpoint or due to stepping.
-  PauseBreakpoint,
-
-  // An isolate has paused due to interruption via pause.
-  PauseInterrupted,
-
-  // An isolate has paused due to an exception.
-  PauseException,
-
-  // An isolate has paused after a service request.
-  PausePostRequest,
-
-  // An isolate has started or resumed execution.
-  Resume,
-
-  // Indicates an isolate is not yet runnable. Only appears in an Isolate's
-  // pauseEvent. Never sent over a stream.
-  None,
-
-  // A breakpoint has been added for an isolate.
-  BreakpointAdded,
-
-  // An unresolved breakpoint has been resolved for an isolate.
-  BreakpointResolved,
-
-  // A breakpoint has been removed.
-  BreakpointRemoved,
-
-  // A garbage collection event.
-  GC,
-
-  // Notification of bytes written, for example, to stdout/stderr.
-  WriteEvent,
-
-  // Notification from dart:developer.inspect.
-  Inspect,
-
-  // Event from dart:developer.postEvent.
-  Extension
-
-  // Event from dart:developer.log.
-  Logging
-
-   // Notification that a Service has been registered into the Service Protocol
-  // from another client.
-  ServiceRegistered,
-
-  // Notification that a Service has been removed from the Service Protocol
-  // from another client.
-  ServiceUnregistered
-}
-```
-
-Adding new values to _EventKind_ is considered a backwards compatible
-change. Clients should ignore unrecognized events.
-
-### ExtensionData
-
-```
-class ExtensionData {
-}
-```
-
-An _ExtensionData_ is an arbitrary map that can have any contents.
-
-### Field
-
-```
-class @Field extends @Object {
-  // The name of this field.
-  string name;
-
-  // The owner of this field, which can be either a Library or a
-  // Class.
-  @Object owner;
-
-  // The declared type of this field.
-  //
-  // The value will always be of one of the kinds:
-  // Type, TypeRef, TypeParameter, BoundedType.
-  @Instance declaredType;
-
-  // Is this field const?
-  bool const;
-
-  // Is this field final?
-  bool final;
-
-  // Is this field static?
-  bool static;
-}
-```
-
-An _@Field_ is a reference to a _Field_.
-
-```
-class Field extends Object {
-  // The name of this field.
-  string name;
-
-  // The owner of this field, which can be either a Library or a
-  // Class.
-  @Object owner;
-
-  // The declared type of this field.
-  //
-  // The value will always be of one of the kinds:
-  // Type, TypeRef, TypeParameter, BoundedType.
-  @Instance declaredType;
-
-  // Is this field const?
-  bool const;
-
-  // Is this field final?
-  bool final;
-
-  // Is this field static?
-  bool static;
-
-  // The value of this field, if the field is static.
-  @Instance staticValue [optional];
-
-  // The location of this field in the source code.
-  SourceLocation location [optional];
-}
-```
-
-A _Field_ provides information about a Dart language field or
-variable.
-
-
-### Flag
-
-```
-class Flag {
-  // The name of the flag.
-  string name;
-
-  // A description of the flag.
-  string comment;
-
-  // Has this flag been modified from its default setting?
-  bool modified;
-
-  // The value of this flag as a string.
-  //
-  // If this property is absent, then the value of the flag was NULL.
-  string valueAsString [optional];
-}
-```
-
-A _Flag_ represents a single VM command line flag.
-
-### FlagList
-
-```
-class FlagList extends Response {
-  // A list of all flags in the VM.
-  Flag[] flags;
-}
-```
-
-A _FlagList_ represents the complete set of VM command line flags.
-
-### Frame
-
-```
-class Frame extends Response {
-  int index;
-  @Function function [optional];
-  @Code code [optional];
-  SourceLocation location [optional];
-  BoundVariable[] vars [optional];
-  FrameKind kind [optional];
-}
-```
-
-### Function
-
-```
-class @Function extends @Object {
-  // The name of this function.
-  string name;
-
-  // The owner of this function, which can be a Library, Class, or a Function.
-  @Library|@Class|@Function owner;
-
-  // Is this function static?
-  bool static;
-
-  // Is this function const?
-  bool const;
-}
-```
-
-An _@Function_ is a reference to a _Function_.
-
-
-```
-class Function extends Object {
-  // The name of this function.
-  string name;
-
-  // The owner of this function, which can be a Library, Class, or a Function.
-  @Library|@Class|@Function owner;
-
-  // The location of this function in the source code.
-  SourceLocation location [optional];
-
-  // The compiled code associated with this function.
-  @Code code [optional];
-}
-```
-
-A _Function_ represents a Dart language function.
-
-### Instance
-
-```
-class @Instance extends @Object {
-  // What kind of instance is this?
-  InstanceKind kind;
-
-  // Instance references always include their class.
-  @Class class;
-
-  // The value of this instance as a string.
-  //
-  // Provided for the instance kinds:
-  //   Null (null)
-  //   Bool (true or false)
-  //   Double (suitable for passing to Double.parse())
-  //   Int (suitable for passing to int.parse())
-  //   String (value may be truncated)
-  //   Float32x4
-  //   Float64x2
-  //   Int32x4
-  //   StackTrace
-  string valueAsString [optional];
-
-  // The valueAsString for String references may be truncated. If so,
-  // this property is added with the value 'true'.
-  //
-  // New code should use 'length' and 'count' instead.
-  bool valueAsStringIsTruncated [optional];
-
-  // The length of a List or the number of associations in a Map or the
-  // number of codeunits in a String.
-  //
-  // Provided for instance kinds:
-  //   String
-  //   List
-  //   Map
-  //   Uint8ClampedList
-  //   Uint8List
-  //   Uint16List
-  //   Uint32List
-  //   Uint64List
-  //   Int8List
-  //   Int16List
-  //   Int32List
-  //   Int64List
-  //   Float32List
-  //   Float64List
-  //   Int32x4List
-  //   Float32x4List
-  //   Float64x2List
-  int length [optional];
-
-  // The name of a Type instance.
-  //
-  // Provided for instance kinds:
-  //   Type
-  string name [optional];
-
-  // The corresponding Class if this Type has a resolved typeClass.
-  //
-  // Provided for instance kinds:
-  //   Type
-  @Class typeClass [optional];
-
-  // The parameterized class of a type parameter:
-  //
-  // Provided for instance kinds:
-  //   TypeParameter
-  @Class parameterizedClass [optional];
-
-
-  // The pattern of a RegExp instance.
-  //
-  // The pattern is always an instance of kind String.
-  //
-  // Provided for instance kinds:
-  //   RegExp
-  @Instance pattern [optional];
-}
-```
-
-_@Instance_ is a reference to an _Instance_.
-
-```
-class Instance extends Object {
-  // What kind of instance is this?
-  InstanceKind kind;
-
-  // Instance references always include their class.
-  @Class class;
-
-  // The value of this instance as a string.
-  //
-  // Provided for the instance kinds:
-  //   Bool (true or false)
-  //   Double (suitable for passing to Double.parse())
-  //   Int (suitable for passing to int.parse())
-  //   String (value may be truncated)
-  string valueAsString [optional];
-
-  // The valueAsString for String references may be truncated. If so,
-  // this property is added with the value 'true'.
-  //
-  // New code should use 'length' and 'count' instead.
-  bool valueAsStringIsTruncated [optional];
-
-  // The length of a List or the number of associations in a Map or the
-  // number of codeunits in a String.
-  //
-  // Provided for instance kinds:
-  //   String
-  //   List
-  //   Map
-  //   Uint8ClampedList
-  //   Uint8List
-  //   Uint16List
-  //   Uint32List
-  //   Uint64List
-  //   Int8List
-  //   Int16List
-  //   Int32List
-  //   Int64List
-  //   Float32List
-  //   Float64List
-  //   Int32x4List
-  //   Float32x4List
-  //   Float64x2List
-  int length [optional];
-
-  // The index of the first element or association or codeunit returned.
-  // This is only provided when it is non-zero.
-  //
-  // Provided for instance kinds:
-  //   String
-  //   List
-  //   Map
-  //   Uint8ClampedList
-  //   Uint8List
-  //   Uint16List
-  //   Uint32List
-  //   Uint64List
-  //   Int8List
-  //   Int16List
-  //   Int32List
-  //   Int64List
-  //   Float32List
-  //   Float64List
-  //   Int32x4List
-  //   Float32x4List
-  //   Float64x2List
-  int offset [optional];
-
-  // The number of elements or associations or codeunits returned.
-  // This is only provided when it is less than length.
-  //
-  // Provided for instance kinds:
-  //   String
-  //   List
-  //   Map
-  //   Uint8ClampedList
-  //   Uint8List
-  //   Uint16List
-  //   Uint32List
-  //   Uint64List
-  //   Int8List
-  //   Int16List
-  //   Int32List
-  //   Int64List
-  //   Float32List
-  //   Float64List
-  //   Int32x4List
-  //   Float32x4List
-  //   Float64x2List
-  int count [optional];
-
-  // The name of a Type instance.
-  //
-  // Provided for instance kinds:
-  //   Type
-  string name [optional];
-
-  // The corresponding Class if this Type is canonical.
-  //
-  // Provided for instance kinds:
-  //   Type
-  @Class typeClass [optional];
-
-  // The parameterized class of a type parameter:
-  //
-  // Provided for instance kinds:
-  //   TypeParameter
-  @Class parameterizedClass [optional];
-
-  // The fields of this Instance.
-  BoundField[] fields [optional];
-
-  // The elements of a List instance.
-  //
-  // Provided for instance kinds:
-  //   List
-  (@Instance|Sentinel)[] elements [optional];
-
-  // The elements of a Map instance.
-  //
-  // Provided for instance kinds:
-  //   Map
-  MapAssociation[] associations [optional];
-
-  // The bytes of a TypedData instance.
-  //
-  // The data is provided as a Base64 encoded string.
-  //
-  // Provided for instance kinds:
-  //   Uint8ClampedList
-  //   Uint8List
-  //   Uint16List
-  //   Uint32List
-  //   Uint64List
-  //   Int8List
-  //   Int16List
-  //   Int32List
-  //   Int64List
-  //   Float32List
-  //   Float64List
-  //   Int32x4List
-  //   Float32x4List
-  //   Float64x2List
-  string bytes [optional];
-
-  // The function associated with a Closure instance.
-  //
-  // Provided for instance kinds:
-  //   Closure
-  @Function closureFunction [optional];
-
-  // The context associated with a Closure instance.
-  //
-  // Provided for instance kinds:
-  //   Closure
-  @Context closureContext [optional];
-
-  // The referent of a MirrorReference instance.
-  //
-  // Provided for instance kinds:
-  //   MirrorReference
-  @Instance mirrorReferent [optional];
-
-  // The pattern of a RegExp instance.
-  //
-  // Provided for instance kinds:
-  //   RegExp
-  String pattern [optional];
-
-  // Whether this regular expression is case sensitive.
-  //
-  // Provided for instance kinds:
-  //   RegExp
-  bool isCaseSensitive [optional];
-
-  // Whether this regular expression matches multiple lines.
-  //
-  // Provided for instance kinds:
-  //   RegExp
-  bool isMultiLine [optional];
-
-  // The key for a WeakProperty instance.
-  //
-  // Provided for instance kinds:
-  //   WeakProperty
-  @Instance propertyKey [optional];
-
-  // The key for a WeakProperty instance.
-  //
-  // Provided for instance kinds:
-  //   WeakProperty
-  @Instance propertyValue [optional];
-
-  // The type arguments for this type.
-  //
-  // Provided for instance kinds:
-  //   Type
-  @TypeArguments typeArguments [optional];
-
-  // The index of a TypeParameter instance.
-  //
-  // Provided for instance kinds:
-  //   TypeParameter
-  int parameterIndex [optional];
-
-  // The type bounded by a BoundedType instance
-  // - or -
-  // the referent of a TypeRef instance.
-  //
-  // The value will always be of one of the kinds:
-  // Type, TypeRef, TypeParameter, BoundedType.
-  //
-  // Provided for instance kinds:
-  //   BoundedType
-  //   TypeRef
-  @Instance targetType [optional];
-
-  // The bound of a TypeParameter or BoundedType.
-  //
-  // The value will always be of one of the kinds:
-  // Type, TypeRef, TypeParameter, BoundedType.
-  //
-  // Provided for instance kinds:
-  //   BoundedType
-  //   TypeParameter
-  @Instance bound [optional];
-}
-```
-
-An _Instance_ represents an instance of the Dart language class _Object_.
-
-### InstanceKind
-
-```
-enum InstanceKind {
-  // A general instance of the Dart class Object.
-  PlainInstance,
-
-  // null instance.
-  Null,
-
-  // true or false.
-  Bool,
-
-  // An instance of the Dart class double.
-  Double,
-
-  // An instance of the Dart class int.
-  Int,
-
-  // An instance of the Dart class String.
-  String,
-
-  // An instance of the built-in VM List implementation. User-defined
-  // Lists will be PlainInstance.
-  List,
-
-  // An instance of the built-in VM Map implementation. User-defined
-  // Maps will be PlainInstance.
-  Map,
-
-  // Vector instance kinds.
-  Float32x4,
-  Float64x2,
-  Int32x4,
-
-  // An instance of the built-in VM TypedData implementations. User-defined
-  // TypedDatas will be PlainInstance.
-  Uint8ClampedList,
-  Uint8List,
-  Uint16List,
-  Uint32List,
-  Uint64List,
-  Int8List,
-  Int16List,
-  Int32List,
-  Int64List,
-  Float32List,
-  Float64List,
-  Int32x4List,
-  Float32x4List,
-  Float64x2List,
-
-  // An instance of the Dart class StackTrace.
-  StackTrace,
-
-  // An instance of the built-in VM Closure implementation. User-defined
-  // Closures will be PlainInstance.
-  Closure,
-
-  // An instance of the Dart class MirrorReference.
-  MirrorReference,
-
-  // An instance of the Dart class RegExp.
-  RegExp,
-
-  // An instance of the Dart class WeakProperty.
-  WeakProperty,
-
-  // An instance of the Dart class Type.
-  Type,
-
-  // An instance of the Dart class TypeParameter.
-  TypeParameter,
-
-  // An instance of the Dart class TypeRef.
-  TypeRef,
-
-  // An instance of the Dart class BoundedType.
-  BoundedType,
-}
-```
-
-Adding new values to _InstanceKind_ is considered a backwards
-compatible change. Clients should treat unrecognized instance kinds
-as _PlainInstance_.
-
-### Isolate
-
-```
-class @Isolate extends Response {
-  // The id which is passed to the getIsolate RPC to load this isolate.
-  string id;
-
-  // A numeric id for this isolate, represented as a string. Unique.
-  string number;
-
-  // A name identifying this isolate. Not guaranteed to be unique.
-  string name;
-}
-```
-
-_@Isolate_ is a reference to an _Isolate_ object.
-
-```
-class Isolate extends Response {
-  // The id which is passed to the getIsolate RPC to reload this
-  // isolate.
-  string id;
-
-  // A numeric id for this isolate, represented as a string. Unique.
-  string number;
-
-  // A name identifying this isolate. Not guaranteed to be unique.
-  string name;
-
-  // The time that the VM started in milliseconds since the epoch.
-  //
-  // Suitable to pass to DateTime.fromMillisecondsSinceEpoch.
-  int startTime;
-
-  // Is the isolate in a runnable state?
-  bool runnable;
-
-  // The number of live ports for this isolate.
-  int livePorts;
-
-  // Will this isolate pause when exiting?
-  bool pauseOnExit;
-
-  // The last pause event delivered to the isolate. If the isolate is
-  // running, this will be a resume event.
-  Event pauseEvent;
-
-  // The root library for this isolate.
-  //
-  // Guaranteed to be initialized when the IsolateRunnable event fires.
-  @Library rootLib [optional];
-
-  // A list of all libraries for this isolate.
-  //
-  // Guaranteed to be initialized when the IsolateRunnable event fires.
-  @Library[] libraries;
-
-  // A list of all breakpoints for this isolate.
-  Breakpoint[] breakpoints;
-
-  // The error that is causing this isolate to exit, if applicable.
-  Error error [optional];
-
-  // The current pause on exception mode for this isolate.
-  ExceptionPauseMode exceptionPauseMode;
-
-  // The list of service extension RPCs that are registered for this isolate,
-  // if any.
-  string[] extensionRPCs [optional];
-}
-```
-
-An _Isolate_ object provides information about one isolate in the VM.
-
-### InboundReferences
-
-```
-class InboundReferences extends Response {
-  // An array of inbound references to an object.
-  InboundReference[] references;
-}
-```
-
-See [getInboundReferences](#getinboundreferences).
-
-### InboundReference
-
-```
-class InboundReference {
-  // The object holding the inbound reference.
-  @Object source;
-
-  // If source is a List, parentListIndex is the index of the inbound reference.
-  int parentListIndex [optional];
-
-  // If source is a field of an object, parentField is the field containing the
-  // inbound reference.
-  @Field parentField [optional];
-}
-```
-
-See [getInboundReferences](#getinboundreferences).
-
-### InstanceSet
-
-```
-class InstanceSet extends Response {
-  // The number of instances of the requested type currently allocated.
-  int totalCount;
-
-  // An array of instances of the requested type.
-  @Object[] instances;
-}
-```
-
-See [getInstances](#getinstances).
-
-### Library
-
-```
-class @Library extends @Object {
-  // The name of this library.
-  string name;
-
-  // The uri of this library.
-  string uri;
-}
-```
-
-_@Library_ is a reference to a _Library_.
-
-```
-class Library extends Object {
-  // The name of this library.
-  string name;
-
-  // The uri of this library.
-  string uri;
-
-  // Is this library debuggable? Default true.
-  bool debuggable;
-
-  // A list of the imports for this library.
-  LibraryDependency[] dependencies;
-
-  // A list of the scripts which constitute this library.
-  @Script[] scripts;
-
-  // A list of the top-level variables in this library.
-  @Field[] variables;
-
-  // A list of the top-level functions in this library.
-  @Function[] functions;
-
-  // A list of all classes in this library.
-  @Class[] classes;
-}
-```
-
-A _Library_ provides information about a Dart language library.
-
-See [setLibraryDebuggable](#setlibrarydebuggable).
-
-### LibraryDependency
-
-```
-class LibraryDependency {
-  // Is this dependency an import (rather than an export)?
-  bool isImport;
-
-  // Is this dependency deferred?
-  bool isDeferred;
-
-  // The prefix of an 'as' import, or null.
-  String prefix;
-
-  // The library being imported or exported.
-  @Library target;
-}
-```
-
-A _LibraryDependency_ provides information about an import or export.
-
-### LogRecord
-
-```
-class LogRecord extends Response {
-  // The log message.
-  @Instance message;
-
-  // The timestamp.
-  int time;
-
-  // The severity level (a value between 0 and 2000).
-  //
-  // See the package:logging `Level` class for an overview of the possible
-  // values.
-  int level;
-
-  // A monotonically increasing sequence number.
-  int sequenceNumber;
-
-  // The name of the source of the log message.
-  @Instance loggerName;
-
-  // The zone where the log was emitted.
-  @Instance zone;
-
-  // An error object associated with this log event.
-  @Instance error;
-
-  // A stack trace associated with this log event.
-  @Instance stackTrace;
-}
-```
-
-### MapAssociation
-
-```
-class MapAssociation {
-  @Instance|Sentinel key;
-  @Instance|Sentinel value;
-}
-```
-
-### MemoryUsage
-
-```
-class MemoryUsage extends Response {
-  // The amount of non-Dart memory that is retained by Dart objects. For
-  // example, memory associated with Dart objects through APIs such as
-  // Dart_NewWeakPersistentHandle and Dart_NewExternalTypedData.  This usage is
-  // only as accurate as the values supplied to these APIs from the VM embedder or
-  // native extensions. This external memory applies GC pressure, but is separate
-  // from heapUsage and heapCapacity.
-  int externalUsage;
-
-  // The total capacity of the heap in bytes. This is the amount of memory used
-  // by the Dart heap from the perspective of the operating system.
-  int heapCapacity;
-
-  // The current heap memory usage in bytes. Heap usage is always less than or
-  // equal to the heap capacity.
-  int heapUsage;
-}
-```
-
-A _MemoryUsage_ object provides heap usage information for a specific
-isolate at a given point in time.
-
-### Message
-
-```
-class Message extends Response {
-  // The index in the isolate's message queue. The 0th message being the next
-  // message to be processed.
-  int index;
-
-  // An advisory name describing this message.
-  string name;
-
-  // An instance id for the decoded message. This id can be passed to other
-  // RPCs, for example, getObject or evaluate.
-  string messageObjectId;
-
-  // The size (bytes) of the encoded message.
-  int size;
-
-  // A reference to the function that will be invoked to handle this message.
-  @Function handler [optional];
-
-  // The source location of handler.
-  SourceLocation location [optional];
-}
-```
-
-A _Message_ provides information about a pending isolate message and the
-function that will be invoked to handle it.
-
-
-### Null
-
-```
-class @Null extends @Instance {
-  // Always 'null'.
-  string valueAsString;
-}
-```
-
-_@Null_ is a reference to an a _Null_.
-
-```
-class Null extends Instance {
-  // Always 'null'.
-  string valueAsString;
-}
-```
-
-A _Null_ object represents the Dart language value null.
-
-### Object
-
-```
-class @Object extends Response {
-  // A unique identifier for an Object. Passed to the
-  // getObject RPC to load this Object.
-  string id;
-
-  // Provided and set to true if the id of an Object is fixed. If true, the id
-  // of an Object is guaranteed not to change or expire. The object may, however,
-  // still be _Collected_.
-  bool fixedId [optional];
-}
-```
-
-_@Object_ is a reference to a _Object_.
-
-```
-class Object extends Response {
-  // A unique identifier for an Object. Passed to the
-  // getObject RPC to reload this Object.
-  //
-  // Some objects may get a new id when they are reloaded.
-  string id;
-
-  // Provided and set to true if the id of an Object is fixed. If true, the id
-  // of an Object is guaranteed not to change or expire. The object may, however,
-  // still be _Collected_.
-  bool fixedId [optional];
-
-  // If an object is allocated in the Dart heap, it will have
-  // a corresponding class object.
-  //
-  // The class of a non-instance is not a Dart class, but is instead
-  // an internal vm object.
-  //
-  // Moving an Object into or out of the heap is considered a
-  // backwards compatible change for types other than Instance.
-  @Class class [optional];
-
-  // The size of this object in the heap.
-  //
-  // If an object is not heap-allocated, then this field is omitted.
-  //
-  // Note that the size can be zero for some objects. In the current
-  // VM implementation, this occurs for small integers, which are
-  // stored entirely within their object pointers.
-  int size [optional];
-}
-```
-
-An _Object_ is a  persistent object that is owned by some isolate.
-
-### ReloadReport
-
-```
-class ReloadReport extends Response {
-  // Did the reload succeed or fail?
-  bool success;
-}
-```
-
-### RetainingObject
-
-```
-class RetainingObject {
-  // An object that is part of a retaining path.
-  @Object value;
-
-  // The offset of the retaining object in a containing list.
-  int parentListIndex [optional];
-
-  // The key mapping to the retaining object in a containing map.
-  @Object parentMapKey [optional];
-
-  // The name of the field containing the retaining object within an object.
-  string parentField [optional];
-}
-```
-
-See [RetainingPath](#retainingpath).
-
-### RetainingPath
-
-```
-class RetainingPath extends Response {
-  // The length of the retaining path.
-  int length;
-
-  // The type of GC root which is holding a reference to the specified object.
-  // Possible values include:
-  //  * class table
-  //  * local handle
-  //  * persistent handle
-  //  * stack
-  //  * user global
-  //  * weak persistent handle
-  //  * unknown
-  string gcRootType;
-
-  // The chain of objects which make up the retaining path.
-  RetainingObject[] elements;
-}
-```
-
-See [getRetainingPath](#getretainingpath).
-
-### Response
-
-```
-class Response {
-  // Every response returned by the VM Service has the
-  // type property. This allows the client distinguish
-  // between different kinds of responses.
-  string type;
-}
-```
-
-Every non-error response returned by the Service Protocol extends _Response_.
-By using the _type_ property, the client can determine which [type](#types)
-of response has been provided.
-
-### Sentinel
-
-```
-class Sentinel extends Response {
-  // What kind of sentinel is this?
-  SentinelKind kind;
-
-  // A reasonable string representation of this sentinel.
-  string valueAsString;
-}
-```
-
-A _Sentinel_ is used to indicate that the normal response is not available.
-
-We use a _Sentinel_ instead of an [error](#errors) for these cases because
-they do not represent a problematic condition. They are normal.
-
-### SentinelKind
-
-```
-enum SentinelKind {
-  // Indicates that the object referred to has been collected by the GC.
-  Collected,
-
-  // Indicates that an object id has expired.
-  Expired,
-
-  // Indicates that a variable or field has not been initialized.
-  NotInitialized,
-
-  // Indicates that a variable or field is in the process of being initialized.
-  BeingInitialized,
-
-  // Indicates that a variable has been eliminated by the optimizing compiler.
-  OptimizedOut,
-
-  // Reserved for future use.
-  Free,
-}
-```
-
-A _SentinelKind_ is used to distinguish different kinds of _Sentinel_ objects.
-
-Adding new values to _SentinelKind_ is considered a backwards
-compatible change. Clients must handle this gracefully.
-
-
-### FrameKind
-```
-enum FrameKind {
-  Regular,
-  AsyncCausal,
-  AsyncSuspensionMarker,
-  AsyncActivation
-}
-```
-
-A _FrameKind_ is used to distinguish different kinds of _Frame_ objects.
-
-### Script
-
-```
-class @Script extends @Object {
-  // The uri from which this script was loaded.
-  string uri;
-}
-```
-
-_@Script_ is a reference to a _Script_.
-
-```
-class Script extends Object {
-  // The uri from which this script was loaded.
-  string uri;
-
-  // The library which owns this script.
-  @Library library;
-
-  int lineOffset [optional];
-
-  int columnOffset [optional];
-
-  // The source code for this script. This can be null for certain built-in
-  // scripts.
-  string source [optional];
-
-  // A table encoding a mapping from token position to line and column. This
-  // field is null if sources aren't available.
-  int[][] tokenPosTable [optional];
-}
-```
-
-A _Script_ provides information about a Dart language script.
-
-The _tokenPosTable_ is an array of int arrays. Each subarray
-consists of a line number followed by _(tokenPos, columnNumber)_ pairs:
-
-> [lineNumber, (tokenPos, columnNumber)*]
-
-The _tokenPos_ is an arbitrary integer value that is used to represent
-a location in the source code.  A _tokenPos_ value is not meaningful
-in itself and code should not rely on the exact values returned.
-
-For example, a _tokenPosTable_ with the value...
-
-> [[1, 100, 5, 101, 8],[2, 102, 7]]
-
-...encodes the mapping:
-
-tokenPos | line | column
--------- | ---- | ------
-100 | 1 | 5
-101 | 1 | 8
-102 | 2 | 7
-
-### ScriptList
-
-```
-class ScriptList extends Response {
-  @Script[] scripts;
-}
-```
-
-### SourceLocation
-
-```
-class SourceLocation extends Response {
-  // The script containing the source location.
-  @Script script;
-
-  // The first token of the location.
-  int tokenPos;
-
-  // The last token of the location if this is a range.
-  int endTokenPos [optional];
-}
-```
-
-The _SourceLocation_ class is used to designate a position or range in
-some script.
-
-### SourceReport
-
-```
-class SourceReport extends Response {
-  // A list of ranges in the program source.  These ranges correspond
-  // to ranges of executable code in the user's program (functions,
-  // methods, constructors, etc.)
-  //
-  // Note that ranges may nest in other ranges, in the case of nested
-  // functions.
-  //
-  // Note that ranges may be duplicated, in the case of mixins.
-  SourceReportRange[] ranges;
-
-  // A list of scripts, referenced by index in the report's ranges.
-  ScriptRef[] scripts;
-}
-```
-
-The _SourceReport_ class represents a set of reports tied to source
-locations in an isolate.
-
-### SourceReportCoverage
-
-```
-class SourceReportCoverage {
-  // A list of token positions in a SourceReportRange which have been
-  // executed.  The list is sorted.
-  int[] hits;
-
-  // A list of token positions in a SourceReportRange which have not been
-  // executed.  The list is sorted.
-  int[] misses;
-}
-```
-
-The _SourceReportCoverage_ class represents coverage information for
-one [SourceReportRange](#sourcereportrange).
-
-Note that _SourceReportCoverage_ does not extend [Response](#response)
-and therefore will not contain a _type_ property.
-
-### SourceReportKind
-
-```
-enum SourceReportKind {
-  // Used to request a code coverage information.
-  Coverage,
-
-  // Used to request a list of token positions of possible breakpoints.
-  PossibleBreakpoints
-}
-```
-
-### SourceReportRange
-
-```
-class SourceReportRange {
-  // An index into the script table of the SourceReport, indicating
-  // which script contains this range of code.
-  int scriptIndex;
-
-  // The token position at which this range begins.
-  int startPos;
-
-  // The token position at which this range ends.  Inclusive.
-  int endPos;
-
-  // Has this range been compiled by the Dart VM?
-  bool compiled;
-
-  // The error while attempting to compile this range, if this
-  // report was generated with forceCompile=true.
-  @Error error [optional];
-
-  // Code coverage information for this range.  Provided only when the
-  // Coverage report has been requested and the range has been
-  // compiled.
-  SourceReportCoverage coverage [optional];
-
-  // Possible breakpoint information for this range, represented as a
-  // sorted list of token positions.  Provided only when the when the
-  // PossibleBreakpoint report has been requested and the range has been
-  // compiled.
-  int[] possibleBreakpoints [optional];
-}
-```
-
-The _SourceReportRange_ class represents a range of executable code
-(function, method, constructor, etc) in the running program.  It is
-part of a [SourceReport](#sourcereport).
-
-Note that _SourceReportRange_ does not extend [Response](#response)
-and therefore will not contain a _type_ property.
-
-### Stack
-
-```
-class Stack extends Response {
-  Frame[] frames;
-  Frame[] asyncCausalFrames [optional];
-  Frame[] awaiterFrames [optional];
-  Message[] messages;
-}
-```
-
-### ExceptionPauseMode
-
-```
-enum ExceptionPauseMode {
-  None,
-  Unhandled,
-  All,
-}
-```
-
-An _ExceptionPauseMode_ indicates how the isolate pauses when an exception
-is thrown.
-
-### StepOption
-
-```
-enum StepOption {
-  Into,
-  Over,
-  OverAsyncSuspension,
-  Out,
-  Rewind
-}
-```
-
-A _StepOption_ indicates which form of stepping is requested in a [resume](#resume) RPC.
-
-### Success
-
-```
-class Success extends Response {
-}
-```
-
-The _Success_ type is used to indicate that an operation completed successfully.
-
-### Timeline
-
-```
-class Timeline extends Response {
-  // A list of timeline events.
-  TimelineEvent[] traceEvents;
-
-  // The start of the period of time in which traceEvents were collected.
-  int timeOriginMicros;
-
-  // The duration of time covered by the timeline.
-  int timeExtentMicros;
-}
-```
-
-### TimelineEvent
-
-```
-class TimelineEvent {
-}
-```
-
-An _TimelineEvent_ is an arbitrary map that contains a [Trace Event Format](https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview) event.
-
-### TimelineFlags
-
-```
-class TimelineFlags extends Response {
-  // The name of the recorder currently in use. Recorder types include, but are
-  // not limited to: Callback, Endless, Fuchsia, Ring, Startup, and Systrace.
-  // Set to "null" if no recorder is currently set.
-  string recorderName;
-
-  // The list of all available timeline streams.
-  string[] availableStreams;
-
-  // The list of timeline streams that are currently enabled.
-  string[] recordedStreams;
-}
-```
-
-### Timestamp
-
-```
-class Timestamp extends Response {
-  // A timestamp in microseconds since epoch.
-  int timestamp;
-}
-```
-
-### TypeArguments
-
-```
-class @TypeArguments extends @Object {
-  // A name for this type argument list.
-  string name;
-}
-```
-
-_@TypeArguments_ is a reference to a _TypeArguments_ object.
-
-```
-class TypeArguments extends Object {
-  // A name for this type argument list.
-  string name;
-
-  // A list of types.
-  //
-  // The value will always be one of the kinds:
-  // Type, TypeRef, TypeParameter, BoundedType.
-  @Instance[] types;
-}
-```
-
-A _TypeArguments_ object represents the type argument vector for some
-instantiated generic type.
-
-### UnresolvedSourceLocation
-
-```
-class UnresolvedSourceLocation extends Response {
-  // The script containing the source location if the script has been loaded.
-  @Script script [optional];
-
-  // The uri of the script containing the source location if the script
-  // has yet to be loaded.
-  string scriptUri [optional];
-
-  // An approximate token position for the source location. This may
-  // change when the location is resolved.
-  int tokenPos [optional];
-
-  // An approximate line number for the source location. This may
-  // change when the location is resolved.
-  int line [optional];
-
-  // An approximate column number for the source location. This may
-  // change when the location is resolved.
-  int column [optional];
-
-}
-```
-
-The _UnresolvedSourceLocation_ class is used to refer to an unresolved
-breakpoint location.  As such, it is meant to approximate the final
-location of the breakpoint but it is not exact.
-
-Either the _script_ or the _scriptUri_ field will be present.
-
-Either the _tokenPos_ or the _line_ field will be present.
-
-The _column_ field will only be present when the breakpoint was
-specified with a specific column number.
-
-### Version
-
-```
-class Version extends Response {
-  // The major version number is incremented when the protocol is changed
-  // in a potentially incompatible way.
-  int major;
-
-  // The minor version number is incremented when the protocol is changed
-  // in a backwards compatible way.
-  int minor;
-}
-```
-
-See [Versioning](#versioning).
-
-### VM
-
-```
-class @VM extends Response {
-  // A name identifying this vm. Not guaranteed to be unique.
-  string name;
-}
-```
-
-_@VM_ is a reference to a _VM_ object.
-
-```
-class VM extends Response {
-  // A name identifying this vm. Not guaranteed to be unique.
-  string name;
-
-  // Word length on target architecture (e.g. 32, 64).
-  int architectureBits;
-
-  // The CPU we are actually running on.
-  string hostCPU;
-
-  // The operating system we are running on.
-  string operatingSystem;
-
-  // The CPU we are generating code for.
-  string targetCPU;
-
-  // The Dart VM version string.
-  string version;
-
-  // The process id for the VM.
-  int pid;
-
-  // The time that the VM started in milliseconds since the epoch.
-  //
-  // Suitable to pass to DateTime.fromMillisecondsSinceEpoch.
-  int startTime;
-
-  // A list of isolates running in the VM.
-  @Isolate[] isolates;
-}
-```
-
-## Revision History
-
-version | comments
-------- | --------
-1.0 | Initial revision
-2.0 | Describe protocol version 2.0.
-3.0 | Describe protocol version 3.0.  Added UnresolvedSourceLocation.  Added Sentinel return to getIsolate.  Add AddedBreakpointWithScriptUri.  Removed Isolate.entry. The type of VM.pid was changed from string to int.  Added VMUpdate events.  Add offset and count parameters to getObject() and offset and count fields to Instance. Added ServiceExtensionAdded event.
-3.1 | Add the getSourceReport RPC.  The getObject RPC now accepts offset and count for string objects.  String objects now contain length, offset, and count properties.
-3.2 | Isolate objects now include the runnable bit and many debugger related RPCs will return an error if executed on an isolate before it is runnable.
-3.3 | Pause event now indicates if the isolate is paused at an await, yield, or yield* suspension point via the 'atAsyncSuspension' field. Resume command now supports the step parameter 'OverAsyncSuspension'. A Breakpoint added synthetically by an 'OverAsyncSuspension' resume command identifies itself as such via the 'isSyntheticAsyncContinuation' field.
-3.4 | Add the superType and mixin fields to Class. Added new pause event 'None'.
-3.5 | Add the error field to SourceReportRange.  Clarify definition of token position.  Add "Isolate must be paused" error code.
-3.6 | Add 'scopeStartTokenPos', 'scopeEndTokenPos', and 'declarationTokenPos' to BoundVariable. Add 'PausePostRequest' event kind. Add 'Rewind' StepOption. Add error code 107 (isolate cannot resume). Add 'reloadSources' RPC and related error codes. Add optional parameter 'scope' to 'evaluate' and 'evaluateInFrame'.
-3.7 | Add 'setFlag'.
-3.8 | Add 'kill'.
-3.9 | Changed numbers for errors related to service extensions.
-3.10 | Add 'invoke'.
-3.11 | Rename 'invoke' parameter 'receiverId' to 'targetId.
-3.12 | Add 'getScripts' RPC and `ScriptList` object.
-3.13 | Class 'mixin' field now properly set for kernel transformed mixin applications.
-3.14 | Flag 'profile_period' can now be set at runtime, allowing for the profiler sample rate to be changed while the program is running.
-3.15 | Added `disableBreakpoints` parameter to `invoke`, `evaluate`, and `evaluateInFrame`.
-3.16 | Add 'getMemoryUsage' RPC and 'MemoryUsage' object.
-3.17 | Add 'Logging' event kind and the LogRecord class.
-3.18 | Add 'getAllocationProfile' RPC and 'AllocationProfile' and 'ClassHeapStats' objects.
-3.19 | Add 'clearVMTimeline', 'getVMTimeline', 'getVMTimelineFlags', 'setVMTimelineFlags', 'Timeline', and 'TimelineFlags'.
-3.20 | Add 'getInstances' RPC and 'InstanceSet' object.
-3.21 | Add 'getVMTimelineMicros' RPC and 'Timestamp' object.
-3.22 | Add `registerService` RPC, `Service` stream, and `ServiceRegistered` and `ServiceUnregistered` event kinds.
-3.23 | Add `VMFlagUpdate` event kind to the `VM` stream.
-3.24 | Add `operatingSystem` property to `VM` object.
-3.25 | Add 'getInboundReferences', 'getRetainingPath' RPCs, and 'InboundReferences', 'InboundReference', 'RetainingPath', and 'RetainingObject' objects.
-
-[discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/runtime/vm/service_test.cc b/runtime/vm/service_test.cc
index 736277a..63ea6eb 100644
--- a/runtime/vm/service_test.cc
+++ b/runtime/vm/service_test.cc
@@ -2,6 +2,8 @@
 // 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 <memory>
+
 #include "platform/globals.h"
 
 #include "include/dart_tools_api.h"
@@ -560,68 +562,6 @@
   EXPECT_NOTSUBSTRING("\"externalSize\":\"128\"", handler.msg());
 }
 
-ISOLATE_UNIT_TEST_CASE(Service_Address) {
-  const char* kScript =
-      "var port;\n"  // Set to our mock port by C++.
-      "\n"
-      "main() {\n"
-      "}";
-
-  Isolate* isolate = thread->isolate();
-  isolate->set_is_runnable(true);
-  Dart_Handle lib;
-  {
-    TransitionVMToNative transition(thread);
-    lib = TestCase::LoadTestScript(kScript, NULL);
-    EXPECT_VALID(lib);
-  }
-
-  // Build a mock message handler and wrap it in a dart port.
-  ServiceTestMessageHandler handler;
-  Dart_Port port_id = PortMap::CreatePort(&handler);
-  Dart_Handle port = Api::NewHandle(thread, SendPort::New(port_id));
-  {
-    TransitionVMToNative transition(thread);
-    EXPECT_VALID(port);
-    EXPECT_VALID(Dart_SetField(lib, NewString("port"), port));
-  }
-
-  const String& str = String::Handle(String::New("foobar", Heap::kOld));
-  Array& service_msg = Array::Handle();
-  // Note: If we ever introduce old space compaction, this test might fail.
-  uword start_addr = RawObject::ToAddr(str.raw());
-  // Expect to find 'str', also from internal addresses.
-  for (int offset = 0; offset < kObjectAlignment; ++offset) {
-    uword addr = start_addr + offset;
-    char buf[1024];
-    bool ref = offset % 2 == 0;
-    Utils::SNPrint(buf, sizeof(buf),
-                   (ref ? "[0, port, '0', '_getObjectByAddress', "
-                          "['address', 'ref'], ['%" Px "', 'true']]"
-                        : "[0, port, '0', '_getObjectByAddress', "
-                          "['address'], ['%" Px "']]"),
-                   addr);
-    service_msg = Eval(lib, buf);
-    HandleIsolateMessage(isolate, service_msg);
-    EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage());
-    EXPECT_SUBSTRING(ref ? "\"type\":\"@Instance\"" : "\"type\":\"Instance\"",
-                     handler.msg());
-    EXPECT_SUBSTRING("\"kind\":\"String\"", handler.msg());
-    EXPECT_SUBSTRING("foobar", handler.msg());
-  }
-  // Expect null when no object is found.
-  service_msg = Eval(lib,
-                     "[0, port, '0', '_getObjectByAddress', "
-                     "['address'], ['7']]");
-  HandleIsolateMessage(isolate, service_msg);
-  EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage());
-  // TODO(turnidge): Should this be a ServiceException instead?
-  EXPECT_SUBSTRING(
-      "{\"type\":\"Sentinel\",\"kind\":\"Free\","
-      "\"valueAsString\":\"<free>\"",
-      handler.msg());
-}
-
 static bool alpha_callback(const char* name,
                            const char** option_keys,
                            const char** option_values,
diff --git a/runtime/vm/stub_code.cc b/runtime/vm/stub_code.cc
index c578da0..d22df2b 100644
--- a/runtime/vm/stub_code.cc
+++ b/runtime/vm/stub_code.cc
@@ -210,7 +210,7 @@
 
       // We notify code observers after finalizing the code in order to be
       // outside a [SafepointOperationScope].
-      Code::NotifyCodeObservers(nullptr, stub, /*optimized=*/false);
+      Code::NotifyCodeObservers(name, stub, /*optimized=*/false);
     }
 #ifndef PRODUCT
     if (FLAG_support_disassembler && FLAG_disassemble_stubs) {
diff --git a/runtime/vm/virtual_memory_posix.cc b/runtime/vm/virtual_memory_posix.cc
index 2bcced1..87cbc04 100644
--- a/runtime/vm/virtual_memory_posix.cc
+++ b/runtime/vm/virtual_memory_posix.cc
@@ -194,6 +194,8 @@
     // The mapping will be RX and stays that way until it will eventually be
     // unmapped.
     MemoryRegion region(region_ptr, size);
+    // DUAL_MAPPING_SUPPORTED is false in TARGET_OS_MACOS and hence support
+    // for MAP_JIT is not required here.
     const int alias_prot = PROT_READ | PROT_EXEC;
     void* alias_ptr =
         MapAligned(fd, alias_prot, size, alignment, allocated_size);
@@ -211,8 +213,13 @@
   const int prot =
       PROT_READ | PROT_WRITE |
       ((is_executable && !FLAG_write_protect_code) ? PROT_EXEC : 0);
-  void* address =
-      mmap(NULL, allocated_size, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  int map_flags = MAP_PRIVATE | MAP_ANONYMOUS;
+#if (defined(HOST_OS_MACOS) && !defined(HOST_OS_IOS))
+  if (is_executable && IsAtLeastOS10_14()) {
+    map_flags |= MAP_JIT;
+  }
+#endif  // defined(HOST_OS_MACOS)
+  void* address = mmap(NULL, allocated_size, prot, map_flags, -1, 0);
   LOG_INFO("mmap(NULL, 0x%" Px ", %u, ...): %p\n", allocated_size, prot,
            address);
   if (address == MAP_FAILED) {
diff --git a/sdk/lib/_http/http_impl.dart b/sdk/lib/_http/http_impl.dart
index 88c0f97..d8376c8 100644
--- a/sdk/lib/_http/http_impl.dart
+++ b/sdk/lib/_http/http_impl.dart
@@ -1990,14 +1990,26 @@
     return connectionTask.then((ConnectionTask task) {
       _socketTasks.add(task);
       Future socketFuture = task.socket;
-      if (client.connectionTimeout != null) {
-        socketFuture =
-            socketFuture.timeout(client.connectionTimeout, onTimeout: () {
+      final Duration connectionTimeout = client.connectionTimeout;
+      if (connectionTimeout != null) {
+        socketFuture = socketFuture.timeout(connectionTimeout, onTimeout: () {
           _socketTasks.remove(task);
           task.cancel();
+          return null;
         });
       }
       return socketFuture.then((socket) {
+        // When there is a timeout, there is a race in which the connectionTask
+        // Future won't be completed with an error before the socketFuture here
+        // is completed with 'null' by the onTimeout callback above. In this
+        // case, propagate a SocketException as specified by the
+        // HttpClient.connectionTimeout docs.
+        if (socket == null) {
+          assert(connectionTimeout != null);
+          throw new SocketException(
+              "HTTP connection timed out after ${connectionTimeout}, "
+              "host: ${host}, port: ${port}");
+        }
         _connecting--;
         socket.setOption(SocketOption.tcpNoDelay, true);
         var connection =
diff --git a/sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart
index dd9e0ec..894aef4 100644
--- a/sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart
+++ b/sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart
@@ -37,7 +37,7 @@
     } else {
       f = _Future.value(value);
     }
-    f = JS('', '#', f._thenNoZoneRegistration(onValue, onError));
+    f = JS('', '#', f._thenAwait(onValue, onError));
     return f;
   }
 
@@ -363,7 +363,7 @@
     } else {
       f = _Future.value(value);
     }
-    f._thenNoZoneRegistration(_runBodyCallback, handleError);
+    f._thenAwait(_runBodyCallback, handleError);
   }
 
   /// Adds element to [stream] and returns true if the caller should terminate
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart
index c198f74..f875336 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart
@@ -9,23 +9,11 @@
 // The default values for these properties are set when the global_ final field
 // in runtime.dart is initialized.
 
-// Override, e.g., for testing
-void trapRuntimeErrors(bool flag) {
-  JS('', 'dart.__trapRuntimeErrors = #', flag);
-}
-
-// TODO(jmesserly): remove this?
-void ignoreAllErrors(bool flag) {
-  JS('', 'dart.__ignoreAllErrors = #', flag);
-}
-
 argumentError(value) {
-  if (JS('!', 'dart.__trapRuntimeErrors')) JS('', 'debugger');
   throw ArgumentError.value(value);
 }
 
 throwUnimplementedError(String message) {
-  if (JS('!', 'dart.__trapRuntimeErrors')) JS('', 'debugger');
   throw UnimplementedError(message);
 }
 
@@ -33,13 +21,10 @@
 // from the stacktrace.
 assertFailed(String message,
     [String fileUri, int line, int column, String conditionSource]) {
-  if (JS('!', 'dart.__trapRuntimeErrors')) JS('', 'debugger');
-
   throw AssertionErrorImpl(message, fileUri, line, column, conditionSource);
 }
 
 throwCyclicInitializationError([Object field]) {
-  if (JS('!', 'dart.__trapRuntimeErrors')) JS('', 'debugger');
   throw CyclicInitializationError(field);
 }
 
@@ -47,7 +32,6 @@
   // TODO(vsm): Per spec, we should throw an NSM here.  Technically, we ought
   // to thread through method info, but that uglifies the code and can't
   // actually be queried ... it only affects how the error is printed.
-  if (JS('!', 'dart.__trapRuntimeErrors')) JS('', 'debugger');
   throw NoSuchMethodError(
       null, Symbol('<Unexpected Null Value>'), null, null, null);
 }
@@ -55,11 +39,6 @@
 castError(obj, expectedType, [@notNull bool isImplicit = false]) {
   var actualType = getReifiedType(obj);
   var message = _castErrorMessage(actualType, expectedType);
-  if (JS('!', 'dart.__ignoreAllErrors')) {
-    JS('', 'console.error(#)', message);
-    return obj;
-  }
-  if (JS('!', 'dart.__trapRuntimeErrors')) JS('', 'debugger');
   var error = isImplicit ? TypeErrorImpl(message) : CastErrorImpl(message);
   throw error;
 }
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
index 1c62090..d3ff62f 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
@@ -677,7 +677,6 @@
 
 /// The default implementation of `noSuchMethod` to match `Object.noSuchMethod`.
 defaultNoSuchMethod(obj, Invocation i) {
-  if (JS('!', 'dart.__trapRuntimeErrors')) JS('', 'debugger');
   throw NoSuchMethodError.withInvocation(obj, i);
 }
 
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart
index d79e835..99e1ab9 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart
@@ -128,11 +128,6 @@
     // These settings must be configured before the application starts so that
     // user code runs with the correct configuration.
     let settings = 'ddcSettings' in globalState ? globalState.ddcSettings : {};
-    $trapRuntimeErrors(
-        'trapRuntimeErrors' in settings ? settings.trapRuntimeErrors : false);
-
-    $ignoreAllErrors(
-        'ignoreAllErrors' in settings ? settings.ignoreAllErrors : false);
 
     $trackProfile(
         'trackProfile' in settings ? settings.trackProfile : false);
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/utils.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/utils.dart
index 8f9431d..2c06179 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/utils.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/utils.dart
@@ -37,13 +37,11 @@
 /// This error indicates a strong mode specific failure, other than a type
 /// assertion failure (TypeError) or CastError.
 void throwTypeError(String message) {
-  if (JS('!', 'dart.__trapRuntimeErrors')) JS('', 'debugger');
   throw TypeErrorImpl(message);
 }
 
 /// This error indicates a bug in the runtime or the compiler.
 void throwInternalError(String message) {
-  if (JS('!', 'dart.__trapRuntimeErrors')) JS('', 'debugger');
   JS('', 'throw Error(#)', message);
 }
 
diff --git a/sdk/lib/_internal/js_dev_runtime/private/foreign_helper.dart b/sdk/lib/_internal/js_dev_runtime/private/foreign_helper.dart
index 02e5c24..588d789 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/foreign_helper.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/foreign_helper.dart
@@ -106,10 +106,7 @@
  */
 // Add additional optional arguments if needed. The method is treated internally
 // as a variable argument method.
-// TODO(vsm): Enforce that this doesn't fall back to dynamic by typing it as:
-//  `T JS<T extends Object>(...)`
-// once we clean up html libraries.
-T JS<T>(String typeDescription, String codeTemplate,
+T JS<T extends Object>(String typeDescription, String codeTemplate,
     [arg0,
     arg1,
     arg2,
diff --git a/sdk/lib/_internal/js_runtime/lib/async_patch.dart b/sdk/lib/_internal/js_runtime/lib/async_patch.dart
index 4b63f9e..68bcbeb 100644
--- a/sdk/lib/_internal/js_runtime/lib/async_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/async_patch.dart
@@ -190,35 +190,29 @@
 }
 
 class _AsyncAwaitCompleter<T> implements Completer<T> {
-  final _completer = new Completer<T>.sync();
+  final _future = new _Future<T>();
   bool isSync;
 
   _AsyncAwaitCompleter() : isSync = false;
 
   void complete([FutureOr<T> value]) {
-    if (isSync) {
-      _completer.complete(value);
-    } else if (value is Future<T>) {
-      value.then(_completer.complete, onError: _completer.completeError);
+    if (!isSync || value is Future<T>) {
+      _future._asyncComplete(value);
     } else {
-      scheduleMicrotask(() {
-        _completer.complete(value);
-      });
+      _future._completeWithValue(value);
     }
   }
 
   void completeError(e, [st]) {
     if (isSync) {
-      _completer.completeError(e, st);
+      _future._completeError(e, st);
     } else {
-      scheduleMicrotask(() {
-        _completer.completeError(e, st);
-      });
+      _future._asyncCompleteError(e, st);
     }
   }
 
-  Future<T> get future => _completer.future;
-  bool get isCompleted => _completer.isCompleted;
+  Future<T> get future => _future;
+  bool get isCompleted => !_future._mayComplete;
 }
 
 /// Creates a Completer for an `async` function.
@@ -295,15 +289,14 @@
   if (object is _Future) {
     // We can skip the zone registration, since the bodyFunction is already
     // registered (see [_wrapJsFunctionForAsync]).
-    object._thenNoZoneRegistration(thenCallback, errorCallback);
+    object._thenAwait(thenCallback, errorCallback);
   } else if (object is Future) {
     object.then(thenCallback, onError: errorCallback);
   } else {
-    _Future future = new _Future();
-    future._setValue(object);
+    _Future future = new _Future().._setValue(object);
     // We can skip the zone registration, since the bodyFunction is already
     // registered (see [_wrapJsFunctionForAsync]).
-    future._thenNoZoneRegistration(thenCallback, null);
+    future._thenAwait(thenCallback, null);
   }
 }
 
@@ -381,7 +374,7 @@
   if (identical(bodyFunctionOrErrorCode, async_error_codes.SUCCESS)) {
     // This happens on return from the async* function.
     if (controller.isCanceled) {
-      controller.cancelationCompleter.complete();
+      controller.cancelationFuture._completeWithValue(null);
     } else {
       controller.close();
     }
@@ -389,7 +382,7 @@
   } else if (identical(bodyFunctionOrErrorCode, async_error_codes.ERROR)) {
     // The error is a js-error.
     if (controller.isCanceled) {
-      controller.cancelationCompleter.completeError(
+      controller.cancelationFuture._completeError(
           unwrapException(object), getTraceFromException(object));
     } else {
       controller.addError(
@@ -465,13 +458,13 @@
 
   bool get isPaused => controller.isPaused;
 
-  Completer cancelationCompleter = null;
+  _Future cancelationFuture = null;
 
   /// True after the StreamSubscription has been cancelled.
   /// When this is true, errors thrown from the async* body should go to the
-  /// [cancelationCompleter] instead of adding them to [controller], and
-  /// returning from the async function should complete [cancelationCompleter].
-  bool get isCanceled => cancelationCompleter != null;
+  /// [cancelationFuture] instead of adding them to [controller], and
+  /// returning from the async function should complete [cancelationFuture].
+  bool get isCanceled => cancelationFuture != null;
 
   add(event) => controller.add(event);
 
@@ -503,7 +496,7 @@
     }, onCancel: () {
       // If the async* is finished we ignore cancel events.
       if (!controller.isClosed) {
-        cancelationCompleter = new Completer();
+        cancelationFuture = new _Future();
         if (isSuspended) {
           // Resume the suspended async* function to run finalizers.
           isSuspended = false;
@@ -511,7 +504,7 @@
             body(async_error_codes.STREAM_WAS_CANCELED, null);
           });
         }
-        return cancelationCompleter.future;
+        return cancelationFuture;
       }
     });
   }
diff --git a/sdk/lib/_internal/js_runtime/lib/instantiation.dart b/sdk/lib/_internal/js_runtime/lib/instantiation.dart
index 0ed4974..bb003e6 100644
--- a/sdk/lib/_internal/js_runtime/lib/instantiation.dart
+++ b/sdk/lib/_internal/js_runtime/lib/instantiation.dart
@@ -18,7 +18,11 @@
     if (JS('bool', 'false')) {
       // [instantiatedGenericFunctionType] is called from injected $signature
       // methods with runtime type representations.
-      instantiatedGenericFunctionType(JS('', '0'), JS('', '0'));
+      if (JS_GET_FLAG('USE_NEW_RTI')) {
+        newRti.instantiatedGenericFunctionType(JS('', '0'), JS('', '0'));
+      } else {
+        instantiatedGenericFunctionType(JS('', '0'), JS('', '0'));
+      }
     }
   }
 
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index e83144b..ec0da69 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -64,7 +64,9 @@
         createRuntimeType,
         evalInInstance,
         getRuntimeType,
-        getTypeFromTypesTable;
+        getTypeFromTypesTable,
+        instanceTypeName,
+        instantiatedGenericFunctionType;
 
 part 'annotations.dart';
 part 'constant_map.dart';
@@ -355,8 +357,14 @@
     if (_typeArgumentCount == 0) return const <Type>[];
     int start = _arguments.length - _typeArgumentCount;
     var list = <Type>[];
-    for (int index = 0; index < _typeArgumentCount; index++) {
-      list.add(createRuntimeType(_arguments[start + index]));
+    if (JS_GET_FLAG('USE_NEW_RTI')) {
+      for (int index = 0; index < _typeArgumentCount; index++) {
+        list.add(newRti.createRuntimeType(_arguments[start + index]));
+      }
+    } else {
+      for (int index = 0; index < _typeArgumentCount; index++) {
+        list.add(createRuntimeType(_arguments[start + index]));
+      }
     }
     return list;
   }
@@ -512,10 +520,15 @@
   }
 
   /// Returns the type of [object] as a string (including type arguments).
+  /// Tries to return a sensible name for non-Dart objects.
   ///
-  /// In minified mode, uses the unminified names if available.
+  /// In minified mode, uses the unminified names if available, otherwise tags
+  /// them with 'minified:'.
   @pragma('dart2js:noInline')
   static String objectTypeName(Object object) {
+    if (JS_GET_FLAG('USE_NEW_RTI')) {
+      return _objectTypeNameNewRti(object);
+    }
     String className = _objectClassName(object);
     String arguments = joinArguments(getRuntimeTypeInfo(object), 0);
     return '${className}${arguments}';
@@ -587,6 +600,54 @@
     return unminifyOrTag(name);
   }
 
+  /// Returns the type of [object] as a string (including type arguments).
+  /// Tries to return a sensible name for non-Dart objects.
+  ///
+  /// In minified mode, uses the unminified names if available, otherwise tags
+  /// them with 'minified:'.
+  static String _objectTypeNameNewRti(Object object) {
+    var dartObjectConstructor = JS_BUILTIN(
+        'depends:none;effects:none;', JsBuiltin.dartObjectConstructor);
+    if (JS('bool', '# instanceof #', object, dartObjectConstructor)) {
+      return newRti.instanceTypeName(object);
+    }
+
+    var interceptor = getInterceptor(object);
+    if (identical(interceptor, JS_INTERCEPTOR_CONSTANT(Interceptor)) ||
+        object is UnknownJavaScriptObject) {
+      // Try to do better.  If we do not find something better, fallthrough to
+      // Dart-type based name that leave the name as 'UnknownJavaScriptObject'
+      // or 'Interceptor' (or the minified versions thereof).
+      //
+      // When we get here via the UnknownJavaScriptObject test (for JavaScript
+      // objects from outside the program), the object's constructor has a
+      // better name that 'UnknownJavaScriptObject'.
+      //
+      // When we get here the Interceptor test (for Native classes that are
+      // declared in the Dart program but have been 'folded' into Interceptor),
+      // the native class's constructor name is better than the generic
+      // 'Interceptor' (an abstract class).
+
+      // Try the [constructorNameFallback]. This gets the constructor name for
+      // any browser (used by [getNativeInterceptor]).
+      String dispatchName = constructorNameFallback(object);
+      if (_saneNativeClassName(dispatchName)) return dispatchName;
+      var constructor = JS('', '#.constructor', object);
+      if (JS('bool', 'typeof # == "function"', constructor)) {
+        var constructorName = JS('', '#.name', constructor);
+        if (constructorName is String &&
+            _saneNativeClassName(constructorName)) {
+          return constructorName;
+        }
+      }
+    }
+
+    return newRti.instanceTypeName(object);
+  }
+
+  static bool _saneNativeClassName(name) =>
+      name != null && name != 'Object' && name != '';
+
   /// In minified mode, uses the unminified names if available.
   static String objectToHumanReadableString(Object object) {
     String name = objectTypeName(object);
@@ -2497,9 +2558,10 @@
   // to be visible to resolution and the generation of extra stubs.
 
   String toString() {
-    String name = Primitives.objectTypeName(this);
-    // Mirrors puts a space in front of some names, so remove it.
-    name = JS('String', '#.trim()', name);
+    var constructor = JS('', '#.constructor', this);
+    String name =
+        constructor == null ? null : JS('String|Null', '#.name', constructor);
+    if (name == null) name = 'unknown';
     return "Closure '$name'";
   }
 }
diff --git a/sdk/lib/_internal/js_runtime/lib/rti.dart b/sdk/lib/_internal/js_runtime/lib/rti.dart
index eac3473..f7ca527 100644
--- a/sdk/lib/_internal/js_runtime/lib/rti.dart
+++ b/sdk/lib/_internal/js_runtime/lib/rti.dart
@@ -136,8 +136,11 @@
   static const kindGenericFunction = 11;
   static const kindGenericFunctionParameter = 12;
 
-  static bool _isFunctionType(Rti rti) {
+  static bool _isUnionOfFunctionType(Rti rti) {
     int kind = Rti._getKind(rti);
+    if (kind == kindStar || kind == kindQuestion || kind == kindFutureOr) {
+      return _isUnionOfFunctionType(_castToRti(_getPrimary(rti)));
+    }
     return kind == kindFunction || kind == kindGenericFunction;
   }
 
@@ -258,6 +261,10 @@
   /// between 'generic class is the base environment' and 'generic class is a
   /// singleton type argument' is resolved [TBD] (either (1) a bind1 cache, or
   /// (2)using `env._eval("@<0>")._bind(args)` in place of `env._bind1(args)`).
+  ///
+  /// On [Rti]s that are generic function types, results of instantiation are
+  /// cached on the generic function type to ensure fast repeated
+  /// instantiations.
   Object _bindCache;
 
   static Object _getBindCache(Rti rti) => rti._bindCache;
@@ -346,15 +353,228 @@
   return _rtiEval(instanceType(instance), recipe);
 }
 
+/// Returns [genericFunctionRti] with type parameters bound to those specified
+/// by [instantiationRti].
+///
+/// [genericFunctionRti] must be an rti representation with a number of generic
+/// type parameters matching the number of types provided by [instantiationRti].
+///
+/// Called from generated code.
+@pragma('dart2js:noInline')
+Rti instantiatedGenericFunctionType(
+    Rti genericFunctionRti, Rti instantiationRti) {
+  var bounds = Rti._getGenericFunctionBounds(genericFunctionRti);
+  var typeArguments = Rti._getInterfaceTypeArguments(instantiationRti);
+  assert(_Utils.arrayLength(bounds) == _Utils.arrayLength(typeArguments));
+
+  var cache = Rti._getBindCache(genericFunctionRti);
+  if (cache == null) {
+    cache = JS('', 'new Map()');
+    Rti._setBindCache(genericFunctionRti, cache);
+  }
+  String key = Rti._getCanonicalRecipe(instantiationRti);
+  var probe = _Utils.mapGet(cache, key);
+  if (probe != null) return _castToRti(probe);
+  Rti rti = _instantiate(_theUniverse(),
+      Rti._getGenericFunctionBase(genericFunctionRti), typeArguments, 0);
+  _Utils.mapSet(cache, key, rti);
+  return rti;
+}
+
+/// Substitutes [typeArguments] for generic function parameters in [rti].
+///
+/// Generic function parameters are de Bruijn indices counting up through the
+/// parameters' scopes to index into [typeArguments].
+///
+/// [depth] is the number of subsequent generic function parameters that are in
+/// scope. This is subtracted off the de Bruijn index for the type parameter to
+/// arrive at an potential index into [typeArguments].
+Rti _instantiate(universe, Rti rti, Object typeArguments, int depth) {
+  int kind = Rti._getKind(rti);
+  switch (kind) {
+    case Rti.kindNever:
+    case Rti.kindDynamic:
+    case Rti.kindVoid:
+    case Rti.kindAny:
+      return rti;
+    case Rti.kindStar:
+      Rti baseType = _castToRti(Rti._getPrimary(rti));
+      Rti instantiatedBaseType =
+          _instantiate(universe, baseType, typeArguments, depth);
+      if (_Utils.isIdentical(instantiatedBaseType, baseType)) return rti;
+      return _Universe._lookupStarRti(universe, instantiatedBaseType);
+    case Rti.kindQuestion:
+      Rti baseType = _castToRti(Rti._getPrimary(rti));
+      Rti instantiatedBaseType =
+          _instantiate(universe, baseType, typeArguments, depth);
+      if (_Utils.isIdentical(instantiatedBaseType, baseType)) return rti;
+      return _Universe._lookupQuestionRti(universe, instantiatedBaseType);
+    case Rti.kindFutureOr:
+      Rti baseType = _castToRti(Rti._getPrimary(rti));
+      Rti instantiatedBaseType =
+          _instantiate(universe, baseType, typeArguments, depth);
+      if (_Utils.isIdentical(instantiatedBaseType, baseType)) return rti;
+      return _Universe._lookupFutureOrRti(universe, instantiatedBaseType);
+    case Rti.kindInterface:
+      Object interfaceTypeArguments = Rti._getInterfaceTypeArguments(rti);
+      Object instantiatedInterfaceTypeArguments = _instantiateArray(
+          universe, interfaceTypeArguments, typeArguments, depth);
+      if (_Utils.isIdentical(
+          instantiatedInterfaceTypeArguments, interfaceTypeArguments))
+        return rti;
+      return _Universe._lookupInterfaceRti(universe, Rti._getInterfaceName(rti),
+          instantiatedInterfaceTypeArguments);
+    case Rti.kindBinding:
+      Rti base = Rti._getBindingBase(rti);
+      Rti instantiatedBase = _instantiate(universe, base, typeArguments, depth);
+      Object arguments = Rti._getBindingArguments(rti);
+      Object instantiatedArguments =
+          _instantiateArray(universe, arguments, typeArguments, depth);
+      if (_Utils.isIdentical(instantiatedBase, base) &&
+          _Utils.isIdentical(instantiatedArguments, arguments)) return rti;
+      return _Universe._lookupBindingRti(
+          universe, instantiatedBase, instantiatedArguments);
+    case Rti.kindFunction:
+      Rti returnType = Rti._getReturnType(rti);
+      Rti instantiatedReturnType =
+          _instantiate(universe, returnType, typeArguments, depth);
+      _FunctionParameters functionParameters = Rti._getFunctionParameters(rti);
+      _FunctionParameters instantiatedFunctionParameters =
+          _instantiateFunctionParameters(
+              universe, functionParameters, typeArguments, depth);
+      if (_Utils.isIdentical(instantiatedReturnType, returnType) &&
+          _Utils.isIdentical(
+              instantiatedFunctionParameters, functionParameters)) return rti;
+      return _Universe._lookupFunctionRti(
+          universe, instantiatedReturnType, instantiatedFunctionParameters);
+    case Rti.kindGenericFunction:
+      Object bounds = Rti._getGenericFunctionBounds(rti);
+      depth += _Utils.arrayLength(bounds);
+      Object instantiatedBounds =
+          _instantiateArray(universe, bounds, typeArguments, depth);
+      Rti base = Rti._getGenericFunctionBase(rti);
+      Rti instantiatedBase = _instantiate(universe, base, typeArguments, depth);
+      if (_Utils.isIdentical(instantiatedBounds, bounds) &&
+          _Utils.isIdentical(instantiatedBase, base)) return rti;
+      return _Universe._lookupGenericFunctionRti(
+          universe, instantiatedBase, instantiatedBounds);
+    case Rti.kindGenericFunctionParameter:
+      int index = Rti._getGenericFunctionParameterIndex(rti);
+      if (index < depth) return null;
+      return _castToRti(_Utils.arrayAt(typeArguments, index - depth));
+    default:
+      throw AssertionError(
+          'Attempted to instantiate unexpected RTI kind $kind');
+  }
+}
+
+Object _instantiateArray(
+    universe, Object rtiArray, Object typeArguments, int depth) {
+  bool changed = false;
+  int length = _Utils.arrayLength(rtiArray);
+  Object result = JS('', '[]');
+  for (int i = 0; i < length; i++) {
+    Rti rti = _castToRti(_Utils.arrayAt(rtiArray, i));
+    Rti instantiatedRti = _instantiate(universe, rti, typeArguments, depth);
+    if (!_Utils.isIdentical(instantiatedRti, rti)) {
+      changed = true;
+    }
+    _Utils.arrayPush(result, instantiatedRti);
+  }
+  return changed ? result : rtiArray;
+}
+
+Object _instantiateNamed(
+    universe, Object namedArray, Object typeArguments, int depth) {
+  bool changed = false;
+  int length = _Utils.arrayLength(namedArray);
+  assert(length.isEven);
+  Object result = JS('', '[]');
+  for (int i = 0; i < length; i += 2) {
+    String name = _Utils.asString(_Utils.arrayAt(namedArray, i));
+    Rti rti = _castToRti(_Utils.arrayAt(namedArray, i + 1));
+    Rti instantiatedRti = _instantiate(universe, rti, typeArguments, depth);
+    if (!_Utils.isIdentical(instantiatedRti, rti)) {
+      changed = true;
+    }
+    _Utils.arrayPush(result, name);
+    _Utils.arrayPush(result, instantiatedRti);
+  }
+  return changed ? result : namedArray;
+}
+
+// TODO(fishythefish): Support required named parameters.
+_FunctionParameters _instantiateFunctionParameters(universe,
+    _FunctionParameters functionParameters, Object typeArguments, int depth) {
+  Object requiredPositional =
+      _FunctionParameters._getRequiredPositional(functionParameters);
+  Object instantiatedRequiredPositional =
+      _instantiateArray(universe, requiredPositional, typeArguments, depth);
+  Object optionalPositional =
+      _FunctionParameters._getOptionalPositional(functionParameters);
+  Object instantiatedOptionalPositional =
+      _instantiateArray(universe, optionalPositional, typeArguments, depth);
+  Object optionalNamed =
+      _FunctionParameters._getOptionalNamed(functionParameters);
+  Object instantiatedOptionalNamed =
+      _instantiateNamed(universe, optionalNamed, typeArguments, depth);
+  if (_Utils.isIdentical(instantiatedRequiredPositional, requiredPositional) &&
+      _Utils.isIdentical(instantiatedOptionalPositional, optionalPositional) &&
+      _Utils.isIdentical(instantiatedOptionalNamed, optionalNamed))
+    return functionParameters;
+  _FunctionParameters result = _FunctionParameters.allocate();
+  _FunctionParameters._setRequiredPositional(
+      result, instantiatedRequiredPositional);
+  _FunctionParameters._setOptionalPositional(
+      result, instantiatedOptionalPositional);
+  _FunctionParameters._setOptionalNamed(result, instantiatedOptionalNamed);
+  return result;
+}
+
+bool _isClosure(object) => _Utils.instanceOf(object,
+    JS_BUILTIN('depends:none;effects:none;', JsBuiltin.dartClosureConstructor));
+
+/// Returns the structural function [Rti] of [closure].
+/// Called from generated code.
+Rti closureFunctionType(closure) {
+  var signatureName = JS_GET_NAME(JsGetName.SIGNATURE_NAME);
+  var signature = JS('', '#[#]', closure, signatureName);
+  if (signature != null) {
+    if (JS('bool', 'typeof # == "number"', signature)) {
+      return getTypeFromTypesTable(_Utils.asInt(signature));
+    }
+    return _castToRti(JS('', '#[#]()', closure, signatureName));
+  }
+  return null;
+}
+
+// Subclasses of Closure are synthetic classes. The synthetic classes all
+// extend a 'normal' class (Closure, BoundClosure, StaticClosure), so make
+// them appear to be the superclass.
+// TODO(sra): Can this be done less expensively, e.g. by putting $ti on the
+// prototype of Closure/BoundClosure/StaticClosure classes?
+Rti _closureInterfaceType(closure) {
+  var rti = JS('', r'#[#]', closure, JS_GET_NAME(JsGetName.RTI_NAME));
+  return rti != null
+      ? _castToRti(rti)
+      : _instanceTypeFromConstructor(
+          JS('', '#.__proto__.__proto__.constructor', closure));
+}
+
 /// Returns the Rti type of [object]. Closures have both an interface type
 /// (Closures implement `Function`) and a structural function type. Uses
 /// [testRti] to choose the appropriate type.
 ///
 /// Called from generated code.
 Rti instanceOrFunctionType(object, Rti testRti) {
-  if (Rti._isFunctionType(testRti)) {
-    Rti rti = _instanceFunctionType(object);
-    if (rti != null) return rti;
+  if (Rti._isUnionOfFunctionType(testRti)) {
+    if (_isClosure(object)) {
+      // If [testRti] is e.g. `FutureOr<Action>` (where `Action` is some
+      // function type), we don't need to worry about the `Future<Action>`
+      // branch because closures can't be `Future`s.
+      Rti rti = closureFunctionType(object);
+      if (rti != null) return rti;
+    }
   }
   return instanceType(object);
 }
@@ -362,6 +582,11 @@
 /// Returns the Rti type of [object].
 /// Called from generated code.
 Rti instanceType(object) {
+  if (_isClosure(object)) return _closureInterfaceType(object);
+  return _nonClosureInstanceType(object);
+}
+
+Rti _nonClosureInstanceType(object) {
   // TODO(sra): Add specializations of this method. One possible way is to
   // arrange that the interceptor has a _getType method that is injected into
   // DartObject, Interceptor and JSArray. Then this method can be replaced-by
@@ -372,38 +597,43 @@
       object,
       JS_BUILTIN(
           'depends:none;effects:none;', JsBuiltin.dartObjectConstructor))) {
-    var rti = JS('', r'#[#]', object, JS_GET_NAME(JsGetName.RTI_NAME));
-    if (rti != null) return _castToRti(rti);
-
-    // Subclasses of Closure are synthetic classes. The synthetic classes all
-    // extend a 'normal' class (Closure, BoundClosure, StaticClosure), so make
-    // them appear to be the superclass.
-    // TODO(sra): Can this be done less expensively, e.g. by putting $ti on the
-    // prototype of Closure/BoundClosure/StaticClosure classes?
-    var closureClassConstructor = JS_BUILTIN(
-        'depends:none;effects:none;', JsBuiltin.dartClosureConstructor);
-    if (_Utils.instanceOf(object, closureClassConstructor)) {
-      return _instanceTypeFromConstructor(
-          JS('', '#.__proto__.__proto__.constructor', object));
-    }
-
-    return _instanceTypeFromConstructor(JS('', '#.constructor', object));
+    return _instanceType(object);
   }
 
   if (_Utils.isArray(object)) {
-    var rti = JS('', r'#[#]', object, JS_GET_NAME(JsGetName.RTI_NAME));
-    // TODO(sra): Do we need to protect against an Array passed between two Dart
-    // programs loaded into the same JavaScript isolate (e.g. via JS-interop).
-    // FWIW, the legacy rti has this problem too. Perhaps JSArrays should use a
-    // program-local `symbol` for the type field.
-    if (rti != null) return _castToRti(rti);
-    return _castToRti(getJSArrayInteropRti());
+    return _arrayInstanceType(object);
   }
 
   var interceptor = getInterceptor(object);
   return _instanceTypeFromConstructor(JS('', '#.constructor', interceptor));
 }
 
+/// Returns the Rti type of JavaScript Array [object].
+/// Called from generated code.
+Rti _arrayInstanceType(object) {
+  // TODO(sra): Do we need to protect against an Array passed between two Dart
+  // programs loaded into the same JavaScript isolate (e.g. via JS-interop).
+  // FWIW, the legacy rti has this problem too. Perhaps JSArrays should use a
+  // program-local `symbol` for the type field.
+  var rti = JS('', r'#[#]', object, JS_GET_NAME(JsGetName.RTI_NAME));
+  return rti != null ? _castToRti(rti) : _castToRti(getJSArrayInteropRti());
+}
+
+/// Returns the Rti type of user-defined class [object].
+/// [object] must not be an intercepted class or a closure.
+/// Called from generated code.
+Rti _instanceType(object) {
+  var rti = JS('', r'#[#]', object, JS_GET_NAME(JsGetName.RTI_NAME));
+  return rti != null
+      ? _castToRti(rti)
+      : _instanceTypeFromConstructor(JS('', '#.constructor', object));
+}
+
+String instanceTypeName(object) {
+  Rti rti = instanceType(object);
+  return _rtiToString(rti, null);
+}
+
 Rti _instanceTypeFromConstructor(constructor) {
   // TODO(sra): Cache Rti on constructor.
   return findType(JS('String', '#.name', constructor));
@@ -411,22 +641,8 @@
 
 /// Returns the structural function type of [object], or `null` if the object is
 /// not a closure.
-Rti _instanceFunctionType(object) {
-  if (_Utils.instanceOf(
-      object,
-      JS_BUILTIN(
-          'depends:none;effects:none;', JsBuiltin.dartClosureConstructor))) {
-    var signatureName = JS_GET_NAME(JsGetName.SIGNATURE_NAME);
-    var signature = JS('', '#[#]', object, signatureName);
-    if (signature != null) {
-      if (JS('bool', 'typeof # == "number"', signature)) {
-        return getTypeFromTypesTable(_Utils.asInt(signature));
-      }
-      return _castToRti(JS('', '#[#]()', object, signatureName));
-    }
-  }
-  return null;
-}
+Rti _instanceFunctionType(object) =>
+    _isClosure(object) ? closureFunctionType(object) : null;
 
 /// Returns Rti from types table. The types table is initialized with recipe
 /// strings.
@@ -443,12 +659,12 @@
 }
 
 Type getRuntimeType(object) {
-  Rti rti = _instanceFunctionType(object) ?? instanceType(object);
-  return _createRuntimeType(rti);
+  Rti rti = _instanceFunctionType(object) ?? _nonClosureInstanceType(object);
+  return createRuntimeType(rti);
 }
 
 /// Called from generated code.
-Type _createRuntimeType(Rti rti) {
+Type createRuntimeType(Rti rti) {
   _Type type = Rti._getCachedRuntimeType(rti);
   if (type != null) return type;
   // TODO(https://github.com/dart-lang/language/issues/428) For NNBD transition,
@@ -461,7 +677,7 @@
 
 /// Called from generated code in the constant pool.
 Type typeLiteral(String recipe) {
-  return _createRuntimeType(findType(recipe));
+  return createRuntimeType(findType(recipe));
 }
 
 /// Implementation of [Type] based on Rti.
@@ -579,7 +795,7 @@
 /// Specialization for 'as bool?'.
 /// Called from generated code.
 bool /*?*/ _asBoolNullable(object) {
-  if (object is bool) return object;
+  if (_isBool(object)) return _Utils.asBool(object);
   if (object == null) return object;
   throw _CastError.forType(object, 'bool');
 }
@@ -587,7 +803,7 @@
 /// Specialization for check on 'bool?'.
 /// Called from generated code.
 bool /*?*/ _checkBoolNullable(object) {
-  if (object is bool) return object;
+  if (_isBool(object)) return _Utils.asBool(object);
   if (object == null) return object;
   throw _TypeError.forType(object, 'bool');
 }
@@ -595,7 +811,7 @@
 /// Specialization for 'as double?'.
 /// Called from generated code.
 double /*?*/ _asDoubleNullable(object) {
-  if (object is double) return object;
+  if (_isNum(object)) return _Utils.asDouble(object);
   if (object == null) return object;
   throw _CastError.forType(object, 'double');
 }
@@ -603,7 +819,7 @@
 /// Specialization for check on 'double?'.
 /// Called from generated code.
 double /*?*/ _checkDoubleNullable(object) {
-  if (object is double) return object;
+  if (_isNum(object)) return _Utils.asDouble(object);
   if (object == null) return object;
   throw _TypeError.forType(object, 'double');
 }
@@ -618,7 +834,7 @@
 /// Specialization for 'as int?'.
 /// Called from generated code.
 int /*?*/ _asIntNullable(object) {
-  if (object is int) return object;
+  if (_isInt(object)) return _Utils.asInt(object);
   if (object == null) return object;
   throw _CastError.forType(object, 'int');
 }
@@ -626,7 +842,7 @@
 /// Specialization for check on 'int?'.
 /// Called from generated code.
 int /*?*/ _checkIntNullable(object) {
-  if (object is int) return object;
+  if (_isInt(object)) return _Utils.asInt(object);
   if (object == null) return object;
   throw _TypeError.forType(object, 'int');
 }
@@ -640,7 +856,7 @@
 /// Specialization for 'as num?'.
 /// Called from generated code.
 num /*?*/ _asNumNullable(object) {
-  if (object is num) return object;
+  if (_isNum(object)) return _Utils.asNum(object);
   if (object == null) return object;
   throw _CastError.forType(object, 'num');
 }
@@ -648,7 +864,7 @@
 /// Specialization for check on 'num?'.
 /// Called from generated code.
 num /*?*/ _checkNumNullable(object) {
-  if (object is num) return object;
+  if (_isNum(object)) return _Utils.asNum(object);
   if (object == null) return object;
   throw _TypeError.forType(object, 'num');
 }
@@ -662,7 +878,7 @@
 /// Specialization for 'as String?'.
 /// Called from generated code.
 String /*?*/ _asStringNullable(object) {
-  if (object is String) return object;
+  if (_isString(object)) return _Utils.asString(object);
   if (object == null) return object;
   throw _CastError.forType(object, 'String');
 }
@@ -670,7 +886,7 @@
 /// Specialization for check on 'String?'.
 /// Called from generated code.
 String /*?*/ _checkStringNullable(object) {
-  if (object is String) return object;
+  if (_isString(object)) return _Utils.asString(object);
   if (object == null) return object;
   throw _TypeError.forType(object, 'String');
 }
@@ -1122,6 +1338,10 @@
   static String _canonicalRecipeOfAny() =>
       Recipe.pushAnyExtensionString + Recipe.extensionOpString;
 
+  static String _canonicalRecipeOfStar(Rti baseType) =>
+      Rti._getCanonicalRecipe(baseType) + Recipe.wrapStarString;
+  static String _canonicalRecipeOfQuestion(Rti baseType) =>
+      Rti._getCanonicalRecipe(baseType) + Recipe.wrapQuestionString;
   static String _canonicalRecipeOfFutureOr(Rti baseType) =>
       Rti._getCanonicalRecipe(baseType) + Recipe.wrapFutureOrString;
 
@@ -1160,18 +1380,33 @@
     return _finishRti(universe, rti);
   }
 
-  static Rti _lookupFutureOrRti(universe, Rti baseType) {
-    String canonicalRecipe = _canonicalRecipeOfFutureOr(baseType);
+  static Rti _lookupStarRti(universe, Rti baseType) => _lookupUnaryRti(
+      universe, Rti.kindStar, baseType, _canonicalRecipeOfStar(baseType));
+
+  static Rti _lookupQuestionRti(universe, Rti baseType) => _lookupUnaryRti(
+      universe,
+      Rti.kindQuestion,
+      baseType,
+      _canonicalRecipeOfQuestion(baseType));
+
+  static Rti _lookupFutureOrRti(universe, Rti baseType) => _lookupUnaryRti(
+      universe,
+      Rti.kindFutureOr,
+      baseType,
+      _canonicalRecipeOfFutureOr(baseType));
+
+  static Rti _lookupUnaryRti(
+      universe, int kind, Rti baseType, String canonicalRecipe) {
     var cache = evalCache(universe);
     var probe = _cacheGet(cache, canonicalRecipe);
     if (probe != null) return _castToRti(probe);
-    return _createFutureOrRti(universe, baseType, canonicalRecipe);
+    return _createUnaryRti(universe, kind, baseType, canonicalRecipe);
   }
 
-  static Rti _createFutureOrRti(
-      universe, Rti baseType, String canonicalRecipe) {
+  static Rti _createUnaryRti(
+      universe, int kind, Rti baseType, String canonicalRecipe) {
     Rti rti = Rti.allocate();
-    Rti._setKind(rti, Rti.kindFutureOr);
+    Rti._setKind(rti, kind);
     Rti._setPrimary(rti, baseType);
     Rti._setCanonicalRecipe(rti, canonicalRecipe);
     return _finishRti(universe, rti);
@@ -1576,6 +1811,22 @@
             handleExtendedOperations(parser, stack);
             break;
 
+          case Recipe.wrapStar:
+            Object u = universe(parser);
+            push(
+                stack,
+                _Universe._lookupStarRti(
+                    u, toType(u, environment(parser), pop(stack))));
+            break;
+
+          case Recipe.wrapQuestion:
+            Object u = universe(parser);
+            push(
+                stack,
+                _Universe._lookupQuestionRti(
+                    u, toType(u, environment(parser), pop(stack))));
+            break;
+
           case Recipe.wrapFutureOr:
             Object u = universe(parser);
             push(
@@ -1896,11 +2147,15 @@
     }
   }
 
-  if (Rti._isFunctionType(t)) {
+  if (isGenericFunctionKind(t)) {
+    return _isGenericFunctionSubtype(universe, s, sEnv, t, tEnv);
+  }
+
+  if (isFunctionKind(t)) {
     return _isFunctionSubtype(universe, s, sEnv, t, tEnv);
   }
 
-  if (Rti._isFunctionType(s)) {
+  if (isFunctionKind(s) || isGenericFunctionKind(s)) {
     return isFunctionType(t);
   }
 
@@ -1911,25 +2166,25 @@
   return _isSubtypeOfInterface(universe, s, sEnv, tName, tArgs, tEnv);
 }
 
+bool _isGenericFunctionSubtype(universe, Rti s, sEnv, Rti t, tEnv) {
+  assert(isGenericFunctionKind(t));
+  if (!isGenericFunctionKind(s)) return false;
+
+  var sBounds = Rti._getGenericFunctionBounds(s);
+  var tBounds = Rti._getGenericFunctionBounds(t);
+  if (!typesEqual(sBounds, tBounds)) return false;
+  // TODO(fishythefish): Extend [sEnv] and [tEnv] with bindings for the [s]
+  // and [t] type parameters to enable checking the bound against
+  // non-type-parameter terms.
+
+  return _isFunctionSubtype(universe, Rti._getGenericFunctionBase(s), sEnv,
+      Rti._getGenericFunctionBase(t), tEnv);
+}
+
 // TODO(fishythefish): Support required named parameters.
 bool _isFunctionSubtype(universe, Rti s, sEnv, Rti t, tEnv) {
-  assert(Rti._isFunctionType(t));
-  if (!Rti._isFunctionType(s)) return false;
-
-  if (isGenericFunctionKind(s)) {
-    if (!isGenericFunctionKind(t)) return false;
-    var sBounds = Rti._getGenericFunctionBounds(s);
-    var tBounds = Rti._getGenericFunctionBounds(t);
-    if (!typesEqual(sBounds, tBounds)) return false;
-    // TODO(fishythefish): Extend [sEnv] and [tEnv] with bindings for the [s]
-    // and [t] type parameters to enable checking the bound against
-    // non-type-parameter terms.
-
-    s = Rti._getGenericFunctionBase(s);
-    t = Rti._getGenericFunctionBase(t);
-  } else if (isGenericFunctionKind(t)) {
-    return false;
-  }
+  assert(isFunctionKind(t));
+  if (!isFunctionKind(s)) return false;
 
   Rti sReturnType = Rti._getReturnType(s);
   Rti tReturnType = Rti._getReturnType(t);
@@ -2123,6 +2378,7 @@
 
 bool isFutureOrType(Rti t) => Rti._getKind(t) == Rti.kindFutureOr;
 
+bool isFunctionKind(Rti t) => Rti._getKind(t) == Rti.kindFunction;
 bool isGenericFunctionKind(Rti t) => Rti._getKind(t) == Rti.kindGenericFunction;
 
 bool isGenericFunctionTypeParameter(Rti t) =>
@@ -2147,7 +2403,10 @@
 
 ///
 class _Utils {
+  static bool asBool(Object o) => JS('bool', '#', o);
+  static double asDouble(Object o) => JS('double', '#', o);
   static int asInt(Object o) => JS('int', '#', o);
+  static num asNum(Object o) => JS('num', '#', o);
   static String asString(Object o) => JS('String', '#', o);
 
   static bool isString(Object o) => JS('bool', 'typeof # == "string"', o);
@@ -2168,6 +2427,9 @@
     JS('', '#[#] = #', array, i, value);
   }
 
+  static JSArray arrayShallowCopy(Object array) =>
+      JS('JSArray', '#.slice()', array);
+
   static JSArray arraySplice(Object array, int position) =>
       JS('JSArray', '#.splice(#)', array, position);
 
diff --git a/sdk/lib/async/future_impl.dart b/sdk/lib/async/future_impl.dart
index 3fd6b59..1ec0791 100644
--- a/sdk/lib/async/future_impl.dart
+++ b/sdk/lib/async/future_impl.dart
@@ -67,6 +67,9 @@
   static const int stateCatcherror = maskError;
   static const int stateCatcherrorTest = maskError | maskTestError;
   static const int stateWhencomplete = maskWhencomplete;
+  static const int maskType =
+      maskValue | maskError | maskTestError | maskWhencomplete;
+  static const int stateIsAwait = 16;
   // Listeners on the same future are linked through this link.
   _FutureListener _nextListener;
   // The future to complete when this listener is activated.
@@ -84,6 +87,13 @@
         errorCallback = errorCallback,
         state = (errorCallback == null) ? stateThen : stateThenOnerror;
 
+  _FutureListener.thenAwait(
+      this.result, _FutureOnValue<S, T> onValue, Function errorCallback)
+      : callback = onValue,
+        errorCallback = errorCallback,
+        state = ((errorCallback == null) ? stateThen : stateThenOnerror)
+              | stateIsAwait ;
+
   _FutureListener.catchError(this.result, this.errorCallback, this.callback)
       : state = (callback == null) ? stateCatcherror : stateCatcherrorTest;
 
@@ -95,8 +105,9 @@
 
   bool get handlesValue => (state & maskValue != 0);
   bool get handlesError => (state & maskError != 0);
-  bool get hasErrorTest => (state == stateCatcherrorTest);
-  bool get handlesComplete => (state == stateWhencomplete);
+  bool get hasErrorTest => (state & maskType == stateCatcherrorTest);
+  bool get handlesComplete => (state & maskType == stateWhencomplete);
+  bool get isAwait => (state & stateIsAwait != 0);
 
   _FutureOnValue<S, T> get _onValue {
     assert(handlesValue);
@@ -229,6 +240,27 @@
   bool get _isComplete => _state >= _stateValue;
   bool get _hasError => _state == _stateError;
 
+  static List<Function> _continuationFunctions(_Future<Object> future) {
+    List<Function> result = null;
+    while (true) {
+      if (future._mayAddListener) return result;
+      assert(!future._isComplete);
+      assert(!future._isChained);
+      // So _resultOrListeners contains listeners.
+      _FutureListener<Object, Object> listener = future._resultOrListeners;
+      if (listener != null &&
+          listener._nextListener == null &&
+          listener.isAwait) {
+        (result ??= <Function>[]).add(listener.handleValue);
+        future = listener.result;
+        assert(!future._isComplete);
+      } else {
+        break;
+      }
+    }
+    return result;
+  }
+
   void _setChained(_Future source) {
     assert(_mayAddListener);
     _state = _stateChained;
@@ -246,14 +278,21 @@
         onError = _registerErrorHandler(onError, currentZone);
       }
     }
-    return _thenNoZoneRegistration<R>(f, onError);
+    _Future<R> result = new _Future<R>();
+    _addListener(new _FutureListener<T, R>.then(result, f, onError));
+    return result;
   }
 
-  // This method is used by async/await.
-  Future<E> _thenNoZoneRegistration<E>(
+  /// Registers a system created result and error continuation.
+  ///
+  /// Used by the implementation of `await` to listen to a future.
+  /// The system created liseners are not registered in the zone,
+  /// and the listener is marked as being from an `await`.
+  /// This marker is used in [_continuationFunctions].
+  Future<E> _thenAwait<E>(
       FutureOr<E> f(T value), Function onError) {
     _Future<E> result = new _Future<E>();
-    _addListener(new _FutureListener<T, E>.then(result, f, onError));
+    _addListener(new _FutureListener<T, E>.thenAwait(result, f, onError));
     return result;
   }
 
diff --git a/sdk/lib/core/list.dart b/sdk/lib/core/list.dart
index a0f67ac..27e1653 100644
--- a/sdk/lib/core/list.dart
+++ b/sdk/lib/core/list.dart
@@ -719,4 +719,13 @@
    *     map.keys.toList(); // [0, 1, 2, 3]
    */
   Map<int, E> asMap();
+
+  /**
+  * Whether this list is equal to [other].
+  *
+  * Lists are, by default, only equal to themselves.
+  * Even if [other] is also a list, the equality comparison
+  * does not compare the elements of the two lists.
+  */
+ bool operator ==(Object other);
 }
diff --git a/sdk/lib/ffi/dynamic_library.dart b/sdk/lib/ffi/dynamic_library.dart
index 46d660e..ec68eeb 100644
--- a/sdk/lib/ffi/dynamic_library.dart
+++ b/sdk/lib/ffi/dynamic_library.dart
@@ -6,11 +6,20 @@
 
 /// Represents a dynamically loaded C library.
 class DynamicLibrary {
-  /// Loads a dynamic library file. This is the equivalent of dlopen.
+  /// Creates a dynamic library holding all global symbols.
+  ///
+  /// Any symbol in a library currently loaded with global visibility (including
+  /// the executable itself) may be resolved in this library.
+  ///
+  /// This feature is not available on Windows, instead an exception is thrown.
+  external factory DynamicLibrary.process();
+
+  /// Creates a dynamic library representing the running executable.
+  external factory DynamicLibrary.executable();
+
+  /// Loads a dynamic library file with local visibility.
   ///
   /// Throws an [ArgumentError] if loading the dynamic library fails.
-  ///
-  /// Note that it loads the functions in the library lazily (RTLD_LAZY).
   external factory DynamicLibrary.open(String name);
 
   /// Looks up a symbol in the [DynamicLibrary] and returns its address in
diff --git a/sdk/lib/ffi/native_type.dart b/sdk/lib/ffi/native_type.dart
index 61f9cde..bd88b28 100644
--- a/sdk/lib/ffi/native_type.dart
+++ b/sdk/lib/ffi/native_type.dart
@@ -8,7 +8,7 @@
 ///
 /// [NativeType]'s subtypes are not constructible in the Dart code and serve
 /// purely as markers in type signatures.
-class NativeType {
+abstract class NativeType {
   const NativeType();
 }
 
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 0752d4e6..0736e06 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -13273,28 +13273,28 @@
 
   final Element offsetParent;
 
-  int get offsetHeight => JS('num', '#.offsetHeight', this).round();
+  int get offsetHeight => JS<num>('num', '#.offsetHeight', this).round();
 
-  int get offsetLeft => JS('num', '#.offsetLeft', this).round();
+  int get offsetLeft => JS<num>('num', '#.offsetLeft', this).round();
 
-  int get offsetTop => JS('num', '#.offsetTop', this).round();
+  int get offsetTop => JS<num>('num', '#.offsetTop', this).round();
 
-  int get offsetWidth => JS('num', '#.offsetWidth', this).round();
+  int get offsetWidth => JS<num>('num', '#.offsetWidth', this).round();
 
-  int get scrollHeight => JS('num', '#.scrollHeight', this).round();
-  int get scrollLeft => JS('num', '#.scrollLeft', this).round();
+  int get scrollHeight => JS<num>('num', '#.scrollHeight', this).round();
+  int get scrollLeft => JS<num>('num', '#.scrollLeft', this).round();
 
   set scrollLeft(int value) {
     JS("void", "#.scrollLeft = #", this, value.round());
   }
 
-  int get scrollTop => JS('num', '#.scrollTop', this).round();
+  int get scrollTop => JS<num>('num', '#.scrollTop', this).round();
 
   set scrollTop(int value) {
     JS("void", "#.scrollTop = #", this, value.round());
   }
 
-  int get scrollWidth => JS('num', '#.scrollWidth', this).round();
+  int get scrollWidth => JS<num>('num', '#.scrollWidth', this).round();
 
   // To suppress missing implicit constructor warnings.
   factory Element._() {
@@ -17194,13 +17194,11 @@
   * and prints its length:
   *
   *     var path = 'myData.json';
-  *     HttpRequest.getString(path)
-  *         .then((String fileContents) {
-  *           print(fileContents.length);
-  *         })
-  *         .catchError((Error error) {
-  *           print(error.toString());
-  *         });
+  *     HttpRequest.getString(path).then((String fileContents) {
+  *       print(fileContents.length);
+  *     }).catchError((error) {
+  *       print(error.toString());
+  *     });
   *
   * ## Fetching data from other servers
   *
@@ -17718,7 +17716,7 @@
   final int status;
 
   /**
-   * The request response string (such as \"200 OK\").
+   * The request response string (such as \"OK\").
    * See also: [HTTP Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
    */
   final String statusText;
@@ -28848,14 +28846,14 @@
 
 // As of Chrome 37, these all changed from long to double.  This code
 // preserves backwards compatibility for the time being.
-  int get __clientX => JS('num', '#.clientX', this).round();
-  int get __clientY => JS('num', '#.clientY', this).round();
-  int get __screenX => JS('num', '#.screenX', this).round();
-  int get __screenY => JS('num', '#.screenY', this).round();
-  int get __pageX => JS('num', '#.pageX', this).round();
-  int get __pageY => JS('num', '#.pageY', this).round();
-  int get __radiusX => JS('num', '#.radiusX', this).round();
-  int get __radiusY => JS('num', '#.radiusY', this).round();
+  int get __clientX => JS<num>('num', '#.clientX', this).round();
+  int get __clientY => JS<num>('num', '#.clientY', this).round();
+  int get __screenX => JS<num>('num', '#.screenX', this).round();
+  int get __screenY => JS<num>('num', '#.screenY', this).round();
+  int get __pageX => JS<num>('num', '#.pageX', this).round();
+  int get __pageY => JS<num>('num', '#.pageY', this).round();
+  int get __radiusX => JS<num>('num', '#.radiusX', this).round();
+  int get __radiusY => JS<num>('num', '#.radiusY', this).round();
 
   Point get client => new Point(__clientX, __clientY);
 
@@ -30617,8 +30615,11 @@
   void _cancelAnimationFrame(int id) native;
 
   _ensureRequestAnimationFrame() {
-    if (JS('bool', '!!(#.requestAnimationFrame && #.cancelAnimationFrame)',
-        this, this)) return;
+    if (JS<bool>(
+        'bool',
+        '!!(#.requestAnimationFrame && #.cancelAnimationFrame)',
+        this,
+        this)) return;
 
     JS(
         'void',
@@ -32110,9 +32111,9 @@
     return db;
   }
 
-  int get pageXOffset => JS('num', '#.pageXOffset', this).round();
+  int get pageXOffset => JS<num>('num', '#.pageXOffset', this).round();
 
-  int get pageYOffset => JS('num', '#.pageYOffset', this).round();
+  int get pageYOffset => JS<num>('num', '#.pageYOffset', this).round();
 
   /**
    * The distance this window has been scrolled horizontally.
@@ -32124,8 +32125,8 @@
    * * [scrollX](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX)
    *   from MDN.
    */
-  int get scrollX => JS('bool', '("scrollX" in #)', this)
-      ? JS('num', '#.scrollX', this).round()
+  int get scrollX => JS<bool>('bool', '("scrollX" in #)', this)
+      ? JS<num>('num', '#.scrollX', this).round()
       : document.documentElement.scrollLeft;
 
   /**
@@ -32138,8 +32139,8 @@
    * * [scrollY](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY)
    *   from MDN.
    */
-  int get scrollY => JS('bool', '("scrollY" in #)', this)
-      ? JS('num', '#.scrollY', this).round()
+  int get scrollY => JS<bool>('bool', '("scrollY" in #)', this)
+      ? JS<num>('num', '#.scrollY', this).round()
       : document.documentElement.scrollTop;
 }
 
@@ -32154,7 +32155,7 @@
     _returnValue = value;
     // FF and IE use the value as the return value, Chrome will return this from
     // the event callback function.
-    if (JS('bool', '("returnValue" in #)', wrapped)) {
+    if (JS<bool>('bool', '("returnValue" in #)', wrapped)) {
       JS('void', '#.returnValue = #', wrapped, value);
     }
   }
diff --git a/sdk/lib/html/html_common/conversions.dart b/sdk/lib/html/html_common/conversions.dart
index f2373b5..a563c05 100644
--- a/sdk/lib/html/html_common/conversions.dart
+++ b/sdk/lib/html/html_common/conversions.dart
@@ -237,9 +237,9 @@
     }
 
     if (isJavaScriptArray(e)) {
-      var l = JS('returns:List;creates:;', '#', e);
+      var l = JS<List>('returns:List;creates:;', '#', e);
       var slot = findSlot(l);
-      var copy = JS('returns:List|Null;creates:;', '#', readSlot(slot));
+      var copy = JS<List>('returns:List|Null;creates:;', '#', readSlot(slot));
       if (copy != null) return copy;
 
       int length = l.length;
diff --git a/tests/co19_2/co19_2-dart2js.status b/tests/co19_2/co19_2-dart2js.status
index 387bd0e..4434d09 100644
--- a/tests/co19_2/co19_2-dart2js.status
+++ b/tests/co19_2/co19_2-dart2js.status
@@ -2,9 +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.
 
-[ $compiler == dartdevc ]
-LanguageFeatures/Extension-methods/*: SkipByDesign # Analyzer DDC is expected to be turned down before releasing extension methods.
-
 [ $compiler == dart2js && $runtime == d8 ]
 LayoutTests/*: SkipByDesign # d8 is not a browser
 LibTest/html/*: SkipByDesign # d8 is not a browser
@@ -37,322 +34,3 @@
 LibTest/io/*: SkipByDesign # dart:io not supported.
 LibTest/isolate/*: SkipByDesign # dart:isolate not supported.
 WebPlatformTest/*: Skip # These tests are going to be removed.
-
-[ $compiler == dartdevc || $compiler == dartdevk ]
-Language/Classes/Constructors/Generative_Constructors/formal_parameter_t07: Skip # Times out
-Language/Classes/Constructors/Generative_Constructors/fresh_instance_t01: Skip # Times out
-Language/Classes/Constructors/Generative_Constructors/implicit_superinitializer_t01: Skip # Times out
-Language/Classes/Constructors/Generative_Constructors/implicit_superinitializer_t02: Skip # Times out
-Language/Classes/Constructors/Generative_Constructors/initializers_t01: Skip # Times out
-Language/Classes/Constructors/Generative_Constructors/initializers_t15: Skip # Times out
-Language/Classes/Constructors/Generative_Constructors/initializing_formals_execution_t01: Skip # Times out
-Language/Classes/Constructors/Generative_Constructors/initializing_this_t01: Skip # Times out
-Language/Classes/Constructors/Generative_Constructors/redirection_t01: Skip # Times out
-Language/Classes/Constructors/Generative_Constructors/syntax_t01: Skip # Times out
-Language/Classes/Constructors/implicit_constructor_t01: Skip # Times out
-Language/Classes/Constructors/implicit_constructor_t02: Skip # Times out
-Language/Classes/Constructors/name_t01: Skip # Times out
-Language/Classes/Constructors/name_t02: Skip # Times out
-Language/Classes/Constructors/name_t03: Skip # Times out
-Language/Classes/Getters/instance_getter_t01: Skip # Times out
-Language/Classes/Getters/instance_getter_t02: Skip # Times out
-Language/Classes/Getters/instance_getter_t03: Skip # Times out
-Language/Classes/Getters/instance_getter_t04: Skip # Times out
-Language/Classes/Getters/instance_getter_t05: Skip # Times out
-Language/Classes/Getters/instance_getter_t06: Skip # Times out
-Language/Classes/Getters/override_t04: Skip # Times out
-Language/Classes/Getters/return_type_t01: Skip # Times out
-Language/Classes/Getters/static_t01/none: Skip # Times out
-Language/Classes/Getters/static_t02: Skip # Times out
-Language/Classes/Getters/syntax_t01: Skip # Times out
-Language/Classes/Getters/void_return_type_t01: Skip # Times out
-Language/Classes/Instance_Methods/Operators/allowed_names_t01: Skip # Times out
-Language/Classes/Instance_Methods/Operators/arity_0_or_1_t01: Skip # Times out
-Language/Classes/Instance_Methods/Operators/arity_0_t01: Skip # Times out
-Language/Classes/Instance_Methods/Operators/syntax_t01: Skip # Times out
-Language/Classes/Instance_Methods/Operators/syntax_t03: Skip # Times out
-Language/Classes/Instance_Methods/override_named_parameters_t03: Skip # Times out
-Language/Classes/Instance_Methods/override_named_parameters_t04: Skip # Times out
-Language/Classes/Instance_Methods/override_named_parameters_t06: Skip # Times out
-Language/Classes/Instance_Methods/override_subtype_t05: Skip # Times out
-Language/Classes/Instance_Methods/override_subtype_t06: Skip # Times out
-Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t01: Skip # Times out
-Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t02: Skip # Times out
-Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t04: Skip # Times out
-Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t05: Skip # Times out
-Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t06: Skip # Times out
-Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t07: Skip # Times out
-Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t08: Skip # Times out
-Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t09: Skip # Times out
-Language/Classes/Instance_Variables/definition_t01: Skip # Times out
-Language/Classes/Instance_Variables/definition_t02: Skip # Times out
-Language/Classes/Instance_Variables/definition_t04: Skip # Times out
-Language/Classes/Setters/instance_setter_t01: Skip # Times out
-Language/Expressions/Function_Invocation/async_generator_invokation_t08: Skip # Times out
-Language/Expressions/Function_Invocation/async_generator_invokation_t10: Skip # Times out
-Language/Types/Interface_Types/subtype_t27: Skip # Times out
-Language/Types/Interface_Types/subtype_t28: Skip # Times out
-LayoutTests/fast/backgrounds/001_t01: Skip # Times out
-LayoutTests/fast/backgrounds/animated-gif-as-background_t01: Skip # Times out
-LayoutTests/fast/backgrounds/multiple-backgrounds-assert_t01: Skip # Times out
-LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.gradient_t01: Skip # Times out
-LayoutTests/fast/canvas/DrawImageSinglePixelStretch_t01: Skip # Times out
-LayoutTests/fast/canvas/canvas-before-css_t01: Skip # Times out
-LayoutTests/fast/canvas/canvas-composite-alpha_t01: Skip # Times out
-LayoutTests/fast/canvas/canvas-composite-canvas_t01: Skip # Times out
-LayoutTests/fast/canvas/canvas-composite-image_t01: Skip # Times out
-LayoutTests/fast/canvas/canvas-composite-stroke-alpha_t01: Skip # Times out
-LayoutTests/fast/canvas/canvas-composite-text-alpha_t01: Skip # Times out
-LayoutTests/fast/canvas/canvas-css-crazy_t01: Skip # Times out
-LayoutTests/fast/canvas/canvas-imageSmoothingEnabled-repaint_t01: Skip # Times out
-LayoutTests/fast/canvas/drawImage-with-valid-image_t01: Skip # Times out
-LayoutTests/fast/canvas/webgl/canvas-resize-crash_t01: Skip # Times out
-LayoutTests/fast/canvas/webgl/gl-teximage_t01: Skip # Times out
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgb565_t01: Skip # Times out
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba4444_t01: Skip # Times out
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba5551_t01: Skip # Times out
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image_t01: Skip # Times out
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgb565_t01: Skip # Times out
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba4444_t01: Skip # Times out
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba5551_t01: Skip # Times out
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video_t01: Skip # Times out
-LayoutTests/fast/canvas/webgl/texture-color-profile_t01: Skip # Times out
-LayoutTests/fast/canvas/webgl/texture-transparent-pixels-initialized_t01: Skip # Times out
-LayoutTests/fast/css-generated-content/bug91547_t01: Skip # Times out
-LayoutTests/fast/css-generated-content/inline-splitting-with-after-float-crash_t01: Skip # Times out
-LayoutTests/fast/css-generated-content/pseudo-animation-before-onload_t01: Skip # Times out
-LayoutTests/fast/css-generated-content/pseudo-animation-display_t01: Skip # Times out
-LayoutTests/fast/css-generated-content/pseudo-animation_t01: Skip # Times out
-LayoutTests/fast/css-generated-content/pseudo-element-events_t01: Skip # Times out
-LayoutTests/fast/css-generated-content/pseudo-transition-event_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/auto-content-resolution-rows_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/breadth-size-resolution-grid_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/calc-resolution-grid-item_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/display-grid-set-get_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/flex-and-minmax-content-resolution-rows_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/flex-content-resolution-columns_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/flex-content-resolution-rows_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/grid-auto-columns-rows-get-set_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/grid-auto-flow-get-set_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/grid-auto-flow-update_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/grid-container-change-explicit-grid-recompute-child_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/grid-element-bad-cast-addchild_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/grid-element-border-grid-item_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/grid-element-border-padding-grid-item_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/grid-element-empty-row-column_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/grid-element-min-max-height_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/grid-element-padding-grid-item_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/grid-element-padding-margin_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/grid-element-remove-svg-child_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/grid-element-shrink-to-fit_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/grid-item-area-get-set_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/grid-item-bad-named-area-auto-placement_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/grid-item-bad-resolution-double-span_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/grid-item-change-order-auto-flow_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/grid-item-display_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows-horiz-bt_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows-vert-lr_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows-vert-rl_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/grid-item-margin-resolution_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/grid-item-order-auto-flow-resolution_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/grid-strict-ordering-crash_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/grid-template-areas-get-set_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/implicit-rows-auto-resolution_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/justify-self-cell_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/minmax-fixed-logical-height-only_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/minmax-fixed-logical-width-only_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track-in-percent-grid_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track-update_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/percent-padding-margin-resolution-grid-item-update_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/percent-padding-margin-resolution-grid-item_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/percent-resolution-grid-item_t01: Skip # Times out
-LayoutTests/fast/css-grid-layout/place-cell-by-index_t01: Skip # Times out
-LayoutTests/fast/css-intrinsic-dimensions/css-tables_t01: Skip # Times out
-LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-absolutes_t01: Skip # Times out
-LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-blocks_t01: Skip # Times out
-LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-column-flex-items_t01: Skip # Times out
-LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-flex-items_t01: Skip # Times out
-LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-replaced-absolutes_t01: Skip # Times out
-LayoutTests/fast/css-intrinsic-dimensions/tables_t01: Skip # Times out
-LayoutTests/fast/css-intrinsic-dimensions/width-shrinks-avoid-floats_t01: Skip # Times out
-LayoutTests/fast/css/cached-sheet-restore-crash_t01: Skip # Times out
-LayoutTests/fast/css/comment-before-charset-external_t01: Skip # Times out
-LayoutTests/fast/css/comment-before-charset_t01: Skip # Times out
-LayoutTests/fast/css/counters/asterisk-counter-update-after-layout-crash_t01: Skip # Times out
-LayoutTests/fast/css/counters/complex-before_t01: Skip # Times out
-LayoutTests/fast/css/counters/counter-before-selector-crash_t01: Skip # Times out
-LayoutTests/fast/css/counters/counter-reparent-table-children-crash_t01: Skip # Times out
-LayoutTests/fast/css/counters/counter-reset-subtree-insert-crash_t01: Skip # Times out
-LayoutTests/fast/css/counters/counter-ruby-text-cleared_t01: Skip # Times out
-LayoutTests/fast/css/counters/counter-traverse-object-crash_t01: Skip # Times out
-LayoutTests/fast/css/font-face-svg-decoding-error_t01: Skip # Times out
-LayoutTests/fast/css/font-face-unicode-range-overlap-load_t01: Skip # Times out
-LayoutTests/fast/css/implicit-attach-marking_t01: Skip # Times out
-LayoutTests/fast/css/link-alternate-stylesheet-1_t01: Skip # Times out
-LayoutTests/fast/css/link-alternate-stylesheet-2_t01: Skip # Times out
-LayoutTests/fast/css/link-alternate-stylesheet-3_t01: Skip # Times out
-LayoutTests/fast/css/link-alternate-stylesheet-4_t01: Skip # Times out
-LayoutTests/fast/css/link-alternate-stylesheet-5_t01: Skip # Times out
-LayoutTests/fast/css/link-disabled-attr-parser_t01: Skip # Times out
-LayoutTests/fast/css/nested-at-rules_t01: Skip # Times out
-LayoutTests/fast/css/percent-min-width-img-src-change_t01: Skip # Times out
-LayoutTests/fast/css/percent-width-img-src-change_t01: Skip # Times out
-LayoutTests/fast/css/pseudo-target-indirect-sibling-001_t01: Skip # Times out
-LayoutTests/fast/css/pseudo-target-indirect-sibling-002_t01: Skip # Times out
-LayoutTests/fast/css/remove-fixed-resizer-crash_t01: Skip # Times out
-LayoutTests/fast/css/sheet-collection-link_t01: Skip # Times out
-LayoutTests/fast/css/sheet-title_t01: Skip # Times out
-LayoutTests/fast/css/space-before-charset-external_t01: Skip # Times out
-LayoutTests/fast/css/space-before-charset_t01: Skip # Times out
-LayoutTests/fast/css/sticky/remove-inline-sticky-crash_t01: Skip # Times out
-LayoutTests/fast/css/sticky/remove-sticky-crash_t01: Skip # Times out
-LayoutTests/fast/css/sticky/sticky-table-col-crash_t01: Skip # Times out
-LayoutTests/fast/css/style-element-process-crash_t01: Skip # Times out
-LayoutTests/fast/css/stylesheet-enable-first-alternate-link_t01: Skip # Times out
-LayoutTests/fast/css/stylesheet-enable-first-alternate-on-load-link_t01: Skip # Times out
-LayoutTests/fast/css/stylesheet-enable-first-alternate-on-load-sheet_t01: Skip # Times out
-LayoutTests/fast/css/stylesheet-enable-second-alternate-link_t01: Skip # Times out
-LayoutTests/fast/css/stylesheet-parentStyleSheet_t01: Skip # Times out
-LayoutTests/fast/css/webkit-keyframes-crash_t01: Skip # Times out
-LayoutTests/fast/css/webkit-marquee-speed-unit-in-quirksmode_t01: Skip # Times out
-LayoutTests/fast/dom/HTMLDocument/active-element-gets-unforcusable_t01: Skip # Times out
-LayoutTests/fast/dom/HTMLDocument/set-focus-on-valid-element_t01: Skip # Times out
-LayoutTests/fast/dom/HTMLImageElement/image-loading-gc_t01: Skip # Times out
-LayoutTests/fast/dom/HTMLImageElement/image-natural-width-height_t01: Skip # Times out
-LayoutTests/fast/dom/HTMLLinkElement/link-and-subresource-test_t01: Skip # Times out
-LayoutTests/fast/dom/HTMLLinkElement/link-beforeload-recursive_t01: Skip # Times out
-LayoutTests/fast/dom/HTMLLinkElement/link-onload-before-page-load_t01: Skip # Times out
-LayoutTests/fast/dom/HTMLLinkElement/link-onload2_t01: Skip # Times out
-LayoutTests/fast/dom/HTMLLinkElement/onload-completion-test_t01: Skip # Times out
-LayoutTests/fast/dom/HTMLLinkElement/prefetch-onload_t01: Skip # Times out
-LayoutTests/fast/dom/HTMLLinkElement/prefetch_t01: Skip # Times out
-LayoutTests/fast/dom/HTMLObjectElement/beforeload-set-text-crash_t01: Skip # Times out
-LayoutTests/fast/dom/HTMLObjectElement/set-type-to-null-crash_t01: Skip # Times out
-LayoutTests/fast/dom/HTMLScriptElement/async-false-inside-async-false-load_t01: Skip # Times out
-LayoutTests/fast/dom/HTMLScriptElement/async-onbeforeload_t01: Skip # Times out
-LayoutTests/fast/dom/HTMLScriptElement/defer-onbeforeload_t01: Skip # Times out
-LayoutTests/fast/dom/HTMLScriptElement/defer-script-invalid-url_t01: Skip # Times out
-LayoutTests/fast/dom/HTMLScriptElement/dont-load-unknown-type_t01: Skip # Times out
-LayoutTests/fast/dom/HTMLScriptElement/remove-in-beforeload_t01: Skip # Times out
-LayoutTests/fast/dom/HTMLScriptElement/remove-source_t01: Skip # Times out
-LayoutTests/fast/dom/HTMLScriptElement/script-for-attribute-unexpected-execution_t01: Skip # Times out
-LayoutTests/fast/dom/HTMLScriptElement/script-load-events_t01: Skip # Times out
-LayoutTests/fast/dom/HTMLScriptElement/script-reexecution_t01: Skip # Times out
-LayoutTests/fast/dom/HTMLScriptElement/script-set-src_t01: Skip # Times out
-LayoutTests/fast/dom/HTMLStyleElement/style-onload-before-page-load_t01: Skip # Times out
-LayoutTests/fast/dom/HTMLTemplateElement/innerHTML-inert_t01: Skip # Times out
-LayoutTests/fast/dom/SelectorAPI/bug-17313_t01: Skip # Times out
-LayoutTests/fast/dom/StyleSheet/detached-style-2_t01: Skip # Times out
-LayoutTests/fast/dom/StyleSheet/detached-style_t01: Skip # Times out
-LayoutTests/fast/dom/StyleSheet/discarded-sheet-owner-null_t01: Skip # Times out
-LayoutTests/fast/dom/css-cached-import-rule_t01: Skip # Times out
-LayoutTests/fast/dom/css-insert-import-rule-twice_t01: Skip # Times out
-LayoutTests/fast/dom/css-insert-import-rule_t01: Skip # Times out
-LayoutTests/fast/dom/css-mediarule-deleteRule-update_t01: Skip # Times out
-LayoutTests/fast/dom/css-mediarule-insertRule-update_t01: Skip # Times out
-LayoutTests/fast/dom/domtimestamp-is-number_t01: Skip # Times out
-LayoutTests/fast/dom/empty-hash-and-search_t01: Skip # Times out
-LayoutTests/fast/dom/gc-image-element-2_t01: Skip # Times out
-LayoutTests/fast/dom/gc-image-element_t01: Skip # Times out
-LayoutTests/fast/dom/horizontal-scrollbar-in-rtl_t01: Skip # Times out
-LayoutTests/fast/dom/horizontal-scrollbar-when-dir-change_t01: Skip # Times out
-LayoutTests/fast/dom/icon-url-change_t01: Skip # Times out
-LayoutTests/fast/dom/icon-url-list_t01: Skip # Times out
-LayoutTests/fast/dom/id-attribute-with-namespace-crash_t01: Skip # Times out
-LayoutTests/fast/dom/image-object_t01: Skip # Times out
-LayoutTests/fast/dom/inner-text_t01: Skip # Times out
-LayoutTests/fast/dom/shadow/insertion-point-list-menu-crash_t01: Skip # Times out
-LayoutTests/fast/dom/shadow/insertion-point-video-crash_t01: Skip # Times out
-LayoutTests/fast/dom/shadow/link-in-shadow-tree_t01: Skip # Times out
-LayoutTests/fast/dom/shadow/no-renderers-for-light-children_t01: Skip # Times out
-LayoutTests/fast/dom/text-node-attach-crash_t01: Skip # Times out
-LayoutTests/fast/dom/vertical-scrollbar-when-dir-change_t01: Skip # Times out
-LayoutTests/fast/dynamic/continuation-detach-crash_t01: Skip # Times out
-LayoutTests/fast/events/change-overflow-on-overflow-change_t01: Skip # Times out
-LayoutTests/fast/events/clipboard-clearData_t01: Skip # Times out
-LayoutTests/fast/events/clipboard-dataTransferItemList_t01: Skip # Times out
-LayoutTests/fast/events/dispatch-event-being-dispatched_t01: Skip # Times out
-LayoutTests/fast/events/document-elementFromPoint_t01: Skip # Times out
-LayoutTests/fast/events/nested-event-remove-node-crash_t01: Skip # Times out
-LayoutTests/fast/events/no-window-load_t01: Skip # Times out
-LayoutTests/fast/events/overflowchanged-event-raf-timing_t01: Skip # Times out
-LayoutTests/fast/events/tabindex-removal-from-focused-element_t01: Skip # Times out
-LayoutTests/fast/events/window-load-capture_t01: Skip # Times out
-LayoutTests/fast/flexbox/crash-flexbox-no-layout-child_t01: Skip # Times out
-LayoutTests/fast/flexbox/layoutHorizontalBox-crash_t01: Skip # Times out
-LayoutTests/fast/flexbox/overhanging-floats-not-removed-crash_t01: Skip # Times out
-LayoutTests/fast/forms/HTMLOptionElement_selected_t01: Skip # Times out
-LayoutTests/fast/forms/activate-and-disabled-elements_t01: Skip # Times out
-LayoutTests/fast/forms/autofocus-focus-only-once_t01: Skip # Times out
-LayoutTests/fast/forms/autofocus-input-css-style-change_t01: Skip # Times out
-LayoutTests/fast/forms/autofocus-opera-007_t01: Skip # Times out
-LayoutTests/fast/forms/autofocus-readonly-attribute_t01: Skip # Times out
-LayoutTests/fast/forms/button/button-disabled-blur_t01: Skip # Times out
-LayoutTests/fast/forms/focus-style-pending_t01: Skip # Times out
-LayoutTests/fast/forms/form-added-to-table_t01: Skip # Times out
-LayoutTests/fast/forms/input-type-change_t01: Skip # Times out
-LayoutTests/fast/forms/input-width-height-attributes-without-renderer-loaded-image_t01: Skip # Times out
-LayoutTests/fast/forms/input-width-height-attributes-without-renderer_t01: Skip # Times out
-LayoutTests/fast/forms/search-popup-crasher_t01: Skip # Times out
-LayoutTests/fast/forms/select-change-popup-to-listbox-in-event-handler_t01: Skip # Times out
-LayoutTests/fast/forms/select-generated-content_t01: Skip # Times out
-LayoutTests/fast/forms/textarea-placeholder-relayout-assertion_t01: Skip # Times out
-LayoutTests/fast/forms/textarea-scrollbar-height_t01: Skip # Times out
-LayoutTests/fast/forms/textfield-focus-out_t01: Skip # Times out
-LayoutTests/fast/html/imports/import-element-removed-flag_t01: Skip # Times out
-LayoutTests/fast/loader/about-blank-hash-change_t01: Skip # Times out
-LayoutTests/fast/loader/about-blank-hash-kept_t01: Skip # Times out
-LayoutTests/fast/loader/hashchange-event-async_t01: Skip # Times out
-LayoutTests/fast/loader/hashchange-event-properties_t01: Skip # Times out
-LayoutTests/fast/loader/local-css-allowed-in-strict-mode_t01: Skip # Times out
-LayoutTests/fast/loader/onhashchange-attribute-listeners_t01: Skip # Times out
-LayoutTests/fast/loader/onload-policy-ignore-for-frame_t01: Skip # Times out
-LayoutTests/fast/loader/scroll-position-restored-on-back_t01: Skip # Times out
-LayoutTests/fast/loader/scroll-position-restored-on-reload-at-load-event_t01: Skip # Times out
-LayoutTests/fast/overflow/scroll-vertical-not-horizontal_t01: Skip # Times out
-LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-anonymous-table-cell_t01: Skip # Times out
-LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-table-cell-ignore-height_t01: Skip # Times out
-LayoutTests/fast/replaced/table-percent-height-text-controls_t01: Skip # Times out
-LayoutTests/fast/replaced/table-percent-height_t01: Skip # Times out
-LayoutTests/fast/replaced/table-percent-width_t01: Skip # Times out
-LayoutTests/fast/replaced/table-replaced-element_t01: Skip # Times out
-LayoutTests/fast/speechsynthesis/speech-synthesis-boundary-events_t01: Skip # Times out
-LayoutTests/fast/speechsynthesis/speech-synthesis-speak_t01: Skip # Times out
-LayoutTests/fast/sub-pixel/float-list-inside_t01: Skip # Times out
-LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t03: Skip # Times out
-LibTest/html/Element/blur_A01_t01: Skip # Times out
-LibTest/html/Element/focus_A01_t01: Skip # Times out
-LibTest/html/Element/loadEvent_A01_t01: Skip # Times out
-LibTest/html/Element/mouseWheelEvent_A01_t01: Skip # Times out
-LibTest/html/Element/onLoad_A01_t01: Skip # Times out
-LibTest/html/Element/onMouseWheel_A01_t01: Skip # Times out
-LibTest/html/Element/onTransitionEnd_A01_t01: Skip # Times out
-LibTest/html/Element/transitionEndEvent_A01_t01: Skip # Times out
-LibTest/html/HttpRequest/onError_A01_t02: Skip # Times out
-LibTest/html/HttpRequest/responseText_A01_t02: Skip # Times out
-LibTest/html/HttpRequestUpload/onError_A01_t02: Skip # Times out
-LibTest/html/HttpRequestUpload/onLoadEnd_A01_t01: Skip # Times out
-LibTest/html/HttpRequestUpload/onLoadStart_A01_t01: Skip # Times out
-LibTest/html/HttpRequestUpload/onLoad_A01_t01: Skip # Times out
-LibTest/html/IFrameElement/blur_A01_t01: Skip # Times out
-LibTest/html/IFrameElement/enteredView_A01_t01: Skip # Times out
-LibTest/html/IFrameElement/focus_A01_t01: Skip # Times out
-LibTest/html/IFrameElement/onMouseWheel_A01_t01: Skip # Times out
-LibTest/html/IFrameElement/onTransitionEnd_A01_t01: Skip # Times out
-WebPlatformTest/DOMEvents/approved/ProcessingInstruction.DOMCharacterDataModified_t01: Skip # Times out
-WebPlatformTest/Utils/test/asyncTestTimeout_t01: Skip # Times out
-WebPlatformTest/dom/nodes/Node-isEqualNode_t01: Skip # Times out
-WebPlatformTest/html/semantics/embedded-content/media-elements/error-codes/error_t01: Skip # Times out
-WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/cues_t01: Skip # Times out
-WebPlatformTest/webstorage/event_local_key_t01: Skip # Times out
-WebPlatformTest/webstorage/event_local_newvalue_t01: Skip # Times out
-WebPlatformTest/webstorage/event_local_oldvalue_t01: Skip # Times out
-WebPlatformTest/webstorage/event_local_storagearea_t01: Skip # Times out
-WebPlatformTest/webstorage/event_local_url_t01: Skip # Times out
-WebPlatformTest/webstorage/event_session_key_t01: Skip # Times out
-WebPlatformTest/webstorage/event_session_newvalue_t01: Skip # Times out
-WebPlatformTest/webstorage/event_session_oldvalue_t01: Skip # Times out
-WebPlatformTest/webstorage/event_session_storagearea_t01: Skip # Times out
-WebPlatformTest/webstorage/event_session_url_t01: Skip # Times out
diff --git a/tests/co19_2/co19_2-dartdevc.status b/tests/co19_2/co19_2-dartdevc.status
new file mode 100644
index 0000000..2219172
--- /dev/null
+++ b/tests/co19_2/co19_2-dartdevc.status
@@ -0,0 +1,325 @@
+# 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.
+
+[ $compiler == dartdevc ]
+LanguageFeatures/Extension-methods/*: SkipByDesign # Analyzer DDC is expected to be turned down before releasing extension methods.
+
+[ $compiler == dartdevc || $compiler == dartdevk ]
+Language/Classes/Constructors/Generative_Constructors/formal_parameter_t07: Skip # Times out
+Language/Classes/Constructors/Generative_Constructors/fresh_instance_t01: Skip # Times out
+Language/Classes/Constructors/Generative_Constructors/implicit_superinitializer_t01: Skip # Times out
+Language/Classes/Constructors/Generative_Constructors/implicit_superinitializer_t02: Skip # Times out
+Language/Classes/Constructors/Generative_Constructors/initializers_t01: Skip # Times out
+Language/Classes/Constructors/Generative_Constructors/initializers_t15: Skip # Times out
+Language/Classes/Constructors/Generative_Constructors/initializing_formals_execution_t01: Skip # Times out
+Language/Classes/Constructors/Generative_Constructors/initializing_this_t01: Skip # Times out
+Language/Classes/Constructors/Generative_Constructors/redirection_t01: Skip # Times out
+Language/Classes/Constructors/Generative_Constructors/syntax_t01: Skip # Times out
+Language/Classes/Constructors/implicit_constructor_t01: Skip # Times out
+Language/Classes/Constructors/implicit_constructor_t02: Skip # Times out
+Language/Classes/Constructors/name_t01: Skip # Times out
+Language/Classes/Constructors/name_t02: Skip # Times out
+Language/Classes/Constructors/name_t03: Skip # Times out
+Language/Classes/Getters/instance_getter_t01: Skip # Times out
+Language/Classes/Getters/instance_getter_t02: Skip # Times out
+Language/Classes/Getters/instance_getter_t03: Skip # Times out
+Language/Classes/Getters/instance_getter_t04: Skip # Times out
+Language/Classes/Getters/instance_getter_t05: Skip # Times out
+Language/Classes/Getters/instance_getter_t06: Skip # Times out
+Language/Classes/Getters/override_t04: Skip # Times out
+Language/Classes/Getters/return_type_t01: Skip # Times out
+Language/Classes/Getters/static_t01/none: Skip # Times out
+Language/Classes/Getters/static_t02: Skip # Times out
+Language/Classes/Getters/syntax_t01: Skip # Times out
+Language/Classes/Getters/void_return_type_t01: Skip # Times out
+Language/Classes/Instance_Methods/Operators/allowed_names_t01: Skip # Times out
+Language/Classes/Instance_Methods/Operators/arity_0_or_1_t01: Skip # Times out
+Language/Classes/Instance_Methods/Operators/arity_0_t01: Skip # Times out
+Language/Classes/Instance_Methods/Operators/syntax_t01: Skip # Times out
+Language/Classes/Instance_Methods/Operators/syntax_t03: Skip # Times out
+Language/Classes/Instance_Methods/override_named_parameters_t03: Skip # Times out
+Language/Classes/Instance_Methods/override_named_parameters_t04: Skip # Times out
+Language/Classes/Instance_Methods/override_named_parameters_t06: Skip # Times out
+Language/Classes/Instance_Methods/override_subtype_t05: Skip # Times out
+Language/Classes/Instance_Methods/override_subtype_t06: Skip # Times out
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t01: Skip # Times out
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t02: Skip # Times out
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t04: Skip # Times out
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t05: Skip # Times out
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t06: Skip # Times out
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t07: Skip # Times out
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t08: Skip # Times out
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t09: Skip # Times out
+Language/Classes/Instance_Variables/definition_t01: Skip # Times out
+Language/Classes/Instance_Variables/definition_t02: Skip # Times out
+Language/Classes/Instance_Variables/definition_t04: Skip # Times out
+Language/Classes/Setters/instance_setter_t01: Skip # Times out
+Language/Expressions/Function_Invocation/async_generator_invokation_t08: Skip # Times out
+Language/Expressions/Function_Invocation/async_generator_invokation_t10: Skip # Times out
+Language/Types/Interface_Types/subtype_t27: Skip # Times out
+Language/Types/Interface_Types/subtype_t28: Skip # Times out
+LayoutTests/fast/backgrounds/001_t01: Skip # Times out
+LayoutTests/fast/backgrounds/animated-gif-as-background_t01: Skip # Times out
+LayoutTests/fast/backgrounds/multiple-backgrounds-assert_t01: Skip # Times out
+LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.gradient_t01: Skip # Times out
+LayoutTests/fast/canvas/DrawImageSinglePixelStretch_t01: Skip # Times out
+LayoutTests/fast/canvas/canvas-before-css_t01: Skip # Times out
+LayoutTests/fast/canvas/canvas-composite-alpha_t01: Skip # Times out
+LayoutTests/fast/canvas/canvas-composite-canvas_t01: Skip # Times out
+LayoutTests/fast/canvas/canvas-composite-image_t01: Skip # Times out
+LayoutTests/fast/canvas/canvas-composite-stroke-alpha_t01: Skip # Times out
+LayoutTests/fast/canvas/canvas-composite-text-alpha_t01: Skip # Times out
+LayoutTests/fast/canvas/canvas-css-crazy_t01: Skip # Times out
+LayoutTests/fast/canvas/canvas-imageSmoothingEnabled-repaint_t01: Skip # Times out
+LayoutTests/fast/canvas/drawImage-with-valid-image_t01: Skip # Times out
+LayoutTests/fast/canvas/webgl/canvas-resize-crash_t01: Skip # Times out
+LayoutTests/fast/canvas/webgl/gl-teximage_t01: Skip # Times out
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgb565_t01: Skip # Times out
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba4444_t01: Skip # Times out
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba5551_t01: Skip # Times out
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image_t01: Skip # Times out
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgb565_t01: Skip # Times out
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba4444_t01: Skip # Times out
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba5551_t01: Skip # Times out
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video_t01: Skip # Times out
+LayoutTests/fast/canvas/webgl/texture-color-profile_t01: Skip # Times out
+LayoutTests/fast/canvas/webgl/texture-transparent-pixels-initialized_t01: Skip # Times out
+LayoutTests/fast/css-generated-content/bug91547_t01: Skip # Times out
+LayoutTests/fast/css-generated-content/inline-splitting-with-after-float-crash_t01: Skip # Times out
+LayoutTests/fast/css-generated-content/pseudo-animation-before-onload_t01: Skip # Times out
+LayoutTests/fast/css-generated-content/pseudo-animation-display_t01: Skip # Times out
+LayoutTests/fast/css-generated-content/pseudo-animation_t01: Skip # Times out
+LayoutTests/fast/css-generated-content/pseudo-element-events_t01: Skip # Times out
+LayoutTests/fast/css-generated-content/pseudo-transition-event_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/auto-content-resolution-rows_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/breadth-size-resolution-grid_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/calc-resolution-grid-item_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/display-grid-set-get_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/flex-and-minmax-content-resolution-rows_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/flex-content-resolution-columns_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/flex-content-resolution-rows_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-auto-columns-rows-get-set_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-auto-flow-get-set_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-auto-flow-update_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-container-change-explicit-grid-recompute-child_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-element-bad-cast-addchild_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-element-border-grid-item_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-element-border-padding-grid-item_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-element-empty-row-column_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-element-min-max-height_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-element-padding-grid-item_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-element-padding-margin_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-element-remove-svg-child_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-element-shrink-to-fit_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-item-area-get-set_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-item-bad-named-area-auto-placement_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-item-bad-resolution-double-span_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-item-change-order-auto-flow_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-item-display_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows-horiz-bt_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows-vert-lr_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows-vert-rl_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-item-margin-resolution_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-item-order-auto-flow-resolution_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-strict-ordering-crash_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-template-areas-get-set_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/implicit-rows-auto-resolution_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/justify-self-cell_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/minmax-fixed-logical-height-only_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/minmax-fixed-logical-width-only_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track-in-percent-grid_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track-update_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/percent-padding-margin-resolution-grid-item-update_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/percent-padding-margin-resolution-grid-item_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/percent-resolution-grid-item_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/place-cell-by-index_t01: Skip # Times out
+LayoutTests/fast/css-intrinsic-dimensions/css-tables_t01: Skip # Times out
+LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-absolutes_t01: Skip # Times out
+LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-blocks_t01: Skip # Times out
+LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-column-flex-items_t01: Skip # Times out
+LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-flex-items_t01: Skip # Times out
+LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-replaced-absolutes_t01: Skip # Times out
+LayoutTests/fast/css-intrinsic-dimensions/tables_t01: Skip # Times out
+LayoutTests/fast/css-intrinsic-dimensions/width-shrinks-avoid-floats_t01: Skip # Times out
+LayoutTests/fast/css/cached-sheet-restore-crash_t01: Skip # Times out
+LayoutTests/fast/css/comment-before-charset-external_t01: Skip # Times out
+LayoutTests/fast/css/comment-before-charset_t01: Skip # Times out
+LayoutTests/fast/css/counters/asterisk-counter-update-after-layout-crash_t01: Skip # Times out
+LayoutTests/fast/css/counters/complex-before_t01: Skip # Times out
+LayoutTests/fast/css/counters/counter-before-selector-crash_t01: Skip # Times out
+LayoutTests/fast/css/counters/counter-reparent-table-children-crash_t01: Skip # Times out
+LayoutTests/fast/css/counters/counter-reset-subtree-insert-crash_t01: Skip # Times out
+LayoutTests/fast/css/counters/counter-ruby-text-cleared_t01: Skip # Times out
+LayoutTests/fast/css/counters/counter-traverse-object-crash_t01: Skip # Times out
+LayoutTests/fast/css/font-face-svg-decoding-error_t01: Skip # Times out
+LayoutTests/fast/css/font-face-unicode-range-overlap-load_t01: Skip # Times out
+LayoutTests/fast/css/implicit-attach-marking_t01: Skip # Times out
+LayoutTests/fast/css/link-alternate-stylesheet-1_t01: Skip # Times out
+LayoutTests/fast/css/link-alternate-stylesheet-2_t01: Skip # Times out
+LayoutTests/fast/css/link-alternate-stylesheet-3_t01: Skip # Times out
+LayoutTests/fast/css/link-alternate-stylesheet-4_t01: Skip # Times out
+LayoutTests/fast/css/link-alternate-stylesheet-5_t01: Skip # Times out
+LayoutTests/fast/css/link-disabled-attr-parser_t01: Skip # Times out
+LayoutTests/fast/css/nested-at-rules_t01: Skip # Times out
+LayoutTests/fast/css/percent-min-width-img-src-change_t01: Skip # Times out
+LayoutTests/fast/css/percent-width-img-src-change_t01: Skip # Times out
+LayoutTests/fast/css/pseudo-target-indirect-sibling-001_t01: Skip # Times out
+LayoutTests/fast/css/pseudo-target-indirect-sibling-002_t01: Skip # Times out
+LayoutTests/fast/css/remove-fixed-resizer-crash_t01: Skip # Times out
+LayoutTests/fast/css/sheet-collection-link_t01: Skip # Times out
+LayoutTests/fast/css/sheet-title_t01: Skip # Times out
+LayoutTests/fast/css/space-before-charset-external_t01: Skip # Times out
+LayoutTests/fast/css/space-before-charset_t01: Skip # Times out
+LayoutTests/fast/css/sticky/remove-inline-sticky-crash_t01: Skip # Times out
+LayoutTests/fast/css/sticky/remove-sticky-crash_t01: Skip # Times out
+LayoutTests/fast/css/sticky/sticky-table-col-crash_t01: Skip # Times out
+LayoutTests/fast/css/style-element-process-crash_t01: Skip # Times out
+LayoutTests/fast/css/stylesheet-enable-first-alternate-link_t01: Skip # Times out
+LayoutTests/fast/css/stylesheet-enable-first-alternate-on-load-link_t01: Skip # Times out
+LayoutTests/fast/css/stylesheet-enable-first-alternate-on-load-sheet_t01: Skip # Times out
+LayoutTests/fast/css/stylesheet-enable-second-alternate-link_t01: Skip # Times out
+LayoutTests/fast/css/stylesheet-parentStyleSheet_t01: Skip # Times out
+LayoutTests/fast/css/webkit-keyframes-crash_t01: Skip # Times out
+LayoutTests/fast/css/webkit-marquee-speed-unit-in-quirksmode_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLDocument/active-element-gets-unforcusable_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLDocument/set-focus-on-valid-element_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLImageElement/image-loading-gc_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLImageElement/image-natural-width-height_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLLinkElement/link-and-subresource-test_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLLinkElement/link-beforeload-recursive_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLLinkElement/link-onload-before-page-load_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLLinkElement/link-onload2_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLLinkElement/onload-completion-test_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLLinkElement/prefetch-onload_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLLinkElement/prefetch_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLObjectElement/beforeload-set-text-crash_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLObjectElement/set-type-to-null-crash_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLScriptElement/async-false-inside-async-false-load_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLScriptElement/async-onbeforeload_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLScriptElement/defer-onbeforeload_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLScriptElement/defer-script-invalid-url_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLScriptElement/dont-load-unknown-type_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLScriptElement/remove-in-beforeload_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLScriptElement/remove-source_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLScriptElement/script-for-attribute-unexpected-execution_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLScriptElement/script-load-events_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLScriptElement/script-reexecution_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLScriptElement/script-set-src_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLStyleElement/style-onload-before-page-load_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLTemplateElement/innerHTML-inert_t01: Skip # Times out
+LayoutTests/fast/dom/SelectorAPI/bug-17313_t01: Skip # Times out
+LayoutTests/fast/dom/StyleSheet/detached-style-2_t01: Skip # Times out
+LayoutTests/fast/dom/StyleSheet/detached-style_t01: Skip # Times out
+LayoutTests/fast/dom/StyleSheet/discarded-sheet-owner-null_t01: Skip # Times out
+LayoutTests/fast/dom/css-cached-import-rule_t01: Skip # Times out
+LayoutTests/fast/dom/css-insert-import-rule-twice_t01: Skip # Times out
+LayoutTests/fast/dom/css-insert-import-rule_t01: Skip # Times out
+LayoutTests/fast/dom/css-mediarule-deleteRule-update_t01: Skip # Times out
+LayoutTests/fast/dom/css-mediarule-insertRule-update_t01: Skip # Times out
+LayoutTests/fast/dom/domtimestamp-is-number_t01: Skip # Times out
+LayoutTests/fast/dom/empty-hash-and-search_t01: Skip # Times out
+LayoutTests/fast/dom/gc-image-element-2_t01: Skip # Times out
+LayoutTests/fast/dom/gc-image-element_t01: Skip # Times out
+LayoutTests/fast/dom/horizontal-scrollbar-in-rtl_t01: Skip # Times out
+LayoutTests/fast/dom/horizontal-scrollbar-when-dir-change_t01: Skip # Times out
+LayoutTests/fast/dom/icon-url-change_t01: Skip # Times out
+LayoutTests/fast/dom/icon-url-list_t01: Skip # Times out
+LayoutTests/fast/dom/id-attribute-with-namespace-crash_t01: Skip # Times out
+LayoutTests/fast/dom/image-object_t01: Skip # Times out
+LayoutTests/fast/dom/inner-text_t01: Skip # Times out
+LayoutTests/fast/dom/shadow/insertion-point-list-menu-crash_t01: Skip # Times out
+LayoutTests/fast/dom/shadow/insertion-point-video-crash_t01: Skip # Times out
+LayoutTests/fast/dom/shadow/link-in-shadow-tree_t01: Skip # Times out
+LayoutTests/fast/dom/shadow/no-renderers-for-light-children_t01: Skip # Times out
+LayoutTests/fast/dom/text-node-attach-crash_t01: Skip # Times out
+LayoutTests/fast/dom/vertical-scrollbar-when-dir-change_t01: Skip # Times out
+LayoutTests/fast/dynamic/continuation-detach-crash_t01: Skip # Times out
+LayoutTests/fast/events/change-overflow-on-overflow-change_t01: Skip # Times out
+LayoutTests/fast/events/clipboard-clearData_t01: Skip # Times out
+LayoutTests/fast/events/clipboard-dataTransferItemList_t01: Skip # Times out
+LayoutTests/fast/events/dispatch-event-being-dispatched_t01: Skip # Times out
+LayoutTests/fast/events/document-elementFromPoint_t01: Skip # Times out
+LayoutTests/fast/events/nested-event-remove-node-crash_t01: Skip # Times out
+LayoutTests/fast/events/no-window-load_t01: Skip # Times out
+LayoutTests/fast/events/overflowchanged-event-raf-timing_t01: Skip # Times out
+LayoutTests/fast/events/tabindex-removal-from-focused-element_t01: Skip # Times out
+LayoutTests/fast/events/window-load-capture_t01: Skip # Times out
+LayoutTests/fast/flexbox/crash-flexbox-no-layout-child_t01: Skip # Times out
+LayoutTests/fast/flexbox/layoutHorizontalBox-crash_t01: Skip # Times out
+LayoutTests/fast/flexbox/overhanging-floats-not-removed-crash_t01: Skip # Times out
+LayoutTests/fast/forms/HTMLOptionElement_selected_t01: Skip # Times out
+LayoutTests/fast/forms/activate-and-disabled-elements_t01: Skip # Times out
+LayoutTests/fast/forms/autofocus-focus-only-once_t01: Skip # Times out
+LayoutTests/fast/forms/autofocus-input-css-style-change_t01: Skip # Times out
+LayoutTests/fast/forms/autofocus-opera-007_t01: Skip # Times out
+LayoutTests/fast/forms/autofocus-readonly-attribute_t01: Skip # Times out
+LayoutTests/fast/forms/button/button-disabled-blur_t01: Skip # Times out
+LayoutTests/fast/forms/focus-style-pending_t01: Skip # Times out
+LayoutTests/fast/forms/form-added-to-table_t01: Skip # Times out
+LayoutTests/fast/forms/input-type-change_t01: Skip # Times out
+LayoutTests/fast/forms/input-width-height-attributes-without-renderer-loaded-image_t01: Skip # Times out
+LayoutTests/fast/forms/input-width-height-attributes-without-renderer_t01: Skip # Times out
+LayoutTests/fast/forms/search-popup-crasher_t01: Skip # Times out
+LayoutTests/fast/forms/select-change-popup-to-listbox-in-event-handler_t01: Skip # Times out
+LayoutTests/fast/forms/select-generated-content_t01: Skip # Times out
+LayoutTests/fast/forms/textarea-placeholder-relayout-assertion_t01: Skip # Times out
+LayoutTests/fast/forms/textarea-scrollbar-height_t01: Skip # Times out
+LayoutTests/fast/forms/textfield-focus-out_t01: Skip # Times out
+LayoutTests/fast/html/imports/import-element-removed-flag_t01: Skip # Times out
+LayoutTests/fast/loader/about-blank-hash-change_t01: Skip # Times out
+LayoutTests/fast/loader/about-blank-hash-kept_t01: Skip # Times out
+LayoutTests/fast/loader/hashchange-event-async_t01: Skip # Times out
+LayoutTests/fast/loader/hashchange-event-properties_t01: Skip # Times out
+LayoutTests/fast/loader/local-css-allowed-in-strict-mode_t01: Skip # Times out
+LayoutTests/fast/loader/onhashchange-attribute-listeners_t01: Skip # Times out
+LayoutTests/fast/loader/onload-policy-ignore-for-frame_t01: Skip # Times out
+LayoutTests/fast/loader/scroll-position-restored-on-back_t01: Skip # Times out
+LayoutTests/fast/loader/scroll-position-restored-on-reload-at-load-event_t01: Skip # Times out
+LayoutTests/fast/overflow/scroll-vertical-not-horizontal_t01: Skip # Times out
+LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-anonymous-table-cell_t01: Skip # Times out
+LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-table-cell-ignore-height_t01: Skip # Times out
+LayoutTests/fast/replaced/table-percent-height-text-controls_t01: Skip # Times out
+LayoutTests/fast/replaced/table-percent-height_t01: Skip # Times out
+LayoutTests/fast/replaced/table-percent-width_t01: Skip # Times out
+LayoutTests/fast/replaced/table-replaced-element_t01: Skip # Times out
+LayoutTests/fast/speechsynthesis/speech-synthesis-boundary-events_t01: Skip # Times out
+LayoutTests/fast/speechsynthesis/speech-synthesis-speak_t01: Skip # Times out
+LayoutTests/fast/sub-pixel/float-list-inside_t01: Skip # Times out
+LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t03: Skip # Times out
+LibTest/html/Element/blur_A01_t01: Skip # Times out
+LibTest/html/Element/focus_A01_t01: Skip # Times out
+LibTest/html/Element/loadEvent_A01_t01: Skip # Times out
+LibTest/html/Element/mouseWheelEvent_A01_t01: Skip # Times out
+LibTest/html/Element/onLoad_A01_t01: Skip # Times out
+LibTest/html/Element/onMouseWheel_A01_t01: Skip # Times out
+LibTest/html/Element/onTransitionEnd_A01_t01: Skip # Times out
+LibTest/html/Element/transitionEndEvent_A01_t01: Skip # Times out
+LibTest/html/HttpRequest/onError_A01_t02: Skip # Times out
+LibTest/html/HttpRequest/responseText_A01_t02: Skip # Times out
+LibTest/html/HttpRequestUpload/onError_A01_t02: Skip # Times out
+LibTest/html/HttpRequestUpload/onLoadEnd_A01_t01: Skip # Times out
+LibTest/html/HttpRequestUpload/onLoadStart_A01_t01: Skip # Times out
+LibTest/html/HttpRequestUpload/onLoad_A01_t01: Skip # Times out
+LibTest/html/IFrameElement/blur_A01_t01: Skip # Times out
+LibTest/html/IFrameElement/enteredView_A01_t01: Skip # Times out
+LibTest/html/IFrameElement/focus_A01_t01: Skip # Times out
+LibTest/html/IFrameElement/onMouseWheel_A01_t01: Skip # Times out
+LibTest/html/IFrameElement/onTransitionEnd_A01_t01: Skip # Times out
+WebPlatformTest/DOMEvents/approved/ProcessingInstruction.DOMCharacterDataModified_t01: Skip # Times out
+WebPlatformTest/Utils/test/asyncTestTimeout_t01: Skip # Times out
+WebPlatformTest/dom/nodes/Node-isEqualNode_t01: Skip # Times out
+WebPlatformTest/html/semantics/embedded-content/media-elements/error-codes/error_t01: Skip # Times out
+WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/cues_t01: Skip # Times out
+WebPlatformTest/webstorage/event_local_key_t01: Skip # Times out
+WebPlatformTest/webstorage/event_local_newvalue_t01: Skip # Times out
+WebPlatformTest/webstorage/event_local_oldvalue_t01: Skip # Times out
+WebPlatformTest/webstorage/event_local_storagearea_t01: Skip # Times out
+WebPlatformTest/webstorage/event_local_url_t01: Skip # Times out
+WebPlatformTest/webstorage/event_session_key_t01: Skip # Times out
+WebPlatformTest/webstorage/event_session_newvalue_t01: Skip # Times out
+WebPlatformTest/webstorage/event_session_oldvalue_t01: Skip # Times out
+WebPlatformTest/webstorage/event_session_storagearea_t01: Skip # Times out
+WebPlatformTest/webstorage/event_session_url_t01: Skip # Times out
diff --git a/tests/co19_2/co19_2-kernel.status b/tests/co19_2/co19_2-kernel.status
index e074d1d..f9896cd 100644
--- a/tests/co19_2/co19_2-kernel.status
+++ b/tests/co19_2/co19_2-kernel.status
@@ -2,6 +2,11 @@
 # 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.
 
+[ $builder_tag == bytecode_interpreter ]
+LibTest/collection/ListBase/ListBase_class_A01_t04: Pass, Slow
+LibTest/collection/ListBase/ListBase_class_A01_t05: Pass, Slow
+LibTest/collection/ListBase/ListBase_class_A01_t06: Pass, Slow
+
 [ $compiler == dartk ]
 LanguageFeatures/Set-literals/syntax_compatibility_A01_t02: RuntimeError
 
diff --git a/tests/compiler/dart2js/analyses/api_allowed.json b/tests/compiler/dart2js/analyses/api_allowed.json
index a97e98f..9a02f59 100644
--- a/tests/compiler/dart2js/analyses/api_allowed.json
+++ b/tests/compiler/dart2js/analyses/api_allowed.json
@@ -87,7 +87,6 @@
     "Dynamic access of 'firstChild'.": 2,
     "Dynamic invocation of 'append'.": 1,
     "Dynamic access of 'tagName'.": 2,
-    "Dynamic invocation of 'round'.": 20,
     "Dynamic invocation of 'call'.": 1,
     "Dynamic invocation of 'dart.dom.html::_initKeyboardEvent'.": 1,
     "Dynamic access of 'attributes'.": 1,
@@ -99,9 +98,7 @@
     "Dynamic invocation of 'createElement'.": 1
   },
   "org-dartlang-sdk:///sdk/lib/html/html_common/conversions.dart": {
-    "Dynamic invocation of '[]='.": 2,
-    "Dynamic access of 'length'.": 1,
-    "Dynamic invocation of '[]'.": 1
+    "Dynamic invocation of '[]='.": 1
   },
   "org-dartlang-sdk:///sdk/lib/html/html_common/filtered_element_list.dart": {
     "Dynamic invocation of 'remove'.": 1
diff --git a/tests/compiler/dart2js/analyses/dart2js_allowed.json b/tests/compiler/dart2js/analyses/dart2js_allowed.json
index 0b70e2e..ff6c98a 100644
--- a/tests/compiler/dart2js/analyses/dart2js_allowed.json
+++ b/tests/compiler/dart2js/analyses/dart2js_allowed.json
@@ -146,6 +146,15 @@
     "Dynamic invocation of '-'.": 1,
     "Dynamic invocation of '+'.": 1
   },
+  "pkg/compiler/lib/src/serialization/binary_sink.dart": {
+    "Dynamic access of 'index'.": 1
+  },
+  "pkg/compiler/lib/src/native/behavior.dart": {
+    "Dynamic invocation of 'add'.": 1
+  },
+  "pkg/compiler/lib/src/util/enumset.dart": {
+    "Dynamic access of 'index'.": 4
+  },
   "pkg/compiler/lib/src/constants/constant_system.dart": {
     "Dynamic invocation of '&'.": 1,
     "Dynamic invocation of '|'.": 1,
@@ -165,9 +174,6 @@
     "Dynamic invocation of '>='.": 1,
     "Dynamic invocation of 'codeUnitAt'.": 1
   },
-  "pkg/compiler/lib/src/serialization/binary_sink.dart": {
-    "Dynamic access of 'index'.": 1
-  },
   "third_party/pkg/dart2js_info/lib/json_info_codec.dart": {
     "Dynamic invocation of '[]'.": 11,
     "Dynamic invocation of 'forEach'.": 2,
@@ -177,12 +183,6 @@
   "third_party/pkg/dart2js_info/lib/binary_serialization.dart": {
     "Dynamic invocation of 'cast'.": 1
   },
-  "pkg/compiler/lib/src/util/enumset.dart": {
-    "Dynamic access of 'index'.": 4
-  },
-  "pkg/compiler/lib/src/native/enqueue.dart": {
-    "Dynamic access of 'isDynamic'.": 1
-  },
   "pkg/compiler/lib/src/inferrer/inferrer_engine.dart": {
     "Dynamic access of 'isVoid'.": 1,
     "Dynamic access of 'isDynamic'.": 1,
@@ -195,8 +195,8 @@
   "pkg/compiler/lib/src/universe/side_effects.dart": {
     "Dynamic access of 'universe.side_effects::_flags'.": 1
   },
-  "pkg/compiler/lib/src/native/behavior.dart": {
-    "Dynamic invocation of 'add'.": 1
+  "pkg/compiler/lib/src/native/enqueue.dart": {
+    "Dynamic access of 'isDynamic'.": 1
   },
   "pkg/compiler/lib/src/ssa/builder_kernel.dart": {
     "Dynamic update to 'instantiatedTypes'.": 1,
@@ -211,17 +211,11 @@
     "Dynamic access of 'treatAsDynamic'.": 1,
     "Dynamic access of 'element'.": 1
   },
-  "pkg/compiler/lib/src/ssa/validate.dart": {
-    "Dynamic invocation of 'isInBasicBlock'.": 2,
-    "Dynamic access of 'usedBy'.": 2,
-    "Dynamic access of 'inputs'.": 1
-  },
-  "third_party/pkg/dart2js_info/lib/src/util.dart": {
-    "Dynamic access of 'name'.": 1,
-    "Dynamic invocation of '-'.": 1
-  },
-  "third_party/pkg/dart2js_info/lib/src/binary/sink.dart": {
-    "Dynamic access of 'index'.": 1
+  "pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart": {
+    "Dynamic access of 'keys'.": 1,
+    "Dynamic invocation of 'toSet'.": 1,
+    "Dynamic invocation of '[]='.": 1,
+    "Dynamic invocation of 'add'.": 1
   },
   "pkg/js_ast/lib/src/builder.dart": {
     "Dynamic invocation of 'call'.": 2
@@ -235,6 +229,13 @@
     "Dynamic invocation of '[]'.": 9,
     "Dynamic invocation of 'toStatement'.": 3
   },
+  "third_party/pkg/dart2js_info/lib/src/util.dart": {
+    "Dynamic access of 'name'.": 1,
+    "Dynamic invocation of '-'.": 1
+  },
+  "third_party/pkg/dart2js_info/lib/src/binary/sink.dart": {
+    "Dynamic access of 'index'.": 1
+  },
   "pkg/compiler/lib/src/inferrer/type_graph_nodes.dart": {
     "Dynamic invocation of 'add'.": 1,
     "Dynamic invocation of 'remove'.": 1,
@@ -250,16 +251,14 @@
     "Dynamic access of 'named'.": 2,
     "Dynamic invocation of '[]'.": 2
   },
-  "pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart": {
-    "Dynamic access of 'keys'.": 1,
-    "Dynamic invocation of 'toSet'.": 1,
-    "Dynamic invocation of '[]='.": 1,
-    "Dynamic invocation of 'add'.": 1
-  },
   "pkg/compiler/lib/src/universe/function_set.dart": {
     "Dynamic access of 'selector'.": 1,
     "Dynamic access of 'receiver'.": 1
   },
+  "pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart": {
+    "Dynamic access of 'superclass'.": 1,
+    "Dynamic access of 'needsTearOff'.": 1
+  },
   "pkg/compiler/lib/src/ssa/variable_allocator.dart": {
     "Dynamic access of 'usedBy'.": 1,
     "Dynamic access of 'isEmpty'.": 1,
@@ -275,9 +274,5 @@
   },
   "pkg/compiler/lib/src/ssa/value_set.dart": {
     "Dynamic invocation of 'add'.": 2
-  },
-  "pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart": {
-    "Dynamic access of 'superclass'.": 1,
-    "Dynamic access of 'needsTearOff'.": 1
   }
 }
\ No newline at end of file
diff --git a/tests/compiler/dart2js/codegen/model_data/dynamic_set.dart b/tests/compiler/dart2js/codegen/model_data/dynamic_set.dart
index ed3aa49..546d97c 100644
--- a/tests/compiler/dart2js/codegen/model_data/dynamic_set.dart
+++ b/tests/compiler/dart2js/codegen/model_data/dynamic_set.dart
@@ -26,15 +26,11 @@
 class Class2a<T> {
   /*strong.member: Class2a.field2:checked,emitted*/
   /*omit.member: Class2a.field2:emitted*/
-  /*strongConst.member: Class2a.field2:checked,emitted*/
-  /*omitConst.member: Class2a.field2:emitted*/
   T field2;
 }
 
 /*strong.member: method2:calls=[set$field2(1)],params=1*/
 /*omit.member: method2:assign=[field2],params=1*/
-/*strongConst.member: method2:calls=[set$field2(1)],params=1*/
-/*omitConst.member: method2:assign=[field2],params=1*/
 @pragma('dart2js:noInline')
 method2(dynamic c) {
   c.field2 = 42;
@@ -43,16 +39,12 @@
 class Class3a {
   /*strong.member: Class3a.field3:checked,emitted*/
   /*omit.member: Class3a.field3:emitted,set=simple*/
-  /*strongConst.member: Class3a.field3:checked,emitted*/
-  /*omitConst.member: Class3a.field3:emitted,set=simple*/
   int field3;
 }
 
 class Class3b {
   /*strong.member: Class3b.field3:checked,emitted*/
   /*omit.member: Class3b.field3:emitted,set=simple*/
-  /*strongConst.member: Class3b.field3:checked,emitted*/
-  /*omitConst.member: Class3b.field3:emitted,set=simple*/
   int field3;
 }
 
@@ -65,16 +57,12 @@
 class Class4a {
   /*strong.member: Class4a.field4:checked,emitted*/
   /*omit.member: Class4a.field4:emitted,set=simple*/
-  /*strongConst.member: Class4a.field4:checked,emitted*/
-  /*omitConst.member: Class4a.field4:emitted,set=simple*/
   int field4;
 }
 
 class Class4b implements Class4a {
   /*strong.member: Class4b.field4:checked,emitted*/
   /*omit.member: Class4b.field4:emitted,set=simple*/
-  /*strongConst.member: Class4b.field4:checked,emitted*/
-  /*omitConst.member: Class4b.field4:emitted,set=simple*/
   @override
   int field4;
 }
diff --git a/tests/compiler/dart2js/codegen/model_data/dynamic_set_unread.dart b/tests/compiler/dart2js/codegen/model_data/dynamic_set_unread.dart
index fcaa994..0c1fa05 100644
--- a/tests/compiler/dart2js/codegen/model_data/dynamic_set_unread.dart
+++ b/tests/compiler/dart2js/codegen/model_data/dynamic_set_unread.dart
@@ -26,15 +26,11 @@
 class Class2a<T> {
   /*strong.member: Class2a.field2:checked,elided*/
   /*omit.member: Class2a.field2:elided*/
-  /*strongConst.member: Class2a.field2:checked,elided*/
-  /*omitConst.member: Class2a.field2:elided*/
   T field2;
 }
 
 /*strong.member: method2:calls=[set$field2(1)],params=1*/
 /*omit.member: method2:params=1*/
-/*strongConst.member: method2:calls=[set$field2(1)],params=1*/
-/*omitConst.member: method2:params=1*/
 @pragma('dart2js:noInline')
 method2(dynamic c) {
   c.field2 = 42;
@@ -43,16 +39,12 @@
 class Class3a {
   /*strong.member: Class3a.field3:checked,elided*/
   /*omit.member: Class3a.field3:elided,set=simple*/
-  /*strongConst.member: Class3a.field3:checked,elided*/
-  /*omitConst.member: Class3a.field3:elided,set=simple*/
   int field3;
 }
 
 class Class3b {
   /*strong.member: Class3b.field3:checked,elided*/
   /*omit.member: Class3b.field3:elided,set=simple*/
-  /*strongConst.member: Class3b.field3:checked,elided*/
-  /*omitConst.member: Class3b.field3:elided,set=simple*/
   int field3;
 }
 
@@ -65,16 +57,12 @@
 class Class4a {
   /*strong.member: Class4a.field4:checked,elided*/
   /*omit.member: Class4a.field4:elided,set=simple*/
-  /*strongConst.member: Class4a.field4:checked,elided*/
-  /*omitConst.member: Class4a.field4:elided,set=simple*/
   int field4;
 }
 
 class Class4b implements Class4a {
   /*strong.member: Class4b.field4:checked,elided*/
   /*omit.member: Class4b.field4:elided,set=simple*/
-  /*strongConst.member: Class4b.field4:checked,elided*/
-  /*omitConst.member: Class4b.field4:elided,set=simple*/
   @override
   int field4;
 }
diff --git a/tests/compiler/dart2js/codegen/model_data/static_tearoff.dart b/tests/compiler/dart2js/codegen/model_data/static_tearoff.dart
index 524b200..5720592 100644
--- a/tests/compiler/dart2js/codegen/model_data/static_tearoff.dart
+++ b/tests/compiler/dart2js/codegen/model_data/static_tearoff.dart
@@ -18,10 +18,8 @@
 @pragma('dart2js:noInline')
 void bar(I2 x) {}
 
-/*strong.member: main:calls=[call$1(new F.A()),call$1(new F.B()),foo(1),foo(1),main__bar$closure(0),main__bar$closure(0)],params=0*/
-/*omit.member: main:calls=[call$1(new F.A()),call$1(new F.B()),foo(1),foo(1),main__bar$closure(0),main__bar$closure(0)],params=0*/
-/*strongConst.member: main:calls=[bar(1),bar(1),foo(1),foo(1)],params=0*/
-/*omitConst.member: main:calls=[bar(1),bar(1),foo(1),foo(1)],params=0*/
+/*strong.member: main:calls=[bar(1),bar(1),foo(1),foo(1)],params=0*/
+/*omit.member: main:calls=[bar(1),bar(1),foo(1),foo(1)],params=0*/
 main() {
   dynamic f = bar;
 
diff --git a/tests/compiler/dart2js/codegen/new_rti_is_test.dart b/tests/compiler/dart2js/codegen/new_rti_is_test.dart
new file mode 100644
index 0000000..06a3604
--- /dev/null
+++ b/tests/compiler/dart2js/codegen/new_rti_is_test.dart
@@ -0,0 +1,132 @@
+// 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.
+
+library new_rti_is_test;
+
+import 'dart:async';
+import 'package:async_helper/async_helper.dart';
+import '../helpers/compiler_helper.dart';
+
+// 'N' tests all have a nullable input so should not reduce is-test.
+// TODO(NNBD): Add tests with non-nullable input types.
+
+const TEST1N = r"""
+foo(int a) {
+  return a is double;
+  // absent: 'return true'
+  // absent: 'return false'
+}
+""";
+
+const TEST2N = r"""
+foo(int a) {
+  return a is num;
+  // absent: 'return true'
+  // absent: 'return false'
+}
+""";
+
+const TEST3N = r"""
+foo(double a) {
+  return a is int;
+  // absent: 'return true'
+  // absent: 'return false'
+}
+""";
+
+const TEST4N = r"""
+foo(double a) {
+  return a is num;
+  // absent: 'return true'
+  // absent: 'return false'
+}
+""";
+
+const TEST5N = r"""
+foo(num a) {
+  return a is int;
+  // absent: 'return true'
+  // absent: 'return false'
+}
+""";
+
+const TEST6N = r"""
+foo(num a) {
+  return a is double;
+  // absent: 'return true'
+  // absent: 'return false'
+}
+""";
+
+const TEST1I = r"""
+foo(a) {
+  if (a is int) return a is double;
+  // present: 'return true'
+}
+""";
+
+const TEST2I = r"""
+foo(a) {
+  if (a is int) return a is num;
+  // present: 'return true'
+}
+""";
+
+const TEST3I = r"""
+foo(a) {
+  if (a is double) return a is int;
+  // absent: 'return true'
+  // absent: 'return false'
+}
+""";
+
+const TEST4I = r"""
+foo(a) {
+  if (a is double) return a is num;
+  // present: 'return true'
+}
+""";
+
+const TEST5I = r"""
+foo(a) {
+  if (a is num) return a is int;
+  // absent: 'return true'
+  // absent: 'return false'
+}
+""";
+
+const TEST6I = r"""
+foo(a) {
+  if (a is num) return a is double;
+  // present: 'return true'
+}
+""";
+
+main() {
+  runTests() async {
+    Future check(String test) {
+      return compile(test,
+          entry: 'foo', check: checkerForAbsentPresent(test), newRti: true);
+    }
+
+    await check(TEST1N);
+    await check(TEST2N);
+    await check(TEST3N);
+    await check(TEST4N);
+    await check(TEST5N);
+    await check(TEST6N);
+
+    await check(TEST1I);
+    await check(TEST2I);
+    await check(TEST3I);
+    await check(TEST4I);
+    await check(TEST5I);
+    await check(TEST6I);
+  }
+
+  asyncTest(() async {
+    print('--test from kernel------------------------------------------------');
+    await runTests();
+  });
+}
diff --git a/tests/compiler/dart2js/dart2js.status b/tests/compiler/dart2js/dart2js.status
index 9bee6c9..17a3670 100644
--- a/tests/compiler/dart2js/dart2js.status
+++ b/tests/compiler/dart2js/dart2js.status
@@ -13,7 +13,6 @@
 codegen/model_test: Pass, Slow
 codegen/side_effect_tdiv_regression_test: Fail # Issue 33050
 codegen/simple_function_subtype_test: Fail # simple_function_subtype_test is temporarily(?) disabled due to new method for building function type tests.
-codegen/string_escapes_test: Fail # Issue 33060
 deferred_loading/deferred_loading_test: Slow, Pass
 end_to_end/dump_info_test: Slow, Pass
 end_to_end/generate_code_with_compile_time_errors_test: RuntimeError # not supported yet with the new FE.
@@ -29,7 +28,6 @@
 inference/simple_inferrer_const_closure_test: Fail # Issue 16507
 inference/simple_inferrer_global_field_closure_test: Fail # Issue 16507
 inference/swarm_test: Slow, Pass, Fail #
-inference/type_mask2_test: RuntimeError # Issue 34095
 inlining/inlining_test: Slow, Pass
 model/native_test: Pass, Slow
 model/no_such_method_enabled_test: Pass, Slow
diff --git a/tests/compiler/dart2js/deferred/constant_emission_test_helper.dart b/tests/compiler/dart2js/deferred/constant_emission_test_helper.dart
index c5f20be..1d4fd35 100644
--- a/tests/compiler/dart2js/deferred/constant_emission_test_helper.dart
+++ b/tests/compiler/dart2js/deferred/constant_emission_test_helper.dart
@@ -6,7 +6,6 @@
 // Files when using deferred loading.
 
 import 'package:compiler/compiler_new.dart';
-import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/constants/values.dart';
 import 'package:compiler/src/deferred_load.dart';
@@ -27,15 +26,10 @@
 }
 
 run(Map<String, String> sourceFiles, List<OutputUnitDescriptor> outputUnits,
-    Map<String, Set<String>> expectedOutputUnits,
-    {bool useCFEConstants: false}) async {
+    Map<String, Set<String>> expectedOutputUnits) async {
   OutputCollector collector = new OutputCollector();
   CompilationResult result = await runCompiler(
-      memorySourceFiles: sourceFiles,
-      outputProvider: collector,
-      options: useCFEConstants
-          ? ['${Flags.enableLanguageExperiments}=constant-update-2018']
-          : ['${Flags.enableLanguageExperiments}=no-constant-update-2018']);
+      memorySourceFiles: sourceFiles, outputProvider: collector);
   Compiler compiler = result.compiler;
   ProgramLookup lookup = new ProgramLookup(compiler.backendStrategy);
   var closedWorld = compiler.backendClosedWorldForTesting;
diff --git a/tests/compiler/dart2js/deferred/deferred_constant3_test.dart b/tests/compiler/dart2js/deferred/deferred_constant3_test.dart
index 239e4b0..7dda970 100644
--- a/tests/compiler/dart2js/deferred/deferred_constant3_test.dart
+++ b/tests/compiler/dart2js/deferred/deferred_constant3_test.dart
@@ -9,13 +9,13 @@
 import 'constant_emission_test_helper.dart';
 
 void main() {
-  runTest({bool useCFEConstants: false}) async {
+  runTest() async {
     Map<String, Set<String>> expectedOutputUnits = {
       'ConstructedConstant(C(x=IntConstant(1)))': {'main'},
       'DeferredGlobalConstant(ConstructedConstant(C(x=IntConstant(1))))':
           // With CFE constants, the references are inlined, so the constant
           // only occurs in main.
-          useCFEConstants ? {} : {'lib2'},
+          {},
       'ConstructedConstant(C(x=IntConstant(2)))': {'lib1'},
       'DeferredGlobalConstant(ConstructedConstant(C(x=IntConstant(2))))': {
         'lib1'
@@ -33,15 +33,12 @@
           OutputUnitDescriptor('memory:lib1.dart', 'm1', 'lib1'),
           OutputUnitDescriptor('memory:lib2.dart', 'm2', 'lib2'),
         ],
-        expectedOutputUnits,
-        useCFEConstants: useCFEConstants);
+        expectedOutputUnits);
   }
 
   asyncTest(() async {
     print('--test from kernel------------------------------------------------');
     await runTest();
-    print('--test from kernel with CFE constants-----------------------------');
-    await runTest(useCFEConstants: true);
   });
 }
 
diff --git a/tests/compiler/dart2js/deferred/dont_inline_deferred_constants_test.dart b/tests/compiler/dart2js/deferred/dont_inline_deferred_constants_test.dart
index 5afdd4e..0bac9fa 100644
--- a/tests/compiler/dart2js/deferred/dont_inline_deferred_constants_test.dart
+++ b/tests/compiler/dart2js/deferred/dont_inline_deferred_constants_test.dart
@@ -9,7 +9,7 @@
 import 'constant_emission_test_helper.dart';
 
 void main() {
-  runTest({bool useCFEConstants: false}) async {
+  runTest() async {
     Map<String, Set<String>> expectedOutputUnits = {
       // Test that the deferred constants are not inlined into the main file.
       'DeferredGlobalConstant(IntConstant(1010))': {'lib1'},
@@ -19,21 +19,21 @@
       'DeferredGlobalConstant(StringConstant("string4"))':
           // TODO(johnniwinther): Should we inline CFE constants within deferred
           // library boundaries?
-          useCFEConstants ? {'lib12'} : {'lib1', 'lib2'},
+          {'lib12'},
       // C(1) is shared between main, lib1 and lib2. Test that lib1 and lib2
       // each has a reference to it. It is defined in the main output file.
       'ConstructedConstant(C(p=IntConstant(1)))': {'main'},
       'DeferredGlobalConstant(ConstructedConstant(C(p=IntConstant(1))))':
           // With CFE constants, the references are inlined, so the constant
           // only occurs in main.
-          useCFEConstants ? {} : {'lib1', 'lib2'},
+          {},
       // C(2) is shared between lib1 and lib2, each of them has their own
       // reference to it.
       'ConstructedConstant(C(p=IntConstant(2)))': {'lib12'},
       'DeferredGlobalConstant(ConstructedConstant(C(p=IntConstant(2))))':
           // With CFE constants, the references are inlined, so the constant
           // occurs in lib12.
-          useCFEConstants ? {'lib12'} : {'lib1', 'lib2'},
+          {'lib12'},
       // Test that the non-deferred constant is inlined.
       'ConstructedConstant(C(p=IntConstant(5)))': {'main'},
     };
@@ -44,15 +44,12 @@
           OutputUnitDescriptor('memory:lib2.dart', 'foo', 'lib2'),
           OutputUnitDescriptor('memory:main.dart', 'foo', 'lib12')
         ],
-        expectedOutputUnits,
-        useCFEConstants: useCFEConstants);
+        expectedOutputUnits);
   }
 
   asyncTest(() async {
     print('--test from kernel------------------------------------------------');
     await runTest();
-    print('--test from kernel with CFE constants-----------------------------');
-    await runTest(useCFEConstants: true);
   });
 }
 
diff --git a/tests/compiler/dart2js/deferred/dont_inline_deferred_globals_test.dart b/tests/compiler/dart2js/deferred/dont_inline_deferred_globals_test.dart
index 3c0ac93..3948747 100644
--- a/tests/compiler/dart2js/deferred/dont_inline_deferred_globals_test.dart
+++ b/tests/compiler/dart2js/deferred/dont_inline_deferred_globals_test.dart
@@ -9,7 +9,7 @@
 import 'constant_emission_test_helper.dart';
 
 void main() {
-  runTest({bool useCFEConstants: false}) async {
+  runTest() async {
     Map<String, Set<String>> expectedOutputUnits = {
       // Test that the deferred globals are not inlined into the main file.
       'ConstructedConstant(C(field=StringConstant("string1")))': {'lib1'},
@@ -21,15 +21,12 @@
     await run(
         MEMORY_SOURCE_FILES,
         const [OutputUnitDescriptor('memory:lib1.dart', 'finalVar', 'lib1')],
-        expectedOutputUnits,
-        useCFEConstants: useCFEConstants);
+        expectedOutputUnits);
   }
 
   asyncTest(() async {
     print('--test from kernel------------------------------------------------');
     await runTest();
-    print('--test from kernel with CFE constants-----------------------------');
-    await runTest(useCFEConstants: true);
   });
 }
 
diff --git a/tests/compiler/dart2js/deferred/follow_constant_dependencies_test.dart b/tests/compiler/dart2js/deferred/follow_constant_dependencies_test.dart
index 9da9d81..971c524 100644
--- a/tests/compiler/dart2js/deferred/follow_constant_dependencies_test.dart
+++ b/tests/compiler/dart2js/deferred/follow_constant_dependencies_test.dart
@@ -5,19 +5,15 @@
 // Test that constants depended on by other constants are correctly deferred.
 
 import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/constants/values.dart';
 import 'package:expect/expect.dart';
 import '../helpers/memory_compiler.dart';
 
 void main() {
-  runTest({bool useCFEConstants: false}) async {
-    CompilationResult result = await runCompiler(
-        memorySourceFiles: MEMORY_SOURCE_FILES,
-        options: useCFEConstants
-            ? ['${Flags.enableLanguageExperiments}=constant-update-2018']
-            : ['${Flags.enableLanguageExperiments}=no-constant-update-2018']);
+  runTest() async {
+    CompilationResult result =
+        await runCompiler(memorySourceFiles: MEMORY_SOURCE_FILES);
 
     Compiler compiler = result.compiler;
     var closedWorld = compiler.backendClosedWorldForTesting;
@@ -52,8 +48,6 @@
   asyncTest(() async {
     print('--test from kernel------------------------------------------------');
     await runTest();
-    print('--test from kernel with CFE constants-----------------------------');
-    await runTest(useCFEConstants: true);
   });
 }
 
diff --git a/tests/compiler/dart2js/deferred/not_in_main_test.dart b/tests/compiler/dart2js/deferred/not_in_main_test.dart
index 85d14e7..35ac334 100644
--- a/tests/compiler/dart2js/deferred/not_in_main_test.dart
+++ b/tests/compiler/dart2js/deferred/not_in_main_test.dart
@@ -7,7 +7,6 @@
 // much be included in the initial download (loaded eagerly).
 
 import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:expect/expect.dart';
 import '../helpers/memory_compiler.dart';
@@ -17,18 +16,11 @@
     print('--test from kernel------------------------------------------------');
     await deferredTest1();
     await deferredTest2();
-    print('--test from kernel with CFE constants-----------------------------');
-    await deferredTest1(useCFEConstants: true);
-    await deferredTest2(useCFEConstants: true);
   });
 }
 
-deferredTest1({bool useCFEConstants: false}) async {
-  CompilationResult result = await runCompiler(
-      memorySourceFiles: TEST1,
-      options: useCFEConstants
-          ? ['${Flags.enableLanguageExperiments}=constant-update-2018']
-          : ['${Flags.enableLanguageExperiments}=no-constant-update-2018']);
+deferredTest1() async {
+  CompilationResult result = await runCompiler(memorySourceFiles: TEST1);
 
   Compiler compiler = result.compiler;
   var closedWorld = compiler.backendClosedWorldForTesting;
@@ -44,12 +36,8 @@
   Expect.notEquals(mainOutputUnit, outputUnitForMember(foo2));
 }
 
-deferredTest2({bool useCFEConstants: false}) async {
-  CompilationResult result = await runCompiler(
-      memorySourceFiles: TEST2,
-      options: useCFEConstants
-          ? ['${Flags.enableLanguageExperiments}=constant-update-2018']
-          : ['${Flags.enableLanguageExperiments}=no-constant-update-2018']);
+deferredTest2() async {
+  CompilationResult result = await runCompiler(memorySourceFiles: TEST2);
 
   Compiler compiler = result.compiler;
   var closedWorld = compiler.backendClosedWorldForTesting;
diff --git a/tests/compiler/dart2js/deferred_loading/libs/basic_deferred_lib.dart b/tests/compiler/dart2js/deferred_loading/data/basic_deferred/lib.dart
similarity index 84%
rename from tests/compiler/dart2js/deferred_loading/libs/basic_deferred_lib.dart
rename to tests/compiler/dart2js/deferred_loading/data/basic_deferred/lib.dart
index 25d4ccd..d0d4c5d 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/basic_deferred_lib.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/basic_deferred/lib.dart
@@ -5,8 +5,7 @@
 /*member: defaultArg:OutputUnit(1, {lib})*/
 defaultArg() => "";
 
-/*strong.member: funky:OutputUnit(1, {lib})*/
-/*strongConst.member: funky:
+/*member: funky:
  OutputUnit(1, {lib}),
  constants=[FunctionConstant(defaultArg)=OutputUnit(1, {lib})]
 */
diff --git a/tests/compiler/dart2js/deferred_loading/data/basic_deferred.dart b/tests/compiler/dart2js/deferred_loading/data/basic_deferred/main.dart
similarity index 74%
rename from tests/compiler/dart2js/deferred_loading/data/basic_deferred.dart
rename to tests/compiler/dart2js/deferred_loading/data/basic_deferred/main.dart
index c8e9b8e..2e1b3d3 100644
--- a/tests/compiler/dart2js/deferred_loading/data/basic_deferred.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/basic_deferred/main.dart
@@ -2,10 +2,9 @@
 // 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 '../libs/basic_deferred_lib.dart' deferred as lib;
+import 'lib.dart' deferred as lib;
 
-/*strong.member: main:OutputUnit(main, {})*/
-/*strongConst.member: main:
+/*member: main:
  OutputUnit(main, {}),
  constants=[FunctionConstant(funky)=OutputUnit(1, {lib})]
 */
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_class_library.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_class/lib.dart
similarity index 92%
rename from tests/compiler/dart2js/deferred_loading/libs/deferred_class_library.dart
rename to tests/compiler/dart2js/deferred_loading/data/deferred_class/lib.dart
index 4910c2a..73a68a9 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_class_library.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_class/lib.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.
 
-// Imported by deferred_class.dart.
+// Imported by main.dart.
 
 library deferred_class_library;
 
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_class.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_class/main.dart
similarity index 85%
rename from tests/compiler/dart2js/deferred_loading/data/deferred_class.dart
rename to tests/compiler/dart2js/deferred_loading/data/deferred_class/main.dart
index 6bd1661..0656d4a 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_class.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_class/main.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.
 
-import '../libs/deferred_class_library.dart' deferred as lib;
+import 'lib.dart' deferred as lib;
 
 /*member: main:OutputUnit(main, {})*/
 main() {
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant1_lib1.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_constant1/lib1.dart
similarity index 82%
rename from tests/compiler/dart2js/deferred_loading/libs/deferred_constant1_lib1.dart
rename to tests/compiler/dart2js/deferred_loading/data/deferred_constant1/lib1.dart
index 8965ddf..6843b34 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant1_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_constant1/lib1.dart
@@ -4,4 +4,4 @@
 
 library deferred_constants1_lib1;
 
-export 'deferred_constant1_lib3.dart' show C, C1;
+export 'lib3.dart' show C, C1;
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant1_lib2.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_constant1/lib2.dart
similarity index 78%
rename from tests/compiler/dart2js/deferred_loading/libs/deferred_constant1_lib2.dart
rename to tests/compiler/dart2js/deferred_loading/data/deferred_constant1/lib2.dart
index ca606bb..ed8ffce 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant1_lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_constant1/lib2.dart
@@ -4,4 +4,4 @@
 
 library deferred_constants1_lib2;
 
-export 'deferred_constant1_lib3.dart' show C2, C3, C4, C5, C6, C7;
+export 'lib3.dart' show C2, C3, C4, C5, C6, C7;
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant1_lib3.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_constant1/lib3.dart
similarity index 68%
rename from tests/compiler/dart2js/deferred_loading/libs/deferred_constant1_lib3.dart
rename to tests/compiler/dart2js/deferred_loading/data/deferred_constant1/lib3.dart
index afd84b4..297fe55 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant1_lib3.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_constant1/lib3.dart
@@ -8,7 +8,7 @@
 class C {
   /*member: C.value:OutputUnit(main, {})*/
   final value;
-  /*strong.member: C.:OutputUnit(main, {})*/
+
   const C(this.value);
 }
 
@@ -16,40 +16,33 @@
 /// Constant used from main: not deferred.
 /// ---------------------------------------------------------------------------
 
-/*strong.member: C1:OutputUnit(main, {})*/
-const C1 = /*strong.OutputUnit(main, {})*/ const C(1);
+const C1 = const C(1);
 
 /// ---------------------------------------------------------------------------
 /// Constant completely deferred.
 /// ---------------------------------------------------------------------------
 
-/*strong.member: C2:OutputUnit(1, {lib2})*/
-const C2 = /*strong.OutputUnit(1, {lib2})*/ const C(2);
+const C2 = const C(2);
 
 /// ---------------------------------------------------------------------------
 /// Constant fields not used from main, but the constant value are: so the field
 /// and the constants are in different output units.
 /// ---------------------------------------------------------------------------
 
-/*strong.member: C3:OutputUnit(1, {lib2})*/
-const C3 = /*strong.OutputUnit(main, {})*/ const C(1);
+const C3 = const C(1);
 
-/*strong.member: C4:OutputUnit(1, {lib2})*/
-const C4 = /*strong.OutputUnit(main, {})*/ const C(4);
+const C4 = const C(4);
 
 /// ---------------------------------------------------------------------------
 /// Constant value used form a closure within main.
 /// ---------------------------------------------------------------------------
 
-/*strong.member: C5:OutputUnit(1, {lib2})*/
-const C5 = /*strong.OutputUnit(main, {})*/ const C(5);
+const C5 = const C(5);
 
 /// ---------------------------------------------------------------------------
 /// Deferred constants, used after a deferred load.
 /// ---------------------------------------------------------------------------
 
-/*strong.member: C6:OutputUnit(1, {lib2})*/
 const C6 = "string6";
 
-/*strong.member: C7:OutputUnit(1, {lib2})*/
-const C7 = /*strong.OutputUnit(1, {lib2})*/ const C(const C(7));
+const C7 = const C(const C(7));
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_constant1.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_constant1/main.dart
similarity index 82%
rename from tests/compiler/dart2js/deferred_loading/data/deferred_constant1.dart
rename to tests/compiler/dart2js/deferred_loading/data/deferred_constant1/main.dart
index 1ed34b3..721461b 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_constant1.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_constant1/main.dart
@@ -2,11 +2,10 @@
 // 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 '../libs/deferred_constant1_lib1.dart';
-import '../libs/deferred_constant1_lib2.dart' deferred as lib2;
+import 'lib1.dart';
+import 'lib2.dart' deferred as lib2;
 
-/*strong.member: main:OutputUnit(main, {})*/
-/*strongConst.member: main:
+/*member: main:
  OutputUnit(main, {}),
  constants=[
   ConstructedConstant(C(value=ConstructedConstant(C(value=IntConstant(7)))))=OutputUnit(1, {lib2}),
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant2_lib.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_constant2/lib.dart
similarity index 78%
rename from tests/compiler/dart2js/deferred_loading/libs/deferred_constant2_lib.dart
rename to tests/compiler/dart2js/deferred_loading/data/deferred_constant2/lib.dart
index dc1516d..1e897c6 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant2_lib.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_constant2/lib.dart
@@ -8,14 +8,16 @@
 class Constant {
   /*member: Constant.value:OutputUnit(1, {lib})*/
   final value;
-  /*strong.member: Constant.:OutputUnit(1, {lib})*/
+
   const Constant(this.value);
 
   /*member: Constant.==:OutputUnit(1, {lib})*/
+  @override
   operator ==(other) => other is Constant && value == other.value;
+
   /*member: Constant.hashCode:OutputUnit(1, {lib})*/
+  @override
   get hashCode => 0;
 }
 
-/*strong.member: C1:OutputUnit(1, {lib})*/
-const C1 = /*strong.OutputUnit(1, {lib})*/ const Constant(499);
+const C1 = const Constant(499);
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_constant2.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_constant2/main.dart
similarity index 77%
rename from tests/compiler/dart2js/deferred_loading/data/deferred_constant2.dart
rename to tests/compiler/dart2js/deferred_loading/data/deferred_constant2/main.dart
index 8306e71..96002d1 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_constant2.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_constant2/main.dart
@@ -4,10 +4,9 @@
 
 import 'package:expect/expect.dart';
 
-import '../libs/deferred_constant2_lib.dart' deferred as lib;
+import 'lib.dart' deferred as lib;
 
-/*strong.member: main:OutputUnit(main, {})*/
-/*strongConst.member: main:
+/*member: main:
  OutputUnit(main, {}),
  constants=[
   ConstructedConstant(Constant(value=IntConstant(499)))=OutputUnit(1, {lib})]
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_lib1.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_constant3/lib1.dart
similarity index 63%
rename from tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_lib1.dart
rename to tests/compiler/dart2js/deferred_loading/data/deferred_constant3/lib1.dart
index 2edad58..1b52c4b 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_constant3/lib1.dart
@@ -2,17 +2,14 @@
 // 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 'deferred_constant3_shared.dart';
-import 'deferred_constant3_lib2.dart' deferred as l2;
+import 'shared.dart';
+import 'lib2.dart' deferred as l2;
 
-/*strong.member: c2:OutputUnit(1, {l1})*/
-const c2 = /*strong.OutputUnit(1, {l1})*/ const C(2);
+const c2 = const C(2);
 
-/*strong.member: c3:OutputUnit(1, {l1})*/
-const c3 = /*strong.OutputUnit(1, {l1})*/ const C(3);
+const c3 = const C(3);
 
-/*strong.member: m1:OutputUnit(1, {l1})*/
-/*strongConst.member: m1:
+/*member: m1:
  OutputUnit(1, {l1}),
  constants=[
   ConstructedConstant(C(x=IntConstant(1)))=OutputUnit(main, {}),
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_constant3/lib2.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_constant3/lib2.dart
new file mode 100644
index 0000000..44df89d
--- /dev/null
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_constant3/lib2.dart
@@ -0,0 +1,24 @@
+// 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.
+
+import 'shared.dart';
+
+const c3 = const C(1);
+
+const c4 = const C(4);
+
+const c5 = const C(5);
+
+/*member: m2:
+ OutputUnit(2, {l2}),
+ constants=[
+  ConstructedConstant(C(x=IntConstant(1)))=OutputUnit(main, {}),
+  ConstructedConstant(C(x=IntConstant(4)))=OutputUnit(2, {l2}),
+  ConstructedConstant(C(x=IntConstant(5)))=OutputUnit(2, {l2})]
+*/
+m2() async {
+  print(c3);
+  print(c4);
+  print(c5);
+}
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_constant3.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_constant3/main.dart
similarity index 62%
rename from tests/compiler/dart2js/deferred_loading/data/deferred_constant3.dart
rename to tests/compiler/dart2js/deferred_loading/data/deferred_constant3/main.dart
index 17a05a9..b006d1e 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_constant3.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_constant3/main.dart
@@ -2,14 +2,12 @@
 // 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 '../libs/deferred_constant3_shared.dart';
-import '../libs/deferred_constant3_lib1.dart' deferred as l1;
+import 'shared.dart';
+import 'lib1.dart' deferred as l1;
 
-/*strong.member: c1:OutputUnit(main, {})*/
-const c1 = /*strong.OutputUnit(main, {})*/ const C(1);
+const c1 = const C(1);
 
-/*strong.member: main:OutputUnit(main, {})*/
-/*strongConst.member: main:
+/*member: main:
  OutputUnit(main, {}),
  constants=[
   ConstructedConstant(C(x=IntConstant(1)))=OutputUnit(main, {}),
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_shared.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_constant3/shared.dart
similarity index 87%
rename from tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_shared.dart
rename to tests/compiler/dart2js/deferred_loading/data/deferred_constant3/shared.dart
index f2a7bdd..5ce79ac 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_shared.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_constant3/shared.dart
@@ -4,7 +4,6 @@
 
 /*class: C:OutputUnit(main, {})*/
 class C {
-  /*strong.member: C.:OutputUnit(main, {})*/
   const C(this.x);
 
   /*member: C.x:OutputUnit(main, {})*/
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_fail_and_retry_lib.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_fail_and_retry/lib.dart
similarity index 100%
rename from tests/compiler/dart2js/deferred_loading/libs/deferred_fail_and_retry_lib.dart
rename to tests/compiler/dart2js/deferred_loading/data/deferred_fail_and_retry/lib.dart
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_fail_and_retry.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_fail_and_retry/main.dart
similarity index 94%
rename from tests/compiler/dart2js/deferred_loading/data/deferred_fail_and_retry.dart
rename to tests/compiler/dart2js/deferred_loading/data/deferred_fail_and_retry/main.dart
index cd5ae14..2d2d2bb 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_fail_and_retry.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_fail_and_retry/main.dart
@@ -4,7 +4,7 @@
 
 // Test that when a deferred import fails to load, it is possible to retry.
 
-import "../libs/deferred_fail_and_retry_lib.dart" deferred as lib;
+import 'lib.dart' deferred as lib;
 import "package:expect/expect.dart";
 import "package:async_helper/async_helper.dart";
 import "dart:js" as js;
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_function_lib.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_function/lib.dart
similarity index 88%
rename from tests/compiler/dart2js/deferred_loading/libs/deferred_function_lib.dart
rename to tests/compiler/dart2js/deferred_loading/data/deferred_function/lib.dart
index 1424c6a..5f88684 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_function_lib.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_function/lib.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.
 
-// Imported by deferred_function.dart and
+// Imported by main.dart and
 
 library deferred_function_library;
 
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_function.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_function/main.dart
similarity index 79%
rename from tests/compiler/dart2js/deferred_loading/data/deferred_function.dart
rename to tests/compiler/dart2js/deferred_loading/data/deferred_function/main.dart
index 47ecc4e..19a41af 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_function.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_function/main.dart
@@ -5,10 +5,9 @@
 // Test that loading of a library (with top-level functions only) can
 // be deferred.
 
-import '../libs/deferred_function_lib.dart' deferred as lib;
+import 'lib.dart' deferred as lib;
 
-/*strong.member: readFoo:OutputUnit(main, {})*/
-/*strongConst.member: readFoo:
+/*member: readFoo:
  OutputUnit(main, {}),
  constants=[FunctionConstant(foo)=OutputUnit(1, {lib})]
 */
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib3.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_overlapping/deferred_overlapping_lib3.dart
similarity index 100%
rename from tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib3.dart
rename to tests/compiler/dart2js/deferred_loading/data/deferred_overlapping/deferred_overlapping_lib3.dart
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib1.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_overlapping/lib1.dart
similarity index 100%
rename from tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib1.dart
rename to tests/compiler/dart2js/deferred_loading/data/deferred_overlapping/lib1.dart
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib2.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_overlapping/lib2.dart
similarity index 100%
rename from tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib2.dart
rename to tests/compiler/dart2js/deferred_loading/data/deferred_overlapping/lib2.dart
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_overlapping.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_overlapping/main.dart
similarity index 79%
rename from tests/compiler/dart2js/deferred_loading/data/deferred_overlapping.dart
rename to tests/compiler/dart2js/deferred_loading/data/deferred_overlapping/main.dart
index 7919162..ce926d1 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_overlapping.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_overlapping/main.dart
@@ -2,8 +2,8 @@
 // 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 "../libs/deferred_overlapping_lib1.dart" deferred as lib1;
-import "../libs/deferred_overlapping_lib2.dart" deferred as lib2;
+import 'lib1.dart' deferred as lib1;
+import 'lib2.dart' deferred as lib2;
 
 // lib1.C1 and lib2.C2 has a shared base class. It will go in its own hunk.
 /*member: main:OutputUnit(main, {})*/
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_typed_map_lib1.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_typed_map/lib1.dart
similarity index 76%
rename from tests/compiler/dart2js/deferred_loading/libs/deferred_typed_map_lib1.dart
rename to tests/compiler/dart2js/deferred_loading/data/deferred_typed_map/lib1.dart
index b435e6d..da54242 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_typed_map_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_typed_map/lib1.dart
@@ -7,10 +7,7 @@
 
 typedef dynamic FF({M b});
 
-/*strong.member: table:OutputUnit(1, {lib})*/
-const table =
-/*strong.OutputUnit(1, {lib})*/
-    const <int, FF>{1: f1, 2: f2};
+const table = const <int, FF>{1: f1, 2: f2};
 
 /*member: f1:OutputUnit(1, {lib})*/
 dynamic f1({M b}) => null;
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_typed_map.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_typed_map/main.dart
similarity index 76%
rename from tests/compiler/dart2js/deferred_loading/data/deferred_typed_map.dart
rename to tests/compiler/dart2js/deferred_loading/data/deferred_typed_map/main.dart
index deed5a1..109f67e 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_typed_map.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_typed_map/main.dart
@@ -2,10 +2,9 @@
 // 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 '../libs/deferred_typed_map_lib1.dart' deferred as lib;
+import 'lib1.dart' deferred as lib;
 
-/*strong.member: main:OutputUnit(main, {})*/
-/*strongConst.member: main:
+/*member: main:
  OutputUnit(main, {}),
  constants=[
   MapConstant(<int, dynamic Function({M b})>{IntConstant(1): FunctionConstant(f1), IntConstant(2): FunctionConstant(f2)})=OutputUnit(1, {lib})]
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_typedef_lib1.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_typedef/lib1.dart
similarity index 67%
rename from tests/compiler/dart2js/deferred_loading/libs/deferred_typedef_lib1.dart
rename to tests/compiler/dart2js/deferred_loading/data/deferred_typedef/lib1.dart
index 4cdfe95..c219ae7 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_typedef_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_typedef/lib1.dart
@@ -12,7 +12,6 @@
   /*member: C.b:OutputUnit(1, {lib1})*/
   final b;
 
-  /*strong.member: C.:OutputUnit(1, {lib1})*/
   const C(this.a, this.b);
 }
 
@@ -23,8 +22,6 @@
 /*member: topLevelMethod:OutputUnit(1, {lib1})*/
 topLevelMethod() {}
 
-/*strong.member: cA:OutputUnit(1, {lib1})*/
-const cA = /*strong.OutputUnit(1, {lib1})*/ const C(MyF1, topLevelMethod);
+const cA = const C(MyF1, topLevelMethod);
 
-/*strong.member: cB:OutputUnit(1, {lib1})*/
-const cB = /*strong.OutputUnit(1, {lib1})*/ MyF2;
+const cB = MyF2;
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_typedef.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_typedef/main.dart
similarity index 78%
rename from tests/compiler/dart2js/deferred_loading/data/deferred_typedef.dart
rename to tests/compiler/dart2js/deferred_loading/data/deferred_typedef/main.dart
index 23578ec..9a6fea8 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_typedef.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_typedef/main.dart
@@ -2,10 +2,9 @@
 // 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 '../libs/deferred_typedef_lib1.dart' deferred as lib1;
+import 'lib1.dart' deferred as lib1;
 
-/*strong.member: main:OutputUnit(main, {})*/
-/*strongConst.member: main:
+/*member: main:
  OutputUnit(main, {}),
  constants=[
   ConstructedConstant(C(a=TypeConstant(void Function()),b=FunctionConstant(topLevelMethod)))=OutputUnit(1, {lib1}),
diff --git a/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_main.dart b/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_constants/exported_main.dart
similarity index 81%
rename from tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_main.dart
rename to tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_constants/exported_main.dart
index 552be6b..6a9d208 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_main.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_constants/exported_main.dart
@@ -2,10 +2,9 @@
 // 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 'dont_inline_deferred_constants_lib1.dart' deferred as lib1;
-import 'dont_inline_deferred_constants_lib2.dart' deferred as lib2;
+import 'lib1.dart' deferred as lib1;
+import 'lib2.dart' deferred as lib2;
 
-/*strong.member: c:OutputUnit(main, {})*/
 const c = "string3";
 
 /*class: C:OutputUnit(main, {})*/
@@ -13,15 +12,13 @@
   /*member: C.p:OutputUnit(main, {})*/
   final p;
 
-  /*strong.member: C.:OutputUnit(main, {})*/
   const C(this.p);
 }
 
 /*member: foo:OutputUnit(2, {lib1, lib2})*/
 foo() => print("main");
 
-/*strong.member: main:OutputUnit(main, {})*/
-/*strongConst.member: main:
+/*member: main:
  OutputUnit(main, {}),
  constants=[
   ConstructedConstant(C(p=IntConstant(1)))=OutputUnit(main, {}),
diff --git a/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_constants/lib1.dart b/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_constants/lib1.dart
new file mode 100644
index 0000000..b0aacb1
--- /dev/null
+++ b/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_constants/lib1.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2017, 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 'exported_main.dart' show C;
+import 'exported_main.dart' as main;
+
+const C1 = "string1";
+
+const C1b = const C("string1");
+
+const C2 = 1010;
+
+const C2b = const C(1010);
+
+/*class: D:null*/
+class D {
+  static const C3 = "string2";
+
+  static const C3b = const C("string2");
+}
+
+const C4 = "string4";
+
+const C5 = const C(1);
+
+const C6 = const C(2);
+
+/*member: foo:OutputUnit(1, {lib1})*/
+foo() {
+  print("lib1");
+  main.foo();
+}
diff --git a/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_constants/lib2.dart b/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_constants/lib2.dart
new file mode 100644
index 0000000..050070b
--- /dev/null
+++ b/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_constants/lib2.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2017, 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 'exported_main.dart' show C;
+import 'exported_main.dart' as main;
+
+const C4 = "string4";
+
+const C5 = const C(1);
+
+const C6 = const C(2);
+
+/*member: foo:OutputUnit(3, {lib2})*/
+foo() {
+  print("lib2");
+  main.foo();
+}
diff --git a/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_constants.dart b/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_constants/main.dart
similarity index 85%
rename from tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_constants.dart
rename to tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_constants/main.dart
index 47347ea..6afae7d 100644
--- a/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_constants.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_constants/main.dart
@@ -4,4 +4,4 @@
 
 // TODO(sigmund): remove this indirection and move the main code here. This is
 // needed because of the id-equivalence frameworks overrides the entrypoint URI.
-export '../libs/dont_inline_deferred_constants_main.dart';
+export 'exported_main.dart';
diff --git a/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_global_lib.dart b/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_global/lib.dart
similarity index 100%
rename from tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_global_lib.dart
rename to tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_global/lib.dart
diff --git a/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_global.dart b/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_global/main.dart
similarity index 85%
rename from tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_global.dart
rename to tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_global/main.dart
index 8dab5c6..964342f 100644
--- a/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_global.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_global/main.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.
 
-import '../libs/dont_inline_deferred_global_lib.dart' deferred as lib;
+import 'lib.dart' deferred as lib;
 
 /*member: main:OutputUnit(main, {})*/
 void main() {
diff --git a/tests/modular/issue37523/def.dart b/tests/compiler/dart2js/deferred_loading/data/future_or/lib1.dart
similarity index 67%
rename from tests/modular/issue37523/def.dart
rename to tests/compiler/dart2js/deferred_loading/data/future_or/lib1.dart
index 3cda2b0..63d79e5 100644
--- a/tests/modular/issue37523/def.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/future_or/lib1.dart
@@ -2,14 +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.
 
-class B {
-  const B();
-}
+import 'lib2.dart';
 
-class A {
-  final B b;
-  const A(this.b);
-}
-
-const ab = A(B());
-const b = B();
+const dynamic field = const A();
diff --git a/tests/compiler/dart2js/deferred_loading/libs/future_or_lib2.dart b/tests/compiler/dart2js/deferred_loading/data/future_or/lib2.dart
similarity index 87%
rename from tests/compiler/dart2js/deferred_loading/libs/future_or_lib2.dart
rename to tests/compiler/dart2js/deferred_loading/data/future_or/lib2.dart
index 634a6b4..d8401d3 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/future_or_lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/future_or/lib2.dart
@@ -4,7 +4,6 @@
 
 /*class: A:OutputUnit(main, {})*/
 class A {
-  /*strong.member: A.:OutputUnit(1, {lib1})*/
   const A();
 
   /*member: A.method:OutputUnit(main, {})*/
diff --git a/tests/compiler/dart2js/deferred_loading/data/future_or.dart b/tests/compiler/dart2js/deferred_loading/data/future_or/main.dart
similarity index 70%
rename from tests/compiler/dart2js/deferred_loading/data/future_or.dart
rename to tests/compiler/dart2js/deferred_loading/data/future_or/main.dart
index a31156a..9b185a1 100644
--- a/tests/compiler/dart2js/deferred_loading/data/future_or.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/future_or/main.dart
@@ -3,11 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:async';
-import '../libs/future_or_lib1.dart' deferred as lib1;
-import '../libs/future_or_lib2.dart' as lib2;
+import 'lib1.dart' deferred as lib1;
+import 'lib2.dart' as lib2;
 
-/*strong.member: main:OutputUnit(main, {})*/
-/*strongConst.member: main:
+/*member: main:
  OutputUnit(main, {}),
  constants=[ConstructedConstant(A())=OutputUnit(1, {lib1})]
 */
diff --git a/tests/compiler/dart2js/deferred_loading/libs/instantiation0_strong_lib1.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation0/lib1.dart
similarity index 87%
rename from tests/compiler/dart2js/deferred_loading/libs/instantiation0_strong_lib1.dart
rename to tests/compiler/dart2js/deferred_loading/data/instantiation0/lib1.dart
index 533595e..fee884e 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/instantiation0_strong_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation0/lib1.dart
@@ -7,8 +7,7 @@
 
 typedef dynamic G<T>(T v);
 
-/*strong.member: m:OutputUnit(1, {b})*/
-/*strongConst.member: m:
+/*member: m:
  OutputUnit(1, {b}),
  constants=[InstantiationConstant([int],FunctionConstant(getFoo))=OutputUnit(1, {b})]
 */
diff --git a/tests/compiler/dart2js/deferred_loading/data/instantiation0.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation0/main.dart
similarity index 87%
rename from tests/compiler/dart2js/deferred_loading/data/instantiation0.dart
rename to tests/compiler/dart2js/deferred_loading/data/instantiation0/main.dart
index 8e008fc..aac590a 100644
--- a/tests/compiler/dart2js/deferred_loading/data/instantiation0.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation0/main.dart
@@ -7,7 +7,7 @@
 /*class: global#Instantiation:OutputUnit(1, {b})*/
 /*class: global#Instantiation1:OutputUnit(1, {b})*/
 
-import '../libs/instantiation0_strong_lib1.dart' deferred as b;
+import 'lib1.dart' deferred as b;
 
 /*member: main:OutputUnit(main, {})*/
 main() async {
diff --git a/tests/compiler/dart2js/deferred_loading/libs/instantiation1_strong_lib1.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation1/lib1.dart
similarity index 87%
rename from tests/compiler/dart2js/deferred_loading/libs/instantiation1_strong_lib1.dart
rename to tests/compiler/dart2js/deferred_loading/data/instantiation1/lib1.dart
index 03ca1d9..b9d2704 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/instantiation1_strong_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation1/lib1.dart
@@ -7,8 +7,7 @@
 
 typedef dynamic G<T>(T v);
 
-/*strong.member: m:OutputUnit(1, {b})*/
-/*strongConst.member: m:
+/*member: m:
  OutputUnit(1, {b}),
  constants=[
   InstantiationConstant([int],FunctionConstant(getFoo))=OutputUnit(1, {b})]
diff --git a/tests/compiler/dart2js/deferred_loading/libs/instantiation1_strong_lib2.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation1/lib2.dart
similarity index 87%
rename from tests/compiler/dart2js/deferred_loading/libs/instantiation1_strong_lib2.dart
rename to tests/compiler/dart2js/deferred_loading/data/instantiation1/lib2.dart
index eaf6318..3836503 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/instantiation1_strong_lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation1/lib2.dart
@@ -7,8 +7,7 @@
 
 typedef dynamic G<T, S>(T v, S w);
 
-/*strong.member: m:OutputUnit(3, {c})*/
-/*strongConst.member: m:
+/*member: m:
  OutputUnit(3, {c}),
  constants=[
   InstantiationConstant([int, int],FunctionConstant(getFoo))=OutputUnit(3, {c})]
diff --git a/tests/compiler/dart2js/deferred_loading/data/instantiation1.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation1/main.dart
similarity index 82%
rename from tests/compiler/dart2js/deferred_loading/data/instantiation1.dart
rename to tests/compiler/dart2js/deferred_loading/data/instantiation1/main.dart
index 174bc54c..8478533 100644
--- a/tests/compiler/dart2js/deferred_loading/data/instantiation1.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation1/main.dart
@@ -9,8 +9,8 @@
 /*class: global#Instantiation1:OutputUnit(1, {b})*/
 /*class: global#Instantiation2:OutputUnit(3, {c})*/
 
-import '../libs/instantiation1_strong_lib1.dart' deferred as b;
-import '../libs/instantiation1_strong_lib2.dart' deferred as c;
+import 'lib1.dart' deferred as b;
+import 'lib2.dart' deferred as c;
 
 /*member: main:OutputUnit(main, {})*/
 main() async {
diff --git a/tests/compiler/dart2js/deferred_loading/libs/instantiation2_strong_lib1.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation2/lib1.dart
similarity index 87%
rename from tests/compiler/dart2js/deferred_loading/libs/instantiation2_strong_lib1.dart
rename to tests/compiler/dart2js/deferred_loading/data/instantiation2/lib1.dart
index a5b2423..449b9d5 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/instantiation2_strong_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation2/lib1.dart
@@ -7,8 +7,7 @@
 
 typedef dynamic G<T>(T v);
 
-/*strong.member: m:OutputUnit(2, {b})*/
-/*strongConst.member: m:
+/*member: m:
  OutputUnit(2, {b}),
  constants=[
   InstantiationConstant([int],FunctionConstant(getFoo))=OutputUnit(2, {b})]
diff --git a/tests/compiler/dart2js/deferred_loading/libs/instantiation2_strong_lib2.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation2/lib2.dart
similarity index 87%
rename from tests/compiler/dart2js/deferred_loading/libs/instantiation2_strong_lib2.dart
rename to tests/compiler/dart2js/deferred_loading/data/instantiation2/lib2.dart
index 7e50462..9263737 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/instantiation2_strong_lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation2/lib2.dart
@@ -7,8 +7,7 @@
 
 typedef dynamic G<T>(T v);
 
-/*strong.member: m:OutputUnit(3, {c})*/
-/*strongConst.member: m:
+/*member: m:
  OutputUnit(3, {c}),
  constants=[
   InstantiationConstant([int],FunctionConstant(getFoo))=OutputUnit(3, {c})]
diff --git a/tests/compiler/dart2js/deferred_loading/data/instantiation2.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation2/main.dart
similarity index 81%
rename from tests/compiler/dart2js/deferred_loading/data/instantiation2.dart
rename to tests/compiler/dart2js/deferred_loading/data/instantiation2/main.dart
index bd99ede..b2b6cfc 100644
--- a/tests/compiler/dart2js/deferred_loading/data/instantiation2.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation2/main.dart
@@ -8,8 +8,8 @@
 /*class: global#Instantiation:OutputUnit(1, {b, c})*/
 /*class: global#Instantiation1:OutputUnit(1, {b, c})*/
 
-import '../libs/instantiation2_strong_lib1.dart' deferred as b;
-import '../libs/instantiation2_strong_lib2.dart' deferred as c;
+import 'lib1.dart' deferred as b;
+import 'lib2.dart' deferred as c;
 
 /*member: main:OutputUnit(main, {})*/
 main() async {
diff --git a/tests/compiler/dart2js/deferred_loading/libs/instantiation3_strong_lib1.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation3/lib1.dart
similarity index 86%
rename from tests/compiler/dart2js/deferred_loading/libs/instantiation3_strong_lib1.dart
rename to tests/compiler/dart2js/deferred_loading/data/instantiation3/lib1.dart
index 74a68cb..a49b089 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/instantiation3_strong_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation3/lib1.dart
@@ -7,8 +7,7 @@
 
 typedef dynamic G<T>(T v);
 
-/*strong.member: m:OutputUnit(1, {b})*/
-/*strongConst.member: m:
+/*member: m:
  OutputUnit(1, {b}),
  constants=[FunctionConstant(getFoo)=OutputUnit(1, {b})]
 */
diff --git a/tests/compiler/dart2js/deferred_loading/data/instantiation3.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation3/main.dart
similarity index 88%
rename from tests/compiler/dart2js/deferred_loading/data/instantiation3.dart
rename to tests/compiler/dart2js/deferred_loading/data/instantiation3/main.dart
index dcc3b55..6d22b9a 100644
--- a/tests/compiler/dart2js/deferred_loading/data/instantiation3.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation3/main.dart
@@ -9,7 +9,7 @@
 
 /*member: global#instantiate1:OutputUnit(1, {b})*/
 
-import '../libs/instantiation3_strong_lib1.dart' deferred as b;
+import 'lib1.dart' deferred as b;
 
 /*member: main:OutputUnit(main, {})*/
 main() async {
diff --git a/tests/compiler/dart2js/deferred_loading/libs/instantiation3_strong_lib1.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation4/lib1.dart
similarity index 86%
copy from tests/compiler/dart2js/deferred_loading/libs/instantiation3_strong_lib1.dart
copy to tests/compiler/dart2js/deferred_loading/data/instantiation4/lib1.dart
index 74a68cb..a49b089 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/instantiation3_strong_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation4/lib1.dart
@@ -7,8 +7,7 @@
 
 typedef dynamic G<T>(T v);
 
-/*strong.member: m:OutputUnit(1, {b})*/
-/*strongConst.member: m:
+/*member: m:
  OutputUnit(1, {b}),
  constants=[FunctionConstant(getFoo)=OutputUnit(1, {b})]
 */
diff --git a/tests/compiler/dart2js/deferred_loading/libs/instantiation4_strong_lib2.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation4/lib2.dart
similarity index 87%
rename from tests/compiler/dart2js/deferred_loading/libs/instantiation4_strong_lib2.dart
rename to tests/compiler/dart2js/deferred_loading/data/instantiation4/lib2.dart
index d1ac5bc..3c506bb 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/instantiation4_strong_lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation4/lib2.dart
@@ -7,8 +7,7 @@
 
 typedef dynamic G<T, S>(T v, S w);
 
-/*strong.member: m:OutputUnit(3, {c})*/
-/*strongConst.member: m:
+/*member: m:
  OutputUnit(3, {c}),
  constants=[FunctionConstant(getFoo)=OutputUnit(3, {c})]
 */
diff --git a/tests/compiler/dart2js/deferred_loading/data/instantiation4.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation4/main.dart
similarity index 84%
rename from tests/compiler/dart2js/deferred_loading/data/instantiation4.dart
rename to tests/compiler/dart2js/deferred_loading/data/instantiation4/main.dart
index 4fe43c2..6bcbdc5 100644
--- a/tests/compiler/dart2js/deferred_loading/data/instantiation4.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation4/main.dart
@@ -12,8 +12,8 @@
 /*member: global#instantiate1:OutputUnit(1, {b})*/
 /*member: global#instantiate2:OutputUnit(3, {c})*/
 
-import '../libs/instantiation4_strong_lib1.dart' deferred as b;
-import '../libs/instantiation4_strong_lib2.dart' deferred as c;
+import 'lib1.dart' deferred as b;
+import 'lib2.dart' deferred as c;
 
 /*member: main:OutputUnit(main, {})*/
 main() async {
diff --git a/tests/compiler/dart2js/deferred_loading/libs/instantiation5_strong_lib1.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation5/lib1.dart
similarity index 86%
rename from tests/compiler/dart2js/deferred_loading/libs/instantiation5_strong_lib1.dart
rename to tests/compiler/dart2js/deferred_loading/data/instantiation5/lib1.dart
index 18813d7..fc0d440 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/instantiation5_strong_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation5/lib1.dart
@@ -7,8 +7,7 @@
 
 typedef dynamic G<T>(T v);
 
-/*strong.member: m:OutputUnit(2, {b})*/
-/*strongConst.member: m:
+/*member: m:
  OutputUnit(2, {b}),
  constants=[FunctionConstant(getFoo)=OutputUnit(2, {b})]
 */
diff --git a/tests/compiler/dart2js/deferred_loading/libs/instantiation5_strong_lib2.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation5/lib2.dart
similarity index 86%
rename from tests/compiler/dart2js/deferred_loading/libs/instantiation5_strong_lib2.dart
rename to tests/compiler/dart2js/deferred_loading/data/instantiation5/lib2.dart
index ddc4f0e9..a30cb28 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/instantiation5_strong_lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation5/lib2.dart
@@ -7,8 +7,7 @@
 
 typedef dynamic G<T>(T v);
 
-/*strong.member: m:OutputUnit(3, {c})*/
-/*strongConst.member: m:
+/*member: m:
  OutputUnit(3, {c}),
  constants=[FunctionConstant(getFoo)=OutputUnit(3, {c})]
 */
diff --git a/tests/compiler/dart2js/deferred_loading/data/instantiation5.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation5/main.dart
similarity index 82%
rename from tests/compiler/dart2js/deferred_loading/data/instantiation5.dart
rename to tests/compiler/dart2js/deferred_loading/data/instantiation5/main.dart
index 6397d89..b3730ff 100644
--- a/tests/compiler/dart2js/deferred_loading/data/instantiation5.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation5/main.dart
@@ -10,8 +10,8 @@
 
 /*member: global#instantiate1:OutputUnit(1, {b, c})*/
 
-import '../libs/instantiation5_strong_lib1.dart' deferred as b;
-import '../libs/instantiation5_strong_lib2.dart' deferred as c;
+import 'lib1.dart' deferred as b;
+import 'lib2.dart' deferred as c;
 
 /*member: main:OutputUnit(main, {})*/
 main() async {
diff --git a/tests/compiler/dart2js/deferred_loading/libs/shared_constant_a.dart b/tests/compiler/dart2js/deferred_loading/data/shared_constant/lib_a.dart
similarity index 74%
rename from tests/compiler/dart2js/deferred_loading/libs/shared_constant_a.dart
rename to tests/compiler/dart2js/deferred_loading/data/shared_constant/lib_a.dart
index 7a5817c..a2bd8dc 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/shared_constant_a.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/shared_constant/lib_a.dart
@@ -2,10 +2,9 @@
 // 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 'shared_constant_shared.dart' deferred as s1;
+import 'shared.dart' deferred as s1;
 
-/*strong.member: doA:OutputUnit(main, {})*/
-/*strongConst.member: doA:
+/*member: doA:
  OutputUnit(main, {}),
  constants=[ConstructedConstant(C())=OutputUnit(1, {s1, s2})]
 */
diff --git a/tests/compiler/dart2js/deferred_loading/libs/shared_constant_b.dart b/tests/compiler/dart2js/deferred_loading/data/shared_constant/lib_b.dart
similarity index 74%
rename from tests/compiler/dart2js/deferred_loading/libs/shared_constant_b.dart
rename to tests/compiler/dart2js/deferred_loading/data/shared_constant/lib_b.dart
index e4cd5e7..aa58162 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/shared_constant_b.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/shared_constant/lib_b.dart
@@ -2,10 +2,9 @@
 // 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 'shared_constant_shared.dart' deferred as s2;
+import 'shared.dart' deferred as s2;
 
-/*strong.member: doB:OutputUnit(main, {})*/
-/*strongConst.member: doB:
+/*member: doB:
  OutputUnit(main, {}),
  constants=[ConstructedConstant(C())=OutputUnit(1, {s1, s2})]
 */
diff --git a/tests/compiler/dart2js/deferred_loading/libs/shared_constant_c.dart b/tests/compiler/dart2js/deferred_loading/data/shared_constant/lib_c.dart
similarity index 87%
rename from tests/compiler/dart2js/deferred_loading/libs/shared_constant_c.dart
rename to tests/compiler/dart2js/deferred_loading/data/shared_constant/lib_c.dart
index 8d1d346..f6b3783 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/shared_constant_c.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/shared_constant/lib_c.dart
@@ -4,7 +4,6 @@
 
 /*class: C:OutputUnit(1, {s1, s2})*/
 class C {
-  /*strong.member: C.:OutputUnit(1, {s1, s2})*/
   const C();
 
   /*member: C.method:OutputUnit(1, {s1, s2})*/
diff --git a/tests/compiler/dart2js/deferred_loading/data/shared_constant.dart b/tests/compiler/dart2js/deferred_loading/data/shared_constant/main.dart
similarity index 87%
rename from tests/compiler/dart2js/deferred_loading/data/shared_constant.dart
rename to tests/compiler/dart2js/deferred_loading/data/shared_constant/main.dart
index c082a4d..6cdd211 100644
--- a/tests/compiler/dart2js/deferred_loading/data/shared_constant.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/shared_constant/main.dart
@@ -8,8 +8,8 @@
 /// deferred import URI, the deferred-constant initializer was incorrectly moved
 /// to the main output unit.
 
-import '../libs/shared_constant_a.dart';
-import '../libs/shared_constant_b.dart';
+import 'lib_a.dart';
+import 'lib_b.dart';
 
 /*member: main:OutputUnit(main, {})*/
 main() async {
diff --git a/tests/compiler/dart2js/deferred_loading/data/shared_constant/shared.dart b/tests/compiler/dart2js/deferred_loading/data/shared_constant/shared.dart
new file mode 100644
index 0000000..1281b4b
--- /dev/null
+++ b/tests/compiler/dart2js/deferred_loading/data/shared_constant/shared.dart
@@ -0,0 +1,7 @@
+// 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.
+
+import 'lib_c.dart';
+
+const constant = const C();
diff --git a/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib1.dart b/tests/compiler/dart2js/deferred_loading/data/static_separate/lib1.dart
similarity index 83%
rename from tests/compiler/dart2js/deferred_loading/libs/static_separate_lib1.dart
rename to tests/compiler/dart2js/deferred_loading/data/static_separate/lib1.dart
index f61fbe9..00ab4d3 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/static_separate/lib1.dart
@@ -9,12 +9,10 @@
   /*member: ConstClass.x:OutputUnit(2, {lib1, lib2})*/
   final x;
 
-  /*strong.member: ConstClass.:OutputUnit(2, {lib1, lib2})*/
   const ConstClass(this.x);
 }
 
-/*strong.member: x:OutputUnit(2, {lib1, lib2})*/
-/*strongConst.member: x:
+/*member: x:
  OutputUnit(2, {lib1, lib2}),
  constants=[ConstructedConstant(ConstClass(x=ConstructedConstant(ConstClass(x=IntConstant(1)))))=OutputUnit(2, {lib1, lib2})]
 */
@@ -40,8 +38,7 @@
 
 /*class: C1:null*/
 class C1 {
-  /*strong.member: C1.foo:OutputUnit(3, {lib2})*/
-  /*strongConst.member: C1.foo:
+  /*member: C1.foo:
    OutputUnit(3, {lib2}),
    constants=[MapConstant({})=OutputUnit(3, {lib2})]
   */
@@ -63,15 +60,13 @@
 
 /*class: C3:OutputUnit(1, {lib1})*/
 class C3 {
-  /*strong.member: C3.foo:OutputUnit(3, {lib2})*/
-  /*strongConst.member: C3.foo:
+  /*member: C3.foo:
    OutputUnit(3, {lib2}),
    constants=[ConstructedConstant(ConstClass(x=ConstructedConstant(ConstClass(x=IntConstant(1)))))=OutputUnit(2, {lib1, lib2})]
   */
   static final foo = const ConstClass(const ConstClass(1));
 
-  /*strong.member: C3.bar:OutputUnit(1, {lib1})*/
-  /*strongConst.member: C3.bar:
+  /*member: C3.bar:
    OutputUnit(1, {lib1}),
    constants=[ConstructedConstant(ConstClass(x=ConstructedConstant(ConstClass(x=IntConstant(1)))))=OutputUnit(2, {lib1, lib2})]
   */
@@ -95,8 +90,7 @@
 
 /*class: C5:OutputUnit(1, {lib1})*/
 class C5 {
-  /*strong.member: C5.foo:OutputUnit(3, {lib2})*/
-  static const foo = /*strong.OutputUnit(3, {lib2})*/ const [
+  static const foo = const [
     const {1: 3}
   ];
 
diff --git a/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib2.dart b/tests/compiler/dart2js/deferred_loading/data/static_separate/lib2.dart
similarity index 87%
rename from tests/compiler/dart2js/deferred_loading/libs/static_separate_lib2.dart
rename to tests/compiler/dart2js/deferred_loading/data/static_separate/lib2.dart
index e0bf128..f5f029d 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/static_separate/lib2.dart
@@ -5,10 +5,9 @@
 library lib2;
 
 import "package:expect/expect.dart";
-import "static_separate_lib1.dart";
+import "lib1.dart";
 
-/*strong.member: foo:OutputUnit(3, {lib2})*/
-/*strongConst.member: foo:
+/*member: foo:
  OutputUnit(3, {lib2}),
  constants=[
   ListConstant(<Map<int,int>>[MapConstant(<int, int>{IntConstant(1): IntConstant(3)})])=OutputUnit(3, {lib2}),
diff --git a/tests/compiler/dart2js/deferred_loading/data/static_separate.dart b/tests/compiler/dart2js/deferred_loading/data/static_separate/main.dart
similarity index 89%
rename from tests/compiler/dart2js/deferred_loading/data/static_separate.dart
rename to tests/compiler/dart2js/deferred_loading/data/static_separate/main.dart
index 22404aa..0ba29ee 100644
--- a/tests/compiler/dart2js/deferred_loading/data/static_separate.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/static_separate/main.dart
@@ -9,8 +9,8 @@
 
 import "package:expect/expect.dart";
 import "package:async_helper/async_helper.dart";
-import "../libs/static_separate_lib1.dart" deferred as lib1;
-import "../libs/static_separate_lib2.dart" deferred as lib2;
+import 'lib1.dart' deferred as lib1;
+import 'lib2.dart' deferred as lib2;
 
 /*member: main:OutputUnit(main, {})*/
 void main() {
diff --git a/tests/compiler/dart2js/deferred_loading/libs/type_argument_dependency_lib1.dart b/tests/compiler/dart2js/deferred_loading/data/type_argument_dependency/lib1.dart
similarity index 87%
rename from tests/compiler/dart2js/deferred_loading/libs/type_argument_dependency_lib1.dart
rename to tests/compiler/dart2js/deferred_loading/data/type_argument_dependency/lib1.dart
index c89d690..d905a5e 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/type_argument_dependency_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/type_argument_dependency/lib1.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.
 
-import 'type_argument_dependency_lib2.dart';
+import 'lib2.dart';
 
 /*member: doCast:OutputUnit(main, {})*/
 doCast(List<dynamic> l) => l.cast<B>().map(/*OutputUnit(main, {})*/ (x) => 1);
diff --git a/tests/compiler/dart2js/deferred_loading/libs/type_argument_dependency_lib2.dart b/tests/compiler/dart2js/deferred_loading/data/type_argument_dependency/lib2.dart
similarity index 100%
rename from tests/compiler/dart2js/deferred_loading/libs/type_argument_dependency_lib2.dart
rename to tests/compiler/dart2js/deferred_loading/data/type_argument_dependency/lib2.dart
diff --git a/tests/compiler/dart2js/deferred_loading/data/type_argument_dependency.dart b/tests/compiler/dart2js/deferred_loading/data/type_argument_dependency/main.dart
similarity index 73%
rename from tests/compiler/dart2js/deferred_loading/data/type_argument_dependency.dart
rename to tests/compiler/dart2js/deferred_loading/data/type_argument_dependency/main.dart
index b64e30e..1e231be 100644
--- a/tests/compiler/dart2js/deferred_loading/data/type_argument_dependency.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/type_argument_dependency/main.dart
@@ -2,8 +2,8 @@
 // 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 '../libs/type_argument_dependency_lib1.dart';
-import '../libs/type_argument_dependency_lib2.dart' deferred as c;
+import 'lib1.dart';
+import 'lib2.dart' deferred as c;
 
 /*member: main:OutputUnit(main, {})*/
 main() async {
diff --git a/tests/compiler/dart2js/deferred_loading/data/type_arguments/lib1.dart b/tests/compiler/dart2js/deferred_loading/data/type_arguments/lib1.dart
new file mode 100644
index 0000000..a55af13
--- /dev/null
+++ b/tests/compiler/dart2js/deferred_loading/data/type_arguments/lib1.dart
@@ -0,0 +1,17 @@
+// 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.
+
+import 'lib3.dart';
+
+/*class: A:OutputUnit(1, {lib1})*/
+class A<T> {
+  const A();
+}
+
+/*class: B:OutputUnit(1, {lib1})*/
+class B {}
+
+const dynamic field1 = const A<B>();
+
+const dynamic field2 = const A<F>();
diff --git a/tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib2.dart b/tests/compiler/dart2js/deferred_loading/data/type_arguments/lib2.dart
similarity index 66%
rename from tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib2.dart
rename to tests/compiler/dart2js/deferred_loading/data/type_arguments/lib2.dart
index 571959b..c7672bb 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/type_arguments/lib2.dart
@@ -4,12 +4,10 @@
 
 /*class: C:OutputUnit(main, {})*/
 class C<T> {
-  /*strong.member: C.:OutputUnit(main, {})*/
   const C();
 }
 
 /*class: D:OutputUnit(main, {})*/
 class D {}
 
-/*strong.member: field:OutputUnit(main, {})*/
-const dynamic field = /*strong.OutputUnit(main, {})*/ const C<D>();
+const dynamic field = const C<D>();
diff --git a/tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib3.dart b/tests/compiler/dart2js/deferred_loading/data/type_arguments/lib3.dart
similarity index 67%
rename from tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib3.dart
rename to tests/compiler/dart2js/deferred_loading/data/type_arguments/lib3.dart
index 2ef8be5..c7aad0d 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib3.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/type_arguments/lib3.dart
@@ -4,12 +4,10 @@
 
 /*class: E:OutputUnit(3, {lib3})*/
 class E<T> {
-  /*strong.member: E.:OutputUnit(3, {lib3})*/
   const E();
 }
 
 /*class: F:OutputUnit(2, {lib1, lib3})*/
 class F {}
 
-/*strong.member: field:OutputUnit(3, {lib3})*/
-const dynamic field = /*strong.OutputUnit(3, {lib3})*/ const E<F>();
+const dynamic field = const E<F>();
diff --git a/tests/compiler/dart2js/deferred_loading/data/type_arguments.dart b/tests/compiler/dart2js/deferred_loading/data/type_arguments/main.dart
similarity index 69%
rename from tests/compiler/dart2js/deferred_loading/data/type_arguments.dart
rename to tests/compiler/dart2js/deferred_loading/data/type_arguments/main.dart
index a39b055..2f6795e 100644
--- a/tests/compiler/dart2js/deferred_loading/data/type_arguments.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/type_arguments/main.dart
@@ -2,12 +2,11 @@
 // 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 '../libs/type_arguments_lib1.dart' deferred as lib1;
-import '../libs/type_arguments_lib2.dart' as lib2;
-import '../libs/type_arguments_lib3.dart' deferred as lib3;
+import 'lib1.dart' deferred as lib1;
+import 'lib2.dart' as lib2;
+import 'lib3.dart' deferred as lib3;
 
-/*strong.member: main:OutputUnit(main, {})*/
-/*strongConst.member: main:
+/*member: main:
  OutputUnit(main, {}),
  constants=[
   ConstructedConstant(A<B>())=OutputUnit(1, {lib1}),
diff --git a/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart b/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
index 749adc9..7920f1e 100644
--- a/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
+++ b/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
@@ -32,9 +32,7 @@
   asyncTest(() async {
     Directory dataDir = new Directory.fromUri(Platform.script.resolve('data'));
     await checkTests(dataDir, const OutputUnitDataComputer(),
-        libDirectory: new Directory.fromUri(Platform.script.resolve('libs')),
-        options: compilerOptions,
-        args: args, setUpFunction: () {
+        options: compilerOptions, args: args, setUpFunction: () {
       importPrefixes.clear();
     }, testedConfigs: allStrongConfigs);
   });
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_lib2.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_lib2.dart
deleted file mode 100644
index 7dbbe8b..0000000
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_lib2.dart
+++ /dev/null
@@ -1,28 +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.
-
-import 'deferred_constant3_shared.dart';
-
-/*strong.member: c3:OutputUnit(2, {l2})*/
-const c3 = /*strong.OutputUnit(main, {})*/ const C(1);
-
-/*strong.member: c4:OutputUnit(2, {l2})*/
-const c4 = /*strong.OutputUnit(2, {l2})*/ const C(4);
-
-/*strong.member: c5:OutputUnit(2, {l2})*/
-const c5 = /*strong.OutputUnit(2, {l2})*/ const C(5);
-
-/*strong.member: m2:OutputUnit(2, {l2})*/
-/*strongConst.member: m2:
- OutputUnit(2, {l2}),
- constants=[
-  ConstructedConstant(C(x=IntConstant(1)))=OutputUnit(main, {}),
-  ConstructedConstant(C(x=IntConstant(4)))=OutputUnit(2, {l2}),
-  ConstructedConstant(C(x=IntConstant(5)))=OutputUnit(2, {l2})]
-*/
-m2() async {
-  print(c3);
-  print(c4);
-  print(c5);
-}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_lib1.dart
deleted file mode 100644
index 837d58c..0000000
--- a/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_lib1.dart
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2017, 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 "dont_inline_deferred_constants_main.dart" show C;
-import "dont_inline_deferred_constants_main.dart" as main;
-
-/*strong.member: C1:OutputUnit(1, {lib1})*/
-const C1 = "string1";
-
-/*strong.member: C1b:OutputUnit(1, {lib1})*/
-const C1b = /*strong.OutputUnit(1, {lib1})*/ const C("string1");
-
-/*strong.member: C2:OutputUnit(1, {lib1})*/
-const C2 = 1010;
-
-/*strong.member: C2b:OutputUnit(1, {lib1})*/
-const C2b = /*strong.OutputUnit(1, {lib1})*/ const C(1010);
-
-/*class: D:null*/
-class D {
-  /*strong.member: D.C3:OutputUnit(1, {lib1})*/
-  static const C3 = "string2";
-
-  /*strong.member: D.C3b:OutputUnit(1, {lib1})*/
-  static const C3b = /*strong.OutputUnit(1, {lib1})*/ const C("string2");
-}
-
-/*strong.member: C4:OutputUnit(1, {lib1})*/
-const C4 = "string4";
-
-/*strong.member: C5:OutputUnit(1, {lib1})*/
-const C5 = /*strong.OutputUnit(main, {})*/ const C(1);
-
-/*strong.member: C6:OutputUnit(1, {lib1})*/
-const C6 = /*strong.OutputUnit(2, {lib1, lib2})*/ const C(2);
-
-/*member: foo:OutputUnit(1, {lib1})*/
-foo() {
-  print("lib1");
-  main.foo();
-}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_lib2.dart b/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_lib2.dart
deleted file mode 100644
index f475d99..0000000
--- a/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_lib2.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2017, 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 "dont_inline_deferred_constants_main.dart" show C;
-import "dont_inline_deferred_constants_main.dart" as main;
-
-/*strong.member: C4:OutputUnit(3, {lib2})*/
-const C4 = "string4";
-
-/*strong.member: C5:OutputUnit(3, {lib2})*/
-const C5 = /*strong.OutputUnit(main, {})*/ const C(1);
-
-/*strong.member: C6:OutputUnit(3, {lib2})*/
-const C6 = /*strong.OutputUnit(2, {lib1, lib2})*/ const C(2);
-
-/*member: foo:OutputUnit(3, {lib2})*/
-foo() {
-  print("lib2");
-  main.foo();
-}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/future_or_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/future_or_lib1.dart
deleted file mode 100644
index c11d4b8..0000000
--- a/tests/compiler/dart2js/deferred_loading/libs/future_or_lib1.dart
+++ /dev/null
@@ -1,8 +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.
-
-import 'future_or_lib2.dart';
-
-/*strong.member: field:OutputUnit(1, {lib1})*/
-const dynamic field = /*strong.OutputUnit(1, {lib1})*/ const A();
diff --git a/tests/compiler/dart2js/deferred_loading/libs/instantiation4_strong_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/instantiation4_strong_lib1.dart
deleted file mode 100644
index 74a68cb..0000000
--- a/tests/compiler/dart2js/deferred_loading/libs/instantiation4_strong_lib1.dart
+++ /dev/null
@@ -1,18 +0,0 @@
-// 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.
-
-/*member: getFoo:OutputUnit(1, {b})*/
-T getFoo<T>(T v) => v;
-
-typedef dynamic G<T>(T v);
-
-/*strong.member: m:OutputUnit(1, {b})*/
-/*strongConst.member: m:
- OutputUnit(1, {b}),
- constants=[FunctionConstant(getFoo)=OutputUnit(1, {b})]
-*/
-m(int x, {G<int> f}) {
-  f ??= getFoo;
-  print(f(x));
-}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/shared_constant_shared.dart b/tests/compiler/dart2js/deferred_loading/libs/shared_constant_shared.dart
deleted file mode 100644
index d11cc9e..0000000
--- a/tests/compiler/dart2js/deferred_loading/libs/shared_constant_shared.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-// 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.
-
-import 'shared_constant_c.dart';
-
-/*strong.member: constant:OutputUnit(1, {s1, s2})*/
-const constant =
-    /*strong.OutputUnit(1, {s1, s2})*/ const C();
diff --git a/tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib1.dart
deleted file mode 100644
index 7d907f9..0000000
--- a/tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib1.dart
+++ /dev/null
@@ -1,20 +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.
-
-import 'type_arguments_lib3.dart';
-
-/*class: A:OutputUnit(1, {lib1})*/
-class A<T> {
-  /*strong.member: A.:OutputUnit(1, {lib1})*/
-  const A();
-}
-
-/*class: B:OutputUnit(1, {lib1})*/
-class B {}
-
-/*strong.member: field1:OutputUnit(1, {lib1})*/
-const dynamic field1 = /*strong.OutputUnit(1, {lib1})*/ const A<B>();
-
-/*strong.member: field2:OutputUnit(1, {lib1})*/
-const dynamic field2 = /*strong.OutputUnit(1, {lib1})*/ const A<F>();
diff --git a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
index 2d986f7..54eeeac 100644
--- a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
+++ b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
@@ -26,57 +26,40 @@
 
 const String strongMarker = 'strong';
 const String omitMarker = 'omit';
-const String strongConstMarker = 'strongConst';
-const String omitConstMarker = 'omitConst';
 
-const TestConfig strongConfig = const TestConfig(strongMarker, 'strong mode',
-    ['${Flags.enableLanguageExperiments}=no-constant-update-2018']);
+const TestConfig strongConfig =
+    const TestConfig(strongMarker, 'strong mode', []);
 
-const TestConfig omitConfig =
-    const TestConfig(omitMarker, 'strong mode without implicit checks', [
-  Flags.omitImplicitChecks,
-  Flags.laxRuntimeTypeToString,
-  '${Flags.enableLanguageExperiments}=no-constant-update-2018'
-]);
-
-const TestConfig strongConstConfig = const TestConfig(
-    strongConstMarker,
-    'strong mode with cfe constants',
-    ['${Flags.enableLanguageExperiments}=constant-update-2018']);
-
-const TestConfig omitConstConfig = const TestConfig(omitConstMarker,
-    'strong mode with cfe constants and without implicit checks', [
-  Flags.omitImplicitChecks,
-  Flags.laxRuntimeTypeToString,
-  '${Flags.enableLanguageExperiments}=constant-update-2018'
-]);
+const TestConfig omitConfig = const TestConfig(
+    omitMarker,
+    'strong mode without implicit checks',
+    [Flags.omitImplicitChecks, Flags.laxRuntimeTypeToString]);
 
 const List<String> allInternalMarkers = const [
   strongMarker,
   omitMarker,
-  strongConstMarker,
-  omitConstMarker,
 ];
 
+/// Default internal configurations not including experimental features.
 const List<TestConfig> defaultInternalConfigs = const [
   strongConfig,
   omitConfig
 ];
 
+/// All internal configurations including experimental features.
 const List<TestConfig> allInternalConfigs = const [
   strongConfig,
   omitConfig,
-  strongConstConfig,
-  omitConstConfig,
 ];
 
+/// Compliance mode configurations (with strong mode checks) including
+/// experimental features.
 const List<TestConfig> allStrongConfigs = const [
   strongConfig,
-  strongConstConfig,
 ];
 
-const TestConfig sharedConfig = const TestConfig(dart2jsMarker, 'dart2js',
-    ['${Flags.enableLanguageExperiments}=constant-update-2018']);
+/// Test configuration used in tests shared with CFE.
+const TestConfig sharedConfig = const TestConfig(dart2jsMarker, 'dart2js', []);
 
 abstract class DataComputer<T> {
   const DataComputer();
@@ -148,7 +131,7 @@
   OutputCollector outputCollector = new OutputCollector();
   DiagnosticCollector diagnosticCollector = new DiagnosticCollector();
   Uri packageConfig;
-  Uri wantedPackageConfig = createUriForFileName(".packages", isLib: false);
+  Uri wantedPackageConfig = createUriForFileName(".packages");
   for (String key in memorySourceFiles.keys) {
     if (key == wantedPackageConfig.path) {
       packageConfig = wantedPackageConfig;
@@ -406,11 +389,10 @@
 /// If [forUserSourceFilesOnly] is true, we examine the elements in the main
 /// file and any supporting libraries.
 Future checkTests<T>(Directory dataDir, DataComputer<T> dataComputer,
-    {List<String> skipForStrong: const <String>[],
+    {List<String> skip: const <String>[],
     bool filterActualData(IdValue idValue, ActualData<T> actualData),
     List<String> options: const <String>[],
     List<String> args: const <String>[],
-    Directory libDirectory: null,
     bool forUserLibrariesOnly: true,
     Callback setUpFunction,
     int shards: 1,
@@ -447,7 +429,8 @@
 
     if (setUpFunction != null) setUpFunction();
 
-    if (skipForStrong.contains(name)) {
+    print('name="${name}"');
+    if (skip.contains(name)) {
       print('--skipped ------------------------------------------------------');
     } else {
       for (TestConfig testConfiguration in testedConfigs) {
@@ -456,6 +439,7 @@
             testConfiguration, dataComputer, testData, testOptions,
             filterActualData: filterActualData,
             verbose: verbose,
+            succinct: succinct,
             testAfterFailures: testAfterFailures,
             forUserLibrariesOnly: forUserLibrariesOnly,
             printCode: printCode)) {
@@ -471,28 +455,23 @@
       shards: shards,
       shardIndex: shardIndex,
       onTest: onTest,
-      libDirectory: libDirectory,
       supportedMarkers: supportedMarkers,
       createUriForFileName: createUriForFileName,
       onFailure: Expect.fail,
       runTest: checkTest);
 }
 
-Uri createUriForFileName(String fileName, {bool isLib}) {
-  String commonTestPath = 'sdk/tests/compiler';
-  if (isLib) {
-    return Uri.parse('memory:$commonTestPath/libs/$fileName');
-  } else {
-    // Pretend this is a dart2js_native test to allow use of 'native'
-    // keyword and import of private libraries.
-    return Uri.parse('memory:$commonTestPath/dart2js_native/$fileName');
-  }
+Uri createUriForFileName(String fileName) {
+  // Pretend this is a dart2js_native test to allow use of 'native'
+  // keyword and import of private libraries.
+  return Uri.parse('memory:sdk/tests/compiler/dart2js_native/$fileName');
 }
 
 Future<bool> runTestForConfiguration<T>(TestConfig testConfiguration,
     DataComputer<T> dataComputer, TestData testData, List<String> options,
     {bool filterActualData(IdValue idValue, ActualData<T> actualData),
     bool verbose: false,
+    bool succinct: false,
     bool printCode: false,
     bool forUserLibrariesOnly: true,
     bool testAfterFailures: false}) async {
@@ -510,7 +489,8 @@
       testData.code, annotations, compiledData, dataComputer.dataValidator,
       filterActualData: filterActualData,
       fatalErrors: !testAfterFailures,
-      onFailure: Expect.fail);
+      onFailure: Expect.fail,
+      succinct: succinct);
 }
 
 /// Compute a [Spannable] from an [id] in the library [mainUri].
diff --git a/tests/compiler/dart2js/field_analysis/jdata/constant_fields.dart b/tests/compiler/dart2js/field_analysis/jdata/constant_fields.dart
index e5874e3..c25d59e 100644
--- a/tests/compiler/dart2js/field_analysis/jdata/constant_fields.dart
+++ b/tests/compiler/dart2js/field_analysis/jdata/constant_fields.dart
@@ -17,7 +17,7 @@
 }
 
 class Class2 {
-  /*strongConst.member: Class2.field2:constant=BoolConstant(true)*/
+  /*strong.member: Class2.field2:constant=BoolConstant(true)*/
   final bool field2;
 
   const Class2({this.field2: false});
diff --git a/tests/compiler/dart2js/field_analysis/jdata/effectively_constant_state.dart b/tests/compiler/dart2js/field_analysis/jdata/effectively_constant_state.dart
index a5a0fbf..22c3126 100644
--- a/tests/compiler/dart2js/field_analysis/jdata/effectively_constant_state.dart
+++ b/tests/compiler/dart2js/field_analysis/jdata/effectively_constant_state.dart
@@ -3,13 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 
 enum Enum {
-  /*strong.member: Enum.a:constant=ConstructedConstant(Enum(_name=StringConstant("Enum.a"),index=IntConstant(0)))*/
   a,
 
-  /*strong.member: Enum.b:constant=ConstructedConstant(Enum(_name=StringConstant("Enum.b"),index=IntConstant(1)))*/
   b,
 
-  /*strong.member: Enum.c:constant=ConstructedConstant(Enum(_name=StringConstant("Enum.c"),index=IntConstant(2)))*/
   c,
 }
 
diff --git a/tests/compiler/dart2js/field_analysis/jdata/simple_initializers.dart b/tests/compiler/dart2js/field_analysis/jdata/simple_initializers.dart
index 0958aad..0a7fe28 100644
--- a/tests/compiler/dart2js/field_analysis/jdata/simple_initializers.dart
+++ b/tests/compiler/dart2js/field_analysis/jdata/simple_initializers.dart
@@ -113,7 +113,6 @@
   use(c2.field13b);
 }
 
-/*strong.member: const1:constant=BoolConstant(true)*/
 const bool const1 = true;
 
 class Class1 {
diff --git a/tests/compiler/dart2js/field_analysis/jdata/static_initializers.dart b/tests/compiler/dart2js/field_analysis/jdata/static_initializers.dart
index b6d316f..831dd9c 100644
--- a/tests/compiler/dart2js/field_analysis/jdata/static_initializers.dart
+++ b/tests/compiler/dart2js/field_analysis/jdata/static_initializers.dart
@@ -134,7 +134,6 @@
 /*member: field4b:constant=IntConstant(5)*/
 var field4b = 2 + 3;
 
-/*strong.member: field4c:constant=IntConstant(5)*/
 const field4c = 2 + 3;
 
 /*member: field5a:constant=FunctionConstant(method)*/
@@ -143,7 +142,6 @@
 /*member: field5b:constant=FunctionConstant(method)*/
 var field5b = method;
 
-/*strong.member: field5c:constant=FunctionConstant(method)*/
 const field5c = method;
 
 /*member: field6a:constant=ConstructedConstant(Class())*/
diff --git a/tests/compiler/dart2js/field_analysis/kdata/simple_initializers.dart b/tests/compiler/dart2js/field_analysis/kdata/simple_initializers.dart
index b2002b6..88bdec5 100644
--- a/tests/compiler/dart2js/field_analysis/kdata/simple_initializers.dart
+++ b/tests/compiler/dart2js/field_analysis/kdata/simple_initializers.dart
@@ -7,7 +7,6 @@
   new Class2();
 }
 
-/*strong.member: const1:complexity=constant,initial=BoolConstant(true)*/
 const bool const1 = true;
 
 class Class1 {
diff --git a/tests/compiler/dart2js/field_analysis/kdata/static_initializers.dart b/tests/compiler/dart2js/field_analysis/kdata/static_initializers.dart
index b2c12c7..9da6e56 100644
--- a/tests/compiler/dart2js/field_analysis/kdata/static_initializers.dart
+++ b/tests/compiler/dart2js/field_analysis/kdata/static_initializers.dart
@@ -65,7 +65,6 @@
 /*member: field1b:complexity=constant,initial=IntConstant(0)*/
 var field1b = 0;
 
-/*strong.member: field1c:complexity=constant,initial=IntConstant(0)*/
 const field1c = 0;
 
 /*member: field2a:complexity=constant,initial=ListConstant([])*/
@@ -74,7 +73,6 @@
 /*member: field2b:complexity=constant,initial=ListConstant([])*/
 var field2b = const [];
 
-/*strong.member: field2c:complexity=constant,initial=ListConstant([])*/
 const field2c = const [];
 
 /*member: field3a:complexity=eager*/
@@ -125,7 +123,6 @@
 /*member: field4b:complexity=lazy,initial=IntConstant(5)*/
 var field4b = 2 + 3;
 
-/*strong.member: field4c:complexity=lazy,initial=IntConstant(5)*/
 const field4c = 2 + 3;
 
 /*member: field5a:complexity=constant,initial=FunctionConstant(method)*/
@@ -134,7 +131,6 @@
 /*member: field5b:complexity=constant,initial=FunctionConstant(method)*/
 var field5b = method;
 
-/*strong.member: field5c:complexity=constant,initial=FunctionConstant(method)*/
 const field5c = method;
 
 /*member: field6a:complexity=constant,initial=ConstructedConstant(Class())*/
diff --git a/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart b/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart
index 8d2feb0..bc5420f1 100644
--- a/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart
+++ b/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart
@@ -38,6 +38,14 @@
     }
     void F11<Q extends C3<Q>>(Q q) {}
     void F12<P extends C3<P>>(P p) {}
+    class C5<T> {
+      Map<T,A> F15<A extends B, B extends T>(A a, B b) => null;
+      Map<T,A> F16<A extends T, B extends A>(A a, B b) => null;
+      T F17<A extends List<B>, B extends Map<T,A>>(A a, B b, T t) => null;
+      T F18<P extends T>(
+         [Q Function<Q extends P>(P, Q, T) f1,
+          X Function<X extends P>(P, X, T) f2]) => null;
+    }
 
     main() {
       ${createUses(existentialTypeData)}
@@ -51,6 +59,10 @@
       F10();
       F11(null);
       F12(null);
+      new C5<num>().F15<int, int>(1, 2);
+      new C5<num>().F16<int, int>(1, 2);
+      new C5<num>().F17(null, null, null);
+      new C5<num>().F18();
     }
     """));
 
@@ -74,6 +86,13 @@
           "Unexpected instantiation of $type with $instantiation: $result");
     }
 
+    void testSubst(List<DartType> arguments, List<DartType> parameters,
+        DartType type1, String expectedToString) {
+      DartType subst = type1.subst(arguments, parameters);
+      Expect.equals(expectedToString, subst.toString(),
+          "$type1.subst($arguments,$parameters)");
+    }
+
     testRelations(DartType a, DartType b,
         {bool areEqual: false, bool isSubtype: false}) {
       if (areEqual) {
@@ -116,6 +135,13 @@
     FunctionType F12 = env.getMemberType('F12');
     FunctionType F13 = env.getFieldType('F13');
     FunctionType F14 = env.getFieldType('F14');
+    ClassEntity C5 = env.getClass('C5');
+    TypeVariableType C5_T =
+        (env.getElementType('C5') as InterfaceType).typeArguments.single;
+    FunctionType F15 = env.getMemberType('F15', C5);
+    FunctionType F16 = env.getMemberType('F16', C5);
+    FunctionType F17 = env.getMemberType('F17', C5);
+    FunctionType F18 = env.getMemberType('F18', C5);
 
     List<FunctionType> all = <FunctionType>[
       F1,
@@ -132,8 +158,14 @@
       F12,
       F13,
       F14,
+      F15,
+      F16,
+      F17,
+      F18,
     ];
 
+    all.forEach(print);
+
     testToString(F1, 'void Function<#A>(#A)');
     testToString(F2, 'void Function<#A>(#A)');
     testToString(F3, 'void Function<#A,#B>(#A,#B)');
@@ -148,6 +180,17 @@
     testToString(F12, 'void Function<#A extends C3<#A>>(#A)');
     testToString(F13, '#A Function<#A>(#A,#A)');
     testToString(F14, '#A Function<#A>(#A,#A)');
+    testToString(
+        F15, 'Map<C5.T,#A> Function<#A extends #B,#B extends C5.T>(#A,#B)');
+    testToString(
+        F16, 'Map<C5.T,#A> Function<#A extends C5.T,#B extends #A>(#A,#B)');
+    testToString(F17,
+        'C5.T Function<#A extends List<#B>,#B extends Map<C5.T,#A>>(#A,#B,Object)');
+    testToString(
+        F18,
+        'C5.T Function<#A extends C5.T>(['
+        '#A2 Function<#A2 extends #A>(#A,#A2,C5.T),'
+        '#A3 Function<#A3 extends #A>(#A,#A3,C5.T)])');
 
     testBounds(F1, [Object_]);
     testBounds(F2, [Object_]);
@@ -182,7 +225,23 @@
     testInstantiate(F12, [C4], 'void Function(C4)');
     testInstantiate(F13, [C1], 'C1 Function(C1,C1)');
     testInstantiate(F14, [C2], 'C2 Function(C2,C2)');
+    testInstantiate(F15, [int_, num_], 'Map<C5.T,int> Function(int,num)');
+    testInstantiate(F16, [num_, int_], 'Map<C5.T,num> Function(num,int)');
 
+    testSubst([num_], [C5_T], F15,
+        'Map<num,#A> Function<#A extends #B,#B extends num>(#A,#B)');
+    testSubst([num_], [C5_T], F16,
+        'Map<num,#A> Function<#A extends num,#B extends #A>(#A,#B)');
+    testSubst([num_], [C5_T], F17,
+        'num Function<#A extends List<#B>,#B extends Map<num,#A>>(#A,#B,Object)');
+
+    testSubst(
+        [num_],
+        [C5_T],
+        F18,
+        'num Function<#A extends num>(['
+        '#A2 Function<#A2 extends #A>(#A,#A2,num),'
+        '#A3 Function<#A3 extends #A>(#A,#A3,num)])');
     Map<FunctionType, List<FunctionType>> expectedEquals =
         <FunctionType, List<FunctionType>>{
       F1: [F2],
diff --git a/tests/compiler/dart2js/helpers/compiler_helper.dart b/tests/compiler/dart2js/helpers/compiler_helper.dart
index a6c1deb..215609c 100644
--- a/tests/compiler/dart2js/helpers/compiler_helper.dart
+++ b/tests/compiler/dart2js/helpers/compiler_helper.dart
@@ -37,6 +37,7 @@
     bool trustJSInteropTypeAnnotations: false,
     bool disableTypeInference: true,
     bool omitImplicitChecks: true,
+    bool newRti: false,
     void check(String generatedEntry),
     bool returnAll: false}) async {
   OutputCollector outputCollector = returnAll ? new OutputCollector() : null;
@@ -59,6 +60,9 @@
   if (disableInlining) {
     options.add(Flags.disableInlining);
   }
+  if (newRti) {
+    options.add(Flags.experimentNewRti);
+  }
 
   // Pretend this is a dart2js_native test to allow use of 'native' keyword
   // and import of private libraries.
diff --git a/tests/compiler/dart2js/impact/data/classes.dart b/tests/compiler/dart2js/impact/data/classes.dart
index d35718d..9c5076d 100644
--- a/tests/compiler/dart2js/impact/data/classes.dart
+++ b/tests/compiler/dart2js/impact/data/classes.dart
@@ -190,24 +190,9 @@
   new ForwardingConstructorGenericClass<int>(null);
 }
 
-enum Enum {
-  /*strong.member: Enum.A:static=[Enum.(2)],
-   type=[
-    inst:JSBool,
-    inst:JSDouble,
-    inst:JSInt,
-    inst:JSNumber,
-    inst:JSPositiveInt,
-    inst:JSString,
-    inst:JSUInt31,
-    inst:JSUInt32,
-    param:Enum]
-  */
-  A
-}
+enum Enum { A }
 
-/*strong.member: testEnum:static=[Enum.A]*/
-/*strongConst.member: testEnum:
+/*strong.member: testEnum:
  static=[
   Enum._name=StringConstant("Enum.A"),
   Enum.index=IntConstant(0)],
diff --git a/tests/compiler/dart2js/impact/data/constants.dart b/tests/compiler/dart2js/impact/data/constants.dart
deleted file mode 100644
index 9ad48e4..0000000
--- a/tests/compiler/dart2js/impact/data/constants.dart
+++ /dev/null
@@ -1,264 +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.
-
-import '../libs/constants_lib.dart';
-import '../libs/constants_lib.dart' deferred as defer;
-
-/*member: main:static=**/
-main() {
-  nullLiteral();
-  boolLiteral();
-  intLiteral();
-  doubleLiteral();
-  stringLiteral();
-  symbolLiteral();
-  listLiteral();
-  mapLiteral();
-  stringMapLiteral();
-  setLiteral();
-  instanceConstant();
-  typeLiteral();
-  instantiation();
-  topLevelTearOff();
-  staticTearOff();
-
-  nullLiteralRef();
-  boolLiteralRef();
-  intLiteralRef();
-  doubleLiteralRef();
-  stringLiteralRef();
-  symbolLiteralRef();
-  listLiteralRef();
-  mapLiteralRef();
-  stringMapLiteralRef();
-  setLiteralRef();
-  instanceConstantRef();
-  typeLiteralRef();
-  instantiationRef();
-  topLevelTearOffRef();
-  staticTearOffRef();
-
-  nullLiteralDeferred();
-  boolLiteralDeferred();
-  intLiteralDeferred();
-  doubleLiteralDeferred();
-  stringLiteralDeferred();
-  symbolLiteralDeferred();
-  listLiteralDeferred();
-  mapLiteralDeferred();
-  stringMapLiteralDeferred();
-  setLiteralDeferred();
-  instanceConstantDeferred();
-  typeLiteralDeferred();
-  instantiationDeferred();
-  topLevelTearOffDeferred();
-  staticTearOffDeferred();
-}
-
-/*member: nullLiteral:type=[inst:JSNull]*/
-nullLiteral() {
-  const dynamic local = null;
-  return local;
-}
-
-/*member: boolLiteral:type=[inst:JSBool]*/
-boolLiteral() {
-  const dynamic local = true;
-  return local;
-}
-
-/*member: intLiteral:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
-intLiteral() {
-  const dynamic local = 42;
-  return local;
-}
-
-/*member: doubleLiteral:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
-doubleLiteral() {
-  const dynamic local = 0.5;
-  return local;
-}
-
-/*member: stringLiteral:type=[inst:JSString]*/
-stringLiteral() {
-  const dynamic local = "foo";
-  return local;
-}
-
-/*member: symbolLiteral:static=[Symbol.(1)],type=[inst:Symbol]*/
-symbolLiteral() => #foo;
-
-/*member: listLiteral:type=[inst:JSBool,inst:List<bool>]*/
-listLiteral() => const [true, false];
-
-/*member: mapLiteral:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool]*/
-mapLiteral() => const {true: false};
-
-/*member: stringMapLiteral:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:JSString]*/
-stringMapLiteral() => const {'foo': false};
-
-/*member: setLiteral:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:_UnmodifiableSet<dynamic>]*/
-setLiteral() => const {true, false};
-
-/*strong.member: instanceConstant:static=[Class.(2)],type=[inst:JSBool]*/
-/*strongConst.member: instanceConstant:
- static=[Class.field2=BoolConstant(false),SuperClass.field1=BoolConstant(true)],
- type=[const:Class,inst:JSBool]
-*/
-instanceConstant() => const Class(true, false);
-
-/*member: typeLiteral:static=[createRuntimeType(1)],type=[inst:Type,inst:TypeImpl,lit:String]*/
-typeLiteral() {
-  const dynamic local = String;
-  return local;
-}
-
-/*member: instantiation:static=[extractFunctionTypeObjectFromInternal(1),id,instantiate1(1),instantiatedGenericFunctionType(2)],type=[inst:Instantiation1<dynamic>]*/
-instantiation() {
-  const int Function(int) local = id;
-  return local;
-}
-
-/*member: topLevelTearOff:static=[topLevelMethod]*/
-topLevelTearOff() {
-  const dynamic local = topLevelMethod;
-  return local;
-}
-
-/*member: staticTearOff:static=[Class.staticMethodField]*/
-staticTearOff() {
-  const dynamic local = Class.staticMethodField;
-  return local;
-}
-
-/*strong.member: nullLiteralRef:static=[nullLiteralField]*/
-/*strongConst.member: nullLiteralRef:type=[inst:JSNull]*/
-nullLiteralRef() => nullLiteralField;
-
-/*strong.member: boolLiteralRef:static=[boolLiteralField]*/
-/*strongConst.member: boolLiteralRef:type=[inst:JSBool]*/
-boolLiteralRef() => boolLiteralField;
-
-/*strong.member: intLiteralRef:static=[intLiteralField]*/
-/*strongConst.member: intLiteralRef:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
-intLiteralRef() => intLiteralField;
-
-/*strong.member: doubleLiteralRef:static=[doubleLiteralField]*/
-/*strongConst.member: doubleLiteralRef:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
-doubleLiteralRef() => doubleLiteralField;
-
-/*strong.member: stringLiteralRef:static=[stringLiteralField]*/
-/*strongConst.member: stringLiteralRef:type=[inst:JSString]*/
-stringLiteralRef() => stringLiteralField;
-
-/*strong.member: symbolLiteralRef:static=[symbolLiteralField]*/
-/*strongConst.member: symbolLiteralRef:static=[Symbol.(1)],type=[inst:Symbol]*/
-symbolLiteralRef() => symbolLiteralField;
-
-/*strong.member: listLiteralRef:static=[listLiteralField]*/
-/*strongConst.member: listLiteralRef:type=[inst:JSBool,inst:List<bool>]*/
-listLiteralRef() => listLiteralField;
-
-/*strong.member: mapLiteralRef:static=[mapLiteralField]*/
-/*strongConst.member: mapLiteralRef:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool]*/
-mapLiteralRef() => mapLiteralField;
-
-/*strong.member: stringMapLiteralRef:static=[stringMapLiteralField]*/
-/*strongConst.member: stringMapLiteralRef:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:JSString]*/
-stringMapLiteralRef() => stringMapLiteralField;
-
-/*strong.member: setLiteralRef:static=[setLiteralField]*/
-/*strongConst.member: setLiteralRef:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:_UnmodifiableSet<dynamic>]*/
-setLiteralRef() => setLiteralField;
-
-/*strong.member: instanceConstantRef:static=[instanceConstantField]*/
-/*strongConst.member: instanceConstantRef:
- static=[Class.field2=BoolConstant(false),SuperClass.field1=BoolConstant(true)],
- type=[const:Class,inst:JSBool]
-*/
-instanceConstantRef() => instanceConstantField;
-
-/*strong.member: typeLiteralRef:static=[typeLiteralField]*/
-/*strongConst.member: typeLiteralRef:static=[createRuntimeType(1)],type=[inst:Type,inst:TypeImpl,lit:String]*/
-typeLiteralRef() => typeLiteralField;
-
-/*strong.member: instantiationRef:static=[instantiationField]*/
-/*strongConst.member: instantiationRef:static=[extractFunctionTypeObjectFromInternal(1),id,instantiate1(1),instantiatedGenericFunctionType(2)],type=[inst:Instantiation1<dynamic>]*/
-instantiationRef() => instantiationField;
-
-/*strong.member: topLevelTearOffRef:static=[topLevelTearOffField]*/
-/*strongConst.member: topLevelTearOffRef:static=[topLevelMethod]*/
-topLevelTearOffRef() => topLevelTearOffField;
-
-/*strong.member: staticTearOffRef:static=[staticTearOffField]*/
-/*strongConst.member: staticTearOffRef:static=[Class.staticMethodField]*/
-staticTearOffRef() => staticTearOffField;
-
-/*strong.member: nullLiteralDeferred:static=[nullLiteralField{defer}]*/
-/*strongConst.member: nullLiteralDeferred:type=[inst:JSNull]*/
-nullLiteralDeferred() => defer.nullLiteralField;
-
-/*strong.member: boolLiteralDeferred:static=[boolLiteralField{defer}]*/
-/*strongConst.member: boolLiteralDeferred:type=[inst:JSBool]*/
-boolLiteralDeferred() => defer.boolLiteralField;
-
-/*strong.member: intLiteralDeferred:static=[intLiteralField{defer}]*/
-/*strongConst.member: intLiteralDeferred:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
-intLiteralDeferred() => defer.intLiteralField;
-
-/*strong.member: doubleLiteralDeferred:static=[doubleLiteralField{defer}]*/
-/*strongConst.member: doubleLiteralDeferred:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
-doubleLiteralDeferred() => defer.doubleLiteralField;
-
-/*strong.member: stringLiteralDeferred:static=[stringLiteralField{defer}]*/
-/*strongConst.member: stringLiteralDeferred:type=[inst:JSString]*/
-stringLiteralDeferred() => defer.stringLiteralField;
-
-/*strong.member: symbolLiteralDeferred:static=[symbolLiteralField{defer}]*/
-// TODO(johnniwinther): Should we record that this is deferred?
-/*strongConst.member: symbolLiteralDeferred:static=[Symbol.(1)],type=[inst:Symbol]*/
-symbolLiteralDeferred() => defer.symbolLiteralField;
-
-/*strong.member: listLiteralDeferred:static=[listLiteralField{defer}]*/
-// TODO(johnniwinther): Should we record that this is deferred?
-/*strongConst.member: listLiteralDeferred:type=[inst:JSBool,inst:List<bool>]*/
-listLiteralDeferred() => defer.listLiteralField;
-
-/*strong.member: mapLiteralDeferred:static=[mapLiteralField{defer}]*/
-// TODO(johnniwinther): Should we record that this is deferred?
-/*strongConst.member: mapLiteralDeferred:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool]*/
-mapLiteralDeferred() => defer.mapLiteralField;
-
-/*strong.member: stringMapLiteralDeferred:static=[stringMapLiteralField{defer}]*/
-// TODO(johnniwinther): Should we record that this is deferred?
-/*strongConst.member: stringMapLiteralDeferred:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:JSString]*/
-stringMapLiteralDeferred() => defer.stringMapLiteralField;
-
-/*strong.member: setLiteralDeferred:static=[setLiteralField{defer}]*/
-// TODO(johnniwinther): Should we record that this is deferred?
-/*strongConst.member: setLiteralDeferred:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:_UnmodifiableSet<dynamic>]*/
-setLiteralDeferred() => defer.setLiteralField;
-
-/*strong.member: instanceConstantDeferred:static=[instanceConstantField{defer}]*/
-/*strongConst.member: instanceConstantDeferred:
- static=[Class.field2=BoolConstant(false),SuperClass.field1=BoolConstant(true)],
- type=[const:Class{defer},inst:JSBool]
-*/
-instanceConstantDeferred() => defer.instanceConstantField;
-
-/*strong.member: typeLiteralDeferred:static=[typeLiteralField{defer}]*/
-/*strongConst.member: typeLiteralDeferred:static=[createRuntimeType(1)],type=[inst:Type,inst:TypeImpl,lit:String{defer}]*/
-typeLiteralDeferred() => defer.typeLiteralField;
-
-/*strong.member: instantiationDeferred:static=[instantiationField{defer}]*/
-/*strongConst.member: instantiationDeferred:static=[extractFunctionTypeObjectFromInternal(1),id{defer},instantiate1(1),instantiatedGenericFunctionType(2)],type=[inst:Instantiation1<dynamic>]*/
-instantiationDeferred() => defer.instantiationField;
-
-/*strong.member: topLevelTearOffDeferred:static=[topLevelTearOffField{defer}]*/
-/*strongConst.member: topLevelTearOffDeferred:static=[topLevelMethod{defer}]*/
-topLevelTearOffDeferred() => defer.topLevelTearOffField;
-
-/*strong.member: staticTearOffDeferred:static=[staticTearOffField{defer}]*/
-/*strongConst.member: staticTearOffDeferred:static=[Class.staticMethodField{defer}]*/
-staticTearOffDeferred() => defer.staticTearOffField;
diff --git a/tests/compiler/dart2js/impact/data/constants/lib.dart b/tests/compiler/dart2js/impact/data/constants/lib.dart
new file mode 100644
index 0000000..fd20974
--- /dev/null
+++ b/tests/compiler/dart2js/impact/data/constants/lib.dart
@@ -0,0 +1,56 @@
+// 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.
+
+const dynamic nullLiteralField = null;
+
+const dynamic boolLiteralField = true;
+
+const dynamic intLiteralField = 42;
+
+const dynamic doubleLiteralField = 0.5;
+
+const dynamic stringLiteralField = "foo";
+
+const dynamic symbolLiteralField = #foo;
+
+const dynamic listLiteralField = [true, false];
+
+const dynamic mapLiteralField = {true: false};
+
+const dynamic stringMapLiteralField = {'foo': false};
+
+const dynamic setLiteralField = {true, false};
+
+class SuperClass {
+  /*member: SuperClass.field1:type=[inst:JSNull]*/
+  final field1;
+
+  const SuperClass(this.field1);
+}
+
+class Class extends SuperClass {
+  /*member: Class.field2:type=[inst:JSNull]*/
+  final field2;
+
+  const Class(field1, this.field2) : super(field1);
+
+  static staticMethodField() {}
+}
+
+const instanceConstantField = const Class(true, false);
+
+const typeLiteralField = String;
+
+/*member: id:static=[checkSubtype(4),checkSubtypeOfRuntimeType(2),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),setRuntimeTypeInfo(2)],type=[inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:Object,param:id.T]*/
+T id<T>(T t) => t;
+
+const int Function(int) _instantiation = id;
+
+const dynamic instantiationField = _instantiation;
+
+topLevelMethod() {}
+
+const dynamic topLevelTearOffField = topLevelMethod;
+
+const dynamic staticTearOffField = Class.staticMethodField;
diff --git a/tests/compiler/dart2js/impact/data/constants/main.dart b/tests/compiler/dart2js/impact/data/constants/main.dart
new file mode 100644
index 0000000..b971c4f
--- /dev/null
+++ b/tests/compiler/dart2js/impact/data/constants/main.dart
@@ -0,0 +1,233 @@
+// 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.
+
+import 'lib.dart';
+import 'lib.dart' deferred as defer;
+
+/*member: main:static=**/
+main() {
+  nullLiteral();
+  boolLiteral();
+  intLiteral();
+  doubleLiteral();
+  stringLiteral();
+  symbolLiteral();
+  listLiteral();
+  mapLiteral();
+  stringMapLiteral();
+  setLiteral();
+  instanceConstant();
+  typeLiteral();
+  instantiation();
+  topLevelTearOff();
+  staticTearOff();
+
+  nullLiteralRef();
+  boolLiteralRef();
+  intLiteralRef();
+  doubleLiteralRef();
+  stringLiteralRef();
+  symbolLiteralRef();
+  listLiteralRef();
+  mapLiteralRef();
+  stringMapLiteralRef();
+  setLiteralRef();
+  instanceConstantRef();
+  typeLiteralRef();
+  instantiationRef();
+  topLevelTearOffRef();
+  staticTearOffRef();
+
+  nullLiteralDeferred();
+  boolLiteralDeferred();
+  intLiteralDeferred();
+  doubleLiteralDeferred();
+  stringLiteralDeferred();
+  symbolLiteralDeferred();
+  listLiteralDeferred();
+  mapLiteralDeferred();
+  stringMapLiteralDeferred();
+  setLiteralDeferred();
+  instanceConstantDeferred();
+  typeLiteralDeferred();
+  instantiationDeferred();
+  topLevelTearOffDeferred();
+  staticTearOffDeferred();
+}
+
+/*member: nullLiteral:type=[inst:JSNull]*/
+nullLiteral() {
+  const dynamic local = null;
+  return local;
+}
+
+/*member: boolLiteral:type=[inst:JSBool]*/
+boolLiteral() {
+  const dynamic local = true;
+  return local;
+}
+
+/*member: intLiteral:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+intLiteral() {
+  const dynamic local = 42;
+  return local;
+}
+
+/*member: doubleLiteral:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+doubleLiteral() {
+  const dynamic local = 0.5;
+  return local;
+}
+
+/*member: stringLiteral:type=[inst:JSString]*/
+stringLiteral() {
+  const dynamic local = "foo";
+  return local;
+}
+
+/*member: symbolLiteral:static=[Symbol.(1)],type=[inst:Symbol]*/
+symbolLiteral() => #foo;
+
+/*member: listLiteral:type=[inst:JSBool,inst:List<bool>]*/
+listLiteral() => const [true, false];
+
+/*member: mapLiteral:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool]*/
+mapLiteral() => const {true: false};
+
+/*member: stringMapLiteral:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:JSString]*/
+stringMapLiteral() => const {'foo': false};
+
+/*member: setLiteral:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:_UnmodifiableSet<dynamic>]*/
+setLiteral() => const {true, false};
+
+/*strong.member: instanceConstant:
+ static=[Class.field2=BoolConstant(false),SuperClass.field1=BoolConstant(true)],
+ type=[const:Class,inst:JSBool]
+*/
+instanceConstant() => const Class(true, false);
+
+/*member: typeLiteral:static=[createRuntimeType(1)],type=[inst:Type,inst:TypeImpl,lit:String]*/
+typeLiteral() {
+  const dynamic local = String;
+  return local;
+}
+
+/*member: instantiation:static=[extractFunctionTypeObjectFromInternal(1),id,instantiate1(1),instantiatedGenericFunctionType(2)],type=[inst:Instantiation1<dynamic>]*/
+instantiation() {
+  const int Function(int) local = id;
+  return local;
+}
+
+/*member: topLevelTearOff:static=[topLevelMethod]*/
+topLevelTearOff() {
+  const dynamic local = topLevelMethod;
+  return local;
+}
+
+/*member: staticTearOff:static=[Class.staticMethodField]*/
+staticTearOff() {
+  const dynamic local = Class.staticMethodField;
+  return local;
+}
+
+/*strong.member: nullLiteralRef:type=[inst:JSNull]*/
+nullLiteralRef() => nullLiteralField;
+
+/*strong.member: boolLiteralRef:type=[inst:JSBool]*/
+boolLiteralRef() => boolLiteralField;
+
+/*strong.member: intLiteralRef:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+intLiteralRef() => intLiteralField;
+
+/*strong.member: doubleLiteralRef:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+doubleLiteralRef() => doubleLiteralField;
+
+/*strong.member: stringLiteralRef:type=[inst:JSString]*/
+stringLiteralRef() => stringLiteralField;
+
+/*strong.member: symbolLiteralRef:static=[Symbol.(1)],type=[inst:Symbol]*/
+symbolLiteralRef() => symbolLiteralField;
+
+/*strong.member: listLiteralRef:type=[inst:JSBool,inst:List<bool>]*/
+listLiteralRef() => listLiteralField;
+
+/*strong.member: mapLiteralRef:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool]*/
+mapLiteralRef() => mapLiteralField;
+
+/*strong.member: stringMapLiteralRef:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:JSString]*/
+stringMapLiteralRef() => stringMapLiteralField;
+
+/*strong.member: setLiteralRef:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:_UnmodifiableSet<dynamic>]*/
+setLiteralRef() => setLiteralField;
+
+/*strong.member: instanceConstantRef:
+ static=[Class.field2=BoolConstant(false),SuperClass.field1=BoolConstant(true)],
+ type=[const:Class,inst:JSBool]
+*/
+instanceConstantRef() => instanceConstantField;
+
+/*strong.member: typeLiteralRef:static=[createRuntimeType(1)],type=[inst:Type,inst:TypeImpl,lit:String]*/
+typeLiteralRef() => typeLiteralField;
+
+/*strong.member: instantiationRef:static=[extractFunctionTypeObjectFromInternal(1),id,instantiate1(1),instantiatedGenericFunctionType(2)],type=[inst:Instantiation1<dynamic>]*/
+instantiationRef() => instantiationField;
+
+/*strong.member: topLevelTearOffRef:static=[topLevelMethod]*/
+topLevelTearOffRef() => topLevelTearOffField;
+
+/*strong.member: staticTearOffRef:static=[Class.staticMethodField]*/
+staticTearOffRef() => staticTearOffField;
+
+/*strong.member: nullLiteralDeferred:type=[inst:JSNull]*/
+nullLiteralDeferred() => defer.nullLiteralField;
+
+/*strong.member: boolLiteralDeferred:type=[inst:JSBool]*/
+boolLiteralDeferred() => defer.boolLiteralField;
+
+/*strong.member: intLiteralDeferred:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+intLiteralDeferred() => defer.intLiteralField;
+
+/*strong.member: doubleLiteralDeferred:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+doubleLiteralDeferred() => defer.doubleLiteralField;
+
+/*strong.member: stringLiteralDeferred:type=[inst:JSString]*/
+stringLiteralDeferred() => defer.stringLiteralField;
+
+// TODO(johnniwinther): Should we record that this is deferred?
+/*strong.member: symbolLiteralDeferred:static=[Symbol.(1)],type=[inst:Symbol]*/
+symbolLiteralDeferred() => defer.symbolLiteralField;
+
+// TODO(johnniwinther): Should we record that this is deferred?
+/*strong.member: listLiteralDeferred:type=[inst:JSBool,inst:List<bool>]*/
+listLiteralDeferred() => defer.listLiteralField;
+
+// TODO(johnniwinther): Should we record that this is deferred?
+/*strong.member: mapLiteralDeferred:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool]*/
+mapLiteralDeferred() => defer.mapLiteralField;
+
+// TODO(johnniwinther): Should we record that this is deferred?
+/*strong.member: stringMapLiteralDeferred:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:JSString]*/
+stringMapLiteralDeferred() => defer.stringMapLiteralField;
+
+// TODO(johnniwinther): Should we record that this is deferred?
+/*strong.member: setLiteralDeferred:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:_UnmodifiableSet<dynamic>]*/
+setLiteralDeferred() => defer.setLiteralField;
+
+/*strong.member: instanceConstantDeferred:
+ static=[Class.field2=BoolConstant(false),SuperClass.field1=BoolConstant(true)],
+ type=[const:Class{defer},inst:JSBool]
+*/
+instanceConstantDeferred() => defer.instanceConstantField;
+
+/*strong.member: typeLiteralDeferred:static=[createRuntimeType(1)],type=[inst:Type,inst:TypeImpl,lit:String{defer}]*/
+typeLiteralDeferred() => defer.typeLiteralField;
+
+/*strong.member: instantiationDeferred:static=[extractFunctionTypeObjectFromInternal(1),id{defer},instantiate1(1),instantiatedGenericFunctionType(2)],type=[inst:Instantiation1<dynamic>]*/
+instantiationDeferred() => defer.instantiationField;
+
+/*strong.member: topLevelTearOffDeferred:static=[topLevelMethod{defer}]*/
+topLevelTearOffDeferred() => defer.topLevelTearOffField;
+
+/*strong.member: staticTearOffDeferred:static=[Class.staticMethodField{defer}]*/
+staticTearOffDeferred() => defer.staticTearOffField;
diff --git a/tests/compiler/dart2js/impact/data/constructors.dart b/tests/compiler/dart2js/impact/data/constructors.dart
index a58c2da..22dd2e0 100644
--- a/tests/compiler/dart2js/impact/data/constructors.dart
+++ b/tests/compiler/dart2js/impact/data/constructors.dart
@@ -104,26 +104,22 @@
   new GenericClass<dynamic, dynamic>.redirect();
 }
 
-/*strong.member: testConstRedirectingFactoryInvoke:static=[Class.generative(0)]*/
-/*strongConst.member: testConstRedirectingFactoryInvoke:type=[const:Class]*/
+/*strong.member: testConstRedirectingFactoryInvoke:type=[const:Class]*/
 testConstRedirectingFactoryInvoke() {
   const Class.redirect();
 }
 
-/*strong.member: testConstRedirectingFactoryInvokeGeneric:static=[GenericClass.generative(0),assertIsSubtype(5),throwTypeError(1)]*/
-/*strongConst.member: testConstRedirectingFactoryInvokeGeneric:type=[const:GenericClass<int,String>]*/
+/*strong.member: testConstRedirectingFactoryInvokeGeneric:type=[const:GenericClass<int,String>]*/
 testConstRedirectingFactoryInvokeGeneric() {
   const GenericClass<int, String>.redirect();
 }
 
-/*strong.member: testConstRedirectingFactoryInvokeGenericRaw:static=[GenericClass.generative(0)]*/
-/*strongConst.member: testConstRedirectingFactoryInvokeGenericRaw:type=[const:GenericClass<dynamic,dynamic>]*/
+/*strong.member: testConstRedirectingFactoryInvokeGenericRaw:type=[const:GenericClass<dynamic,dynamic>]*/
 testConstRedirectingFactoryInvokeGenericRaw() {
   const GenericClass.redirect();
 }
 
-/*strong.member: testConstRedirectingFactoryInvokeGenericDynamic:static=[GenericClass.generative(0)]*/
-/*strongConst.member: testConstRedirectingFactoryInvokeGenericDynamic:type=[const:GenericClass<dynamic,dynamic>]*/
+/*strong.member: testConstRedirectingFactoryInvokeGenericDynamic:type=[const:GenericClass<dynamic,dynamic>]*/
 testConstRedirectingFactoryInvokeGenericDynamic() {
   const GenericClass<dynamic, dynamic>.redirect();
 }
diff --git a/tests/compiler/dart2js/impact/data/initializers.dart b/tests/compiler/dart2js/impact/data/initializers.dart
index 53b2ff0..9dce347 100644
--- a/tests/compiler/dart2js/impact/data/initializers.dart
+++ b/tests/compiler/dart2js/impact/data/initializers.dart
@@ -29,11 +29,9 @@
 }
 
 /*strong.member: testDefaultValuesPositional:type=[inst:JSBool,param:bool]*/
-/*strongConst.member: testDefaultValuesPositional:type=[inst:JSBool,param:bool]*/
 testDefaultValuesPositional([bool value = false]) {}
 
 /*strong.member: testDefaultValuesNamed:type=[inst:JSBool,param:bool]*/
-/*strongConst.member: testDefaultValuesNamed:type=[inst:JSBool,param:bool]*/
 testDefaultValuesNamed({bool value: false}) {}
 
 class ClassFieldInitializer1 {
diff --git a/tests/compiler/dart2js/impact/data/invokes.dart b/tests/compiler/dart2js/impact/data/invokes.dart
index ffbbce5..3d24c7d 100644
--- a/tests/compiler/dart2js/impact/data/invokes.dart
+++ b/tests/compiler/dart2js/impact/data/invokes.dart
@@ -318,11 +318,9 @@
 /*member: testTopLevelFieldLazy:static=[topLevelFieldLazy]*/
 testTopLevelFieldLazy() => topLevelFieldLazy;
 
-/*strong.member: topLevelFieldConst:type=[inst:JSNull]*/
 const topLevelFieldConst = null;
 
-/*strong.member: testTopLevelFieldConst:static=[topLevelFieldConst]*/
-/*strongConst.member: testTopLevelFieldConst:type=[inst:JSNull]*/
+/*strong.member: testTopLevelFieldConst:type=[inst:JSNull]*/
 testTopLevelFieldConst() => topLevelFieldConst;
 
 /*member: topLevelFieldFinal:static=[throwCyclicInit(1),topLevelFunction1(1)],type=[inst:JSNull]*/
diff --git a/tests/compiler/dart2js/impact/data/literals.dart b/tests/compiler/dart2js/impact/data/literals.dart
index afb6bdd..740209d 100644
--- a/tests/compiler/dart2js/impact/data/literals.dart
+++ b/tests/compiler/dart2js/impact/data/literals.dart
@@ -86,11 +86,7 @@
 */
 testStringInterpolation() => '${true}';
 
-/*strong.member: testStringInterpolationConst:
- dynamic=[toString(0)],
- static=[S(1)],type=[inst:JSBool,inst:JSString]
-*/
-/*strongConst.member: testStringInterpolationConst:type=[inst:JSString]*/
+/*strong.member: testStringInterpolationConst:type=[inst:JSString]*/
 testStringInterpolationConst() {
   const b = '${true}';
   return b;
@@ -106,67 +102,13 @@
 /*member: testSymbol:static=[Symbol.(1)],type=[inst:Symbol]*/
 testSymbol() => #main;
 
-/*strong.member: testConstSymbol:
- static=[Symbol.(1),Symbol.(1),Symbol.validated(1)],
- type=[inst:JSString,inst:Symbol]
-*/
-/*strongConst.member: testConstSymbol:static=[Symbol.(1)],type=[inst:Symbol]*/
+/*strong.member: testConstSymbol:static=[Symbol.(1)],type=[inst:Symbol]*/
 testConstSymbol() => const Symbol('main');
 
-/*strong.member: complexSymbolField1:
- dynamic=[String.length,int.==],
- type=[inst:JSBool,inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSString,inst:JSUInt31,inst:JSUInt32,param:bool]
-*/
 const complexSymbolField1 = "true".length == 4;
 
-/*strong.member: complexSymbolField2:
- dynamic=[toString(0)],
- static=[S(1)],
- type=[inst:JSBool,inst:JSNull,inst:JSString,param:String]
-*/
 const complexSymbolField2 = "true" "false" "${true}${null}";
 
-/*strong.member: complexSymbolField3:
-  dynamic=[int.+,int.unary-],
-  static=[
-   GenericClass.generative(0),
-   String.fromEnvironment(1),
-   Symbol.(1),
-   assertIsSubtype(5),
-   bool.fromEnvironment(1,defaultValue),
-   checkSubtype(4),
-   getRuntimeTypeArgument(3),
-   getRuntimeTypeArgumentIntercepted(4),
-   getRuntimeTypeInfo(1),
-   getTypeArgumentByIndex(2),
-   identical(2),
-   int.fromEnvironment(1,defaultValue),
-   override,
-   setRuntimeTypeInfo(2),
-   testComplexConstSymbol,
-   throwTypeError(1)],
-  type=[
-   inst:ConstantMap<dynamic,dynamic>,
-   inst:ConstantProtoMap<dynamic,dynamic>,
-   inst:ConstantStringMap<dynamic,dynamic>,
-   inst:GeneralConstantMap<dynamic,dynamic>,
-   inst:JSArray<dynamic>,
-   inst:JSBool,
-   inst:JSDouble,
-   inst:JSExtendableArray<dynamic>,
-   inst:JSFixedArray<dynamic>,
-   inst:JSInt,
-   inst:JSMutableArray<dynamic>,
-   inst:JSNumber,
-   inst:JSPositiveInt,
-   inst:JSString,
-   inst:JSUInt31,
-   inst:JSUInt32,
-   inst:JSUnmodifiableArray<dynamic>,
-   inst:List<int>,
-   inst:Symbol,
-   param:Map<Object,Object>]
-*/
 const complexSymbolField3 = const {
   0: const bool.fromEnvironment('a', defaultValue: true),
   false: const int.fromEnvironment('b', defaultValue: 42),
@@ -178,29 +120,13 @@
   override: const GenericClass<int, String>.generative(),
 };
 
-/*strong.member: complexSymbolField:
- static=[
-  complexSymbolField1,
-  complexSymbolField2,
-  complexSymbolField3],
- type=[inst:JSBool,param:Object]
-*/
 const complexSymbolField =
     complexSymbolField1 ? complexSymbolField2 : complexSymbolField3;
 
-/*strong.member: testComplexConstSymbol:
- static=[Symbol.(1),Symbol.(1),Symbol.validated(1),complexSymbolField],
- type=[impl:String,inst:JSBool,inst:Symbol]
-*/
-/*strongConst.member: testComplexConstSymbol:static=[Symbol.(1)],type=[inst:Symbol]*/
+/*strong.member: testComplexConstSymbol:static=[Symbol.(1)],type=[inst:Symbol]*/
 testComplexConstSymbol() => const Symbol(complexSymbolField);
 
-/*strong.member: testIfNullConstSymbol:
- dynamic=[Null.==],
- static=[Symbol.(1),Symbol.(1),Symbol.validated(1)],
- type=[inst:JSNull,inst:JSString,inst:Symbol]
-*/
-/*strongConst.member: testIfNullConstSymbol:static=[Symbol.(1)],type=[inst:Symbol]*/
+/*strong.member: testIfNullConstSymbol:static=[Symbol.(1)],type=[inst:Symbol]*/
 testIfNullConstSymbol() => const Symbol(null ?? 'foo');
 
 /*member: testTypeLiteral:
@@ -209,8 +135,7 @@
 */
 testTypeLiteral() => Object;
 
-/*strong.member: testBoolFromEnvironment:static=[bool.fromEnvironment(1)],type=[inst:JSString]*/
-/*strongConst.member: testBoolFromEnvironment:type=[inst:JSBool]*/
+/*strong.member: testBoolFromEnvironment:type=[inst:JSBool]*/
 testBoolFromEnvironment() => const bool.fromEnvironment('FOO');
 
 /*member: testEmptyListLiteral:type=[inst:List<dynamic>]*/
@@ -250,6 +175,5 @@
 testNonEmptyMapLiteral() => {null: true};
 
 class GenericClass<X, Y> {
-  /*strong.member: GenericClass.generative:static=[Object.(0)]*/
   const GenericClass.generative();
 }
diff --git a/tests/compiler/dart2js/impact/impact_test.dart b/tests/compiler/dart2js/impact/impact_test.dart
index 2fddf60..c50850d 100644
--- a/tests/compiler/dart2js/impact/impact_test.dart
+++ b/tests/compiler/dart2js/impact/impact_test.dart
@@ -19,19 +19,16 @@
 main(List<String> args) {
   asyncTest(() async {
     Directory dataDir = new Directory.fromUri(Platform.script.resolve('data'));
-    Directory libDirectory =
-        new Directory.fromUri(Platform.script.resolve('libs'));
     print('Testing direct computation of ResolutionImpact');
     print('==================================================================');
     useImpactDataForTesting = false;
     await checkTests(dataDir, const ImpactDataComputer(),
-        libDirectory: libDirectory, args: args, testedConfigs: [strongConfig]);
+        args: args, testedConfigs: [strongConfig]);
 
     print('Testing computation of ResolutionImpact through ImpactData');
     print('==================================================================');
     useImpactDataForTesting = true;
     await checkTests(dataDir, const ImpactDataComputer(),
-        libDirectory: libDirectory,
         args: args,
         testedConfigs: allStrongConfigs);
   });
diff --git a/tests/compiler/dart2js/impact/libs/constants_lib.dart b/tests/compiler/dart2js/impact/libs/constants_lib.dart
deleted file mode 100644
index 02bbc81..0000000
--- a/tests/compiler/dart2js/impact/libs/constants_lib.dart
+++ /dev/null
@@ -1,94 +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.
-
-/*strong.member: nullLiteralField:type=[inst:JSNull]*/
-const dynamic nullLiteralField = null;
-
-/*strong.member: boolLiteralField:type=[inst:JSBool]*/
-const dynamic boolLiteralField = true;
-
-/*strong.member: intLiteralField:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
-const dynamic intLiteralField = 42;
-
-/*strong.member: doubleLiteralField:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
-const dynamic doubleLiteralField = 0.5;
-
-/*strong.member: stringLiteralField:type=[inst:JSString]*/
-const dynamic stringLiteralField = "foo";
-
-/*strong.member: symbolLiteralField:static=[Symbol.(1)],type=[inst:Symbol]*/
-const dynamic symbolLiteralField = #foo;
-
-/*strong.member: listLiteralField:type=[inst:JSBool,inst:List<bool>]*/
-const dynamic listLiteralField = [true, false];
-
-/*strong.member: mapLiteralField:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool]*/
-const dynamic mapLiteralField = {true: false};
-
-/*strong.member: stringMapLiteralField:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:JSString]*/
-const dynamic stringMapLiteralField = {'foo': false};
-
-/*strong.member: setLiteralField:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:_UnmodifiableSet<dynamic>]*/
-const dynamic setLiteralField = {true, false};
-
-class SuperClass {
-  /*member: SuperClass.field1:type=[inst:JSNull]*/
-  final field1;
-
-  /*strong.member: SuperClass.:static=[Object.(0),init:SuperClass.field1]*/
-  const SuperClass(this.field1);
-}
-
-class Class extends SuperClass {
-  /*member: Class.field2:type=[inst:JSNull]*/
-  final field2;
-
-  /*strong.member: Class.:static=[SuperClass.(1),init:Class.field2]*/
-  const Class(field1, this.field2) : super(field1);
-
-  static staticMethodField() {}
-}
-
-/*strong.member: instanceConstantField:static=[Class.(2)],type=[inst:JSBool,param:Class]*/
-const instanceConstantField = const Class(true, false);
-
-/*strong.member: typeLiteralField:static=[createRuntimeType(1)],type=[inst:JSBool,inst:Type,inst:TypeImpl,lit:String,param:Type]*/
-const typeLiteralField = String;
-
-/*member: id:static=[checkSubtype(4),checkSubtypeOfRuntimeType(2),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),setRuntimeTypeInfo(2)],type=[inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:Object,param:id.T]*/
-T id<T>(T t) => t;
-
-/*strong.member: _instantiation:
- static=[
-  checkSubtype(4),
-  extractFunctionTypeObjectFromInternal(1),
-  getRuntimeTypeArgument(3),
-  getRuntimeTypeArgumentIntercepted(4),
-  getRuntimeTypeInfo(1),
-  getTypeArgumentByIndex(2),
-  id,instantiate1(1),
-  instantiatedGenericFunctionType(2),
-  setRuntimeTypeInfo(2)],
- type=[
-  inst:Instantiation1<dynamic>,
-  inst:JSArray<dynamic>,
-  inst:JSBool,
-  inst:JSExtendableArray<dynamic>,
-  inst:JSFixedArray<dynamic>,
-  inst:JSMutableArray<dynamic>,
-  inst:JSUnmodifiableArray<dynamic>,
-  param:int Function(int)]
-*/
-const int Function(int) _instantiation = id;
-
-/*strong.member: instantiationField:static=[_instantiation]*/
-const dynamic instantiationField = _instantiation;
-
-topLevelMethod() {}
-
-/*strong.member: topLevelTearOffField:static=[topLevelMethod]*/
-const dynamic topLevelTearOffField = topLevelMethod;
-
-/*strong.member: staticTearOffField:static=[Class.staticMethodField]*/
-const dynamic staticTearOffField = Class.staticMethodField;
diff --git a/tests/compiler/dart2js/inference/data/call_method_function_typed_value.dart b/tests/compiler/dart2js/inference/data/call_method_function_typed_value.dart
index d9c18f2..52d6d13 100644
--- a/tests/compiler/dart2js/inference/data/call_method_function_typed_value.dart
+++ b/tests/compiler/dart2js/inference/data/call_method_function_typed_value.dart
@@ -11,8 +11,6 @@
         int
             /*strong.[null|subclass=Object]*/
             /*omit.[null|subclass=JSInt]*/
-            /*strongConst.[null|subclass=Object]*/
-            /*omitConst.[null|subclass=JSInt]*/
             i) =>
     2 /*invoke: [exact=JSUInt31]*/ * i;
 
diff --git a/tests/compiler/dart2js/inference/data/closure_tracer_28919.dart b/tests/compiler/dart2js/inference/data/closure_tracer_28919.dart
index ba4ae4b..011b9ed 100644
--- a/tests/compiler/dart2js/inference/data/closure_tracer_28919.dart
+++ b/tests/compiler/dart2js/inference/data/closure_tracer_28919.dart
@@ -57,8 +57,6 @@
         /*[null]*/ (int
             /*strong.[null|subclass=Object]*/
             /*omit.[null|subclass=JSInt]*/
-            /*strongConst.[null|subclass=Object]*/
-            /*omitConst.[null|subclass=JSInt]*/
             x) {
       res = x;
       sum = x /*invoke: [null|subclass=JSInt]*/ + i;
diff --git a/tests/compiler/dart2js/inference/data/const_closure.dart b/tests/compiler/dart2js/inference/data/const_closure.dart
index 551def4..ca22d2e 100644
--- a/tests/compiler/dart2js/inference/data/const_closure.dart
+++ b/tests/compiler/dart2js/inference/data/const_closure.dart
@@ -13,12 +13,8 @@
   return a;
 }
 
-/*strong.member: foo1:[subclass=Closure]*/
-/*omit.member: foo1:[subclass=Closure]*/
 const foo1 = method1;
 
-/*strong.member: foo2:[subclass=Closure]*/
-/*omit.member: foo2:[subclass=Closure]*/
 const foo2 = method2;
 
 /*member: returnInt1:[null|subclass=Object]*/
diff --git a/tests/compiler/dart2js/inference/data/const_closure2.dart b/tests/compiler/dart2js/inference/data/const_closure2.dart
index 2dc19f6..64f75e3 100644
--- a/tests/compiler/dart2js/inference/data/const_closure2.dart
+++ b/tests/compiler/dart2js/inference/data/const_closure2.dart
@@ -8,8 +8,6 @@
   return a;
 }
 
-/*strong.member: foo:[subclass=Closure]*/
-/*omit.member: foo:[subclass=Closure]*/
 const foo = method;
 
 /*member: returnNum:[null|subclass=Object]*/
diff --git a/tests/compiler/dart2js/inference/data/const_closure3.dart b/tests/compiler/dart2js/inference/data/const_closure3.dart
index eb19bcb..31bcc35 100644
--- a/tests/compiler/dart2js/inference/data/const_closure3.dart
+++ b/tests/compiler/dart2js/inference/data/const_closure3.dart
@@ -8,8 +8,6 @@
   return a;
 }
 
-/*strong.member: foo:[subclass=Closure]*/
-/*omit.member: foo:[subclass=Closure]*/
 const foo = method;
 
 /*member: returnInt:[null|subclass=Object]*/
diff --git a/tests/compiler/dart2js/inference/data/const_closure4.dart b/tests/compiler/dart2js/inference/data/const_closure4.dart
index 2dc19f6..64f75e3 100644
--- a/tests/compiler/dart2js/inference/data/const_closure4.dart
+++ b/tests/compiler/dart2js/inference/data/const_closure4.dart
@@ -8,8 +8,6 @@
   return a;
 }
 
-/*strong.member: foo:[subclass=Closure]*/
-/*omit.member: foo:[subclass=Closure]*/
 const foo = method;
 
 /*member: returnNum:[null|subclass=Object]*/
diff --git a/tests/compiler/dart2js/inference/data/const_closure5.dart b/tests/compiler/dart2js/inference/data/const_closure5.dart
index 57e976e..36b822d 100644
--- a/tests/compiler/dart2js/inference/data/const_closure5.dart
+++ b/tests/compiler/dart2js/inference/data/const_closure5.dart
@@ -8,8 +8,6 @@
   return a;
 }
 
-/*strong.member: foo:[subclass=Closure]*/
-/*omit.member: foo:[subclass=Closure]*/
 const foo = method;
 
 /*member: returnInt:[null|subclass=Object]*/
diff --git a/tests/compiler/dart2js/inference/data/enum.dart b/tests/compiler/dart2js/inference/data/enum.dart
index 5e93aea..6e288fa 100644
--- a/tests/compiler/dart2js/inference/data/enum.dart
+++ b/tests/compiler/dart2js/inference/data/enum.dart
@@ -16,8 +16,6 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 enum Enum1 {
-  /*strong.member: Enum1.a:[exact=Enum1]*/
-  /*omit.member: Enum1.a:[exact=Enum1]*/
   a,
 }
 
@@ -29,8 +27,6 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 enum Enum2 {
-  /*strong.member: Enum2.a:[exact=Enum2]*/
-  /*omit.member: Enum2.a:[exact=Enum2]*/
   a,
 }
 
@@ -42,11 +38,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 enum Enum3 {
-  /*strong.member: Enum3.a:[exact=Enum3]*/
-  /*omit.member: Enum3.a:[exact=Enum3]*/
   a,
-  /*strong.member: Enum3.b:[exact=Enum3]*/
-  /*omit.member: Enum3.b:[exact=Enum3]*/
   b,
 }
 
@@ -58,8 +50,6 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 enum Enum4 {
-  /*strong.member: Enum4.a:[exact=Enum4]*/
-  /*omit.member: Enum4.a:[exact=Enum4]*/
   a,
 }
 
@@ -73,11 +63,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 enum Enum5 {
-  /*strong.member: Enum5.a:[exact=Enum5]*/
-  /*omit.member: Enum5.a:[exact=Enum5]*/
   a,
-  /*strong.member: Enum5.b:[exact=Enum5]*/
-  /*omit.member: Enum5.b:[exact=Enum5]*/
   b,
 }
 
diff --git a/tests/compiler/dart2js/inference/data/global_field_closure.dart b/tests/compiler/dart2js/inference/data/global_field_closure.dart
index 34f39b7..616c6f1 100644
--- a/tests/compiler/dart2js/inference/data/global_field_closure.dart
+++ b/tests/compiler/dart2js/inference/data/global_field_closure.dart
@@ -13,16 +13,10 @@
   return a;
 }
 
-/*strong.member: foo1:[null|subclass=Closure]*/
-/*omit.member: foo1:[null|subclass=Closure]*/
-/*strongConst.member: foo1:[subclass=Closure]*/
-/*omitConst.member: foo1:[subclass=Closure]*/
+/*member: foo1:[subclass=Closure]*/
 var foo1 = method1;
 
-/*strong.member: foo2:[null|subclass=Closure]*/
-/*omit.member: foo2:[null|subclass=Closure]*/
-/*strongConst.member: foo2:[subclass=Closure]*/
-/*omitConst.member: foo2:[subclass=Closure]*/
+/*member: foo2:[subclass=Closure]*/
 var foo2 = method2;
 
 /*member: returnInt1:[null|subclass=Object]*/
diff --git a/tests/compiler/dart2js/inference/data/global_field_closure2.dart b/tests/compiler/dart2js/inference/data/global_field_closure2.dart
index 3946304..42991dc 100644
--- a/tests/compiler/dart2js/inference/data/global_field_closure2.dart
+++ b/tests/compiler/dart2js/inference/data/global_field_closure2.dart
@@ -8,10 +8,7 @@
   return a;
 }
 
-/*strong.member: foo:[null|subclass=Closure]*/
-/*omit.member: foo:[null|subclass=Closure]*/
-/*strongConst.member: foo:[subclass=Closure]*/
-/*omitConst.member: foo:[subclass=Closure]*/
+/*member: foo:[subclass=Closure]*/
 var foo = method;
 
 /*member: returnInt:[null|subclass=Object]*/
diff --git a/tests/compiler/dart2js/inference/data/list.dart b/tests/compiler/dart2js/inference/data/list.dart
index 2a650bd..eb14295 100644
--- a/tests/compiler/dart2js/inference/data/list.dart
+++ b/tests/compiler/dart2js/inference/data/list.dart
@@ -108,8 +108,6 @@
 // Create a Uint16List using a const top-level field as length.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*strong.member: _field3:[exact=JSUInt31]*/
-/*omit.member: _field3:[exact=JSUInt31]*/
 const _field3 = 12;
 
 /*member: newUint16List:Container([exact=NativeUint16List], element: [exact=JSUInt31], length: 12)*/
@@ -135,8 +133,6 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 abstract class Class1 {
-  /*strong.member: Class1.field:[exact=JSUInt31]*/
-  /*omit.member: Class1.field:[exact=JSUInt31]*/
   static const field = 15;
 }
 
diff --git a/tests/compiler/dart2js/inference/data/list_huge.dart b/tests/compiler/dart2js/inference/data/list_huge.dart
index 3ef9fba..d2a23ce 100644
--- a/tests/compiler/dart2js/inference/data/list_huge.dart
+++ b/tests/compiler/dart2js/inference/data/list_huge.dart
@@ -18,34 +18,17 @@
 /*member: hugeList1:Container([exact=JSFixedArray], element: [null], length: null)*/
 hugeList1() => List(_huge1);
 
-/*strong.member: _huge2a:[subclass=JSPositiveInt]*/
-/*omit.member: _huge2a:[subclass=JSPositiveInt]*/
-const _huge2a = 10000000000
-    /*strong.invoke: [subclass=JSPositiveInt]*/
-    /*omit.invoke: [subclass=JSPositiveInt]*/
-    *
-    10000000000;
+const _huge2a = 10000000000 * 10000000000;
 
-/*strong.member: _huge2b:[null|subclass=JSPositiveInt]*/
-/*omit.member: _huge2b:[null|subclass=JSPositiveInt]*/
-/*strongConst.member: _huge2b:[subclass=JSPositiveInt]*/
-/*omitConst.member: _huge2b:[subclass=JSPositiveInt]*/
+/*member: _huge2b:[subclass=JSPositiveInt]*/
 final _huge2b = _huge2a;
 
 /*member: hugeList2:Container([exact=JSFixedArray], element: [null], length: null)*/
 hugeList2() => List(_huge2b);
 
-/*strong.member: _huge3a:[subclass=JSInt]*/
-/*omit.member: _huge3a:[subclass=JSInt]*/
-const _huge3a =
-    /*strong.invoke: [exact=JSUInt31]*/
-    /*omit.invoke: [exact=JSUInt31]*/
-    -10000000;
+const _huge3a = -10000000;
 
-/*strong.member: _huge3b:[null|subclass=JSInt]*/
-/*omit.member: _huge3b:[null|subclass=JSInt]*/
-/*strongConst.member: _huge3b:[subclass=JSInt]*/
-/*omitConst.member: _huge3b:[subclass=JSInt]*/
+/*member: _huge3b:[subclass=JSInt]*/
 final _huge3b = _huge3a;
 
 /*member: hugeList3:Container([exact=JSFixedArray], element: [null], length: null)*/
diff --git a/tests/compiler/dart2js/inference/data/map_tracer_const.dart b/tests/compiler/dart2js/inference/data/map_tracer_const.dart
index 42a1d9f..f238ad0 100644
--- a/tests/compiler/dart2js/inference/data/map_tracer_const.dart
+++ b/tests/compiler/dart2js/inference/data/map_tracer_const.dart
@@ -7,15 +7,11 @@
     int
         /*strong.Union([exact=JSDouble], [exact=JSUInt31])*/
         /*omit.[exact=JSUInt31]*/
-        /*strongConst.Union([exact=JSDouble], [exact=JSUInt31])*/
-        /*omitConst.[exact=JSUInt31]*/
         x) {
   return x;
 }
 
 class A {
-  /*strong.member: A.DEFAULT:Dictionary([subclass=ConstantMap], key: Value([exact=JSString], value: "fun"), value: [null|subclass=Closure], map: {fun: [subclass=Closure]})*/
-  /*omit.member: A.DEFAULT:Dictionary([subclass=ConstantMap], key: Value([exact=JSString], value: "fun"), value: [null|subclass=Closure], map: {fun: [subclass=Closure]})*/
   static const DEFAULT = const {'fun': closure};
 
   /*member: A.map:Dictionary([subclass=ConstantMap], key: Value([exact=JSString], value: "fun"), value: [null|subclass=Closure], map: {fun: [subclass=Closure]})*/
diff --git a/tests/compiler/dart2js/inference/libs/mixin_constructor_default_parameter_values_lib.dart b/tests/compiler/dart2js/inference/data/mixin_constructor_default_parameter_values/lib.dart
similarity index 100%
rename from tests/compiler/dart2js/inference/libs/mixin_constructor_default_parameter_values_lib.dart
rename to tests/compiler/dart2js/inference/data/mixin_constructor_default_parameter_values/lib.dart
diff --git a/tests/compiler/dart2js/inference/data/mixin_constructor_default_parameter_values.dart b/tests/compiler/dart2js/inference/data/mixin_constructor_default_parameter_values/main.dart
similarity index 93%
rename from tests/compiler/dart2js/inference/data/mixin_constructor_default_parameter_values.dart
rename to tests/compiler/dart2js/inference/data/mixin_constructor_default_parameter_values/main.dart
index 8528a7e..eb3692a 100644
--- a/tests/compiler/dart2js/inference/data/mixin_constructor_default_parameter_values.dart
+++ b/tests/compiler/dart2js/inference/data/mixin_constructor_default_parameter_values/main.dart
@@ -7,7 +7,7 @@
 // to D without optional parameters is inferred using D's context, the default
 // value `_SECRET` will not be visible and compilation will fail.
 
-import '../libs/mixin_constructor_default_parameter_values_lib.dart';
+import 'lib.dart';
 
 class Mixin {
   /*member: Mixin.foo:[exact=JSString]*/
diff --git a/tests/compiler/dart2js/inference/data/no_such_method.dart b/tests/compiler/dart2js/inference/data/no_such_method.dart
index 6fc1c46..af9d00a 100644
--- a/tests/compiler/dart2js/inference/data/no_such_method.dart
+++ b/tests/compiler/dart2js/inference/data/no_such_method.dart
@@ -17,8 +17,6 @@
           Invocation
               /*strong.[null|subclass=Object]*/
               /*omit.[null|exact=JSInvocationMirror]*/
-              /*strongConst.[null|subclass=Object]*/
-              /*omitConst.[null|exact=JSInvocationMirror]*/
               _) =>
       42;
 
@@ -43,8 +41,6 @@
           Invocation
               /*strong.[null|subclass=Object]*/
               /*omit.[null|exact=JSInvocationMirror]*/
-              /*strongConst.[null|subclass=Object]*/
-              /*omitConst.[null|exact=JSInvocationMirror]*/
               _) =>
       42;
 
@@ -69,8 +65,6 @@
       Invocation
           /*strong.[null|subclass=Object]*/
           /*omit.[null|exact=JSInvocationMirror]*/
-          /*strongConst.[null|subclass=Object]*/
-          /*omitConst.[null|exact=JSInvocationMirror]*/
           invocation) {
     return invocation
         .
@@ -107,8 +101,6 @@
       Invocation
           /*strong.[null|subclass=Object]*/
           /*omit.[null|exact=JSInvocationMirror]*/
-          /*strongConst.[null|subclass=Object]*/
-          /*omitConst.[null|exact=JSInvocationMirror]*/
           invocation) {
     this. /*update: [exact=Class4]*/ field = invocation
         .
diff --git a/tests/compiler/dart2js/inference/data/no_such_method1.dart b/tests/compiler/dart2js/inference/data/no_such_method1.dart
index c80bfb6..0c38fde 100644
--- a/tests/compiler/dart2js/inference/data/no_such_method1.dart
+++ b/tests/compiler/dart2js/inference/data/no_such_method1.dart
@@ -8,8 +8,6 @@
   noSuchMethod(
           /*strong.[null|subclass=Object]*/
           /*omit.[null|exact=JSInvocationMirror]*/
-          /*strongConst.[null|subclass=Object]*/
-          /*omitConst.[null|exact=JSInvocationMirror]*/
           im) =>
       42;
 }
diff --git a/tests/compiler/dart2js/inference/data/no_such_method2.dart b/tests/compiler/dart2js/inference/data/no_such_method2.dart
index 45a3251..f75d722 100644
--- a/tests/compiler/dart2js/inference/data/no_such_method2.dart
+++ b/tests/compiler/dart2js/inference/data/no_such_method2.dart
@@ -8,8 +8,6 @@
   noSuchMethod(
           /*strong.[null|subclass=Object]*/
           /*omit.[null|exact=JSInvocationMirror]*/
-          /*strongConst.[null|subclass=Object]*/
-          /*omitConst.[null|exact=JSInvocationMirror]*/
           im) =>
       42;
 }
@@ -35,8 +33,6 @@
   noSuchMethod(
           /*strong.[null|subclass=Object]*/
           /*omit.[null|exact=JSInvocationMirror]*/
-          /*strongConst.[null|subclass=Object]*/
-          /*omitConst.[null|exact=JSInvocationMirror]*/
           im) =>
       42.5;
 }
diff --git a/tests/compiler/dart2js/inference/data/no_such_method3.dart b/tests/compiler/dart2js/inference/data/no_such_method3.dart
index 0a41b65..0ba1d1e 100644
--- a/tests/compiler/dart2js/inference/data/no_such_method3.dart
+++ b/tests/compiler/dart2js/inference/data/no_such_method3.dart
@@ -10,8 +10,6 @@
   noSuchMethod(
           /*strong.[null|subclass=Object]*/
           /*omit.[null|exact=JSInvocationMirror]*/
-          /*strongConst.[null|subclass=Object]*/
-          /*omitConst.[null|exact=JSInvocationMirror]*/
           im) =>
       throw 'foo';
 }
diff --git a/tests/compiler/dart2js/inference/data/parameters_trust.dart b/tests/compiler/dart2js/inference/data/parameters_trust.dart
index e9b8e84..63fbb49 100644
--- a/tests/compiler/dart2js/inference/data/parameters_trust.dart
+++ b/tests/compiler/dart2js/inference/data/parameters_trust.dart
@@ -18,8 +18,6 @@
     int
         /*strong.Union([exact=JSString], [exact=JSUInt31])*/
         /*omit.[exact=JSUInt31]*/
-        /*strongConst.Union([exact=JSString], [exact=JSUInt31])*/
-        /*omitConst.[exact=JSUInt31]*/
         i) {
   return i;
 }
diff --git a/tests/compiler/dart2js/inference/data/static.dart b/tests/compiler/dart2js/inference/data/static.dart
index 2187263..e3edc37 100644
--- a/tests/compiler/dart2js/inference/data/static.dart
+++ b/tests/compiler/dart2js/inference/data/static.dart
@@ -189,10 +189,7 @@
 /*member: _method1:[exact=JSUInt31]*/
 _method1() => 42;
 
-/*strong.member: _field2:[null|subclass=Closure]*/
-/*omit.member: _field2:[null|subclass=Closure]*/
-/*strongConst.member: _field2:[subclass=Closure]*/
-/*omitConst.member: _field2:[subclass=Closure]*/
+/*member: _field2:[subclass=Closure]*/
 dynamic _field2 = _method1;
 
 /*member: invokeStaticFieldTearOff:[null|subclass=Object]*/
@@ -205,10 +202,7 @@
 /*member: _method5:Value([exact=JSString], value: "")*/
 String _method5() => '';
 
-/*strong.member: _field5:[null|subclass=Closure]*/
-/*omit.member: _field5:[null|subclass=Closure]*/
-/*strongConst.member: _field5:[subclass=Closure]*/
-/*omitConst.member: _field5:[subclass=Closure]*/
+/*member: _field5:[subclass=Closure]*/
 String Function() _field5 = _method5;
 
 /*member: invokeStaticTypedFieldTearOff:[null|exact=JSString]*/
@@ -222,10 +216,7 @@
 /*member: _method2:[exact=JSUInt31]*/
 _method2(/*[exact=JSUInt31]*/ o) => 42;
 
-/*strong.member: _field3:[null|subclass=Closure]*/
-/*omit.member: _field3:[null|subclass=Closure]*/
-/*strongConst.member: _field3:[subclass=Closure]*/
-/*omitConst.member: _field3:[subclass=Closure]*/
+/*member: _field3:[subclass=Closure]*/
 dynamic _field3 = _method2;
 
 /*member: invokeStaticFieldTearOffParameters:[null|subclass=Object]*/
@@ -251,16 +242,10 @@
 /*member: _method6:[exact=JSUInt31]*/
 int _method6() => 0;
 
-/*strong.member: _field7:[null|subclass=Closure]*/
-/*omit.member: _field7:[null|subclass=Closure]*/
-/*strongConst.member: _field7:[subclass=Closure]*/
-/*omitConst.member: _field7:[subclass=Closure]*/
+/*member: _field7:[subclass=Closure]*/
 int Function() _field7 = _method6;
 
-/*strong.member: _getter3:[null|subclass=Closure]*/
-/*omit.member: _getter3:[null|subclass=Closure]*/
-/*strongConst.member: _getter3:[subclass=Closure]*/
-/*omitConst.member: _getter3:[subclass=Closure]*/
+/*member: _getter3:[subclass=Closure]*/
 int Function() get _getter3 => _field7;
 
 /*member: invokeStaticTypedGetterTearOff:[null|subclass=JSInt]*/
@@ -299,10 +284,7 @@
 /// arguments.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*strong.member: _field4:[null|subclass=Closure]*/
-/*omit.member: _field4:[null|subclass=Closure]*/
-/*strongConst.member: _field4:[subclass=Closure]*/
-/*omitConst.member: _field4:[subclass=Closure]*/
+/*member: _field4:[subclass=Closure]*/
 T Function<T>(T) _field4 = _method4;
 
 /*member: invokeStaticGenericField1:[null|subclass=JSInt]*/
diff --git a/tests/compiler/dart2js/inference/inference_test_helper.dart b/tests/compiler/dart2js/inference/inference_test_helper.dart
index 5d4b610..06da02c 100644
--- a/tests/compiler/dart2js/inference/inference_test_helper.dart
+++ b/tests/compiler/dart2js/inference/inference_test_helper.dart
@@ -18,9 +18,9 @@
 import '../equivalence/id_equivalence.dart';
 import '../equivalence/id_equivalence_helper.dart';
 
-const List<String> skipForStrong = const <String>[
+const List<String> skip = const <String>[
   // TODO(johnniwinther): Remove this when issue 31767 is fixed.
-  'mixin_constructor_default_parameter_values.dart',
+  'mixin_constructor_default_parameter_values',
 ];
 
 main(List<String> args) {
@@ -31,12 +31,11 @@
   asyncTest(() async {
     Directory dataDir = new Directory.fromUri(Platform.script.resolve('data'));
     await checkTests(dataDir, const TypeMaskDataComputer(),
-        libDirectory: new Directory.fromUri(Platform.script.resolve('libs')),
         forUserLibrariesOnly: true,
         args: args,
         options: [stopAfterTypeInference],
         testedConfigs: allInternalConfigs,
-        skipForStrong: skipForStrong,
+        skip: skip,
         shardIndex: shardIndex ?? 0,
         shards: shardIndex != null ? 4 : 1);
   });
diff --git a/tests/compiler/dart2js/inference/side_effects/foreign.dart b/tests/compiler/dart2js/inference/side_effects/foreign.dart
index 1eb5a1f..ab10b35 100644
--- a/tests/compiler/dart2js/inference/side_effects/foreign.dart
+++ b/tests/compiler/dart2js/inference/side_effects/foreign.dart
@@ -29,20 +29,12 @@
   return JS_BUILTIN('String', JsBuiltin.rawRtiToJsConstructorName, null);
 }
 
-/*strong.member: jsEmbeddedGlobal_getTypeFromName:SideEffects(reads static; writes nothing)*/
-/*omit.member: jsEmbeddedGlobal_getTypeFromName:SideEffects(reads static; writes nothing)*/
-// With CFE constant we no longer get the noise from the static get if GET_TYPE_FROM_NAME.
-/*strongConst.member: jsEmbeddedGlobal_getTypeFromName:SideEffects(reads nothing; writes nothing)*/
-/*omitConst.member: jsEmbeddedGlobal_getTypeFromName:SideEffects(reads nothing; writes nothing)*/
+/*member: jsEmbeddedGlobal_getTypeFromName:SideEffects(reads nothing; writes nothing)*/
 jsEmbeddedGlobal_getTypeFromName() {
   return JS_EMBEDDED_GLOBAL('', GET_TYPE_FROM_NAME);
 }
 
-/*strong.member: jsEmbeddedGlobal_libraries:SideEffects(reads static; writes nothing)*/
-/*omit.member: jsEmbeddedGlobal_libraries:SideEffects(reads static; writes nothing)*/
-// With CFE constant we no longer get the noise from the static get if LIBRARIES.
-/*strongConst.member: jsEmbeddedGlobal_libraries:SideEffects(reads nothing; writes nothing)*/
-/*omitConst.member: jsEmbeddedGlobal_libraries:SideEffects(reads nothing; writes nothing)*/
+/*member: jsEmbeddedGlobal_libraries:SideEffects(reads nothing; writes nothing)*/
 jsEmbeddedGlobal_libraries() {
   return JS_EMBEDDED_GLOBAL('JSExtendableArray|Null', LIBRARIES);
 }
diff --git a/tests/compiler/dart2js/member_usage/data/constant_folding.dart b/tests/compiler/dart2js/member_usage/data/constant_folding.dart
index 195684c..4c601de 100644
--- a/tests/compiler/dart2js/member_usage/data/constant_folding.dart
+++ b/tests/compiler/dart2js/member_usage/data/constant_folding.dart
@@ -42,7 +42,6 @@
   /*member: TestOp.result:init,read*/
   final result;
 
-  /*strong.member: TestOp.:invoke*/
   const TestOp(this.expected, this.result);
 
   /*member: TestOp.checkAll:invoke*/
@@ -62,7 +61,6 @@
   /*member: BitNot.arg:init,read*/
   final arg;
 
-  /*strong.member: BitNot.:invoke*/
   const BitNot(this.arg, expected) : super(expected, ~arg);
 
   /*member: BitNot.check:invoke*/
diff --git a/tests/compiler/dart2js/model/cfe_annotations_test.dart b/tests/compiler/dart2js/model/cfe_annotations_test.dart
index e01dba6..b35ac4b 100644
--- a/tests/compiler/dart2js/model/cfe_annotations_test.dart
+++ b/tests/compiler/dart2js/model/cfe_annotations_test.dart
@@ -4,7 +4,6 @@
 
 import 'package:args/args.dart';
 import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/ir/annotations.dart';
@@ -191,10 +190,7 @@
           memorySourceFiles: source,
           packageConfig: packageConfig,
           librariesSpecificationUri: librariesSpecificationUri,
-          options: (useIr
-              ? ['${Flags.enableLanguageExperiments}=constant-update-2018']
-              : [])
-            ..addAll(options));
+          options: options);
       Expect.isTrue(result.isSuccess);
       Compiler compiler = result.compiler;
       KernelFrontendStrategy frontendStrategy = compiler.frontendStrategy;
diff --git a/tests/compiler/dart2js/model/cfe_constant_evaluation_test.dart b/tests/compiler/dart2js/model/cfe_constant_evaluation_test.dart
index 12c4bca..5dabc0f 100644
--- a/tests/compiler/dart2js/model/cfe_constant_evaluation_test.dart
+++ b/tests/compiler/dart2js/model/cfe_constant_evaluation_test.dart
@@ -569,12 +569,9 @@
   print(source);
 
   Future runTest() async {
-    CompilationResult result = await runCompiler(memorySourceFiles: {
-      'main.dart': source
-    }, options: [
-      Flags.enableAsserts,
-      '${Flags.enableLanguageExperiments}=constant-update-2018',
-    ]);
+    CompilationResult result = await runCompiler(
+        memorySourceFiles: {'main.dart': source},
+        options: [Flags.enableAsserts]);
     Compiler compiler = result.compiler;
     KernelFrontendStrategy frontEndStrategy = compiler.frontendStrategy;
     KernelToElementMapImpl elementMap = frontEndStrategy.elementMap;
diff --git a/tests/compiler/dart2js/model/cfe_constant_swarm_test.dart b/tests/compiler/dart2js/model/cfe_constant_swarm_test.dart
index 1a7dd18..5a8997b 100644
--- a/tests/compiler/dart2js/model/cfe_constant_swarm_test.dart
+++ b/tests/compiler/dart2js/model/cfe_constant_swarm_test.dart
@@ -4,7 +4,6 @@
 
 import 'package:args/args.dart';
 import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/commandline_options.dart';
 
 import '../helpers/args_helper.dart';
 import '../helpers/memory_compiler.dart';
@@ -23,7 +22,6 @@
         entryPoint: entryPoint,
         packageConfig: packageConfig,
         librariesSpecificationUri: librariesSpecificationUri,
-        options: ['${Flags.enableLanguageExperiments}=constant-update-2018']
-          ..addAll(options));
+        options: options);
   });
 }
diff --git a/tests/compiler/dart2js/model/no_such_method_enabled_test.dart b/tests/compiler/dart2js/model/no_such_method_enabled_test.dart
index 08a9bf9..7e45417 100644
--- a/tests/compiler/dart2js/model/no_such_method_enabled_test.dart
+++ b/tests/compiler/dart2js/model/no_such_method_enabled_test.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/common_elements.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/elements/entities.dart';
@@ -235,15 +234,12 @@
 ];
 
 main() {
-  runTests({bool useCFEConstants: false}) async {
+  runTests() async {
     for (NoSuchMethodTest test in TESTS) {
       print('---- testing -------------------------------------------------');
       print(test.code);
-      CompilationResult result = await runCompiler(
-          memorySourceFiles: {'main.dart': test.code},
-          options: useCFEConstants
-              ? ['${Flags.enableLanguageExperiments}=constant-update-2018']
-              : []);
+      CompilationResult result =
+          await runCompiler(memorySourceFiles: {'main.dart': test.code});
       Expect.isTrue(result.isSuccess);
       Compiler compiler = result.compiler;
       checkTest(compiler, test);
@@ -253,8 +249,6 @@
   asyncTest(() async {
     print('--test from kernel------------------------------------------------');
     await runTests();
-    print('--test from kernel with CFE constants-----------------------------');
-    await runTests(useCFEConstants: true);
   });
 }
 
diff --git a/tests/compiler/dart2js/rti/emission/static_argument.dart b/tests/compiler/dart2js/rti/emission/static_argument.dart
index d840003..f90c477 100644
--- a/tests/compiler/dart2js/rti/emission/static_argument.dart
+++ b/tests/compiler/dart2js/rti/emission/static_argument.dart
@@ -6,16 +6,15 @@
 /*omit.class: I1:*/
 class I1 {}
 
-/*strong.class: I2:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*omit.class: I2:checkedTypeArgument,checks=[],typeArgument*/
+/*strong.class: I2:checkedInstance*/
 class I2 {}
 
 /*strong.class: A:checks=[$isI2],instance*/
-/*omit.class: A:checks=[$isI2],instance*/
+/*omit.class: A:checks=[],instance*/
 class A implements I1, I2 {}
 
 /*strong.class: B:checks=[$isI2],instance*/
-/*omit.class: B:checks=[$isI2],instance*/
+/*omit.class: B:checks=[],instance*/
 class B implements I1, I2 {}
 
 @pragma('dart2js:noInline')
diff --git a/tests/compiler/dart2js/serialization/serialization_test.dart b/tests/compiler/dart2js/serialization/serialization_test.dart
index 496787d..75dcb9a 100644
--- a/tests/compiler/dart2js/serialization/serialization_test.dart
+++ b/tests/compiler/dart2js/serialization/serialization_test.dart
@@ -13,17 +13,12 @@
   asyncTest(() async {
     Directory dataDir = new Directory.fromUri(Platform.script.resolve('data'));
     Directory libDir = new Directory.fromUri(Platform.script.resolve('libs'));
-    print('--testing without CFE constants-----------------------------------');
     await checkTests(dataDir, options: [], args: args, libDirectory: libDir);
-    print('--testing with CFE constants--------------------------------------');
-    await checkTests(dataDir,
-        options: [], args: args, libDirectory: libDir, testCFEConstants: true);
   });
 }
 
 Future checkTests(Directory dataDir,
-    {bool testCFEConstants: false,
-    List<String> options: const <String>[],
+    {List<String> options: const <String>[],
     List<String> args: const <String>[],
     Directory libDirectory: null,
     bool forUserLibrariesOnly: true,
@@ -54,10 +49,6 @@
     if (shouldContinue) continued = true;
     testCount++;
     List<String> testOptions = options.toList();
-    if (testCFEConstants) {
-      testOptions
-          .add('${Flags.enableLanguageExperiments}=constant-update-2018');
-    }
     testOptions.add(Flags.dumpInfo);
     testOptions.add('--out=out.js');
     if (onTest != null) {
diff --git a/tests/compiler/dart2js/sourcemaps/stacktrace_test.dart b/tests/compiler/dart2js/sourcemaps/stacktrace_test.dart
index b3ca79e..a4a6fa0 100644
--- a/tests/compiler/dart2js/sourcemaps/stacktrace_test.dart
+++ b/tests/compiler/dart2js/sourcemaps/stacktrace_test.dart
@@ -63,13 +63,6 @@
       writeJs: writeJs,
       verbose: verbose,
       inlineData: inlineData);
-  print('---from kernel with CFE constants-----------------------------------');
-  await runTest(test, kernelMarker,
-      printJs: printJs,
-      writeJs: writeJs,
-      verbose: verbose,
-      inlineData: inlineData,
-      options: ['${Flags.enableLanguageExperiments}=constant-update-2018']);
 }
 
 Future runTest(Test test, String config,
diff --git a/tests/compiler/dart2js/static_type/data/null_access.dart b/tests/compiler/dart2js/static_type/data/null_access.dart
index 4c7735a..c21b149 100644
--- a/tests/compiler/dart2js/static_type/data/null_access.dart
+++ b/tests/compiler/dart2js/static_type/data/null_access.dart
@@ -15,8 +15,9 @@
 }
 
 test1() {
+  // TODO(johnniwinther): Compute actual type of constants?
   const Class1 c = null;
-  return /*Null*/ c. /*invoke: [Null]->void*/ method1();
+  return c. /*invoke: [Class1]->void*/ method1();
 }
 
 class Class2<T> {
@@ -28,7 +29,7 @@
 test2() {
   const Class2<int> c = null;
   // TODO(johnniwinther): Track the unreachable code properly.
-  return /*Null*/ c. /*invoke: [Null]-><bottom>*/ method2();
+  return c. /*invoke: [Class2<int>]->int*/ method2();
 }
 
 class Class3<T> {
@@ -40,5 +41,5 @@
 test3() {
   const Class3<int> c = null;
   // TODO(johnniwinther): Track the unreachable code properly.
-  return /*Null*/ c. /*invoke: [Null]->Class3<<bottom>>*/ method3();
+  return c. /*invoke: [Class3<int>]->Class3<int>*/ method3();
 }
diff --git a/tests/ffi/dynamic_library_test.dart b/tests/ffi/dynamic_library_test.dart
index 7b29a18..f3d53c8 100644
--- a/tests/ffi/dynamic_library_test.dart
+++ b/tests/ffi/dynamic_library_test.dart
@@ -8,12 +8,13 @@
 
 library FfiTest;
 
+import 'dart:io';
 import 'dart:ffi';
 
-import 'dylib_utils.dart';
-
 import 'package:expect/expect.dart';
 
+import 'dylib_utils.dart';
+
 void main() {
   testOpen();
   testOpenError();
@@ -42,6 +43,20 @@
   DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
   var timesFour = l.lookupFunction<NativeDoubleUnOp, DoubleUnOp>("timesFour");
   Expect.approxEquals(12.0, timesFour(3));
+
+  if (Platform.isMacOS ||
+      Platform.isIOS ||
+      Platform.isAndroid ||
+      Platform.isLinux) {
+    // Lookup a symbol from 'libc' since it's loaded with global visibility.
+    DynamicLibrary p = DynamicLibrary.process();
+    Expect.isTrue(p.lookup<Void>("strcmp") != nullptr);
+  } else {
+    Expect.throws<UnsupportedError>(() => DynamicLibrary.process());
+  }
+
+  DynamicLibrary e = DynamicLibrary.executable();
+  Expect.isTrue(e.lookup("Dart_Invoke") != nullptr);
 }
 
 void testLookupError() {
diff --git a/tests/ffi/regress_37780_test.dart b/tests/ffi/regress_37780_test.dart
new file mode 100644
index 0000000..a6b9f7e
--- /dev/null
+++ b/tests/ffi/regress_37780_test.dart
@@ -0,0 +1,20 @@
+// 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.
+//
+// SharedObjects=ffi_test_functions
+
+import 'dart:ffi';
+
+import 'dylib_utils.dart';
+
+DynamicLibrary ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
+
+final triggerGc = ffiTestFunctions
+    .lookupFunction<Void Function(), void Function()>("TriggerGC");
+
+main(List<String> args) {
+  final foo = [Float(), Double(), Uint8()];
+  triggerGc();
+  print(foo);
+}
diff --git a/tests/language_2/abstract_syntax_test.dart b/tests/language_2/abstract_syntax_test.dart
index c020800..fba3725 100644
--- a/tests/language_2/abstract_syntax_test.dart
+++ b/tests/language_2/abstract_syntax_test.dart
@@ -11,7 +11,7 @@
 
 class A {
   foo(); // //# 00: compile-time error
-  static bar(); // //# 01: compile-time error
+  static bar(); // //# 01: syntax error
 }
 
 class B extends A {
diff --git a/tests/language_2/bad_constructor_test.dart b/tests/language_2/bad_constructor_test.dart
index 4ae6751..10b9f42 100644
--- a/tests/language_2/bad_constructor_test.dart
+++ b/tests/language_2/bad_constructor_test.dart
@@ -4,7 +4,7 @@
 
 // A constructor can't be static.
 class A {
-  static //# 00: compile-time error
+  static //# 00: syntax error
   A();
 }
 
diff --git a/tests/language_2/const_double_in_int_op_test.dart b/tests/language_2/const_double_in_int_op_test.dart
new file mode 100644
index 0000000..d9432f1
--- /dev/null
+++ b/tests/language_2/const_double_in_int_op_test.dart
@@ -0,0 +1,40 @@
+// 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=constant-update-2018,triple-shift
+
+main() {
+  const dynamic i1 = 3;
+  const dynamic i2 = 2;
+  const dynamic d1 = 3.3;
+  const dynamic d2 = 2.2;
+
+  const sum = 0 + //
+      (i1 | i2) + //# ii1: ok
+      (i1 & i2) + //# ii2: ok
+      (i1 ^ i2) + //# ii3: ok
+      (i1 << i2) + //# ii4: ok
+      (i1 >> i2) + //# ii5: ok
+      (i1 >>> i2) + //# ii6: ok
+      (i1 | d2) + //# id1: compile-time error
+      (i1 & d2) + //# id2: compile-time error
+      (i1 ^ d2) + //# id3: compile-time error
+      (i1 << d2) + //# id4: compile-time error
+      (i1 >> d2) + //# id5: compile-time error
+      (i1 >>> d2) + //# id6: compile-time error
+      (d1 | i2) + //# di1: compile-time error
+      (d1 & i2) + //# di2: compile-time error
+      (d1 ^ i2) + //# di3: compile-time error
+      (d1 << i2) + //# di4: compile-time error
+      (d1 >> i2) + //# di5: compile-time error
+      (d1 >>> i2) + //# di6: compile-time error
+      (d1 | d2) + //# dd1: compile-time error
+      (d1 & d2) + //# dd2: compile-time error
+      (d1 ^ d2) + //# dd3: compile-time error
+      (d1 << d2) + //# dd4: compile-time error
+      (d1 >> d2) + //# dd5: compile-time error
+      (d1 >>> d2) + //# dd6: compile-time error
+      0;
+  print(sum);
+}
diff --git a/tests/language_2/extension_methods/static_extension_bounds_error_test.dart b/tests/language_2/extension_methods/static_extension_bounds_error_test.dart
index 5ee6ce1..1707f79 100644
--- a/tests/language_2/extension_methods/static_extension_bounds_error_test.dart
+++ b/tests/language_2/extension_methods/static_extension_bounds_error_test.dart
@@ -35,15 +35,15 @@
   // Inferred type of String does not satisfy the bound.
   s.e1;
 //  ^^
-// [analyzer] unspecified
+// [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
 // [cfe] unspecified
   E1(s).e1;
-//      ^^
-// [analyzer] unspecified
+//^^
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
 // [cfe] unspecified
   E1<String>(s).e1;
-//              ^^
-// [analyzer] unspecified
+//   ^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
 // [cfe] unspecified
 
   // Inferred types of int and double are ok
@@ -57,15 +57,15 @@
   // Inferred type of String does not satisfy the bound.
   s.e2;
 //  ^^
-// [analyzer] unspecified
+// [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
 // [cfe] unspecified
   E2(s).e2;
-//      ^^
-// [analyzer] unspecified
+//^^
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
 // [cfe] unspecified
   E2<String, num>(s).e2;
-//                   ^^
-// [analyzer] unspecified
+//   ^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
 // [cfe] unspecified
 
   // Inferred types of int and double are ok
@@ -80,15 +80,15 @@
   // bound of String
   s.f3(3);
 //  ^^
-// [analyzer] unspecified
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
 // [cfe] unspecified
   E3(s).f3(3);
 //      ^^
-// [analyzer] unspecified
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
 // [cfe] unspecified
   E3<String>(s).f3(3);
 //              ^^
-// [analyzer] unspecified
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
 // [cfe] unspecified
 
   // Inferred type int for method type parameter is ok
@@ -100,15 +100,15 @@
   // bound of double
   d.f3(3);
 //  ^^
-// [analyzer] unspecified
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
 // [cfe] unspecified
   E3(d).f3(3);
 //      ^^
-// [analyzer] unspecified
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
 // [cfe] unspecified
   E3<double>(d).f3(3);
 //              ^^
-// [analyzer] unspecified
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
 // [cfe] unspecified
 
   RecSolution recs = RecSolution();
@@ -122,14 +122,14 @@
   // Inferred super-bounded type is invalid as type argument
   superRec.e4;
 //         ^^
-// [analyzer] unspecified
+// [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
 // [cfe] unspecified
   E4(superRec).e4;
-//             ^^
-// [analyzer] unspecified
+//^^
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
 // [cfe] unspecified
   E4<Rec<dynamic>>(superRec).e4;
-//                           ^^
-// [analyzer] unspecified
+//   ^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
 // [cfe] unspecified
 }
\ No newline at end of file
diff --git a/tests/language_2/extension_methods/static_extension_internal_name_conflict_error_test.dart b/tests/language_2/extension_methods/static_extension_internal_name_conflict_error_test.dart
new file mode 100644
index 0000000..4bd5a29
--- /dev/null
+++ b/tests/language_2/extension_methods/static_extension_internal_name_conflict_error_test.dart
@@ -0,0 +1,242 @@
+// 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=extension-methods
+
+// Tests that errors are given for internal name conflicts in extension methods.
+
+// It is an error to have duplicate type parameter names.
+extension E1<T, T> on int {
+//              ^
+// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+// [cfe] unspecified
+}
+
+extension E2 on int {}
+
+// It is an error to have duplicate extension names.
+extension E2 on int {}
+//        ^^
+// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+// [cfe] unspecified
+
+
+class E2 {}
+//    ^^
+// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+// [cfe] unspecified
+
+typedef E2 = int Function(int);
+//      ^^
+// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+// [cfe] unspecified
+
+void E2(int x) {}
+//   ^^
+// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+// [cfe] unspecified
+
+int E2 = 3;
+//  ^^
+// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+// [cfe] unspecified
+
+////////////////////////////////////////////////////////////////////
+// It is an error to have two static members with the same base name
+// unless one is a setter and one is a getter.
+//
+// The next set of tests check various combinations of member name
+// conflicts: first testing that members of the same kind (e.g.
+// method/method) induce conflicts for the various combinations of
+// static/instance; and then testing that members of different kind (e.g.
+// method/getter) induce conflicts for the various combinations of
+// static/instance.
+////////////////////////////////////////////////////////////////////
+
+// Check static members colliding with static members (of the same kind)
+extension E3 on int {
+  static int method() => 0;
+  static int get property => 1;
+  static void set property(int value) {}
+  static int field = 3;
+  static int field2 = 4;
+
+  static int method() => 0;
+  //         ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] unspecified
+  static int get property => 1;
+  //             ^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] unspecified
+  static void set property(int value) {}
+  //              ^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] unspecified
+  static int field = 3;
+  //         ^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] unspecified
+  static int get field2 => 1;
+  //             ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] unspecified
+  static void set field2(int value) {}
+  //              ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] unspecified
+}
+
+// Check instance members colliding with instance members (of the same kind).
+extension E4 on int {
+  int method() => 0;
+  int get property => 1;
+  void set property(int value) {}
+
+  int method() => 0;
+  //  ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] unspecified
+  int get property => 1;
+  //      ^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] unspecified
+  void set property(int value) {}
+  //       ^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] unspecified
+}
+
+
+// Check static members colliding with static members (of the same kind).
+extension E5 on int {
+  static int method() => 0;
+  //         ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] unspecified
+  static int get property => 1;
+  //             ^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] unspecified
+  static void set property(int value) {}
+  //              ^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] unspecified
+  static int get property2 => 1;
+  //             ^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] unspecified
+  static void set property3(int x) {}
+  //              ^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] unspecified
+  static int field = 3;
+  //         ^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] unspecified
+  static int field2 = 3;
+  //         ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] unspecified
+
+  int method() => 0;
+  int get property => 1;
+  void set property(int value) {}
+  void set property2(int value) {}
+  int get property3 => 1;
+  void set field(int value) {}
+  int get field2 => 1;
+}
+
+// Check a static method colliding with a static getter.
+extension E6 on int {
+  static int method() => 0;
+  static int get method => 1;
+  //             ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] unspecified
+}
+
+// Check a static method colliding with a static setter.
+extension E7 on int {
+  static int method() => 0;
+  static void set method(int value) {}
+  //              ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] unspecified
+}
+
+// Check a static method colliding with a static field.
+extension E8 on int {
+  static int method() => 0;
+  static int method = 3;
+  //         ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] unspecified
+}
+
+// Check an instance method colliding with an instance getter.
+extension E9 on int {
+  int method() => 0;
+  int get method => 1;
+  //      ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] unspecified
+}
+
+// Check an instance method colliding with an instance setter.
+extension E10 on int {
+  int method() => 0;
+  void set method(int value) {}
+  //       ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] unspecified
+}
+
+// Check a static method colliding with an instance getter.
+extension E11 on int {
+  static int method() => 0;
+  //         ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] unspecified
+  int get method => 1;
+}
+
+// Check a static method colliding with an instance setter.
+extension E12 on int {
+  static int method() => 0;
+  //         ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] unspecified
+  void set method(int value) {}
+}
+
+// Check an instance method colliding with a static getter.
+extension E13 on int {
+  int method() => 0;
+  static int get method => 1;
+  //             ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] unspecified
+}
+
+// Check an instance method colliding with a static setter.
+extension E14 on int {
+  int method() => 0;
+  static void set method(int value) {}
+  //              ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] unspecified
+}
+
+// Check an instance method colliding with a static field.
+extension E15 on int {
+  int method() => 0;
+  static int method = 3;
+  //         ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] unspecified
+}
+
+void main() {}
\ No newline at end of file
diff --git a/tests/language_2/extension_methods/static_extension_internal_resolution_3_error_test.dart b/tests/language_2/extension_methods/static_extension_internal_resolution_3_error_test.dart
index 534222e..e1f92af 100644
--- a/tests/language_2/extension_methods/static_extension_internal_resolution_3_error_test.dart
+++ b/tests/language_2/extension_methods/static_extension_internal_resolution_3_error_test.dart
@@ -96,24 +96,18 @@
       // [cfe] unspecified
       //             ^^^^^^^^^^^^^^^^^^
       // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_METHOD_ACCESS
-      //             ^^^^^^^^^^^^^^^^^^
-      // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
       checkExtensionValue(t0);
       bool t1 = this.getterInGlobalScope;
       //             ^^^
       // [cfe] unspecified
       //             ^^^^^^^^^^^^^^^^^^^
       // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_METHOD_ACCESS
-      //             ^^^^^^^^^^^^^^^^^^^
-      // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
       checkExtensionValue(t1);
       this.setterInGlobalScope = extensionValue;
       //   ^^^
       // [cfe] unspecified
       //   ^^^^^^^^^^^^^^^^^^^
       // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_METHOD_ACCESS
-      //   ^^^^^^^^^^^^^^^^^^^
-      // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_SETTER
       bool t2 = this.methodInGlobalScope();
       //             ^^^
       // [cfe] unspecified
@@ -150,24 +144,18 @@
       // [cfe] unspecified
       //             ^^^^^^^^^^^^^^^^^^
       // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_METHOD_ACCESS
-      //             ^^^^^^^^^^^^^^^^^^
-      // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
       checkExtensionValue(t0);
       bool t1 = self.getterInGlobalScope;
       //             ^^^
       // [cfe] unspecified
       //             ^^^^^^^^^^^^^^^^^^^
       // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_METHOD_ACCESS
-      //             ^^^^^^^^^^^^^^^^^^^
-      // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
       checkExtensionValue(t1);
       self.setterInGlobalScope = extensionValue;
       //   ^^^
       // [cfe] unspecified
       //   ^^^^^^^^^^^^^^^^^^^
       // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_METHOD_ACCESS
-      //   ^^^^^^^^^^^^^^^^^^^
-      // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_SETTER
       bool t2 = self.methodInGlobalScope();
       //             ^^^
       // [cfe] unspecified
@@ -245,22 +233,16 @@
     // [cfe] unspecified
     //          ^^^^^^^^^^^^^^^^^^
     // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_METHOD_ACCESS
-    //          ^^^^^^^^^^^^^^^^^^
-    // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
     checkExtensionValue(t0);
     bool t1 = a.getterInGlobalScope;
     //          ^^^
     // [cfe] unspecified
     //          ^^^^^^^^^^^^^^^^^^^
     // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_METHOD_ACCESS
-    //          ^^^^^^^^^^^^^^^^^^^
-    // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
     checkExtensionValue(t1);
     a.setterInGlobalScope = extensionValue;
     //^^^^^^^^^^^^^^^^^^^
     // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_METHOD_ACCESS
-    //^^^^^^^^^^^^^^^^^^^
-    // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_SETTER
     // ^^^
     // [cfe] unspecified
     bool t2 = a.methodInGlobalScope();
diff --git a/tests/language_2/extension_methods/static_extension_internal_resolution_4_error_test.dart b/tests/language_2/extension_methods/static_extension_internal_resolution_4_error_test.dart
index 801a528..db4b51b 100644
--- a/tests/language_2/extension_methods/static_extension_internal_resolution_4_error_test.dart
+++ b/tests/language_2/extension_methods/static_extension_internal_resolution_4_error_test.dart
@@ -96,24 +96,18 @@
       // [cfe] unspecified
       //             ^^^^^^^^^^^^^^^^^^
       // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_METHOD_ACCESS
-      //             ^^^^^^^^^^^^^^^^^^
-      // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
       checkExtensionValue(t0);
       bool t1 = this.getterInGlobalScope;
       //             ^^^
       // [cfe] unspecified
       //             ^^^^^^^^^^^^^^^^^^^
       // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_METHOD_ACCESS
-      //             ^^^^^^^^^^^^^^^^^^^
-      // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
       checkExtensionValue(t1);
       this.setterInGlobalScope = extensionValue;
       //   ^^^
       // [cfe] unspecified
       //   ^^^^^^^^^^^^^^^^^^^
       // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_METHOD_ACCESS
-      //   ^^^^^^^^^^^^^^^^^^^
-      // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_SETTER
       bool t2 = this.methodInGlobalScope();
       //             ^^^
       // [cfe] unspecified
@@ -135,24 +129,18 @@
       // [cfe] unspecified
       //             ^^^^^^^^^^^^^^^^^^^^^
       // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_METHOD_ACCESS
-      //             ^^^^^^^^^^^^^^^^^^^^^
-      // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
       checkExtensionValue(t0);
       bool t1 = this.getterInExtensionScope;
       //             ^^^
       // [cfe] unspecified
       //             ^^^^^^^^^^^^^^^^^^^^^^
       // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_METHOD_ACCESS
-      //             ^^^^^^^^^^^^^^^^^^^^^^
-      // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
       checkExtensionValue(t1);
       this.setterInExtensionScope = extensionValue;
       //   ^^^
       // [cfe] unspecified
       //   ^^^^^^^^^^^^^^^^^^^^^^
       // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_METHOD_ACCESS
-      //   ^^^^^^^^^^^^^^^^^^^^^^
-      // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_SETTER
       bool t2 = this.methodInExtensionScope();
       //             ^^^
       // [cfe] unspecified
@@ -178,24 +166,18 @@
       // [cfe] unspecified
       //             ^^^^^^^^^^^^^^^^^^
       // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_METHOD_ACCESS
-      //             ^^^^^^^^^^^^^^^^^^
-      // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
       checkExtensionValue(t0);
       bool t1 = self.getterInGlobalScope;
       //             ^^^
       // [cfe] unspecified
       //             ^^^^^^^^^^^^^^^^^^^
       // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_METHOD_ACCESS
-      //             ^^^^^^^^^^^^^^^^^^^
-      // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
       checkExtensionValue(t1);
       self.setterInGlobalScope = extensionValue;
       //   ^^^
       // [cfe] unspecified
       //   ^^^^^^^^^^^^^^^^^^^
       // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_METHOD_ACCESS
-      //   ^^^^^^^^^^^^^^^^^^^
-      // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_SETTER
       bool t2 = self.methodInGlobalScope();
       //             ^^^
       // [cfe] unspecified
@@ -217,24 +199,18 @@
       // [cfe] unspecified
       //             ^^^^^^^^^^^^^^^^^^^^^
       // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_METHOD_ACCESS
-      //             ^^^^^^^^^^^^^^^^^^^^^
-      // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
       checkExtensionValue(t0);
       bool t1 = self.getterInExtensionScope;
       //             ^^^
       // [cfe] unspecified
       //             ^^^^^^^^^^^^^^^^^^^^^^
       // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_METHOD_ACCESS
-      //             ^^^^^^^^^^^^^^^^^^^^^^
-      // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
       checkExtensionValue(t1);
       self.setterInExtensionScope = extensionValue;
       //   ^^^
       // [cfe] unspecified
       //   ^^^^^^^^^^^^^^^^^^^^^^
       // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_METHOD_ACCESS
-      //   ^^^^^^^^^^^^^^^^^^^^^^
-      // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_SETTER
       bool t2 = self.methodInExtensionScope();
       //             ^^^
       // [cfe] unspecified
@@ -330,22 +306,16 @@
     // [cfe] unspecified
     //          ^^^^^^^^^^^^^^^^^^
     // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_METHOD_ACCESS
-    //          ^^^^^^^^^^^^^^^^^^
-    // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
     checkExtensionValue(t0);
     bool t1 = a.getterInGlobalScope;
     //          ^^^
     // [cfe] unspecified
     //          ^^^^^^^^^^^^^^^^^^^
     // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_METHOD_ACCESS
-    //          ^^^^^^^^^^^^^^^^^^^
-    // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
     checkExtensionValue(t1);
     a.setterInGlobalScope = extensionValue;
     //^^^^^^^^^^^^^^^^^^^
     // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_METHOD_ACCESS
-    //^^^^^^^^^^^^^^^^^^^
-    // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_SETTER
     // ^^^
     // [cfe] unspecified
     bool t2 = a.methodInGlobalScope();
@@ -369,22 +339,16 @@
     // [cfe] unspecified
     //          ^^^^^^^^^^^^^^^^^^^^^
     // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_METHOD_ACCESS
-    //          ^^^^^^^^^^^^^^^^^^^^^
-    // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
     checkExtensionValue(t0);
     bool t1 = a.getterInExtensionScope;
     //          ^^^
     // [cfe] unspecified
     //          ^^^^^^^^^^^^^^^^^^^^^^
     // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_METHOD_ACCESS
-    //          ^^^^^^^^^^^^^^^^^^^^^^
-    // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
     checkExtensionValue(t1);
     a.setterInExtensionScope = extensionValue;
     //^^^^^^^^^^^^^^^^^^^^^^
     // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_METHOD_ACCESS
-    //^^^^^^^^^^^^^^^^^^^^^^
-    // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_SETTER
     // ^^^
     // [cfe] unspecified
     bool t2 = a.methodInExtensionScope();
diff --git a/tests/language_2/extension_methods/static_extension_internal_resolution_6_error_test.dart b/tests/language_2/extension_methods/static_extension_internal_resolution_6_error_test.dart
index edfa8ef..bd1ddf0 100644
--- a/tests/language_2/extension_methods/static_extension_internal_resolution_6_error_test.dart
+++ b/tests/language_2/extension_methods/static_extension_internal_resolution_6_error_test.dart
@@ -56,11 +56,19 @@
 extension StaticExt on AGlobal {
   // Valid to overlap static names with the target type symbols
   static bool get fieldInInstanceScope => extensionValue;
+  //              ^^^^^^^^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
   static bool get getterInInstanceScope => extensionValue;
+  //              ^^^^^^^^^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
   static set setterInInstanceScope(bool x) {
+  //         ^^^^^^^^^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
     checkExtensionValue(x);
   }
   static bool methodInInstanceScope() => extensionValue;
+  //          ^^^^^^^^^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
 
   // Add the global symbols
   static bool get fieldInGlobalScope => extensionValue;
@@ -73,21 +81,17 @@
   // Invalid to overlap the static and extension scopes
   bool get fieldInInstanceScope => extensionValue;
   //       ^^^
-  // [analyzer] unspecified
   // [cfe] unspecified
   bool get getterInInstanceScope => extensionValue;
   //       ^^^
-  // [analyzer] unspecified
   // [cfe] unspecified
   set setterInInstanceScope(bool x) {
   //  ^^^
-  // [analyzer] unspecified
   // [cfe] unspecified
     checkExtensionValue(x);
   }
   bool methodInInstanceScope() => extensionValue;
   //   ^^^
-  // [analyzer] unspecified
   // [cfe] unspecified
 
 
diff --git a/tests/language_2/extension_methods/static_extension_setter_getter_assignability_error_test.dart b/tests/language_2/extension_methods/static_extension_setter_getter_assignability_error_test.dart
new file mode 100644
index 0000000..e5005da
--- /dev/null
+++ b/tests/language_2/extension_methods/static_extension_setter_getter_assignability_error_test.dart
@@ -0,0 +1,29 @@
+// 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=extension-methods
+
+// It is an error to have a setter and a getter in an extension where
+// the return type of the getter is not assignable to the argument type
+// of the setter.
+extension E1 on int {
+  static int get property => 1;
+  //     ^^
+  // [cfe] unspecified
+  //             ^^^^^^^^
+  // [analyzer] STATIC_WARNING.MISMATCHED_GETTER_AND_SETTER_TYPES
+  static void set property(String value) {}
+  //                       ^^
+  // [cfe] unspecified
+  int get property2 => 1;
+  //  ^^
+  // [cfe] unspecified
+  //      ^^^^^^^^^
+  // [analyzer] STATIC_WARNING.MISMATCHED_GETTER_AND_SETTER_TYPES
+  void set property2(String x) {}
+  //                 ^^
+  // [cfe] unspecified
+}
+
+void main() {}
\ No newline at end of file
diff --git a/tests/language_2/extension_methods/static_extension_syntax_test.dart b/tests/language_2/extension_methods/static_extension_syntax_test.dart
index 2e6c811..1ab928a 100644
--- a/tests/language_2/extension_methods/static_extension_syntax_test.dart
+++ b/tests/language_2/extension_methods/static_extension_syntax_test.dart
@@ -71,13 +71,13 @@
 
   Expect.equals(0, object.e19);
   Expect.equals(19, recs.e19);
-  Expect.type<RecSolution>(recs.list19);
-  checkStaticType<RecSolution>(recs.list19);
+  Expect.type<List<RecSolution>>(recs.list19);
+  checkStaticType<List<RecSolution>>(recs.list19);
 
   Expect.equals(0, object.e20);
   Expect.equals(20, recs.e20);
-  Expect.type<RecSolution>(recs.list20);
-  checkStaticType<RecSolution>(recs.list20);
+  Expect.type<List<RecSolution>>(recs.list20);
+  checkStaticType<List<RecSolution>>(recs.list20);
 }
 
 extension on Object {
diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status
index f23a8de..eb9a51e 100644
--- a/tests/language_2/language_2_dartdevc.status
+++ b/tests/language_2/language_2_dartdevc.status
@@ -30,6 +30,10 @@
 const_cast2_test/01: CompileTimeError
 const_cast2_test/none: CompileTimeError
 const_constructor3_test/04: MissingCompileTimeError # Side-effect of working around issue 33441 for int-to-double
+const_double_in_int_op_test/dd6: Skip # Triple shift
+const_double_in_int_op_test/di6: Skip # Triple shift
+const_double_in_int_op_test/id6: Skip # Triple shift
+const_double_in_int_op_test/ii6: Skip # Triple shift
 covariant_override/tear_off_type_test: RuntimeError # Issue 28395
 covariant_subtyping_with_mixin_test: CompileTimeError # Issue 34329
 deferred_load_library_wrong_args_test/01: MissingRuntimeError, RuntimeError # Issue 29920
diff --git a/tests/language_2/language_2_spec_parser.status b/tests/language_2/language_2_spec_parser.status
index 1c7952a..28ae988 100644
--- a/tests/language_2/language_2_spec_parser.status
+++ b/tests/language_2/language_2_spec_parser.status
@@ -13,6 +13,7 @@
 deep_nesting_expression_test: Skip # JVM stack overflow.
 deep_nesting_statement_test: Skip # JVM stack overflow.
 double_invalid_test: Skip # Contains illegaly formatted double.
+extension_methods: Skip # Not yet supported.
 external_test/21: Fail # Test expects `runtime error`, it is a syntax error.
 getter_declaration_negative_test: Fail # Negative, uses getter with parameter.
 inst_field_initializer1_negative_test: Skip # Negative, not syntax.
@@ -34,7 +35,8 @@
 new_expression1_negative_test: Fail # Negative, uses `new id`.
 new_expression2_negative_test: Fail # Negative, uses `new id(`.
 new_expression3_negative_test: Fail # Negative, uses `new id(...`.
-nnbd/*: Skip # Not yet included.
+nnbd/syntax/opt_out_nnbd_modifiers_test: Skip # Requires opt-out of NNBD.
+nnbd/syntax/pre_nnbd_modifiers_test: Skip # Requires opt-out of NNBD.
 no_such_method_negative_test: Skip # Negative, not syntax.
 non_const_super_negative_test: Skip # Negative, not syntax.
 operator1_negative_test: Fail # Negative, declares static operator.
@@ -65,4 +67,3 @@
 unary_plus_negative_test: Fail # Negative, uses non-existing unary plus.
 vm/debug_break_enabled_vm_test/01: Fail # Uses debug break.
 vm/debug_break_enabled_vm_test/none: Fail # Uses debug break.
-void/void_type_function_types_test: Skip # Not yet supported.
diff --git a/tests/language_2/mock_writable_final_field_test.dart b/tests/language_2/mock_writable_final_field_test.dart
index 88919a9..d8a68f7 100644
--- a/tests/language_2/mock_writable_final_field_test.dart
+++ b/tests/language_2/mock_writable_final_field_test.dart
@@ -24,6 +24,16 @@
   final int x = 42;
 }
 
+class _Baz implements Foo {
+  final int x = 42;
+
+  noSuchMethod(Invocation i) {
+    var expected = i.isGetter ? #x : const Symbol("x=");
+    Expect.equals(expected.toString(), i.memberName.toString());
+    values.add(i.positionalArguments[0]);
+  }
+}
+
 void main() {
   {
     Bar b = new Bar();
@@ -40,4 +50,12 @@
     Expect.listEquals([123], values);
     values.clear();
   }
+  {
+    // It works the same if the noSuchMethod is defined directly in the class.
+    Foo b = new _Baz();
+    Expect.equals(b.x, 42);
+    b.x = 123;
+    Expect.listEquals([123], values);
+    values.clear();
+  }
 }
diff --git a/tests/language_2/nnbd/static_errors/this_reference_in_late_field_test.dart b/tests/language_2/nnbd/static_errors/this_reference_in_late_field_test.dart
index 84c36f4..0493a27 100644
--- a/tests/language_2/nnbd/static_errors/this_reference_in_late_field_test.dart
+++ b/tests/language_2/nnbd/static_errors/this_reference_in_late_field_test.dart
@@ -11,5 +11,5 @@
 
 class C {
   var x = this; //# 00: compile-time error
-  late x = this; //# 01: ok
+  late var x = this; //# 01: ok
 }
diff --git a/tests/language_2/nnbd/static_errors/unchecked_use_of_nullable_test.dart b/tests/language_2/nnbd/static_errors/unchecked_use_of_nullable_test.dart
index caa0b7e..b30ce5d 100644
--- a/tests/language_2/nnbd/static_errors/unchecked_use_of_nullable_test.dart
+++ b/tests/language_2/nnbd/static_errors/unchecked_use_of_nullable_test.dart
@@ -219,7 +219,7 @@
   _null + 4; //# 165: compile-time error
   -_null; //# 169: compile-time error
   _null++; //# 170: compile-time error
-  ++null; //# 171: compile-time error
+  ++_null; //# 171: compile-time error
   _null..isEven; //# 172: compile-time error
   _null[3]; //# 170: compile-time error
   _null[3] = 0; //# 171: compile-time error
diff --git a/tests/language_2/nnbd/syntax/class_member_declarations_test.dart b/tests/language_2/nnbd/syntax/class_member_declarations_test.dart
new file mode 100644
index 0000000..21553d7
--- /dev/null
+++ b/tests/language_2/nnbd/syntax/class_member_declarations_test.dart
@@ -0,0 +1,80 @@
+// 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=non-nullable
+
+class A {
+  static late x1; //# 01: syntax error
+  static late final x2;
+  static late int x3;
+  static late final A x4;
+  static late x5 = 0; //# 02: syntax error
+  static late final x6 = 0;
+  static late int x7 = 0;
+  static late final A? x8 = null;
+
+  static final late x9; //# 03: syntax error
+  static final late A x10; //# 04: syntax error
+  static final late x11 = 0; //# 05: syntax error
+  static final late A x12 = null; //# 06: syntax error
+
+  covariant late var x13;
+  covariant late var x14 = '';
+  covariant late x15; //# 07: syntax error
+  covariant late x16 = ''; //# 08: syntax error
+
+  late covariant var x17; //# 09: syntax error
+  late covariant var x18 = '';  //# 10: syntax error
+  late covariant x19; //# 11: syntax error
+  late covariant x20 = ''; //# 12: syntax error
+
+  covariant var late x21; //# 13: syntax error
+  covariant var late x22 = '';  //# 14: syntax error
+
+  covariant late double x23;
+  covariant late String x24 = '';
+
+  covariant double late x23; //# 15: syntax error
+  covariant String late x24 = ''; //# 16: syntax error
+
+  late x25; //# 17: syntax error
+  late final x26;
+  late int x27;
+  late final A x28;
+  late x29 = 0; //# 18: syntax error
+  late final x30 = 0;
+  late int x31 = 0;
+  late final A? x32 = null;
+
+  final late x33; //# 19: syntax error
+  int late x34; //# 20: syntax error
+  var late x35; //# 21: syntax error
+  final late A x36; //# 22: syntax error
+  final late x37 = 0; //# 23: syntax error
+  int late x38 = 0; //# 24: syntax error
+  var late x39 = 0; //# 25: syntax error
+  final late A? x40 = null; //# 26: syntax error
+
+  List foo() {
+    final x41 = true;
+    late final x42;
+    late final x43 = [], x44 = {};
+    return x43;
+  }
+}
+
+abstract class B {
+  m1(int some, regular, covariant parameters, {
+      required p1,
+      // required p2 = null, // Likely intended to be an error.
+      required covariant p3,
+      required covariant int p4,
+  });
+}
+
+main() {
+  A? a;
+  String? s = '';
+  a?..foo().length..x27 = s!..toString().length;
+}
diff --git a/tests/language_2/nnbd/syntax/late_modifier_error_test.dart b/tests/language_2/nnbd/syntax/late_modifier_error_test.dart
index 5fd1289..2e1e994 100644
--- a/tests/language_2/nnbd/syntax/late_modifier_error_test.dart
+++ b/tests/language_2/nnbd/syntax/late_modifier_error_test.dart
@@ -6,15 +6,15 @@
 
 // Invalid uses of "late" modifier
 
-late //# 01: compile-time error
+late //# 01: syntax error
 int f1(
   late //# 02: compile-time error
   int x
 ) {}
 
-late //# 03: compile-time error
+late //# 03: syntax error
 class C1 {
-  late //# 04: compile-time error
+  late //# 04: syntax error
   int m() {}
 }
 
diff --git a/tests/language_2/nnbd/syntax/non_null_assertion_test.dart b/tests/language_2/nnbd/syntax/non_null_assertion_test.dart
index e9c2717..265dfed 100644
--- a/tests/language_2/nnbd/syntax/non_null_assertion_test.dart
+++ b/tests/language_2/nnbd/syntax/non_null_assertion_test.dart
@@ -70,6 +70,6 @@
   });
 
   int i = 0;
-  var x13 = [i++!]; // ignore: unnecessary_non_null_assertion
+  var x13 = [(i++)!]; // ignore: unnecessary_non_null_assertion
   listOfObject = x13;
 }
diff --git a/tests/language_2/nnbd/syntax/nullable_type_error_test.dart b/tests/language_2/nnbd/syntax/nullable_type_error_test.dart
index 3cd9b8f..106cf2d 100644
--- a/tests/language_2/nnbd/syntax/nullable_type_error_test.dart
+++ b/tests/language_2/nnbd/syntax/nullable_type_error_test.dart
@@ -12,12 +12,12 @@
   // The grammar for types does not allow multiple successive ? operators on a
   // type.  Note: we test both with and without a space between `?`s because the
   // scanner treats `??` as a single token.
-  int?? x1 = 0; //# 01: compile-time error
-  core.int?? x2 = 0; //# 02: compile-time error
-  List<int>?? x3 = <int>[]; //# 03: compile-time error
-  void Function()?? x4 = f; //# 04: compile-time error
-  int? ? x5 = 0; //# 05: compile-time error
-  core.int? ? x6 = 0; //# 06: compile-time error
-  List<int>? ? x7 = <int>[]; //# 07: compile-time error
-  void Function()? ? x4 = f; //# 08: compile-time error
+  int?? x1 = 0; //# 01: syntax error
+  core.int?? x2 = 0; //# 02: syntax error
+  List<int>?? x3 = <int>[]; //# 03: syntax error
+  void Function()?? x4 = f; //# 04: syntax error
+  int? ? x5 = 0; //# 05: syntax error
+  core.int? ? x6 = 0; //# 06: syntax error
+  List<int>? ? x7 = <int>[]; //# 07: syntax error
+  void Function()? ? x4 = f; //# 08: syntax error
 }
diff --git a/tests/language_2/nnbd/syntax/required_modifier_error_test.dart b/tests/language_2/nnbd/syntax/required_modifier_error_test.dart
index d471abb..6bf7395 100644
--- a/tests/language_2/nnbd/syntax/required_modifier_error_test.dart
+++ b/tests/language_2/nnbd/syntax/required_modifier_error_test.dart
@@ -6,22 +6,22 @@
 
 // Invalid uses of "required" modifier
 
-required //# 01: compile-time error
+required //# 01: syntax error
 int f1(
-  required //# 02: compile-time error
+  required //# 02: syntax error
   int x
 ) {}
 
-required //# 03: compile-time error
+required //# 03: syntax error
 class C1 {
-  required //# 04: compile-time error
+  required //# 04: syntax error
   int f2 = 0;
 }
 
 // Duplicate modifier
 void f2({
   required
-  required //# 05: compile-time error
+  required //# 05: syntax error
   int i,
 }){
 }
@@ -30,8 +30,8 @@
 class C2 {
   void m({
     required int i1,
-    covariant required int i2, //# 07: compile-time error
-    final required int i3, //# 08: compile-time error
+    covariant required int i2, //# 07: syntax error
+    final required int i3, //# 08: syntax error
   }) {
   }
 }
diff --git a/tests/language_2/vm/clamp_37868_test.dart b/tests/language_2/vm/clamp_37868_test.dart
new file mode 100755
index 0000000..181f895
--- /dev/null
+++ b/tests/language_2/vm/clamp_37868_test.dart
@@ -0,0 +1,34 @@
+// 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.
+
+// VMOptions=--deterministic
+
+import "package:expect/expect.dart";
+
+import 'dart:typed_data';
+
+// Found by "value-guided" DartFuzzing: incorrect clamping.
+// https://github.com/dart-lang/sdk/issues/37868
+@pragma("vm:never-inline")
+foo(List<int> x) => Uint8ClampedList.fromList(x);
+
+main() {
+  var x = [
+    9223372036854775807,
+    -9223372036854775808,
+    9223372032559808513,
+    -9223372032559808513,
+    5000000000,
+    -5000000000,
+    2147483647,
+    -2147483648,
+    255,
+    -255,
+  ];
+  var y = foo(x);
+  for (int i = 0; i < y.length; i += 2) {
+    Expect.equals(255, y[i]);
+    Expect.equals(0, y[i + 1]);
+  }
+}
diff --git a/tests/language_2/vm/mixin_test.dart b/tests/language_2/vm/mixin_test.dart
new file mode 100755
index 0000000..b086b73
--- /dev/null
+++ b/tests/language_2/vm/mixin_test.dart
@@ -0,0 +1,37 @@
+// 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.
+
+// Illustrates inlining heuristic issue of
+// https://github.com/dart-lang/sdk/issues/37126
+// (mixins introduce one extra depth of inlining).
+
+// VMOptions=--deterministic
+
+import "package:expect/expect.dart";
+
+class X {
+  const X();
+  int foo() {
+    return 1;
+  }
+}
+
+mixin YMixin {
+  int bar() {
+    return 2;
+  }
+}
+
+class Y with YMixin {
+  const Y();
+}
+
+@pragma("vm:never-inline")
+int foobar() {
+  return new X().foo() + new Y().bar();
+}
+
+main() {
+  Expect.equals(3, foobar());
+}
diff --git a/tests/modular/issue37523/main.dart b/tests/modular/issue37523/main.dart
deleted file mode 100644
index ecf904f..0000000
--- a/tests/modular/issue37523/main.dart
+++ /dev/null
@@ -1,15 +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.
-
-import 'package:expect/expect.dart';
-
-import 'def.dart';
-
-main() {
-  const v1 = A(B());
-  const v2 = ab;
-  const v3 = A(b);
-  Expect.equals(v1, v2);
-  Expect.equals(v2, v3);
-}
diff --git a/tests/modular/nested_constants/main.dart b/tests/modular/nested_constants/main.dart
index 6d4327c..88fedf3 100644
--- a/tests/modular/nested_constants/main.dart
+++ b/tests/modular/nested_constants/main.dart
@@ -12,4 +12,10 @@
 main() {
   Expect.equals(c1, c2);
   Expect.equals(c2, c3);
+
+  const v1 = A(B());
+  const v2 = ab;
+  const v3 = A(b);
+  Expect.equals(v1, v2);
+  Expect.equals(v2, v3);
 }
diff --git a/tests/standalone_2/io/file_system_watcher_test.dart b/tests/standalone_2/io/file_system_watcher_test.dart
index 00b6a60..492379a 100644
--- a/tests/standalone_2/io/file_system_watcher_test.dart
+++ b/tests/standalone_2/io/file_system_watcher_test.dart
@@ -4,6 +4,7 @@
 
 import "dart:async";
 import "dart:io";
+import "dart:isolate";
 
 import "package:async_helper/async_helper.dart";
 import "package:expect/expect.dart";
@@ -313,6 +314,75 @@
   dir2.renameSync(join(dir.path, 'new_dir'));
 }
 
+testWatchConsistentModifiedFile() async {
+  // When file modification starts before the watcher listen() is called and the first event
+  // happens in a very short period of time the modifying event will be missed before the
+  // stream listen has been set up and the watcher will hang forever.
+  // Bug: https://github.com/dart-lang/sdk/issues/37233
+  asyncStart();
+  ReceivePort receivePort = ReceivePort();
+  await Isolate.spawn(modifyFiles, receivePort.sendPort);
+
+  await for (var object in receivePort) {
+    if (object == 'end') {
+      receivePort.close();
+      break;
+    }
+    var sendPort = object[0];
+    var path = object[1];
+    var dir = new Directory(path);
+
+    sendPort.send('start');
+    // Delay some time to ensure that watcher is created when modification is running consistently.
+    await Future.delayed(Duration(milliseconds: 10));
+    var watcher = dir.watch();
+    var subscription;
+
+    // Wait for event and check the type
+    subscription = watcher.listen((data) {
+      if (data is FileSystemModifyEvent) {
+        Expect.isTrue(data.path.endsWith('file'));
+        subscription.cancel();
+      }
+    });
+
+    // Create a file to signal modifier isolate to stop modification and clean up temp directory.
+    var file = new File(join(dir.path, 'EventReceived'));
+    file.createSync();
+    sendPort.send('end');
+  }
+  asyncEnd();
+}
+
+void modifyFiles(SendPort sendPort) {
+  // Send sendPort back to listen for modification signal.
+  ReceivePort receivePort = ReceivePort();
+  var dir = Directory.systemTemp.createTempSync('dart_file_system_watcher');
+
+  // Create file within the directory and keep modifying.
+  var file = new File(join(dir.path, 'file'));
+  file.createSync();
+  var subscription;
+  sendPort.send([receivePort.sendPort, dir.path]);
+  subscription = receivePort.listen((data) {
+    if (data == 'end') {
+      // Clean up the directory and files
+      dir.deleteSync(recursive: true);
+      sendPort.send('end');
+      subscription.cancel();
+    } else {
+      // This signal file is created once watcher isolate receives the event.
+      var signal = new File(join(dir.path, 'EventReceived'));
+      while (!signal.existsSync()) {
+        // Start modifying the file continuously before watcher start watching.
+        for (int i = 0; i < 100; i++) {
+          file.writeAsStringSync('a');
+        }
+      }
+    }
+  });
+}
+
 void main() {
   if (!FileSystemEntity.isWatchSupported) return;
   testWatchCreateFile();
@@ -326,4 +396,5 @@
   testWatchNonRecursive();
   testWatchNonExisting();
   testWatchMoveSelf();
+  testWatchConsistentModifiedFile();
 }
diff --git a/tests/standalone_2/io/process_run_test.dart b/tests/standalone_2/io/process_run_test.dart
index cb63455..a4a470a 100644
--- a/tests/standalone_2/io/process_run_test.dart
+++ b/tests/standalone_2/io/process_run_test.dart
@@ -5,6 +5,7 @@
 import 'dart:io';
 
 import "package:expect/expect.dart";
+import "package:path/path.dart" as path;
 
 import "process_test_util.dart";
 
@@ -26,6 +27,37 @@
   Expect.isTrue(result.stderr is List<int>);
 }
 
+void testProcessPathWithSpace() {
+  // Bug: https://github.com/dart-lang/sdk/issues/37751
+  var processTest = new File(getProcessTestFileName());
+  var dir = Directory.systemTemp.createTempSync('process_run_test');
+  try {
+    File(path.join(dir.path, 'path')).createSync();
+    var innerDir = Directory(path.join(dir.path, 'path with space'));
+    innerDir.createSync();
+    processTest = processTest.copySync(path.join(
+        innerDir.path, 'process_run_test${getPlatformExecutableExtension()}'));
+    // It will run executables without throwing exception.
+    var result = Process.runSync(processTest.path, []);
+    // Kill the isolate because next test reuse the exe file.
+    Process.killPid(result.pid);
+    // Manually escape the path
+    if (Platform.isWindows) {
+      result = Process.runSync('"${processTest.path}"', []);
+      Process.killPid(result.pid);
+    }
+    result = Process.runSync('${processTest.path}', []);
+    Process.killPid(result.pid);
+  } catch (e) {
+    Expect.fail('System should find process_run_test executable');
+    print(e);
+  } finally {
+    // Clean up the temp files and directory
+    dir.deleteSync(recursive: true);
+  }
+}
+
 void main() {
   testProcessRunBinaryOutput();
+  testProcessPathWithSpace();
 }
diff --git a/tools/VERSION b/tools/VERSION
index a5d8aa2..69ff003 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -33,7 +33,7 @@
 MAJOR 2
 MINOR 5
 PATCH 0
-PRERELEASE 2
-PRERELEASE_PATCH 1
+PRERELEASE 3
+PRERELEASE_PATCH 0
 ABI_VERSION 11
 OLDEST_SUPPORTED_ABI_VERSION 11
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index da9071a..f713ade 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -30,6 +30,7 @@
       "tests/angular/",
       "tests/co19_2/co19_2-analyzer.status",
       "tests/co19_2/co19_2-dart2js.status",
+      "tests/co19_2/co19_2-dartdevc.status",
       "tests/co19_2/co19_2-kernel.status",
       "tests/co19_2/co19_2-runtime.status",
       "tests/compiler/",
@@ -70,6 +71,7 @@
       "tests/angular/",
       "tests/co19_2/co19_2-analyzer.status",
       "tests/co19_2/co19_2-dart2js.status",
+      "tests/co19_2/co19_2-dartdevc.status",
       "tests/co19_2/co19_2-kernel.status",
       "tests/co19_2/co19_2-runtime.status",
       "tests/compiler/",
@@ -107,6 +109,7 @@
       "tests/angular/",
       "tests/co19_2/co19_2-analyzer.status",
       "tests/co19_2/co19_2-dart2js.status",
+      "tests/co19_2/co19_2-dartdevc.status",
       "tests/co19_2/co19_2-kernel.status",
       "tests/co19_2/co19_2-runtime.status",
       "tests/compiler/",
@@ -205,6 +208,7 @@
       "tests/angular/",
       "tests/co19_2/co19_2-analyzer.status",
       "tests/co19_2/co19_2-dart2js.status",
+      "tests/co19_2/co19_2-dartdevc.status",
       "tests/co19_2/co19_2-kernel.status",
       "tests/co19_2/co19_2-runtime.status",
       "tests/compiler/",
diff --git a/tools/bots/try_benchmarks.sh b/tools/bots/try_benchmarks.sh
index e30eeb2..ca38187 100755
--- a/tools/bots/try_benchmarks.sh
+++ b/tools/bots/try_benchmarks.sh
@@ -84,6 +84,8 @@
     tar -czf linux-ia32_profile.tar.gz \
       --exclude .git \
       --exclude .gitignore \
+      --exclude pkg/analysis_server/language_model \
+      --exclude out/ReleaseIA32/dart-sdk/model \
       -- \
       third_party/d8/linux/ia32/natives_blob.bin \
       third_party/d8/linux/ia32/snapshot_blob.bin \
@@ -167,6 +169,8 @@
     tar -czf linux-ia32.tar.gz \
       --exclude .git \
       --exclude .gitignore \
+      --exclude pkg/analysis_server/language_model \
+      --exclude out/ReleaseIA32/dart-sdk/model \
       -- \
       third_party/d8/linux/ia32/natives_blob.bin \
       third_party/d8/linux/ia32/snapshot_blob.bin \
@@ -239,16 +243,13 @@
     ./tools/build.py --mode=release --arch=x64 runtime
     ./tools/build.py --mode=release --arch=x64 gen_snapshot
     ./tools/build.py --mode=release --arch=x64 dart_precompiled_runtime
-    ./tools/build.py --mode=release --arch=simdbc64 runtime
   elif [ "$command" = linux-x64-archive ] ||
        [ "$command" = linux-x64-bytecode-archive ]; then
-    simdbc_dart=out/ReleaseSIMDBC64/dart
-    if [ "$command" = linux-x64-bytecode-archive ]; then
-      simdbc_dart=
-    fi
     tar -czf linux-x64_profile.tar.gz \
       --exclude .git \
       --exclude .gitignore \
+      --exclude pkg/analysis_server/language_model \
+      --exclude out/ReleaseX64/dart-sdk/model \
       -- \
       third_party/d8/linux/x64/natives_blob.bin \
       third_party/d8/linux/x64/snapshot_blob.bin \
@@ -256,7 +257,6 @@
       out/ReleaseX64/vm_platform_strong.dill \
       out/ReleaseX64/gen/kernel_service.dill \
       out/ReleaseX64/dart-sdk \
-      $simdbc_dart \
       out/ReleaseX64/dart \
       out/ReleaseX64/gen_snapshot \
       out/ReleaseX64/gen_kernel_bytecode.dill \
@@ -352,6 +352,8 @@
     tar -czf linux-x64.tar.gz \
       --exclude .git \
       --exclude .gitignore \
+      --exclude pkg/analysis_server/language_model \
+      --exclude out/ReleaseX64/dart-sdk/model \
       -- \
       third_party/d8/linux/x64/natives_blob.bin \
       third_party/d8/linux/x64/snapshot_blob.bin \
@@ -359,7 +361,6 @@
       out/ReleaseX64/vm_platform_strong.dill \
       out/ReleaseX64/gen/kernel_service.dill \
       out/ReleaseX64/dart-sdk \
-      $simdbc_dart \
       out/ReleaseX64/dart \
       out/ReleaseX64/gen_snapshot \
       out/ReleaseX64/gen_kernel_bytecode.dill \
@@ -395,9 +396,6 @@
     out/ReleaseX64/dart --profile-period=10000 --packages=.packages --enable-interpreter --compilation-counter-threshold=-1 hello.dart
     out/ReleaseX64/dart --profile-period=10000 --packages=.packages --use-bytecode-compiler hello.dart
     out/ReleaseX64/dart --profile-period=10000 --packages=.packages --use-bytecode-compiler --optimization-counter-threshold=-1 hello.dart
-    if [ "$command" = linux-x64-benchmark ]; then
-      out/ReleaseSIMDBC64/dart --profile-period=10000 --packages=.packages hello.dart
-    fi
     out/ReleaseX64/dart pkg/front_end/tool/perf.dart parse hello.dart
     out/ReleaseX64/dart pkg/front_end/tool/perf.dart scan hello.dart
     out/ReleaseX64/dart pkg/front_end/tool/fasta_perf.dart --legacy kernel_gen_e2e hello.dart
diff --git a/tools/dom/docs/docs.json b/tools/dom/docs/docs.json
index 7055e99..c827d9a 100644
--- a/tools/dom/docs/docs.json
+++ b/tools/dom/docs/docs.json
@@ -4335,7 +4335,7 @@
         ],
         "statusText": [
           "/**",
-          "   * The request response string (such as \\\"200 OK\\\").",
+          "   * The request response string (such as \\\"OK\\\").",
           "   * See also: [HTTP Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)",
           "   */"
         ],
diff --git a/tools/dom/templates/html/impl/impl_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate
index 2786eee..8783228 100644
--- a/tools/dom/templates/html/impl/impl_Element.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Element.darttemplate
@@ -1492,28 +1492,28 @@
 
   final Element offsetParent;
 
-  int get offsetHeight => JS('num', '#.offsetHeight', this).round();
+  int get offsetHeight => JS<num>('num', '#.offsetHeight', this).round();
 
-  int get offsetLeft => JS('num', '#.offsetLeft', this).round();
+  int get offsetLeft => JS<num>('num', '#.offsetLeft', this).round();
 
-  int get offsetTop => JS('num', '#.offsetTop', this).round();
+  int get offsetTop => JS<num>('num', '#.offsetTop', this).round();
 
-  int get offsetWidth => JS('num', '#.offsetWidth', this).round();
+  int get offsetWidth => JS<num>('num', '#.offsetWidth', this).round();
 
-  int get scrollHeight => JS('num', '#.scrollHeight', this).round();
-  int get scrollLeft => JS('num', '#.scrollLeft', this).round();
+  int get scrollHeight => JS<num>('num', '#.scrollHeight', this).round();
+  int get scrollLeft => JS<num>('num', '#.scrollLeft', this).round();
 
   set scrollLeft(int value) {
     JS("void", "#.scrollLeft = #", this, value.round());
   }
 
-  int get scrollTop => JS('num', '#.scrollTop', this).round();
+  int get scrollTop => JS<num>('num', '#.scrollTop', this).round();
 
   set scrollTop(int value) {
     JS("void", "#.scrollTop = #", this, value.round());
   }
 
-  int get scrollWidth => JS('num', '#.scrollWidth', this).round();
+  int get scrollWidth => JS<num>('num', '#.scrollWidth', this).round();
 
 $!MEMBERS
 }
diff --git a/tools/dom/templates/html/impl/impl_Touch.darttemplate b/tools/dom/templates/html/impl/impl_Touch.darttemplate
index ef3b5c2..2d84399 100644
--- a/tools/dom/templates/html/impl/impl_Touch.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Touch.darttemplate
@@ -9,14 +9,14 @@
 
 // As of Chrome 37, these all changed from long to double.  This code
 // preserves backwards compatibility for the time being.
-  int get __clientX => JS('num', '#.clientX', this).round();
-  int get __clientY => JS('num', '#.clientY', this).round();
-  int get __screenX => JS('num', '#.screenX', this).round();
-  int get __screenY => JS('num', '#.screenY', this).round();
-  int get __pageX => JS('num', '#.pageX', this).round();
-  int get __pageY => JS('num', '#.pageY', this).round();
-  int get __radiusX => JS('num', '#.radiusX', this).round();
-  int get __radiusY => JS('num', '#.radiusY', this).round();
+  int get __clientX => JS<num>('num', '#.clientX', this).round();
+  int get __clientY => JS<num>('num', '#.clientY', this).round();
+  int get __screenX => JS<num>('num', '#.screenX', this).round();
+  int get __screenY => JS<num>('num', '#.screenY', this).round();
+  int get __pageX => JS<num>('num', '#.pageX', this).round();
+  int get __pageY => JS<num>('num', '#.pageY', this).round();
+  int get __radiusX => JS<num>('num', '#.radiusX', this).round();
+  int get __radiusY => JS<num>('num', '#.radiusY', this).round();
 
   Point get client => new Point(__clientX, __clientY);
 
diff --git a/tools/dom/templates/html/impl/impl_Window.darttemplate b/tools/dom/templates/html/impl/impl_Window.darttemplate
index ec7d83c..9553f4a 100644
--- a/tools/dom/templates/html/impl/impl_Window.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Window.darttemplate
@@ -129,7 +129,7 @@
   void _cancelAnimationFrame(int id) native;
 
   _ensureRequestAnimationFrame() {
-    if (JS('bool',
+    if (JS<bool>('bool',
            '!!(#.requestAnimationFrame && #.cancelAnimationFrame)', this, this))
       return;
 
@@ -241,9 +241,9 @@
     return db;
   }
 
-  int get pageXOffset => JS('num', '#.pageXOffset', this).round();
+  int get pageXOffset => JS<num>('num', '#.pageXOffset', this).round();
 
-  int get pageYOffset => JS('num', '#.pageYOffset', this).round();
+  int get pageYOffset => JS<num>('num', '#.pageYOffset', this).round();
 
   /**
    * The distance this window has been scrolled horizontally.
@@ -255,8 +255,8 @@
    * * [scrollX](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX)
    *   from MDN.
    */
-  int get scrollX => JS('bool', '("scrollX" in #)', this) ?
-      JS('num', '#.scrollX', this).round() :
+  int get scrollX => JS<bool>('bool', '("scrollX" in #)', this) ?
+      JS<num>('num', '#.scrollX', this).round() :
       document.documentElement.scrollLeft;
 
   /**
@@ -269,8 +269,8 @@
    * * [scrollY](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY)
    *   from MDN.
    */
-  int get scrollY => JS('bool', '("scrollY" in #)', this) ?
-      JS('num', '#.scrollY', this).round() :
+  int get scrollY => JS<bool>('bool', '("scrollY" in #)', this) ?
+      JS<num>('num', '#.scrollY', this).round() :
       document.documentElement.scrollTop;
 }
 
@@ -285,7 +285,7 @@
     _returnValue = value;
     // FF and IE use the value as the return value, Chrome will return this from
     // the event callback function.
-    if (JS('bool', '("returnValue" in #)', wrapped)) {
+    if (JS<bool>('bool', '("returnValue" in #)', wrapped)) {
       JS('void', '#.returnValue = #', wrapped, value);
     }
   }
diff --git a/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate b/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
index c15f496..36af958 100644
--- a/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
+++ b/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
@@ -17,13 +17,11 @@
   * and prints its length:
   *
   *     var path = 'myData.json';
-  *     HttpRequest.getString(path)
-  *         .then((String fileContents) {
-  *           print(fileContents.length);
-  *         })
-  *         .catchError((Error error) {
-  *           print(error.toString());
-  *         });
+  *     HttpRequest.getString(path).then((String fileContents) {
+  *       print(fileContents.length);
+  *     }).catchError((error) {
+  *       print(error.toString());
+  *     });
   *
   * ## Fetching data from other servers
   *
diff --git a/tools/experimental_features.yaml b/tools/experimental_features.yaml
index 6d4fdb3..ce25f88 100644
--- a/tools/experimental_features.yaml
+++ b/tools/experimental_features.yaml
@@ -70,10 +70,6 @@
 # a warning that the experiment has been retired or rejected, but the tool
 # should continue to run.
 
-constant-update-2018:
-  help: "Enhanced constant expressions"
-  enabledIn: '2.4.1'
-
 extension-methods:
   help: "Extension Methods"
 
@@ -88,6 +84,11 @@
 # on the command line, and will eventually be removed.
 #
 
+constant-update-2018:
+  help: "Enhanced constant expressions"
+  enabledIn: '2.4.1'
+  expired: true
+
 control-flow-collections:
   help: "Control Flow Collections"
   enabledIn: '2.2.2'
diff --git a/tools/make_version.py b/tools/make_version.py
index 8c11cb3..184699d 100755
--- a/tools/make_version.py
+++ b/tools/make_version.py
@@ -55,6 +55,17 @@
         else:
             git_hash = utils.GetShortGitHash()
             version_string = ("%s.%s-%s" % (latest, custom_for_pub, git_hash))
+        # TODO(athom): remove the custom 2.5.0 logic post release.
+        # For 2.5.0, we want flutter to claim Dart is 2.5.0 even before it is
+        # decided what exactly 2.5.0 will be. Dart & Flutter stable releases
+        # will be synced, so that what will be released as Dart 2.5.0 will also
+        # be what will be packaged with Flutter.
+        version = utils.ReadVersionFile()
+        custom_version_string = "%s.%s.%s" % (version.major, version.minor, version.patch)
+        if custom_version_string == "2.5.0" and custom_for_pub == "flutter":
+            version_string = "2.5.0"
+
+
     else:
         version_string = utils.GetSemanticSDKVersion(no_git_hash=no_git_hash)
     if not quiet:
diff --git a/tools/spec_parser/Dart.g b/tools/spec_parser/Dart.g
index dd71d27..23a8f91 100644
--- a/tools/spec_parser/Dart.g
+++ b/tools/spec_parser/Dart.g
@@ -149,11 +149,13 @@
     |    setterSignature functionBody
     |    functionSignature functionBody
     |    (FINAL | CONST) type? staticFinalDeclarationList ';'
+    |    LATE FINAL type? initializedIdentifierList ';'
     |    topLevelVariableDeclaration ';'
     ;
 
 topLevelVariableDeclaration
-    :    varOrType identifier ('=' expression)? (',' initializedIdentifier)*
+    :    LATE? varOrType identifier ('=' expression)?
+         (',' initializedIdentifier)*
     ;
 
 declaredIdentifier
@@ -161,9 +163,9 @@
     ;
 
 finalConstVarOrType
-    :    FINAL type?
+    :    LATE? FINAL type?
     |    CONST type?
-    |    varOrType
+    |    LATE? varOrType
     ;
 
 varOrType
@@ -207,15 +209,16 @@
 
 formalParameterList
     :    '(' ')'
-    |    '(' normalFormalParameters (','? | ',' optionalFormalParameters) ')'
-    |    '(' optionalFormalParameters ')'
+    |    '(' normalFormalParameters ','? ')'
+    |    '(' normalFormalParameters ',' optionalOrNamedFormalParameters ')'
+    |    '(' optionalOrNamedFormalParameters ')'
     ;
 
 normalFormalParameters
     :    normalFormalParameter (',' normalFormalParameter)*
     ;
 
-optionalFormalParameters
+optionalOrNamedFormalParameters
     :    optionalPositionalFormalParameters
     |    namedFormalParameters
     ;
@@ -240,7 +243,7 @@
 
 // NB: It is an anomaly that a functionFormalParameter cannot be FINAL.
 functionFormalParameter
-    :    COVARIANT? type? identifierNotFUNCTION formalParameterPart
+    :    COVARIANT? type? identifierNotFUNCTION formalParameterPart '?'?
     ;
 
 simpleFormalParameter
@@ -258,7 +261,7 @@
     ;
 
 defaultNamedParameter
-    :    normalFormalParameter ((':' | '=') expression)?
+    :    REQUIRED? normalFormalParameter ((':' | '=') expression)?
     ;
 
 typeWithParameters
@@ -324,11 +327,12 @@
     |    EXTERNAL constructorSignature
     |    (EXTERNAL STATIC?)? getterSignature
     |    (EXTERNAL STATIC?)? setterSignature
+    |    (EXTERNAL STATIC?)? functionSignature
     |    EXTERNAL? operatorSignature
     |    STATIC (FINAL | CONST) type? staticFinalDeclarationList
-    |    FINAL type? initializedIdentifierList
-    |    (STATIC | COVARIANT)? (VAR | type) initializedIdentifierList
-    |    EXTERNAL? STATIC? functionSignature
+    |    STATIC LATE FINAL type? initializedIdentifierList
+    |    (STATIC | COVARIANT) LATE? varOrType initializedIdentifierList
+    |    LATE? (FINAL type? | varOrType) initializedIdentifierList
     |    redirectingFactoryConstructorSignature
     |    constantConstructorSignature (redirection | initializers)?
     |    constructorSignature (redirection | initializers)?
@@ -394,7 +398,7 @@
     ;
 
 fieldInitializer
-    :    (THIS '.')? identifier '=' conditionalExpression cascadeSection*
+    :    (THIS '.')? identifier '=' conditionalExpression cascadeSequence?
     ;
 
 factoryConstructorSignature
@@ -455,7 +459,7 @@
     :    functionExpression
     |    throwExpression
     |    assignableExpression assignmentOperator expression
-    |    conditionalExpression cascadeSection*
+    |    conditionalExpression cascadeSequence?
     ;
 
 expressionWithoutCascade
@@ -623,11 +627,21 @@
     :    label expression
     ;
 
+cascadeSequence
+    :     ('?..' | '..') cascadeSection ('..' cascadeSection)*
+    ;
+
 cascadeSection
-    :    '..'
-         (cascadeSelector argumentPart*)
-         (assignableSelector argumentPart*)*
-         (assignmentOperator expressionWithoutCascade)?
+    :    cascadeSelector cascadeSectionTail
+    ;
+
+cascadeSectionTail
+    :    cascadeAssignment
+    |    selector* (assignableSelector cascadeAssignment)?
+    ;
+
+cascadeAssignment
+    :    assignmentOperator expressionWithoutCascade
     ;
 
 cascadeSelector
@@ -795,7 +809,8 @@
     ;
 
 selector
-    :    assignableSelector
+    :    '!'
+    |    assignableSelector
     |    argumentPart
     ;
 
@@ -810,13 +825,13 @@
 
 assignableExpression
     :    SUPER unconditionalAssignableSelector
-    |    constructorInvocation assignableSelectorPart+
-    |    primary assignableSelectorPart+
+    |    constructorInvocation assignableSelectorPart
+    |    primary assignableSelectorPart
     |    identifier
     ;
 
 assignableSelectorPart
-    :    argumentPart* assignableSelector
+    :    selector* assignableSelector
     ;
 
 unconditionalAssignableSelector
@@ -827,6 +842,7 @@
 assignableSelector
     :    unconditionalAssignableSelector
     |    '?.' identifier
+    |    '?.[' expression ']'
     ;
 
 identifierNotFUNCTION
@@ -847,6 +863,7 @@
     |    MIXIN // Built-in identifier.
     |    OPERATOR // Built-in identifier.
     |    PART // Built-in identifier.
+    |    REQUIRED // Built-in identifier.
     |    SET // Built-in identifier.
     |    STATIC // Built-in identifier.
     |    TYPEDEF // Built-in identifier.
@@ -1095,24 +1112,23 @@
     ;
 
 type
-    :    functionTypeTails
-    |    typeNotFunction functionTypeTails
+    :    functionType '?'?
     |    typeNotFunction
     ;
 
+typeNotVoid
+    :    functionType '?'?
+    |    typeNotVoidNotFunction
+    ;
+
 typeNotFunction
     :    typeNotVoidNotFunction
     |    VOID
     ;
 
-typeNotVoid
-    :    functionType
-    |    typeNotVoidNotFunction
-    ;
-
 typeNotVoidNotFunction
-    :    typeName typeArguments?
-    |    FUNCTION
+    :    typeName typeArguments? '?'?
+    |    FUNCTION '?'?
     ;
 
 typeName
@@ -1150,7 +1166,7 @@
     ;
 
 functionTypeTails
-    :    functionTypeTail functionTypeTails
+    :    functionTypeTail '?'? functionTypeTails
     |    functionTypeTail
     ;
 
@@ -1185,7 +1201,11 @@
     ;
 
 namedParameterTypes
-    :    LBRACE typedIdentifier (',' typedIdentifier)* ','? RBRACE
+    :    LBRACE namedParameterType (',' namedParameterType)* ','? RBRACE
+    ;
+
+namedParameterType
+    :    REQUIRED? typedIdentifier
     ;
 
 typedIdentifier
@@ -1260,6 +1280,14 @@
     :    'final'
     ;
 
+LATE
+    :    'late'
+    ;
+
+REQUIRED
+    :    'required'
+    ;
+
 CONST
     :    'const'
     ;
diff --git a/utils/bazel/kernel_worker.dart b/utils/bazel/kernel_worker.dart
index d13bb1a..e34fc7b 100644
--- a/utils/bazel/kernel_worker.dart
+++ b/utils/bazel/kernel_worker.dart
@@ -139,6 +139,7 @@
   ..addOption('output')
   ..addFlag('reuse-compiler-result', defaultsTo: false)
   ..addFlag('use-incremental-compiler', defaultsTo: false)
+  ..addOption('used-inputs')
   ..addFlag('track-widget-creation', defaultsTo: false)
   ..addMultiOption('enable-experiment',
       help: 'Enable a language experiment when invoking the CFE.');
@@ -242,6 +243,7 @@
 
   fe.InitializedCompilerState state;
   bool usingIncrementalCompiler = false;
+  bool recordUsedInputs = parsedArgs["used-inputs"] != null;
   if (parsedArgs['use-incremental-compiler'] &&
       linkedInputs.isEmpty &&
       isWorker) {
@@ -264,7 +266,8 @@
         target,
         fileSystem,
         (parsedArgs['enable-experiment'] as List<String>),
-        summaryOnly);
+        summaryOnly,
+        trackNeededDillLibraries: recordUsedInputs);
   } else {
     state = await fe.initializeCompiler(
         // TODO(sigmund): pass an old state once we can make use of it.
@@ -285,11 +288,29 @@
   }
 
   List<int> kernel;
+  bool wroteUsedDills = false;
   if (usingIncrementalCompiler) {
     state.options.onDiagnostic = onDiagnostic;
     Component incrementalComponent = await state.incrementalCompiler
         .computeDelta(entryPoints: sources, fullComponent: true);
 
+    if (recordUsedInputs) {
+      Set<Uri> usedOutlines = {};
+      for (Library lib in state.incrementalCompiler.neededDillLibraries) {
+        if (lib.importUri.scheme == "dart") continue;
+        Uri uri = state.libraryToInputDill[lib.importUri];
+        if (uri == null) {
+          throw new StateError("Library ${lib.importUri} was recorded as used, "
+              "but was not in the list of known libraries.");
+        }
+        usedOutlines.add(uri);
+      }
+      var outputUsedFile = new File(parsedArgs["used-inputs"]);
+      outputUsedFile.createSync(recursive: true);
+      outputUsedFile.writeAsStringSync(usedOutlines.join("\n"));
+      wroteUsedDills = true;
+    }
+
     kernel = await state.incrementalCompiler.context.runInContext((_) {
       if (summaryOnly) {
         incrementalComponent.uriToSource.clear();
@@ -300,7 +321,11 @@
             includeSources: false, includeOffsets: false));
       }
 
-      return Future.value(fe.serializeComponent(incrementalComponent));
+      return Future.value(fe.serializeComponent(incrementalComponent,
+          filter: excludeNonSources
+              ? (library) => sources.contains(library.importUri)
+              : null,
+          includeOffsets: true));
     });
   } else if (summaryOnly) {
     kernel = await fe.compileSummary(state, sources, onDiagnostic,
@@ -316,6 +341,15 @@
   }
   state.options.onDiagnostic = null; // See http://dartbug.com/36983.
 
+  if (!wroteUsedDills && recordUsedInputs) {
+    // The path taken didn't record inputs used: Say we used everything.
+    var outputUsedFile = new File(parsedArgs["used-inputs"]);
+    outputUsedFile.createSync(recursive: true);
+    Set<Uri> allFiles = {...summaryInputs, ...linkedInputs};
+    outputUsedFile.writeAsStringSync(allFiles.join("\n"));
+    wroteUsedDills = true;
+  }
+
   if (kernel != null) {
     var outputFile = new File(parsedArgs['output']);
     outputFile.createSync(recursive: true);
diff --git a/utils/kernel-service/BUILD.gn b/utils/kernel-service/BUILD.gn
index 846640b..9f926e3 100644
--- a/utils/kernel-service/BUILD.gn
+++ b/utils/kernel-service/BUILD.gn
@@ -31,6 +31,9 @@
     "--train",
     "file:///" + rebase_path("../../pkg/compiler/lib/src/dart2js.dart"),
   ]
+  if (dart_platform_bytecode) {
+    training_args += [ "--bytecode" ]
+  }
   output = "$root_gen_dir/kernel-service.dart.snapshot"
 }